From 01d97e4f841db7afa7b5b23594a5f6bb88937b52 Mon Sep 17 00:00:00 2001 From: Debdatta Kunda <87335885+kundadebdatta@users.noreply.github.com> Date: Mon, 23 Oct 2023 22:02:37 -0700 Subject: [PATCH] [Internal] Msdata/Direct: Refactors msdata/direct branch with latest v3 master and Cosmos.Direct Release v3.31.5 (#4152) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [Internal] Client Telemetry: Fixes tests leaking environment variables (#3517) * Adding log lines * More logs * Debugging further * Removing other builds * And more debugging * Wrong build parameters * Wrong category * Removing noise * Fixing test * Adding utils * Adding test with client telemetry enabled * Fixing leak in Client Telemetry Tests * Reenabling test * cpu monitor initialization * Adding name details * Undo another file * Updated change log and bumped up the version. (#3526) * Query: Fixes performance regression on target partition on some ORDER BY queries with continuation (#3525) * Revert performance regression caused by https://github.com/Azure/azure-cosmos-dotnet-v3/pull/1289/ * Remove irrelevant comment * Add a test for validating formatted filters for the target partition * [Internal] AI Integration: Adds SubStatusCode Information in attributes (#3533) * wip * regenerated baseline * add test * fix test Co-authored-by: Sourabh Jain * Diagnostics: Removes unused properties and reduces size (#3519) * Remove starttime and id from diagnostics string * Remove starttime and id from diagnostics string * Update xml files for trace baseline tests * Update xml files for trace baseline tests * Update xml files for trace baseline tests * Whitespaces update * Changed starttime position based on code review Co-authored-by: Matias Quaranta * [Internal] docs: Add address caches conceptual flow (#3534) * Rough draft * Some more changes * Adding a new section * Some more refinement * Some changes Lets get the feedback * Some MISC changes * Release: Adds SDK version and changelog for 3.31.2 (#3546) * Bumped SDK version and changelog * Added contracts file for 3.31.2 * [Internal] Documentation: Removes invalid comment from ReadThroughputAsync (#3516) * [Internal] nugetconfig: Removes specific overrides (#3551) * Query: Fixes partition range evaluation for spatial queries (#3495) * Initial commit * Update. * Pull/Rebase * Addressed comments. * Build fix * [Internal] Documentation: Refactors cache content on its own document (#3554) * Add cache file * Moving content away * [Internal] Emulator unit tests: Adds IdEncoding unit tests for ComputeGateway (#3556) * Adding IdEncoding unit tests for ComputeGateway * Reacting to code review feedback * Updating md files * Change Feed Processor: Adds support for Resource Tokens (#3566) * Adding rid parsing * Test * Removing dead code * Contract update * [Internal] AI integration: Refactor code how container and database name is flowing to opentelemetry module (#3532) * wip * WIP * Revert "WIP" This reverts commit 71275de54b9e67fa54a37e79d450b9597e173934. * Revert "wip" This reverts commit 586fa9865cc3f40dabd7ef90fb3e0cf499a045bc. * wip add containe and database info * redesign how container and database name information flows into opne telemetry data * test fix * fix test * fix tests * fix typos * baseline test fix Co-authored-by: Sourabh Jain * [Internal] AI Integration: Adds a new flag in DistributedTracingOptions (#3562) * add flag in diagnostic options * test fixes * rename variable * test fix * add validation * fix baseline * test fix Co-authored-by: Sourabh Jain * Query: Fixes default to BadRequestException in case of internal errors in ServiceInterop (#3399) * Don't default to BadRequestException in case of errors in ServiceInterop * Incorporate code review feedback * Fix build error * fix up failing test * [Internal] Query: Adds unit tests for Merge/Split implementation with OptimisticDirectExecution pipeline (#3510) * Added tests to test different aspects of merge/split support with OptimisticDirectExecution pipeline. Tests check for gone exception handling, pipeline switching etc. * Added gone exception simulation tests. * Added new tests and improved test infra * Removed ParalleContEvocation test. Fixed comments * Removed CreateParallelCrossPartitionPipelineStateAsync() as it is not being used anymore * Removed while loop in CreateDocumentContainerAsync() * Fixed comments. * Updated ExecuteGoneExceptionOnODEPipeline() * Added type Assert for ExecuteGoneExceptionOnODEPipeline() * Updated OptimisticDirectExecution pipeline abbreviation * Updated TestBaseline folder with new xml * Client Retry Policy: Adds HTTP timeouts with request-level cross-region retry (#3555) * Fixes to ReadThroughputAsync for databases with no provisioned throughput and null as request options * fixed failure to ReadReplaceThroughputResponseTests * Added Stream Method * Ran UpdateContract.ps1 * Encryption implemtation * Fixed spelling error * Update Microsoft.Azure.Cosmos.Encryption/src/EncryptionDatabase.cs Co-authored-by: Matias Quaranta * Variable name change * Update Microsoft.Azure.Cosmos/src/Resource/Database/Database.cs Co-authored-by: Matias Quaranta * Suggested Changes and fixes * Removed manufactured ResponseMessage + nits * Simplified PR * nits * nits * initial changes TODO: Update tests * updated tests * nits' * Ran UpdateContracts.ps1 * nits + requested changes * Delete NuGet.Config * Update Microsoft.Azure.Cosmos/src/HttpClient/CosmosHttpClientCore.cs Co-authored-by: Matias Quaranta * Update Microsoft.Azure.Cosmos/src/HttpClient/HttpTimeoutPolicy.cs Co-authored-by: Matias Quaranta * Update Microsoft.Azure.Cosmos/src/HttpClient/HttpTimeoutPolicy.cs Co-authored-by: Matias Quaranta * Update Microsoft.Azure.Cosmos/src/HttpClient/HttpTimeoutPolicy.cs Co-authored-by: Matias Quaranta * Use Cosmos Exception Factory, Simplified Tests * removed unused code * nits: removed unused code * removed unused code Co-authored-by: Matias Quaranta Co-authored-by: Nalu Tripician * Documentation: Fixes EUAP in Comments (#3579) * Query: Fixes incorrect FeedResponse.Count when result contains undefined elements (#3574) * Do not maintain an independent count on QueryResponse that can go out of sync * Add more test coverage for QueryResponse.Count * Output the correct count from CosmosElementSerializer when the input contains CosmosUndefined * Add untyped tests for CosmosUndefined * Remove commented code * removed allr eference (#3581) Co-authored-by: Sourabh Jain * Trace: Fixes Tracing/diagnostics hour-times to 24Hours (#3577) * Trace: Fixes Tracing/diagnostics hour-times to 24Hours * fixing baseline tests Co-authored-by: Matias Quaranta * AI Integration: Adds cosmetic fixes (#3576) * wip * status code int and internal and client kind activity * remove unused imports * update baselines * fix test * fixed baseline tests * fix tests * update base tetss Co-authored-by: Sourabh Jain * Query: Adds ALL Scalar Expression (#3509) * Add SqlAllScalarExpression to v3 DOM * updated generated parser files * Parsing for ALL * Added tests for ALL and baselines * Added more tests * added new test, cleanup * cleaning & fix typos * fixed typo * Added new baseline test file names to csproj file * renamed AggregateAll to AggregateSubquery to accomodate FIRST and LAST later * Added keywords for 'left' and 'right' and respective function calls * fixed bug from last commit * cleaning * replace tabs with spaces * cleaning * Release: Adds API contracts for 3.31.2-preview (#3586) * [Internal] sccignore: Adds a .sccignore file to apply an exception for artifacts configuration issues (#3589) * [Internal] PermissionTests: Adds CosmosPermissionTests Coverage (#3593) * Ensures that both Direct and Gateway connection modes are tested * Validates that container read works with PermissionMode.Read (test was previously only validating that Delete was blocked - i.e. the negative case). * [Internal] AI Integration: Refactors to Operation prefix and add tests (#3583) * add tests for otel and custome listener * clean up * null pointer fix * fix tets * handle event generation also at operation level * added documentation * wip * change event sourcename * rename event Name Co-authored-by: Sourabh Jain * [Internal] HttpTimeoutPolicy: Removes Data Plane Writes from being able to be retried (#3607) * data plane writes no longer failover on timeout * removed duplication of test\ * [Internal] Performance Testing: Adds Distributed Tracing option in benchmarks (#3611) Co-authored-by: Sourabh Jain * [Internal] Benchmark: Refactors code to make Memory Stream capacity configurable (#3624) Co-authored-by: Sourabh Jain * add new LatestVersion changefeed mode that has same behavior as Incremental; renamed FullFidelity to AllVersionsAndDeletes (#3596) * Query: Fixes handling of CosmosUndefined, CosmosGuid and CosmosBinary in unordered DISTINCT (#3632) * Handle CosmosUndefined, CosmosGuid and CosmosBinary in DistinctMap.UnorderedDistinctMap * Address code review feedback and remove unnecessary allocations from DistinctQueryPipelineStageTests * [Internal] Subpartitioning: Adds updates to test coverage for subpartitioning (#3618) * updates to test coverage for subpartitioning * bug fixes * now useses Assert.ThrowsException * Seperated into multiple tests for clarity * Put MultiHash test into seperate test file * nit * [Internal] ContainerProperties: Fixes version reset when setting PartitionKeyPath (#3637) * Remember previous value * test * [Internal] AI Integration: Adds CorrelationId and Activity Id Attributes for query operation (#3630) * add activityid in Otel attributes * added correlation id * operation type fix * remove test changes * test fix * fix baseline test * rename correlationId * fix tests again * include only not null attributes in test * fixed tests * changefeedxml * test fix * ordering activity in operationname oerder * fix test * review comments * refator header getter setter * clean up Co-authored-by: Sourabh Jain * Documentation: Fixes CosmosClientBuilder.WithConnectionModeGateway parameter description (#3643) * Fixed CosmosClientBuilder.WithConnectionModeGateway documentation * Update Microsoft.Azure.Cosmos/src/Fluent/CosmosClientBuilder.cs Co-authored-by: Ruben Bartelink Co-authored-by: Augsten Co-authored-by: Ruben Bartelink * Upgrade Resiliency: Refactors Implementation for Opening Rntbd Connections to Backend Replicas in Direct Mode. (#3640) * Code changes to refactor implementations for opening connections to all replicas. Fixed test failures due to Direct package upgrade. * Code changes to add poland central region as a part of Regions.cs * Code changes to update contract to reflect new regions. * Revert "Code changes to update contract to reflect new regions." This reverts commit f171b3c1c9889043556ddf96bcd33ccd79565ad9. * Revert "Code changes to add poland central region as a part of Regions.cs" This reverts commit 1aafbf18f6d80e9a92baa301b6b23cf065e4b155. * [Preview] AI integration: Adds IsDistributedTracingEnabled flag as public API to enable/disable this feature (#3598) * make api public for preview * add null check * fix tests * singleton listener initialization * assign null to listeners * fix test * concurrent bag in listener * renamed to LatencyThresholdForDiagnosticEvent * renamed to IsDistributedTracingEnabled * updated xml * update contract * made latency threshold flag internal * fix test * regeneratebaselines * update documentation * rename builder api * add docs * updated contracts and all * doc update * import cleanup Co-authored-by: Sourabh Jain * Change Feed Processor: Fixes behavior with StartTime on Local (#3645) * To UTC * Test * [Internal] Client Telemetry: Refactors code to use base useragent string (#3653) * [Internal] AI Integration: Refactors code to rename event name (#3648) * first draft * rename event name * updated xmls * update files * Region Availability: Adds Poland Central Region For Public Usage (#3656) * Client Encryption: Adds validation code to check if the Key Vault URI provided in wrap metadata is a valid key identifier. (#3642) * Check if the key vault uri provided is a valid Kid * test fix. * update changelog and build props * Update Directory.Build.props * Update Microsoft.Azure.Cosmos.Encryption.csproj * Fixed preview version * Refactor * Update EncryptionDatabaseExtensions.cs * [Internal] Query: Adds Split Support for Ode (#3572) * Added tests to test different aspects of merge/split support with OptimisticDirectExecution pipeline. Tests check for gone exception handling, pipeline switching etc. * Added gone exception simulation tests. * Added new tests and improved test infra * Removed ParalleContEvocation test. Fixed comments * Removed CreateParallelCrossPartitionPipelineStateAsync() as it is not being used anymore * Removed while loop in CreateDocumentContainerAsync() * Fixed comments. * Updated ExecuteGoneExceptionOnODEPipeline() * Added type Assert for ExecuteGoneExceptionOnODEPipeline() * Replaced try-catch with if statement in MoveNextAsync() * Added delegate to access TryCreateCoreContextAsync() * Added check to confirm Ode pipeline is not called in fallback plan * Updated method name from OptimisticDirectExecutionContext() to TryCreateOptimisticDirectExecutionContext() * Using delegate instead of Func<>. * Ode fallback plan always calls Specialized pipeline * Using ServiceInterop/Gateway to get QueryPlan for Specialized Pipeline * Added new test to check handling of failing fallback pipeline * Code cleanup * Added logic for handling non ODE continuation tokens * Moved delegate away from member variables * Added tests for Merge case * Updated method names * Added checks for tryCatch * Updated SetCancellationToken() to use Try * Updated TryUnwrapContinuationToken() * Removed changes in FlakyDocumentContainer.cs * Removed unused imports * Updated comments * Fixed comments and cleaned up test code * Added CosmosElement null check in TryUnwrapContinuationToken() * Removed FlakyDocumentContainer.cs from pull request * Removed unused imports * Updated TryUnwrapContinuationToken() * Update MoveNextAsync() call in OptimisticDirectExecutionQueryBaselineTests.cs * Made MergeTestUtil.IsFailedFallbackPipelineTest a readonly property * Added IsPartitionSplitException() overload to take CosmosElement * Fixed bug regarding syntax error queries * [Internal] AI Integration : Fixes operation type for batch (#3660) * fix op type * fix conflict * CosmosClientOptions: Adds ServerCertificateCustomValidationCallback for Http and TCP (#3636) * Adding ServerCertificateCustomValidationCallback in clientoptions * Adding Server callback for Http and fixing tests * Fixing failing E2Etests * Resolving merge conflicts * Running update contracts script * Running Update contracts script * Running Update contracts script * Reverting the v3 version change * Update based on review comments * Added unit tests * Added remarks for callback delegate * Ran update contracts script * Update based on review comments * Ran update contracts script * Updated unit tests * Making ssl validation function private * Updating test files * Update remarks for sslvalidation public contract * Added emulator tests for server validation Co-authored-by: Debdatta Kunda <87335885+kundadebdatta@users.noreply.github.com> * Query: Adds EnableOptimisticDirectExecution flag to QueryRequestOptions (#3664) * Added new flag to QueryRequestOptions to allow customers to use Ode pipeline * Updated comments in QueryRequestOptions.cs * Renamed enabledOde to enableOde * Removed default setting for EnableOptimisticDirectExecution * [Internal] Tests: Removes Direct/HTTPS emulator tests (#3679) * Removing direct/https tests * mppreference * [Internal] Benchmark : Fixes issue with dependency on Cosmos Project (#3673) * users/sourabhjain/benchmarkfix * update pipeline * Revert "users/sourabhjain/benchmarkfix" This reverts commit 81b48f0e47aed7a75540c2c83f62cea98d86824f. * fix compilation error * add parama for preview pkg also --------- Co-authored-by: Matias Quaranta * LocalQuorum: Adds Quorum reads on Consistent Prefix Accounts (#3680) Co-authored-by: DESKTOP-ED57J7H\Prashanth Venkataram * 3.32.0: Adds new SDK version and contract files (#3687) * 3.32.0: Adds new SDK version and contract files * 3.32.0: Adds new SDK version and contract files * Updating changelog version * Updating changelog version * Added more commits to changelog and updated release contract * Added documentation tags PR in changelog * Updated changelog based on reviews * Updated PR decsription in changelog * Update changelog.md Updated full fidelity change description Co-authored-by: Matias Quaranta --------- Co-authored-by: Matias Quaranta * [Internal] Samples: Adds change feed pull model samples (#3646) * add change feed pull samples * refactor appsettings validation * addressing pr comments * move task delay * update sample to use latest change feed mode names --------- Co-authored-by: Matias Quaranta * [Internal] Tests: Refactors emulator CI (#3688) * [Internal] GitHub Template: Adds needs-investigation label (#3708) By default, all "Bug report" issues will have "needs-investigation" * Adding fabric bot action (#3709) * CosmosNullReferenceException: Refactors CosmosNullReferenceException to pass along InnerException property on parent NullReferenceException (#3713) * Passed inner exception details to NullReferenceException ctor when instantiating CosmosNullReferenceException. * Added unit tests. * Addressed PR feedback. * [Internal] PriorityRequests: Fixes header value (#3714) Co-authored-by: Matias Quaranta * [Internal] Query: Adds single physical partition check for OptimisticDirectExecution queries (#3699) * Added single physical partition check for Ode queries. Updated test infrastructure for Ode emulator tests too. * Refactored emulator tests to have all the test cases at the top of the file * Updated TryGetTargetRangeOptimisticDirectExecutionAsync() * Uodated logic on how many times CreateIngestQueryDeleteAsync() gets called * Added debug asserts for partitionKeyDefinition * Added pageSizeOptions parameter in CreateInput() in EmulatorTests * Fixed comments * [Internal] CTL: Fixes Reservoir Sampling Logic (#3712) * Code changes to fix the reservoir sampling logic in CTL * Code changes to modify help text on reservoir type. * Code changes to address minor code refactor. * Diagnostics: Adds startDate in Summary (#3707) * Adding start date * Updated trace files * PR comment * Committing missing tests --------- Co-authored-by: Matias Quaranta * [Internal] Client Telemetry: Adds network information in the payload (#3691) * first draft * clean code * add test * fix test * add replica info collection * fix substatuscode and operation type error * fix code * collect http infor in cache also * message to stacktrace * remove rntbd recording from cache * print proper exception message * fix test * cleanup unused code and added few status codes in ignore list * fixed all exception logging * refactor conditions * fix tests * Documentation: Fixes Database.ReadAsync description (#3457) * Documentation: Modify retry time to timespan Modify retry time in seconds to timespan of parameter maxRetryWaitTimeOnThrottledRequests (Method: [WithThrottlingRetryOptions](https://docs.microsoft.com/en-us/dotnet/api/microsoft.azure.cosmos.fluent.cosmosclientbuilder.withthrottlingretryoptions?view=azure-dotnet#feedback)) Resolves https://github.com/Azure/azure-sdk-for-net/issues/29567 * Documentation: Fixes DeleteItemAsync Example Documentation: Fixes DeleteItemAsync Example * Documentation: Fixes ItemRequestOptions Example Documentation: Fixes ItemRequestOptions Example * Documentation:Update Database.ReadAsync description Documentation: Update Database.ReadAsync description * Documentation: Update Database.ReadAsync description Documentation: Update Database.ReadAsync description * Documentation: Updated ToStreamIterator example Documentation: Updated ToStreamIterator example * Modified StreamIterator section * Update Microsoft.Azure.Cosmos/src/Resource/Database/Database.cs Co-authored-by: Matias Quaranta * Remarks correction * Revert the StreamIterator changes Revert the StreamIterator changes Co-authored-by: Matias Quaranta Co-authored-by: Kiran Kumar Kolli * Upgrade Resiliency: Adds Implementation for Validating the Unhealthy Backend Replicas in Direct mode (#3631) * Code changes to implement replica validation in dotnet v3 sdk. * Cosmetic changes to add inline code comments. * Code chages to address review comments. * Code changes to cover a scenario for async cache. * Code changes to refactor async non-blocking cache code. * Code changes to address minor review comments. --------- Co-authored-by: Kiran Kumar Kolli * ReadMany: Fixes BadRequest when using Ids with single quotes (#3732) * Use parameters * Emulator tests * Release: Adds SDK version and changelog for 3.32.1 (#3733) * version bump * Contracts * [Internal] Build: Fixes static tool analysis versions (#3736) * Update Binskim and follow warnings * Fixing task * More version bumps * binskim args * Padding * policheck * postanalysis parameters * analysis settings * Query: Fixes System.ArgumentException when using PartitionKey.None on x86, Linux or in Optimistic Direct Execution (#3730) * Minor clean up of OptimisticDirectExecutionQueryTests * More minor cleanup in OptimisticDirectExecutionQueryTests * Add emulator tests for the bypass query parsing scenario * Handle PartitionKey.None while creating QueryIterator. This is a workaround for the PartitionKeyInternal.None not following its own contract * Fix up to correctly handle PartitionKey.None using the CachedContainerQueryProperties * Add more tests where PartitionKey.None maps to PartitionKey.Undefined --------- Co-authored-by: Matias Quaranta * Query: Adds FIRST and LAST Scalar Expressions (#3629) * Add FIRST and LAST objects and update visitors * add FIRST LAST evaluation and update offline engine visitors * Add FIRST and LAST to parser * update another visitor * Fix typo * fix typo * added new tests and baselines * cleaning * cleaning --------- Co-authored-by: neildsh <35383880+neildsh@users.noreply.github.com> Co-authored-by: Matias Quaranta * Subpartitioning: Adds support for Prefix Partition Key searches for sub partitioned containers (#3109) * 1st round of changes to support subpartitioning for ChangeFeed * name change and moved a method to FeedRangePartitionKey * support for prefix partition change feed and query including unit and emulator tests. need to verify using FeedRange with QueryIterator * splitting out unit tests from emulator tests * 1st round of changes to support subpartitioning for ChangeFeed * name change and moved a method to FeedRangePartitionKey * support for prefix partition change feed and query including unit and emulator tests. need to verify using FeedRange with QueryIterator * splitting out unit tests from emulator tests * moved logic to choose for prefix partition query and change feed * additional conditional to check for MultiHash partitionkeydefinition kind * removed unnecessary using * cleanup * unnecessary using * removed PREVIEW from proj * unit tests for ResolveFeedRangeBasedOnPrefixContainerAsync * change access modifier * since I changed to static, needed to fix tests * dealing with some testing nits * removed Console.Writeline * slight change in test use containerProperties and partitionKeyDefinition * big fix for resolve feedrange, changes to error behavior, added additional test coverage * test changes * ran updateContracts.ps1 * reverting to 3ad5309e9e22a7376e836cfdbe11fa2438a59133 * Ran Update Contracts * ran updateContracts.ps1 * UpdateContracts.ps1 * updatecontracts * removed bad check from test, removed changes from updatecontracts.ps1 * revert UpdateContracts changes * Reverting to 756a123160d14c424c5e11c4f3520094115aa5d4 * removed accidental change from changelog * removed unwanted change from Directory.build.props * added test clean up * removed console.writelines * updates to query test * removed preview flag * ran UpdateContrats.ps1 * no longer recread feedRange for queries unless using prefix pk * simplified if statement * fixed bug --------- Co-authored-by: Nalu Tripician * [Internal] ClientTelemetry: Adds logic to limit payload size to 2 MB (#3717) * first draft wip fix test and logic * resolve conflicts * limit 2 mb * ad callback * fix tests * code refactor * cosmos json to newtosoft json * clean up files * fix logging to argumrnt based * code refactor * add null check * Query: Fixes regression from LINQ custom serializer fix (#3749) Co-authored-by: Minh Le Co-authored-by: Matias Quaranta * [Internal] LocalQuorum: Refactors override (i.e. strong) to allow from any account consistency (#3753) - Localquorum override (i.e. strong) to allow from any account consistency - Facilitates no-downtime downgrade of existing accounts (i.e. existing Strong/bounded accounts migration to Eventual) * Release: Adds SDK version and change log for 3.32.2 (#3752) * version bump * contract * changelog * version bump * Fixing changelog text * Add another PR * Subpartitioning: Adds APIs for public release and increase REST API version (#3763) * initial commit, Http version issues still needs to be resolved * updateContracts + update Http Version * updateded version in test * update contracts * requested changed * changed name in comments to subpartitioning from multihash * undid changes to TestLiteralSerialization.xml * removed changes to non API.json files * removed non XXXAPI.json file changes * changed verbage on public comments * changed error message to reflect verbage change * Change Feed Processor: Fixes LeaseLostException leaks on notification APIs for Renew scenarios (#3775) * Adding cases * Tests * Upgrade Resiliency: Refactors GatewayAddressCache to Mark TransportAddresses to Unhealthy when Connection Reset Event Occurs (#3768) * Code changes to mark the transport uri to unhealthy for which a connection reset event occures through the connection state listener. * Code changes to bump up the direct version. * Code changes to clean up Gateway Address Cache. * Code changes to fix pipeline build. * Code changes to fix serilization test failures. * Code changes to add force refresh to the gateway function callback delegate. * [Preview] PriorityBasedExecution: Adds PriorityLevel as a RequestOption (#3672) * Added Priority Level as a Request Option * Changed Priority Level Low and High to 1 and 2 respectively * Bumped DirectVersion * Added made PriorityLevel internal for non preview packages * Deleted PriorityLevelTests.cs * Added description of Priority Level in RequestOptions.cs * Modified comments for PriorityLevel in RequestOptions.cs * Updated Contracts * Modified Remarks for PriorityLevel and added see also link. * Updated contracts --------- Co-authored-by: Matias Quaranta * [Internal] Client Telemetry: Adds sampling logic for network level telemetry (#3750) * sampling logic add * throttlinfix * fix tests * fix tests * remove dispose from sampler * add 412 * draft push * refactor code for sampling * clean up * start testing * adding tests * wip * test fix * fix test * fix tests * deleted extra file * remove one toList * add custome logic for sampling * code refactor * replace key * remove commented code from test * added more comments * simpler sampler logic * refactor code * [Internal] Emulator Test : Fixes test when running with distributed tracing enabled. (#3751) * enable DT for everything * try1 * code refactoring * fix pipeline * try 2 * Revert "try 2" This reverts commit 61643f9b4dcd2ab1898fd68b111897bed0bc6bcf. * Revert "fix pipeline" This reverts commit 4b217f5f6a087b1dd889b804fd8b477accd46419. * Revert "code refactoring" This reverts commit d1ff0ddc17ad655360988d171bd033617752f91f. * Revert "try1" This reverts commit bf9c41b43684f59719c3673d6f9c7450bbdc5142. * lazy factory and threadsafe * scope factory in function * try non static * add flag * fix test * add consoles * more console with fix * fix tests * temporarily enable dt * fuix tests * dispose listener * fix tests * remove delay * revert flag change * dynamically get number of test in trace class * Release: Adds SDK version and changelog for 3.32.3 (#3788) * Adding contract and version bump * Adding changelog * SummaryDiagnostics: Refactors Code to Remove Dependency of HttpResponseHeadersWrapper to fetch Sub Status Codes (#3792) * Code changes to fetch sub status code from http response/ content headers. * Code changes to address review comments. * Code changes to return the first element from the sub status list. * Code changes to update first or default. * [Internal] Documentation: Fixes API name to NoSQL (#3795) * [Internal] CTL: Fixes docker image pipeline (#3794) * [Internal] AI Integration : Refactors useragent attribute name as per Otel conventions (#3784) Co-authored-by: Fabian Meiswinkel * HttpClient: Adds Properties to the Http messages if available (#3803) * Passing properties * test * Documentation: Refactors SQL API reference to NoSQL API (#3793) Co-authored-by: Kiran Kumar Kolli * [Internal] Perf test: Refactors code to re-enable performance tests (#3785) * enable perf tests * updated json * upgrade benchmark * update results * updated benchmark results * HttpClient: Adds detection of DNS changes through use of SocketsHttpHandler for .NET 6 and above (#3762) * initial commit * removed unneeded usings * added validation callback, still needs tests * nits + fixes * added additional test * test change * removed unneeded Dispose calls * removed unnneed dispose calls * requested changes * added pooledConnectionLifetime as client option * nit Co-authored-by: Kevin Pilch * Update Microsoft.Azure.Cosmos/src/HttpClient/CosmosHttpClientCore.cs Co-authored-by: Matias Quaranta * Update Microsoft.Azure.Cosmos/src/CosmosClientOptions.cs Co-authored-by: Matias Quaranta * suggested changes * remove test, reorder usings * updated contracts * removed all non XXXAPI.json changes from UpdateContracts run * removed public surface, added random timespan * removed change from unrelated file * Update Microsoft.Azure.Cosmos/src/HttpClient/CosmosHttpClientCore.cs Co-authored-by: Matias Quaranta * added thread safe random method * nit * fixed merge mistake * added reflection failsafe/error tracing * nits * added back removed if * fixed formatting * changed random method, fixed serverCertificateCustomValidation --------- Co-authored-by: Kevin Pilch Co-authored-by: Matias Quaranta * [Internal] Tests: Fixes Open Telemetry attributes for ReadMany test (#3805) * Fixing test * New baseline * Undo some changes * [Internal] Client Telemetry: Refactors code to run client telemetry data processing task in background. (#3783) * first draft * remove failure count test * refactporing * code refactor * create task with timeout * fix test * code refactoring * fix timeout code * space fix * not failing if processor is taking time * fix procrsser test * code refactor * refactor and test fix * Patch: Adds Move Operation (#3389) * Basic changes to introduce move operator * Added "from" object in patch spec operation. Added testcase block. * Fixed testcase. * Changes made to address comments' * Added comment regarding enum mutations * Formatted comment Co-authored-by: Matias Quaranta * Moved summary location. * Ran UpdateContracts.ps1 --------- Co-authored-by: Amaan Haque Co-authored-by: Amaan Haque Co-authored-by: Matias Quaranta * [Internal] Pipelines: Adds nightly build to produce packages (#3802) * Support cleaning * wire previous content delete * as text * with variable * another test * param with types * as string * no delete * no quotes * undoing * re-adding quotes * testing empty * trying another test * readding version * fixing publishing artifacts * fixing parameter * Fixing official pipeline * version 5 * fixing main pipeline * test with true * using start time * nightly preview * passing parameters to pack * Fixing nuget version * arguments on the nuget pack * folder structure * testing v5 * Using only content * Removing currentDate * [Internal] OpenTelemetry: Direct Package update and replacing diagnostic files (#3797) * Direct Package update and replacing dagnostic files * Resolve merge conflicts * Running updateCOnstracts script * Removed LinqTranslationWithCustomSerializerBaseline file * Adding isDistributedTracingEnabled flag * Running update contracts * Running update contracts * Running update contracts * fix test * Code cleanup for test fix * Code cleanup for test fix * Making regex expression readable * Adding comment for regex expression --------- Co-authored-by: Sourabh Jain * [Internal] MerlinBot: Adds auto-merge and cleanup automation (#3813) * Add config changes * Polishing automerge config * Update fabricbot.json (#3824) * [Internal] Upgrade Resiliency: Adds Logic to Validate `Unknown` Replicas along with `Unhealthy`. (#3820) * Code changes to add aggressive validation logic. * Code changes to enable aggressive validation for all regions. * Code changes to pull in msdata cosmos.direct changes related to aggresive validation logic. * Code changes to make minor cosmetic changes. * Code changes to address review comments. * Serialization: Fixes call to CosmosSerializer.FromStream on Gateway mode when EnableContentResponseOnWrite is false (#3814) * Do not call serializer if ResponseMessage.Content is empty. * Add unit test * Update unit tests * Remove unused usings --------- Co-authored-by: Matias Quaranta * [Internal] Documentation: Adds documentation covering build pipelines (#3822) * Add doc * Move benchmark * Fixing texts * Client Encryption: Adds release version of Microsoft.Azure.Cosmos to Microsoft.Azure.Cosmos.Encryption.Custom (#3799) * cosmos version change * changing preview to release * resolving code review comments --------- Co-authored-by: Santosh Kulkarni <66682828+kr-santosh@users.noreply.github.com> * SDK 3.33.0 : Adds version bump and changelog (#3823) * release 3.30.0 * added changelog * updated changelog * updated changelog * suggested change to changelog * updated changelog --------- Co-authored-by: Matias Quaranta * [Internal] Documentation: Adds msdata/direct Sync-up Guide. (#3828) * Code changes to add msdata/direct sync-up documentation. * Code changes to address review comments. * Code changes to address further review comments. * Code changes to address minor review comments. * Removed internal links. * Query: Adds TRIM string system function support in LINQ (#3833) * add trim support * Added some test coverage * address reviews --------- Co-authored-by: Minh Le * Query: Fixes Parsing Error in SQL DOM when CultureInfo is available (#3832) * add fix * Add cultural info to test to verify correct behavior * address pr review to restore to restore culture * fix comment --------- Co-authored-by: Minh Le * Client Encryption: Adds api FetchDataEncryptionKeyWithoutRawKeyAsync and FetchDataEncryptionKeyAsync to get DEK without and with raw key respectively. (#3809) * added raw key to MdeEncryption * adding ray key to Mde Algo * test case changes * resolving code review comments * code optimization to reduce keyvault calls * removed Microsoft.Data.Encryption.Cryptography nuget package * added api for dek with raw key * resolved code review comments * adding change log * code review changes * Initial commit (#3826) * Query: Adds Computed Property SDK Support (#3761) * Initial commit * Restored settings.json changes. * Update * Addressed comments; still need to be tested using Emulator. * Fixes after test run. * Ignored the computed property tests based on the sync this morning (to allow for preview release). * Suite0 fixes. * Test update. * Suite0 fixes * [Internal] Samples: Adds OpenTelemetry and Application Insights samples (#3818) * add opentelemetry and application insights samples * address pr comments * [Internal] Query: Added custom serializer coverage tests to ExpressionToSQL.cs (#3722) * Ensure enum as string is preserved for custom serializer * Failing test * Added failing tests * Updated requested names * Ignore result of test for now * Added additional comment on why the test is ignored * Replaced with sample code * Remove ignore attribute from tests, documented misbehavior for future use * Updated comment --------- Co-authored-by: leminh98 * Query: Added remaining Cosmos Type checking functions to CosmosLinqExtensions (#3724) * Added the remaining Cosmos Type checking functions to the CosmosLinqExtensions * Added comments requested * Updated comment * Updated baseline * Improve readability of dictionary initialization * Aligned with code style guide * Revert change to baseline * Executed update baseline script --------- Co-authored-by: neildsh <35383880+neildsh@users.noreply.github.com> Co-authored-by: leminh98 * update sdk version and section tags (#3841) * PackageLicense: Removes PackageLicenseUrl and Adds PackageLicenseFile since PackageLicenseUrl is deprecated (#3847) * proposal to add PackageLicenseFile since PackageLicenseUrl is deprecated. https://github.com/NuGet/Home/issues/4628 * adding attribute Visible=false * making ChangeFeedMode.LatestVersion accessible to the public (#3854) * AI Integration: Fixes Operation Name in the activity and end to end Tests. (#3845) * first draft * second draft * 3rd draft * remove untouched file * test fix * fix order * change order * refactor * skip network activities in test * remove network attributes * SDK 3.34.0 : Adds version bump and changelog (#3855) * SDK 3.34.0: Adds version bump and changelog * adding changelog changes * added a missing PREVIEW PR * Update changelog.md Co-authored-by: Justine Cocchi * Update changelog.md Co-authored-by: Kiran Kumar Kolli * removed 3840 as it was not committed * change text for 3832 * fix merge issue * add 3724 * Update changelog.md Co-authored-by: Matias Quaranta * Update changelog.md Co-authored-by: Matias Quaranta * including 3845 --------- Co-authored-by: Justine Cocchi Co-authored-by: Kiran Kumar Kolli Co-authored-by: Matias Quaranta * Release: Fixes changelog.md change for 3845 to preview (#3859) * removing ThirdPartyNotice.txt from content and contentfiles folders (#3864) * Documentation: Adds see also link to Container.CreateTransactionalBatch (#3860) * Linking limit documentation to Container.CreateTransactionalBatch(PartitionKey) method * Resolved PR comments * Links update * Using learn.microsoft instead of docs.microsoft in the links --------- Co-authored-by: Matias Quaranta * Query: Adds type-markers with count and length for large arrays (#3852) * initial commit * cleanup * update test output * cleanup * typo * Pr comments * [Internal] AI Integration or Open Telemetry: Design Document (#3858) * first draft * redesign * ädd link * updated observability url * Benchmarking: Adds use of ARM Templates for benchmarking (#3838) * initial commit DONT REVIEW * fixes and documentation * Apply suggestions from code review Co-authored-by: Matias Quaranta * requested changes * Apply suggestions from code review Co-authored-by: Matias Quaranta * name changes * readme changes * nits + changing case of parameters file --------- Co-authored-by: Matias Quaranta * Update README.md (#3875) URL typo. * moved to new file (#3876) * Direct Package Upgrade 3.31.0: Refactors code to make compatible with latest direct (#3877) * upgrade to 3.31.0 * add more regions * enable dt for operations * updated contract file * [Preview] Integrated cache: Adds BypassIntegratedCache to DedicatedGatewayRequestOptions (#3836) * Integrated cache: Add BypassIntegratedCache to DedicatedGatewayRequestOptions Currently, integrated cache is used by default for Dedicated Gateway. Customers cannot skip cache for particular requests or data unless they shift to multi-tenant Gateway,which will lose the benefits of Dedicated Gateway. For customers to have more control over integrated cache, we're introducing a new "RequestOption" called "BypassIntegratedCache". This option will allow the customer to decide whether to use integrated cache for each request or not. If this value is set to true, the item/query will be served from backend and won't be cached in Dedicated Gateway. * Move this feature to public preview * Address comments 1. Add more tests 2. Add more detail and example code for BypassIntegratedCache * Revert changes in EncryptionCustomAPI --------- Co-authored-by: Jiajun Peng Co-authored-by: Matias Quaranta * Client Encryption: Adds Microsoft.Azure.Cosmos compatibility to version 3.34.0 (#3874) * chaging Microsoft.Azure.Cosmos support version * resolved merge conflicts * CosmosClient: Fixes missing Trace when converting HTTP Timeout to 503 (#3866) * Added tracing when converting HTTP Timeout to 503 * Fixed tracing when converting HTTP Timeout to 503 * Resolved PR comments * Using ITrace as part of ClientSideRequestStatisticsTraceDatum * Refactoring * Test update * Unit tests fix * AI Integration: Fixes Open Telemetry Example (#3868) * first draft * add filter * revert csproj * fix sample * changed log message * remove unused library * [Internal] Query: Adds OptimisticDirectExecute and RequiresDistribution headers (#3882) * Adding ODE and RequiresDistribution Headers * Fixed comments * Updated parameter in SwitchToFallbackPipelineAsync * Renamed TryUnwrapContinuationToken to UnwrapContinuationToken --------- Co-authored-by: neildsh <35383880+neildsh@users.noreply.github.com> * Query: Refactors the EnableOptimisticDirectExecution flag to be public (#3883) * Made EnableOptimisticDirectExecution a public flag * Updated contract * [Internal] OpenTelemetry : Adds Telemetry Distributed Tracing functionality (#3801) * Direct Package update and replacing dagnostic files * Resolve merge conflicts * Running updateCOnstracts script * Add code changes for distributed tracing open telemetry changes * Add distributed tracing tests * Updated tests for distributed tracing * Addin traceID for diagnostics * Running update contract script * Removed LinqTranslationWithCustomSerializerBaseline file * Adding isDistributedTracingEnabled flag * Running update contracts * Running update contracts * Updates based on differnt code review comments * Running update contracts * Running update contracts * Running update contracts * fix test * Code cleanup for test fix * Running Update contracts * resolving merge conflicts * resolving merge conflicts * Set EnableDistributedTracing to true for performance tests * Benchmark project change for distributed tracing * Updating tests * Updated unit tests * Updated unit tests * Updated tests and constructors based on review comments * Updated scope name in recorder * Updated distributedOtel tests to cover more scenarios * Updated distributedOtel tests * Reverting benchmark performance test changes * Update DistributedOpentelemetry tests * Update test cleanup * Update distributed tests with custom builder * Update distributed open telemetry tests * Update contracts * Cleanup files * Update distributed Otel tests * Update distributed Otel tests * code refactoring * fix custom listener * Update direct package to 3.31.1 * Code clean up * Update tests with display name --------- Co-authored-by: Sourabh Jain * Documentation: Adds additional remarks to CosmosClient (#3891) * CosmosClient documentation improvements * Cref fix * Link fix * Documentation fix * Typo fix --------- Co-authored-by: Matias Quaranta * Open Telemetry End To End Test: Adds baseline for network level requests trace (#3887) * enable request level in end to end * made some changes * fix tests * fix display name * hardcoded containername and databasenam * fix tests * temp * fix tests * update contracts * fix tests * fixed display name * [Internal] Design Docs: Adds Design Document for Client Telemetry (#3590) * sdk design for client telemetry * Otel design * update optel design * added more nformation * updated ct design * remove otel design * Client Telemetry Design * update typos * fix typos * fix typos * added limitation * updated docs * updated doc * updated text * Update docs/observability.md Co-authored-by: Kiran Kumar Kolli * Update docs/observability.md Co-authored-by: Kiran Kumar Kolli * Update docs/observability.md Co-authored-by: Kiran Kumar Kolli * Update docs/observability.md Co-authored-by: Kiran Kumar Kolli * Update docs/observability.md Co-authored-by: Kiran Kumar Kolli * move stuff here and there. --------- Co-authored-by: Kiran Kumar Kolli * [Internal] Design Docs: Adds Design Document for Client Telemetry Part 2 (#3903) * updated doc * Update docs/observability.md Co-authored-by: Justine Cocchi * updated text --------- Co-authored-by: Justine Cocchi * ConnectionPolicy: Refactors Code to Reduce Default Request Timeout to 6 Seconds. (#3902) * Code changes to reduce default request timeout to 6 seconds. * Code changes to update API doc default request timeout to 6 seconds. * [Internal] Upgrade Resiliency: Adds Replica Health State Diagnostics. (#3835) * Code changes to add replica health status in diagnostics. * Code changes to fix performance test build failure. * Code changes to add health state capture logic in address cache. * Code changes to fix benchmark test execution. * Code changes to add tests to validate health state cache. * Code changes to reduce default request timeout to 5 seconds. * Revert "Code changes to reduce default request timeout to 5 seconds." This reverts commit 139f37e588fc9dfed608431f4186c567a080e622. * Subpartitioning: Fixes handling of split physical partitions (#3879) * Initial Commit DO NOT REVIEW * bug fix, needs Direct Package Changes * fix for change feed and query plus tests * clean up * query + clean up --------- Co-authored-by: Kiran Kumar Kolli * [Query] Fixes empty property name parsing exception (#3907) * inital commit * cleanup * test cleanup * PR comments * PR comment * [Preview] Query: Refactors EnableOptimisticDirectExecution to true by default in Preview mode (#3909) * Setting EnableODE to true by default in Preview Mode. * Added seperate if block for default value * Updated property * Removed unused Usings * Updated contracts * Updated test * Updated directive indentation * Documentations: Adds links to PatchItems docs (#3910) * Added links to PatchItems docs * Undo changes from internal file * [Internal] Direct Package Upgrade: Refactors Code to Bump Up `Cosmos.Direct` Package to `3.31.2` (#3918) * Code changes to bump up the direct version. * Code changes to mark the Israel Central region as public. * Code changes to update contracts. * Code changes to fix test failure. Some clean ups. * Code changes to add detailed message for open channels count. * SDK 3.35.0 : Adds version bump and changelog (#3920) * release PR * updated changelog.md * more changelog updates * [Internal] Last minute fix to changelog for 3.35.0 (#3921) * release PR * updated changelog.md * more changelog updates * changelog fix * Update changelog.md * Update changelog.md * [Internal] Query: Adds new header SupportedSerializationFormats (#3911) * Binary Serilaization Response test * Added new header SupportedSerializationFormats * Modified existing use of CosmosSerializationFormatOptions * Modified tests and removed unused code * Addressed comments * Added more negative cases * Revert changes * Added spaces * Addressed comments * Addressed comments * Removed SupportedSerializationFormats from Headers file * Removed unused JsonSerilazationFormats option * Addressed comments * Addressed comments * Addressed comments * Addressed comments * Added new enum TransportSerializationFormat * Added new enum TransportSerializationFormat * Addressed comments * Removed unused parameter * Addressed comments * updating API * remove tests * Text fixes * fix typo * remove TransportSerializationFormat header * text reverts * revert * test update * PR comments * remove test owner headers HeadersValidationTests.cs * PR comments - remove unsupported tests and scope client --------- Co-authored-by: Heet Co-authored-by: neildsh <35383880+neildsh@users.noreply.github.com> Co-authored-by: Matias Quaranta * Code changes to optimize the rntbd open connection logic to open connections in parallel. (#3939) * Query : Adds support for newtonsoft member access via ExtensionData (#3834) * Support newtonsoft member access via ExtensionData * Return null instead of empty string * Added tests for select & where * Updated baseline with note --------- Co-authored-by: leminh98 * HttpTransport: Fixes HttpTimeoutPolicies to not accidentally suppress retries (#3944) * Fix HttpTimeoutPolicies to not accidentally suppress retries * Removing HttpTimeoutPolicy.MaxRetryTimeLimit altogether * SDK 3.35.1 : Adds version bump and changelog (#3945) * version bump * changelog * contract * [Internal] Changelog: Fixes recommended version and title (#3948) * SDK 3.35.1: Adds version bump and changelog * Update changelog.md * Update changelog.md * Update changelog.md * Update changelog.md * Update changelog.md * [Internal] Dependencies: Fixes dependabot alert for System.Linq.Dynamic.Core (#3957) * Removing 1 * Removing 2 * Removing 3 * [Internal] Upgrade Resiliency: Adds Code to Enable Replica Validation Feature for Preview (#3951) * Code changes to add replica validation feature in cosmos client options. * Code changes to upgrade the cosmos direct version to 3.31.3. * Adding emulator test to cover replica validation. * Code changes to address cosmetic clean ups. * Code changes to address review comments. Fixed preview build failures. * Code changes to enable replica validation for preview package by default. * Code changes to address review comments. * Code changes to fix preview unit tests. * Code changes to disable environment variable at the end of the test. * Client Encryption: Adds package reference Microsoft.Azure.Cosmos version 3.35.1-preview (#3956) * changing cosmos preview version * updating build file --------- Co-authored-by: Matias Quaranta * [Internal] FabricBot: Adds GitOps.ResourceManagement because of FabricBot decommissioning (#3966) * Add prIssueManagement.yml to onboard repo to GitOps.ResourceManagement as FabricBot replacement Owners of the FabricBot configuration should have received email notification. The same information contained in the email is published internally at: https://aka.ms/gim/fabricbot. Details on the replacement service and the syntax of the new yaml configuration file is available publicly at: https://microsoft.github.io/GitOps/policies/resource-management.html Please review and merge this PR to complete the process of onboarding to the new service. * Deleting fabricbot.json --------- Co-authored-by: microsoft-github-policy-service[bot] <77245923+microsoft-github-policy-service[bot]@users.noreply.github.com> * [Internal] Query: Refactors certain tests to not fail when EnableOptimisticDirectExecution is set to true in 3.35.0-preview package (#3955) * Updated emulator and baseline tests to not fail when ODE is set to default true in PREVIEW mode * Fixed QueryAsync() test * Fixed QueryAsync() in EndToEndTraceBaselineTests * Undid changes to IndexMetrics baseline file * Updated EndToEndTraceWriterBaselineTests.QueryAsync xml * Updated xml * Updated xml to have request options tag * Diagnostics: Fixes verbose levels for "Operation will NOT be retried" (#3969) * Query: Fixes malformed continuation token exception type and message (#3917) * Fixed malformed continuation token issue where Exception was not CosmosExceptionan and did not have the correct Status and Sub Status codes. * Fixed incorrect indentation * Added type check for incoming exception * Replaced if/else with extra catch block * Moved fix to a higher point in the call stack * Removed unused Usings * Updated test code --------- Co-authored-by: Matias Quaranta * [Internal] Upgrade Resiliency: Refactors Code to Enable Replica Validation Feature Through `CosmosClientOptions` And Environment Variable (#3974) * Code changes to use client options to enable or disable replica validation. * Code changes to fix preview build failures. * Query : Adds string comparison alternative when converting LINQ to SQL (#3668) * string.Compare supported with LINQ to SQL * Update tests * Update test name * Update tests * Add test * Create helper ReverseExpressionTypeForStrings * PR feedback * Update tests * Update base line --------- Co-authored-by: Aditya Co-authored-by: Matias Quaranta * AI Integration: Fixes event generation for failed requests (#3973) * first draft * fix code * included feedback * flip condition * updated docs * Update docs/observability.md Co-authored-by: Matias Quaranta * Update observability.md * updated contract --------- Co-authored-by: Matias Quaranta * [Internal] Category: Refactors Cosmos benchmark operations (#3961) * Refactoring: base classes for operations. * Updating comments. * Adding new line at the end of the file. * Fixing code review points. * Restore PrepareAsync to be virtual. * 3.35.2: Adds new SDK versions and contract files (#3985) * Updated change log and bumped up the version. * Changing the version to 3.35.2 * Code changes to address review comments. * Code changes to make minor fixes. * Code changes to move some fixes into preview. * [INTERNAL] LocalQuorum: Adds documentation for LocalQuorum (#3993) * Draft of local-quorum documentation * Adding experimental to header * Adding cross-region read guarantees * Reads Bounded clarification * Adding account consistency step also * Non-Prod usage note at top * Addressing review comments * Some more refinement * Code changes to update release note. (#3996) * Client Encryption: Adds fix for supporting Prefix Partition Key (Hierarchical partitioning) (#3979) * Hirarchical pk bug fix * Hirarchical pk bug fix * Hirarchical pk bug fix * Hirarchical pk bug fix * Hirarchical pk bug fix * testing new version * adding more tests * adding more tests * adding more tests * code review changes * test fix * test fix * test fix * test fix --------- Co-authored-by: Nalu Tripician <27316859+NaluTripician@users.noreply.github.com> * Query: Refactors changelog.md with Optimistic Direct Execution recommendation (#4004) * Update changelog.md This is a recommendation for customers if they would like to use the ODE features. * Updated release notes for ODE * [Internal] Query: Adds performance testing for OptimisticDirectExecution pipeline (#3839) * Infrastructure for performance testing with ODE pipeline. * Resolve comments * Removed randomization from data creation process * Fixed comments * Removed Query and EnableODE from QueryStatisticsMetrics, as they do not relate to query statistics. * Removed try catch to make CreateItemAsync call always succeed * Removed one liner functions * Removed code from MetricsSerializer and QueryStatisticsDatumVisitor files * Fixed comments * Removed request Charge check * Bug in Debug Assert * Test * Bug in debug assert fix * Fixed second bug in Metrics Accumalator class * Added ignore flag to ode perf tests so that they do not run on every loop build * Added comment explaining the Ignore flag. * Query: Adds ODE continuation token support for non-ODE pipelines (#4009) * Added code to throw exception if ODE continuation token goes into non ODE pipeline * Removed count variable * Updated test name * Removed ODE continuation token logic from caller class * Simplified code * Fixed comments * Updated continuation token cast * Removed const string for continuation token * Added Ignore flag for test * Added baseline test * Updated baseline test * Code changes to fix concurrency issues. * Code changes to disable replica validation in preview package. (#4019) * 3.35.3: Adds new SDK versions and contract files (#4024) * Updated change log and bumped up the patch version. * Code changes to update the change log message. * [Internal] Distributed tracing: Adds a sample to collect activities and events using custom listener (#4021) * custom listener example * removed unwanted code * add comments * fix appsettings * revert changes * Code changes to fix race condition by calling dispose too early. (#4030) * Code changes to update change log for release 3.35.3 (#4032) * Documentation: Fixes article links (replaced links V2 to V3 SDK version) + Azure Cosmos DB typo (#4031) * Documentation link fix * Fixed Typo "Azure CosmosDB"→"Azure Cosmos DB" * [Internal] Benchmark tool: Adds Cosmos Benchmark Metrics (#3950) * Adding metrics for Benchmark tool. * Adding OpenTelemetry. * Revert "Adding OpenTelemetry." This reverts commit c7da0884697064103145099e284892365f4ebb68. * Telemetry for windowed percentiles. * OpenTelemetry, AppInsights and Dashboard. * Removing DiagnosticDataListener. * Code styling, comments and clean-up. * Fixing issues with dashboard. * Fixing positions of charts on the dashboard. * Fixing the dashboard. * Updating titles and subtitles. * Removing ILogger and other not required references. * Fixing code review points. * Fixing issues after rebase. * Removing unnecessary changes. * Fixing code review points. * Adding metrics for Benchmark tool. * Adding OpenTelemetry. * Revert "Adding OpenTelemetry." This reverts commit c7da0884697064103145099e284892365f4ebb68. * Telemetry for windowed percentiles. * OpenTelemetry, AppInsights and Dashboard. * Removing DiagnosticDataListener. * Code styling, comments and clean-up. * Fixing issues with dashboard. * Fixing positions of charts on the dashboard. * Fixing the dashboard. * Updating titles and subtitles. * Removing ILogger and other not required references. * Fixing code review points. * Fixing issues after rebase. * Removing unnecessary changes. * Fixing code review points. * Fixing code review points. * make MetrcisCollectorProvider non static and remove locks * fix * fixes * use static class name TelemetrySpan.IncludePercentile * use app insights connection string * modified: Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/Program.cs * modified: Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/Program.cs * rename AppInsightsConnectionString * fix * fix comments * fix if AppInsights c string is not set * summary * fix * remove unnecessary collector types * remove unnecesary metere provicer * add event source * remove folder * fix * split success and failed latencies * fix * fix --------- Co-authored-by: David Chaava Co-authored-by: David Chaava * GatewayAddressCache: Fixes Unobserved Exception During Background Address Refresh (#4039) * Code changes to fix unobserved exception during background address refresh. * Code changes to add exception handler in task. * Code changes to fix null ref exception. * Revert "Code changes to fix null ref exception." This reverts commit 83f90d578bd301339f6fa13981a0fe2fc3d65fa6. * Revert "Code changes to add exception handler in task." This reverts commit c49ed8162758217a09df28417a6f76649eab6a26. * Code changes to address review comments. * Revert "Code changes to address review comments." This reverts commit d2b9f6b501f64f1a50b8a49de3ea76fbb9b5c853. * Documentation: Adds additional note for GetContactedRegions method (#4042) * Added small remark for GetContactedRegions method documentation * Moved to remarks * Revert "Code changes to fix concurrency issues." This reverts commit 726e9ac4c8a6e429f04c19f4d6efd24dd07a1cef. * [Internal] Client Telemetry: Adds Client Telemetry pipeline sending data to service (#3900) * first draft * comment other pipelines * pint variables * commnet other pipelines * added env variable * minor changes * update env variable * print env variable * add space in end * fix test * fix tests * fix test * fix tests * remove response interceptor * logs * debuug mode * 3failing test to print llgs * minor refactoring * 2nd windows-2019 * fix ct tests * 2remove debugging * fix tests * revert * ncomment pipelines * fix test * minor changes * release and emulator pipeline * update pipelines * ignore abstract class test * fixing pipeline * refactor code * change it to class name to run tests * added emulator setup * 1 temp commit * env variable * renames env variable * fix tests * add condition * fix tests * reorder env variable * revert pipeline * did some clean up * change to revert * Revert "change to revert" This reverts commit 03db3c104505dc7b8f3cea267835c92ca530f8f4. * fix typos * throw if exception intercepter is null * remove modelling changes * removed virtaul * Update Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Utils/HttpHandlerHelper.cs Co-authored-by: Matias Quaranta * added condition for pipelines * Revert "added condition for pipelines" This reverts commit f9a208cd28e01badee97a2eb770a486cea67c1f0. * changed cond * fix codn * more enhancement * testing for release pipeline * refactore code and using test category * added comments on test * refactor pipeline code * fix variables * fix pipeline --------- Co-authored-by: Matias Quaranta * [Internal] Client Telemetry: Refactors code for collectors (#4037) * refactored code * implemented review comments * test fix * fix tests * fix test * fix test * logger fix * update contract * fic test * updated benchmarks * [Internal] Automation: Adds logic to tag customer-reported issues (#4047) * Added customer-reported label * Changing condition * padding * more padding * permission name * padding * [Internal] Benchmark tool: Adds requests diagnostic data capture and upload to storage (#3926) * azure-cosmos-dotnet-v3/issues/3889 add diagnostics data capturing during bechmark and storing into blob storage after finish * modified: Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/README.md * modified: Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/AzureVmBenchmark/scripts/custom-script.sh * fix bug * fix review comments * fix comments * fix comments * fix case * add tests and refactoring * fix * unify logging * add summaries * fix method summary * fix BOM * fix review comments * fix comment * fix line breaks * modified: Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/AzureVmBenchmark/azuredeploy.json * modified: Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/ARMTemplate/README.md * modified: Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/README.md * modified: Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/README.md * catch exceptions * add container prefix * ResultStorageContainerPrefix * modified: Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/AzureVmBenchmark/azuredeploy.json * modified: Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/AzureVmBenchmark/scripts/execute.sh * modified: Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/AzureVmBenchmark/scripts/custom-script.sh * modified: Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/AzureVmBenchmark/azuredeploy.json * modified: Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/AzureVmBenchmark/azuredeploy.json * modified: Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/AzureVmBenchmark/azuredeploy.json * modified: Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/AzureVmBenchmark/azuredeploy.json * modified: Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/AzureVmBenchmark/azuredeploy.json * modified: Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/AzureVmBenchmark/azuredeploy.json * modified: Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/AzureVmBenchmark/azuredeploy.json * modified: Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/AzureVmBenchmark/azuredeploy.json * Update Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/BenchmarkConfig.cs Co-authored-by: Kiran Kumar Kolli * Update Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/AzureVmBenchmark/azuredeploy.json Co-authored-by: Matias Quaranta * Update Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/BenchmarkConfig.cs Co-authored-by: Kiran Kumar Kolli * Update Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/Fx/DiagnosticDataListener.cs Co-authored-by: Matias Quaranta * fix comments * fix comments * modified: Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/README.md * modified: Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/AzureVmBenchmark/scripts/execute.sh * make BlobCLient Lazy singleton * new file: Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/AzureVmBenchmark/README.md modified: Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/AzureVmBenchmark/azuredeploy.json * modified: Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/AzureVmBenchmark/README.md * modified: Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/AzureVmBenchmark/scripts/execute.sh * modified: Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/AzureVmBenchmark/scripts/execute.sh * check on diagnostic colletiong * remove locks and improve logs appending * removed unnecesary directory * removed unnecesary directory * removed unnecesary directory * new file: Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/ARMTemplate/README.md * add dashboard * fix arm template * change branch * fix * add dashboard name * fix dashboard * add logging * fix * trace error * fix devide zero * add trace errors * fix * fix * fix * fix * fix * migrate to text writer * fixes * diagnostic logs * add diagnostic logs * remove flush and reset * metric collection window lock * collection window * force flush every n seconds * fix bug * fix * Update Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/README.md Co-authored-by: Matias Quaranta * change deafult metric interval * constant * fix container creating conflict issue * change azuredeply branch name * remove ArmTemplate folder * fix DiagnosticLatencyThresholdInMs default value --------- Co-authored-by: David Chaava Co-authored-by: Kiran Kumar Kolli Co-authored-by: Matias Quaranta * [Internal] Benchmark tool: Adds feature to the dashboard that generate plots queries for metrics with a workload name prefix, depending on the benchmark workload type. #4048 (#4053) * Merge remote-tracking branch 'origin/master' into users/v-dchaava/benchmark-diagnostics/3889 * modified: Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/AzureVmBenchmark/README.md * add metrics prefixes * fix chart metrics names * fix dashboard queries according selected workload type --------- Co-authored-by: David Chaava * [Internal] Client Telemetry: Adds client config api call to get latest flag status (#4050) * first draft * tets fix * fix dependent projects * reduce refresh time in tests * fix tests and added comments * fix diagnostic handler fix * fix test * adding test * ret pushmove console * fix test * provide options to enable/disable this featire in benchmark and ctl proj * updated trace message Co-authored-by: Matias Quaranta * remove import * updated traces Co-authored-by: Matias Quaranta * test fix * remove null assignment * fix test --------- Co-authored-by: Matias Quaranta * [Internal] Benchmark tool: Fixes benchmark run command using OSSProjectRef parameter (#4066) * fix benchmark run command using OSSProjectRef parameter * remove ShouldUnsetParentConfigurationAndPlatform=false --------- Co-authored-by: David Chaava * [Query] Adds public backend metrics property to Diagnostics (#4001) * initial commit * some pr comments, WIP * Refactor * more * Public constructors and modify accumulators * accumulator updates and undo test changes * add test * PR comments * bug fix * ToString() refactor * contract updates * test updates * small fixes * text fix * Update accumulators * fix * PR comments * small fix * Rename BE -> ServerSide * more renaming * Update API and tests * separate public and internal classes * API update * change namespace * Pr comments * public constructors and bug fix * API updates * renaming and test updates * PR comments * more PR comments * PR comments, test additions * API updates and more tests * tests and pkrangeid update * PR comments * more PR comments * smol test fix * PR comments - renaming properties and constructor rehash * contract update * seal classes and private fields. * update indexHitRatio calc * mocking refactor to abstract classes * contract updates * PR comments - Update documentation * [Query][Internal] Adds tests for aggregate queries with invalid continuation tokens (#4052) * partial test * Tests and error handling update * update error message * typo * update original err msg * combine tests * test cleanup * undo error message update * [Internal] Benchmark tool: Fixes code refractoring to model the metrics as EventSource (#4040) * Adding metrics for Benchmark tool. * Adding OpenTelemetry. * Revert "Adding OpenTelemetry." This reverts commit c7da0884697064103145099e284892365f4ebb68. * Telemetry for windowed percentiles. * OpenTelemetry, AppInsights and Dashboard. * Removing DiagnosticDataListener. * Code styling, comments and clean-up. * Fixing issues with dashboard. * Fixing positions of charts on the dashboard. * Fixing the dashboard. * Updating titles and subtitles. * Removing ILogger and other not required references. * Fixing code review points. * Fixing issues after rebase. * Removing unnecessary changes. * Fixing code review points. * Adding metrics for Benchmark tool. * Adding OpenTelemetry. * Revert "Adding OpenTelemetry." This reverts commit c7da0884697064103145099e284892365f4ebb68. * Telemetry for windowed percentiles. * OpenTelemetry, AppInsights and Dashboard. * Removing DiagnosticDataListener. * Code styling, comments and clean-up. * Fixing issues with dashboard. * Fixing positions of charts on the dashboard. * Fixing the dashboard. * Updating titles and subtitles. * Removing ILogger and other not required references. * Fixing code review points. * Fixing issues after rebase. * Removing unnecessary changes. * Fixing code review points. * Fixing code review points. * make MetrcisCollectorProvider non static and remove locks * fix * fixes * use static class name TelemetrySpan.IncludePercentile * use app insights connection string * modified: Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/Program.cs * modified: Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/Program.cs * rename AppInsightsConnectionString * fix * fix comments * fix if AppInsights c string is not set * summary * fix * remove unnecessary collector types * remove unnecesary metere provicer * add event source * remove folder * fix * split success and failed latencies * Code refractor to use EvenSource design pattern for metrics * Fixing build breaks * Removing BenchmarkExecutionEventSource * Fixign misc things * Some extra cleanup * use TimeSpan except milliseconds * fix metrics publication * fix metrics publication * move tests to benchmark folder * move back benchmark test * use background task for flushing metrics * remove sync metrics flushing * split failed and success operations * fix latenclies charts * fix benchmark run command * remove ShouldUnsetParentConfigurationAndPlatform=false --------- Co-authored-by: Mikhail Lipin Co-authored-by: David Chaava Co-authored-by: David Chaava * first draft (#4079) * Subpartitioning: Fixes bug for queries on subpartitioned containers (#3934) * initial fix, needs testing on prod * test fix * clean up pr * query rework * refactors previous changes * requested changes and bug fixes * nits * requested changes * bug fixes * start of test * added test * nit: changed name of EffectivePartitionKeyRanges to EffectiveRangesForPartitionKey * Address code comments * Address code comments * saving work * addresses code comments * nit, spacing * PartitionKeyHash fixes * Fixes bugs in tests * Removed bad method, added additional test coverage * Removed EffectivePartitionKeyString use * test fix * requested changes * Requested changes * fixed test * Test fix * Added comment --------- Co-authored-by: SrinikhilReddy * [Internal] Query: Fixes LINQ Test Organization (#4076) * preliminary change * Add some more boiler plate code * move all linq test to the same folder; add some groupBy test * fix references error in test refactoring add code for group by substitution. Still need to adjust binding post groupby * preliminary for the groupby functions with key and value selector * trying to change collection inputs for group by * Undo the LINQ GROUP BY part * fix accidental changes --------- Co-authored-by: Minh Le * ClientTelemetry : Adds logic to call client config in every 10 minutes (#4071) * first draft * fix tests * fixes * fix tests * remove consoles * added exception * remove comment * fix tests * fix test * rev comments * rev comments * refactor code * remove log from api exception * SDK 3.35.4: Adds version bump and changelog (#4087) * bump version and changelog * added apis * Update changelog.md * [Internal] Query: Fixes escaped string parsing in SqlParser (#4054) * Initial commit * Addressed comments. * Bechmark : Fixes benchmark runs (#4088) * pk to result container * set pk * pk value fix * update run.sh * remove changes value * remove telemetry service end point * cleanup * [Internal] Query: Adds Index Metrics V2 Object Model (#4058) * making necessary ownership change * made change to ownerships * header test * Call to TryCreate instead of Create in Responsemessage * Add baseline test infra for index metric parser * update baseline files * Add parse retry logic * Update headers test * address code review * address code review * fix tests * Update csproj file * Adopt the new header * update the response to parse with text instead of base 64 * test for headers adoption of uri escape * Add URI Decode logic * Update baseline * Update with the new header name from back end * update the query parsing requirement * New Index Metrics DOM * fix build error * Code clean up * Address code review * Turn off switching to V2 * Fix test * fix test errors * Address code review comment * addressed code review * removed the empty entity * update test parse * update test --------- Co-authored-by: Minh Le * Distributed Tracing: Fixes dependency failure on appinsights (#4098) * first draft * refactor * fix tests * fixed condition * [Internal] Query: Adds deserializing logic for ClientQL Coordinator Distribution Plan (#3988) * First commit. * Added remaining classes for ClientQL structure * Added ClientQLDeserializing class and added CoordinatorDistributionPlan folder * Added support for all Enumerable and Scalar Expressions * Added baseline tests for testing CoordinatorDistributionPlan deserializing * Made ClientQL objects immutable * Added error and null checks for Value calls * Updated List<> with IReadOnlyList<> * Made most functions in the Deserializing class private and static * Added static constant class for Enumerable expressions * Added null checking for arrays * Removed null checks from deserializing array functions * Removed support for JavaScript * Removed support for Unwind * Function names changed * Removed few functions. * Updated constants class * Function Formatting for ClientQL Deserializing (#4062) * Adding error handling for Deserializing functions * Finished updating code to remove all dependency on Newtonsoft.Json * Removed try catch for all upper level functions * Resolved comments * Resolved comments pt2 * Updated error message * Resolved comments pt3 * Changed parameter types from int to long * Removed ClientQLDelegate * Syntax Fixes * Removed ClientQLFlattenEnumerable file. This is JS. * Fixed List helper functions * Made singleton constructors from public to private * Updated the DeserializeClientQLBinaryLiteral function * Renamed ClientQL to QL * Fixed variable names * Updated more variable names * Removed support for Type * Removed all extra newlines * Added null checks * Updated the name CoordinatorDistributionPlan to ClientDistributionPlan * Removed all support for Cassandra, Mongo and Binary Literal * Updaed ClientQL to Cql * Updated baseline test class property. * [Internal] Query: Adds check to detect unsupported queries for Optimistic Direct Execution code path (#4090) * Added query validity function on Ode code path * Fixed syntax * Updated to use string search instead of query parsing * Updated string search to now be regex * Changed location of caller for QueryValidityCheck() * Updated regex string * Added extra test coverage * Added const string to error messages * Added compile flag to Regex * Fixed comments * Added missing null reference coverage * Removed extra foreach loop in test * Removed useQueryPlan bool in test code * [Internal] Query: Fixes minor issues with TestQueryValidityCheckWithODEAsync (#4105) * Fixed typos and made test more readable * Another typo * Query: Adds LINQ RegexMatch Extension method (#4078) * Add support for translation to REgexmatch * Add test and fix some indexing issues * remove visit explicit, add some comment. Update public contract and added the baseline for the test * add the missing baseline * added test * address code review * update csproj --------- Co-authored-by: Minh Le * Chaning Bounded to Strong (#4103) * Client Telemetry: Adds new public APIs (#4056) * Revert "[Internal] Client Telemetry: Refactors code for collectors (#4037)" This reverts commit e2311a9fdcca392ec7d49c13939aaff3404deb85. * Revert "Revert "[Internal] Client Telemetry: Refactors code for collectors (#4037)"" This reverts commit f04234b76174180b482eadfa0f6f412c80d380c3. * firdst draft * initialize object * null handle * update contracts * compilation charges * fix tests * public API changes * add docs * contract updated * fixed tests * by default switch of te;emetry in sdk * fix tests * fix assertion * incorporate review comments * fetaure flag fix in script * switch case * add test * fix tests * fix test * fixed run.sh * minor changes * code refactor * changed default values and fix tests * [Internal] Build: Adds CodeQL support in nightly builds (#4113) * Update azure-pipelines-nightly.yml * Newlines in variables sections * Benchmark: Fixes to show estimated cost of a container only when new container is getting created (#4109) * Showing Estimated Cost only when new container is getting created * read container to get container response * disable client telemetry by default * removed unused imports * resolve merge conflict * fixed name * fix container not found * removed the message * Update Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/Program.cs Co-authored-by: Matias Quaranta * removed line space --------- Co-authored-by: Kiran Kumar Kolli Co-authored-by: Matias Quaranta * Distributed Tracing: Fixes SDK responses compatibility with opentelemetry response (#4097) * adding tets * wip * wip2 * fix code * add tests * fix test * fix test * remove consoles * fix indent and remove unused imports * internal to private rollback * added docs * removed unused imports * added exception in message * fix exception catching * Revert "Query: Adds new system strings in JsonBinaryEncoding, replacing 1-byte user strings (#3400)" (#4108) This reverts commit 9140890d788cd43d5668d12072be6b965995a28a. * CosmosClientOptions: Adds support for multiple formats of Azure region names (#4016) * Allow ComosClientOptions to take ApplicationRegion and ApplicationPreferredRegions in multiple region name formats. This is a proposed fix for - https://github.com/Azure/azure-cosmos-dotnet-v3/issues/2330 * Address PR comment to avoid duplicating list of names. * Remove the map table cache The map table is only used on initialization, so there's no need to keep a cache of it for the lifetime of the application * Only convert the region names when the client is initializing The cache is created before converting all the names, so it only needs created once, but doesn't remain for the entire lifetime of the application * Update tests * Make RegionNameMapper an instantiable class Instead of having a prepare/clear cache system on a static class, make RegionNameMapper a class that gets instantiated for use and let the ctor handle it. * Remove debugging * Update tests to actually test things --------- Co-authored-by: Pradeep Chellappan Co-authored-by: Pradeep Chellappan <94089783+pradeep-chellappan@users.noreply.github.com> Co-authored-by: Matias Quaranta Co-authored-by: Kiran Kumar Kolli * Distributed Tracing: Fixes traceid null exception issue (#4111) * Fix traceid null exception issue * Fixing merge conflicts * Fixing merge conflicts * Update script * Code cleanup * Updated change description * updated comment description * updated comment description --------- Co-authored-by: Matias Quaranta * Telemetry Options: Adds telemetry options in GA package (#4117) * GA telemetry options and updated contract * enabe requuest level option * added request option in public contract * [Internal] Direct Package: Adds version bump (#4120) * direct version bump * Code changes to fix emulator tests to comply with direct release 3.31.5. --------- Co-authored-by: Debdatta Kunda * Query : Adds Missing QueryMetrics Documentation (#4127) * Update ServerSidePartitionedMetrics.cs * Update ServerSidePartitionedMetrics.cs * TriggerOperation: Adds Upsert Operation Support (#4119) * Added Upsert Trigger Operation Support * updated contract * fix test * SDK 3.36.0 : Adds version bump and changelog (#4118) * first draft * updated changelog * remove already released PRs * updated pr links * changelog and contract changes * updated changelog * updated changelog * updated changelog * remove 4071 from changelog as it should be internal PR * removed an query internal log * updated contracts * Release 3.36.0: Fixes pipeline by removing ReleasePackage variable (#4130) * remove release variable * revert build config variable change also * Item Operations: Fixes JsonSerialization exception when MissingMemberHandling = Error on Json default settings when NotFound on Item operations. (#4125) * issue 4115 initial checkin. need insight from issuer on reproducing this issue * test refactoring and adding more coverage for other NotFound scenarios * commit on some actionables * setting JsonConvert.DefaultSettings to null so that other tests will not fail * as requested, removed catches from test methods * [Internal] Query : Adds test coverage for custom serializers (#4114) * initial cleanup * test updates - working * cleanup * more cleanup * more * whoops * Add results to basline * adding payload to xml * some generics * cleanup * Add datamember serializer * reorder functions and test fix * tostring() update and add case * fix payload * fix datamembertest * cleanup * cleanup * PR comment --------- Co-authored-by: Matias Quaranta * Release 3.36.0 : Fixes Client Telemetry Release Test (#4132) * Client Telemetry Release test fix * get endpoint from env variable * read client telemetry endpoint service from env * updated yaml * Update CosmosItemTests.cs (#4141) * Code changes to sync up cosmos v3 master with direct release 3.31.5. --------- Co-authored-by: Matias Quaranta Co-authored-by: neildsh <35383880+neildsh@users.noreply.github.com> Co-authored-by: Sourabh Jain Co-authored-by: Sourabh Jain Co-authored-by: aavasthy <113193425+aavasthy@users.noreply.github.com> Co-authored-by: Kiran Kumar Kolli Co-authored-by: Aditya Co-authored-by: Fabian Meiswinkel Co-authored-by: akotalwar <94020786+akotalwar@users.noreply.github.com> Co-authored-by: Nalu Tripician Co-authored-by: Nalu Tripician Co-authored-by: Pramod Valavala <43602528+PramodValavala-MSFT@users.noreply.github.com> Co-authored-by: Ezra Haleva <115735172+ezrahaleva-msft@users.noreply.github.com> Co-authored-by: Vivek Ravindran Co-authored-by: Prasad Ullal <36418906+prasadu-microsoft@users.noreply.github.com> Co-authored-by: Philip Thomas <86612891+philipthomas-MSFT@users.noreply.github.com> Co-authored-by: Arthur Augsten Co-authored-by: Augsten Co-authored-by: Ruben Bartelink Co-authored-by: Santosh Kulkarni <66682828+kr-santosh@users.noreply.github.com> Co-authored-by: pravengithub <124255233+pravengithub@users.noreply.github.com> Co-authored-by: DESKTOP-ED57J7H\Prashanth Venkataram Co-authored-by: Justine Cocchi Co-authored-by: Abhijeet Mohanty Co-authored-by: Achint-Agrawal <45819170+Achint-Agrawal@users.noreply.github.com> Co-authored-by: Nimit Shah Co-authored-by: SaurabhSharma-MSFT <38112130+SaurabhSharma-MSFT@users.noreply.github.com> Co-authored-by: leminh98 Co-authored-by: Minh Le Co-authored-by: Nalu Tripician <27316859+NaluTripician@users.noreply.github.com> Co-authored-by: Scott Addie <10702007+scottaddie@users.noreply.github.com> Co-authored-by: Kevin Pilch Co-authored-by: Amaan-Haque <54414760+Amaan-Haque@users.noreply.github.com> Co-authored-by: Amaan Haque Co-authored-by: Amaan Haque Co-authored-by: Baltima <130716409+Baltima@users.noreply.github.com> Co-authored-by: vipulvishal-ms <110802706+vipulvishal-ms@users.noreply.github.com> Co-authored-by: Erik O'Leary <969938+onionhammer@users.noreply.github.com> Co-authored-by: Rinat Minibaev <132935507+rinatmini@users.noreply.github.com> Co-authored-by: Maya-Painter <130110800+Maya-Painter@users.noreply.github.com> Co-authored-by: jiajunpeng-msft <32749342+jiajunpeng-msft@users.noreply.github.com> Co-authored-by: Jiajun Peng Co-authored-by: Heet Co-authored-by: microsoft-github-policy-service[bot] <77245923+microsoft-github-policy-service[bot]@users.noreply.github.com> Co-authored-by: ernesto1596 Co-authored-by: Mikhail Lipin Co-authored-by: Mikhail Lipin Co-authored-by: David Chaava Co-authored-by: David Chaava Co-authored-by: SrinikhilReddy Co-authored-by: Kevin Pilch Co-authored-by: iain Co-authored-by: Pradeep Chellappan Co-authored-by: Pradeep Chellappan <94089783+pradeep-chellappan@users.noreply.github.com> --- .github/policies/resourceManagement.yml | 14 + Directory.Build.props | 10 +- .../changelog.md | 10 + .../src/EncryptionContainer.cs | 17 +- .../Microsoft.Azure.Cosmos.Encryption.csproj | 4 +- .../tests/EmulatorTests/MdeEncryptionTests.cs | 388 +++- .../Benchmark/AzureVmBenchmark/README.md | 111 ++ .../AzureVmBenchmark/azuredeploy.json | 1161 ++++++++++++ .../AzureVmBenchmark/scripts/custom-script.sh | 28 + .../AzureVmBenchmark/scripts/execute.sh | 9 + .../AzureVmBenchmark/system/cloud-init.txt | 13 + .../Tools/Benchmark/BenchmarkConfig.cs | 67 +- .../Benchmark/BenchmarkLatencyEventSource.cs | 17 +- .../Tools/Benchmark/BenchmarkProgress.cs | 55 + .../Tools/Benchmark/CosmosBenchmark.csproj | 2 + .../Benchmark/CosmosBenchmarkEventListener.cs | 92 + .../Benchmark/Fx/DiagnosticDataListener.cs | 227 +++ .../Tools/Benchmark/Fx/IExecutionStrategy.cs | 2 +- .../Tools/Benchmark/Fx/IExecutor.cs | 3 +- .../Tools/Benchmark/Fx/IMetricsCollector.cs | 24 + .../Tools/Benchmark/Fx/MetricsCollector.cs | 177 ++ .../Tools/Benchmark/Fx/OperationResult.cs | 1 + .../Benchmark/Fx/ParallelExecutionStrategy.cs | 20 +- .../Benchmark/Fx/SerialOperationExecutor.cs | 16 +- .../Tools/Benchmark/Fx/TelemetrySpan.cs | 57 +- .../Tools/Benchmark/MetricCollectionWindow.cs | 45 + .../Tools/Benchmark/Program.cs | 156 +- .../Tools/Benchmark/README.md | 9 +- .../Tools/Benchmark/Utility.cs | 6 + .../Tools/Benchmark/loop.sh | 1 - .../v2/InsertV2BenchmarkOperation.cs | 1 + ...QueryStreamSinglePkV2BenchmarkOperation.cs | 1 + .../v2/QueryTSinglePkV2BenchmarkOperation.cs | 1 + .../v2/ReadFeedStreamV2BenchmarkOperation.cs | 1 + .../v2/ReadNotExistsV2BenchmarkOperation.cs | 1 + .../ReadStreamExistsV2BenchmarkOperation.cs | 1 + .../v2/ReadTExistsV2BenchmarkOperation.cs | 1 + .../v3/InsertV3BenchmarkOperation.cs | 1 + .../v3/QueryTV3BenchmarkOperation.cs | 1 + .../v3/ReadFeedStreamV3BenchmarkOperation.cs | 1 + .../v3/ReadNotExistsV3BenchmarkOperation.cs | 1 + .../ReadStreamExistsV3BenchmarkOperation.cs | 1 + ...istsWithDiagnosticsV3BenchmarkOperation.cs | 1 + .../v3/ReadTExistsV3BenchmarkOperation.cs | 1 + .../Tools/CTL/CTLConfig.cs | 21 +- .../Tools/CTL/Program.cs | 14 - .../CosmosBenchmarkTests.csproj | 23 + .../Fx/DiagnosticDataListenerTests.cs | 54 + .../Usage/Cosmos.Samples.Usage.sln | 8 +- .../CustomDiagnosticAndEventListener.cs | 167 ++ .../CustomDiagnosticAndEventListener.csproj | 20 + .../Program.cs | 90 + .../contracts/API_3.35.3-preview.txt | 1563 ++++++++++++++++ .../contracts/API_3.35.3.txt | 1502 +++++++++++++++ .../contracts/API_3.35.4-preview.txt | 1563 ++++++++++++++++ .../contracts/API_3.35.4.txt | 1502 +++++++++++++++ .../contracts/API_3.36.0-preview.txt | 1610 +++++++++++++++++ .../contracts/API_3.36.0.txt | 1551 ++++++++++++++++ .../src/ConnectionPolicy.cs | 25 +- Microsoft.Azure.Cosmos/src/CosmosClient.cs | 26 +- .../src/CosmosClientOptions.cs | 52 +- .../src/CosmosClientTelemetryOptions.cs | 38 + .../src/CosmosThresholdOptions.cs | 26 + .../src/Diagnostics/CosmosDiagnostics.cs | 20 +- .../src/Diagnostics/CosmosTraceDiagnostics.cs | 24 +- Microsoft.Azure.Cosmos/src/DocumentClient.cs | 81 +- .../src/Fluent/CosmosClientBuilder.cs | 71 +- .../src/GlobalSuppressions.cs | 818 ++++++++- .../src/Handler/ClientPipelineBuilder.cs | 9 +- .../src/Handler/DiagnosticsHandler.cs | 4 +- .../src/Handler/DiagnosticsHandlerHelper.cs | 78 +- .../src/Handler/ResponseMessage.cs | 22 +- .../src/Handler/TelemetryHandler.cs | 38 +- .../JsonBinaryEncoding.FirstValueOffsets.cs | 4 +- .../src/Json/JsonBinaryEncoding.NodeTypes.cs | 4 +- .../Json/JsonBinaryEncoding.StringLengths.cs | 24 +- .../src/Json/JsonBinaryEncoding.Strings.cs | 29 +- .../Json/JsonBinaryEncoding.SystemStrings.cs | 214 +-- .../Json/JsonBinaryEncoding.SystemStrings.tt | 32 - .../src/Json/JsonBinaryEncoding.TypeMarker.cs | 33 +- .../Json/JsonBinaryEncoding.ValueLengths.cs | 4 +- .../src/Json/JsonReader.JsonBinaryReader.cs | 4 +- .../src/Json/JsonWriter.JsonBinaryWriter.cs | 12 +- .../BuiltinFunctionVisitor.cs | 7 + .../StringBuiltinFunctions.cs | 41 + .../src/Linq/CosmosLinqExtensions.cs | 44 + .../src/Linq/ExpressionToSQL.cs | 15 +- .../src/Microsoft.Azure.Cosmos.csproj | 76 +- .../ClientDistributionPlanDeserializer.cs | 561 ++++++ .../Cql/ClientDistributionPlan.cs | 18 + .../Cql/CqlAggregate.cs | 16 + .../Cql/CqlAggregateEnumerableExpression.cs | 22 + .../Cql/CqlAggregateKind.cs | 12 + .../Cql/CqlAggregateOperatorKind.cs | 19 + .../Cql/CqlArrayCreateScalarExpression.cs | 25 + .../Cql/CqlArrayIndexerScalarExpression.cs | 22 + .../Cql/CqlArrayLiteral.cs | 20 + .../Cql/CqlBinaryScalarExpression.cs | 25 + .../Cql/CqlBinaryScalarOperatorKind.cs | 29 + .../Cql/CqlBooleanLiteral.cs | 17 + .../Cql/CqlBuiltinAggregate.cs | 17 + .../Cql/CqlBuiltinScalarFunctionKind.cs | 126 ++ .../Cql/CqlDistinctEnumerableExpression.cs | 26 + .../Cql/CqlEnumerableExpression.cs | 16 + .../Cql/CqlEnumerableExpressionKind.cs | 20 + .../Cql/CqlEnumerationKind.cs | 14 + .../Cql/CqlFunctionIdentifier.cs | 18 + .../Cql/CqlGroupByEnumerableExpression.cs | 26 + .../Cql/CqlInputEnumerableExpression.cs | 19 + .../Cql/CqlIsOperatorKind.cs | 11 + .../Cql/CqlIsOperatorScalarExpression.cs | 23 + .../Cql/CqlLetScalarExpression.cs | 25 + .../ClientDistributionPlan/Cql/CqlLiteral.cs | 16 + .../Cql/CqlLiteralKind.cs | 17 + .../Cql/CqlLiteralScalarExpression.cs | 19 + .../Cql/CqlMuxScalarExpression.cs | 25 + .../Cql/CqlNullLiteral.cs | 16 + .../Cql/CqlNumberLiteral.cs | 19 + .../Cql/CqlObjectCreateScalarExpression.cs | 25 + .../Cql/CqlObjectLiteral.cs | 20 + .../Cql/CqlObjectLiteralProperty.cs | 21 + .../Cql/CqlObjectProperty.cs | 21 + .../Cql/CqlOrderByEnumerableExpression.cs | 26 + .../Cql/CqlOrderByItem.cs | 21 + .../Cql/CqlPropertyRefScalarExpression.cs | 23 + .../Cql/CqlScalarAsEnumerableExpression.cs | 22 + .../Cql/CqlScalarExpression.cs | 16 + .../Cql/CqlScalarExpressionKind.cs | 25 + .../Cql/CqlSelectEnumerableExpression.cs | 25 + .../Cql/CqlSelectManyEnumerableExpression.cs | 25 + .../Cql/CqlSortOrder.cs | 12 + .../Cql/CqlStringLiteral.cs | 19 + .../CqlSystemFunctionCallScalarExpression.cs | 23 + .../Cql/CqlTakeEnumerableExpression.cs | 25 + .../Cql/CqlTupleAggregate.cs | 20 + .../Cql/CqlTupleCreateScalarExpression.cs | 20 + .../Cql/CqlTupleItemRefScalarExpression.cs | 22 + .../Cql/CqlUnaryScalarExpression.cs | 22 + .../Cql/CqlUnaryScalarOperatorKind.cs | 14 + .../Cql/CqlUndefinedLiteral.cs | 16 + ...UserDefinedFunctionCallScalarExpression.cs | 26 + .../ClientDistributionPlan/Cql/CqlVariable.cs | 21 + .../Cql/CqlVariableRefScalarExpression.cs | 19 + .../Cql/CqlWhereEnumerableExpression.cs | 25 + .../src/Query/Core/Metrics/BackendMetrics.cs | 237 --- .../Query/Core/Metrics/ClientSideMetrics.cs | 38 - .../Metrics/ClientSideMetricsAccumulator.cs | 47 + .../Metrics/CompositeIndexIndexMetrics.cs | 48 + .../Query/Core/Metrics/IndexMetricsInfo.cs | 83 + .../Core/Metrics/IndexMetricsInfoEntity.cs | 43 + ...xMetricWriter.cs => IndexMetricsWriter.cs} | 34 +- .../Core/Metrics/IndexUtilizationInfo.cs | 80 +- .../IndexUtilizationInfoAccumulator.cs | 51 + .../src/Query/Core/Metrics/QueryMetrics.cs | 70 +- .../Core/Metrics/QueryMetricsAccumulator.cs | 48 + .../Core/Metrics/QueryMetricsTextWriter.cs | 4 +- .../Query/Core/Metrics/QueryMetricsWriter.cs | 28 +- .../Core/Metrics/QueryPreparationTimes.cs | 104 -- .../QueryPreparationTimesAccumulator.cs | 51 + .../Metrics/QueryPreparationTimesInternal.cs | 65 + .../Core/Metrics/RuntimeExecutionTimes.cs | 91 - .../RuntimeExecutionTimesAccumulator.cs | 48 + .../Metrics/RuntimeExecutionTimesInternal.cs | 56 + .../Metrics/ServerSideCumulativeMetrics.cs | 23 + .../ServerSideCumulativeMetricsInternal.cs | 29 + .../Query/Core/Metrics/ServerSideMetrics.cs | 74 + .../Core/Metrics/ServerSideMetricsInternal.cs | 153 ++ .../ServerSideMetricsInternalAccumulator.cs | 146 ++ ...csParser.cs => ServerSideMetricsParser.cs} | 164 +- ...nizer.cs => ServerSideMetricsTokenizer.cs} | 4 +- .../Core/Metrics/ServerSideMetricsUtils.cs | 13 + .../Metrics/ServerSidePartitionedMetrics.cs | 30 + .../ServerSidePartitionedMetricsInternal.cs | 40 + .../Core/Metrics/SingleIndexIndexMetrics.cs | 47 + .../src/Query/Core/Parser/CstToAstVisitor.cs | 42 +- .../CosmosQueryExecutionContextFactory.cs | 127 +- ...imisticDirectExecutionContinuationToken.cs | 16 +- .../QueryClient/ContainerQueryProperties.cs | 11 +- .../Core/QueryClient/CosmosQueryClient.cs | 9 +- .../DefaultDocumentQueryExecutionContext.cs | 2 +- .../Query/v3Query/CosmosQueryClientCore.cs | 35 +- .../src/Query/v3Query/QueryResponse.cs | 9 +- .../src/RMResources.Designer.cs | 5 +- .../src/RegionNameMapper.cs | 53 + .../src/RequestOptions/QueryRequestOptions.cs | 1 + .../src/RequestOptions/RequestOptions.cs | 5 +- .../src/Resource/ClientContextCore.cs | 6 +- .../Resource/Container/ContainerCore.Items.cs | 5 - .../CosmosExceptionFactory.cs | 9 +- .../Settings/AccountClientConfiguration.cs | 29 + .../Settings/ClientTelemetryConfiguration.cs | 27 + .../DedicatedGatewayRequestOptions.cs | 4 +- .../src/Resource/Settings/TriggerOperation.cs | 7 +- Microsoft.Azure.Cosmos/src/RetryOptions.cs | 4 +- .../src/Routing/ClientCollectionCache.cs | 42 +- .../src/Routing/GatewayAddressCache.cs | 27 +- .../src/Routing/PartitionKeyHash.cs | 30 +- .../src/Routing/PartitionKeyHashRange.cs | 2 +- .../src/Routing/PartitionKeyHashRanges.cs | 14 +- .../Serializer/CosmosLinqSerializerOptions.cs | 4 - .../SqlFunctionCallScalarExpression.cs | 3 + .../src/Telemetry/ClientTelemetry.cs | 159 +- .../src/Telemetry/ClientTelemetryOptions.cs | 67 +- .../src/Telemetry/ClientTelemetryProcessor.cs | 12 +- .../Collector/ITelemetryCollector.cs | 25 + .../Telemetry/Collector/TelemetryCollector.cs | 77 + .../Collector/TelemetryCollectorNoOp.cs | 21 + .../Collector/TelemetryInformation.cs | 30 + .../OpenTelemetry/CosmosDbEventSource.cs | 4 +- .../DistributedTracingOptions.cs | 30 - .../Filters/DiagnosticsFilterHelper.cs | 59 +- .../OpenTelemetryCoreRecorder.cs | 23 +- .../OpenTelemetryRecorderFactory.cs | 28 +- .../OpenTelemetry/OpenTelemetryResponse.cs | 52 +- .../OpenTelemetry/OpenTelemetryResponse{T}.cs | 56 +- .../src/Telemetry/TelemetryToServiceHelper.cs | 256 +++ .../src/Telemetry/VmMetadataApiHandler.cs | 6 +- .../ClientSideRequestStatisticsTraceDatum.cs | 2 +- .../src/Util/ConfigurationManager.cs | 4 +- .../src/direct/AddressEnumerator.cs | 18 +- Microsoft.Azure.Cosmos/src/direct/Channel.cs | 46 +- .../src/direct/ChannelCallArguments.cs | 30 + .../src/direct/ChannelDictionary.cs | 42 +- .../src/direct/ClientSideRequestStatistics.cs | 3 +- .../src/direct/CustomTypeExtensions.cs | 2 +- .../src/direct/Dispatcher.cs | 32 +- .../src/direct/DocumentCollection.cs | 2 + .../direct/DocumentServiceRequestContext.cs | 6 + .../FaultInjection/IChaosInterceptor.cs | 56 + .../src/direct/GoneAndRetryWithRetryPolicy.cs | 3 - .../src/direct/IChannelDictionary.cs | 20 + .../direct/IClientSideRequestStatistics.cs | 7 +- .../direct/LinuxSystemUtilizationReader.cs | 2 - .../src/direct/LoadBalancingChannel.cs | 17 +- .../src/direct/LoadBalancingPartition.cs | 84 +- Microsoft.Azure.Cosmos/src/direct/Snapshot.cs | 2 + .../src/direct/StoreClientFactory.cs | 10 +- .../src/direct/TimerPool.cs | 1 - .../src/direct/ValueStopwatch.cs | 6 +- .../direct/WindowsSystemUtilizationReader.cs | 2 - .../src/direct/rntbd2/TransportClient.cs | 19 +- ...iterBaselineTests.BatchOperationsAsync.xml | 37 +- ...riterBaselineTests.BulkOperationsAsync.xml | 983 +++++----- ...aceWriterBaselineTests.ChangeFeedAsync.xml | 888 +++++---- ...eWriterBaselineTests.MiscellanousAsync.xml | 86 +- ...neTests.PointOperationsExceptionsAsync.xml | 725 ++++---- ...EndTraceWriterBaselineTests.QueryAsync.xml | 1079 ++++++----- ...TraceWriterBaselineTests.ReadFeedAsync.xml | 592 +++--- ...TraceWriterBaselineTests.ReadManyAsync.xml | 222 ++- ...selineTests.StreamPointOperationsAsync.xml | 148 +- ...aselineTests.TypedPointOperationsAsync.xml | 148 +- ...onBaselineTests.TestRegexMatchFunction.xml | 170 ++ ...slationBaselineTests.TestStringCompare.xml | 120 +- ...seline.TestMemberInitializerDataMember.xml | 236 +++ ...erBaseline.TestMemberInitializerDotNet.xml | 236 +++ ...e.TestMemberInitializerMultiSerializer.xml | 236 +++ ...seline.TestMemberInitializerNewtonsoft.xml | 236 +++ .../ClientCreateAndInitializeTest.cs | 7 +- .../ClientTelemetryConfigurationTest.cs | 274 +++ .../ClientTelemetryReleaseTests.cs | 157 ++ .../ClientTelemetryTests.cs | 1089 +---------- .../ClientTelemetryTestsBase.cs | 1057 +++++++++++ .../CosmosBasicQueryTests.cs | 53 +- .../CosmosItemLinqTests.cs | 59 +- .../CosmosItemTests.cs | 494 ++++- .../CosmosQueryClientCoreTest.cs | 2 +- .../CustomSerializationTests.cs | 32 +- .../DistributedTracingOTelTests.cs | 96 +- .../IndexMetricsParserBaselineTest.cs | 1 + .../LinqAggregateFunctionsBaselineTests.cs | 8 +- .../LinqAttributeContractBaselineTests.cs | 0 .../LinqConstantFoldingBaselineTests.cs | 0 .../{ => Linq}/LinqGeneralBaselineTests.cs | 85 +- .../LinqSQLTranslationBaselineTests.cs | 20 +- .../{ => Linq}/LinqTestData.cs | 2 +- .../{ => Linq}/LinqTestsCommon.cs | 136 +- .../LinqTranslationBaselineTests.cs | 41 +- ...TranslationWithCustomSerializerBaseline.cs | 407 +++++ ...icrosoft.Azure.Cosmos.EmulatorTests.csproj | 22 +- .../Query/PopulateIndexMetricsTest.cs | 10 - .../ContentSerializationPerformanceTests.cs | 18 +- .../QueryPerfTest/MetricsAccumulator.cs | 8 +- ...timisticDirectExecutionPerformanceTests.cs | 469 +++++ .../QueryStatisticsDatumVisitor.cs | 14 +- .../QueryPerfTest/QueryStatisticsMetrics.cs | 6 + .../QueryTests.cs | 28 +- .../SynchronizationContextTests.cs | 46 +- .../Tracing/AssertActivity.cs | 72 +- .../Tracing/CustomListener.cs | 29 +- .../Tracing/CustomOtelExporter.cs | 3 +- .../EndToEndTraceWriterBaselineTests.cs | 67 +- .../TriggersTests.cs | 60 +- .../Utils/HttpHandlerHelper.cs | 18 +- .../Utils/TestCommon.cs | 3 +- .../Utils/TransportClientHelper.cs | 9 +- .../Utils/Util.cs | 14 - .../settings.json | 18 +- .../Contracts/BenchmarkResults.json | 2 +- .../Mocks/HttpHandlerHelper.cs | 67 + .../Mocks/MockDocumentClient.cs | 75 +- .../Query/Metrics/Performance.cs | 2 +- .../BaselineTest/BaselineTests.cs | 4 +- ...tClientDistributionPlanDeserialization.xml | 606 +++++++ .../PartitionKeyHashBaselineTest.Lists.xml | 32 + ...onSqlParserBaselineTests.StringLiteral.xml | 38 + .../TraceWriterBaselineTests.TraceData.xml | 2 +- .../Contracts/DotNetPreviewSDKAPI.json | 36 - .../Contracts/DotNetSDKAPI.json | 372 ++++ .../CosmosClientOptionsUnitTests.cs | 185 +- .../CosmosClientTests.cs | 34 +- .../DiagnosticHandlerHelperTests.cs | 98 + .../HandlerTests.cs | 24 +- .../Json/JsonReaderTests.cs | 20 +- .../Json/JsonWriterTests.cs | 20 +- .../Microsoft.Azure.Cosmos.Tests.csproj | 9 + .../Pagination/InMemoryContainer.cs | 164 +- .../ClientDistributionPlanBaselineTests.cs | 100 + .../Query/Metrics/ClientSideMetricsTests.cs | 8 +- .../Metrics/IndexUtilizationInfoTests.cs | 13 +- .../Query/Metrics/QueryMetricsTests.cs | 16 +- ...ricsTests.cs => ServerSideMetricsTests.cs} | 68 +- ...misticDirectExecutionQueryBaselineTests.cs | 145 +- .../ScalarExpressionSqlParserBaselineTests.cs | 24 + .../Query/SplitPartitionQueryTests.cs | 77 + .../Routing/PartitionKeyHashBaselineTest.cs | 63 + .../PartitionKeyHashRangeSplitterAndMerger.cs | 49 +- .../SettingsContractTests.cs | 13 +- .../Telemetry/ClientTelemetryTests.cs | 22 +- .../Telemetry/DiagnosticsFilterHelperTest.cs | 36 +- .../Telemetry/OpenTelemetryRecorderTests.cs | 201 ++ .../Tracing/TraceWriterBaselineTests.cs | 4 +- .../Utils/MockCosmosUtil.cs | 18 +- .../Utils/MockDocumentClient.cs | 17 +- azure-pipelines-nightly.yml | 7 +- azure-pipelines-official.yml | 33 + changelog.md | 52 +- docs/LocalQuorum.md | 10 +- templates/build-test.yml | 6 +- 338 files changed, 28075 insertions(+), 5683 deletions(-) create mode 100644 Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/AzureVmBenchmark/README.md create mode 100644 Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/AzureVmBenchmark/azuredeploy.json create mode 100644 Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/AzureVmBenchmark/scripts/custom-script.sh create mode 100644 Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/AzureVmBenchmark/scripts/execute.sh create mode 100644 Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/AzureVmBenchmark/system/cloud-init.txt create mode 100644 Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/BenchmarkProgress.cs create mode 100644 Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/CosmosBenchmarkEventListener.cs create mode 100644 Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/Fx/DiagnosticDataListener.cs create mode 100644 Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/Fx/IMetricsCollector.cs create mode 100644 Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/Fx/MetricsCollector.cs create mode 100644 Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/MetricCollectionWindow.cs create mode 100644 Microsoft.Azure.Cosmos.Samples/Tools/CosmosBenchmarkTests/CosmosBenchmarkTests.csproj create mode 100644 Microsoft.Azure.Cosmos.Samples/Tools/CosmosBenchmarkTests/Fx/DiagnosticDataListenerTests.cs create mode 100644 Microsoft.Azure.Cosmos.Samples/Usage/CustomDiagnosticAndEventListener/CustomDiagnosticAndEventListener.cs create mode 100644 Microsoft.Azure.Cosmos.Samples/Usage/CustomDiagnosticAndEventListener/CustomDiagnosticAndEventListener.csproj create mode 100644 Microsoft.Azure.Cosmos.Samples/Usage/CustomDiagnosticAndEventListener/Program.cs create mode 100644 Microsoft.Azure.Cosmos/contracts/API_3.35.3-preview.txt create mode 100644 Microsoft.Azure.Cosmos/contracts/API_3.35.3.txt create mode 100644 Microsoft.Azure.Cosmos/contracts/API_3.35.4-preview.txt create mode 100644 Microsoft.Azure.Cosmos/contracts/API_3.35.4.txt create mode 100644 Microsoft.Azure.Cosmos/contracts/API_3.36.0-preview.txt create mode 100644 Microsoft.Azure.Cosmos/contracts/API_3.36.0.txt create mode 100644 Microsoft.Azure.Cosmos/src/CosmosClientTelemetryOptions.cs create mode 100644 Microsoft.Azure.Cosmos/src/CosmosThresholdOptions.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/ClientDistributionPlanDeserializer.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/ClientDistributionPlan.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlAggregate.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlAggregateEnumerableExpression.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlAggregateKind.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlAggregateOperatorKind.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlArrayCreateScalarExpression.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlArrayIndexerScalarExpression.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlArrayLiteral.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlBinaryScalarExpression.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlBinaryScalarOperatorKind.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlBooleanLiteral.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlBuiltinAggregate.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlBuiltinScalarFunctionKind.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlDistinctEnumerableExpression.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlEnumerableExpression.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlEnumerableExpressionKind.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlEnumerationKind.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlFunctionIdentifier.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlGroupByEnumerableExpression.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlInputEnumerableExpression.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlIsOperatorKind.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlIsOperatorScalarExpression.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlLetScalarExpression.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlLiteral.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlLiteralKind.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlLiteralScalarExpression.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlMuxScalarExpression.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlNullLiteral.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlNumberLiteral.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlObjectCreateScalarExpression.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlObjectLiteral.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlObjectLiteralProperty.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlObjectProperty.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlOrderByEnumerableExpression.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlOrderByItem.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlPropertyRefScalarExpression.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlScalarAsEnumerableExpression.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlScalarExpression.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlScalarExpressionKind.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlSelectEnumerableExpression.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlSelectManyEnumerableExpression.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlSortOrder.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlStringLiteral.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlSystemFunctionCallScalarExpression.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlTakeEnumerableExpression.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlTupleAggregate.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlTupleCreateScalarExpression.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlTupleItemRefScalarExpression.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlUnaryScalarExpression.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlUnaryScalarOperatorKind.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlUndefinedLiteral.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlUserDefinedFunctionCallScalarExpression.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlVariable.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlVariableRefScalarExpression.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlWhereEnumerableExpression.cs delete mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/Metrics/BackendMetrics.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ClientSideMetricsAccumulator.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/Metrics/CompositeIndexIndexMetrics.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/Metrics/IndexMetricsInfo.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/Metrics/IndexMetricsInfoEntity.cs rename Microsoft.Azure.Cosmos/src/Query/Core/Metrics/{IndexMetricWriter.cs => IndexMetricsWriter.cs} (65%) create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/Metrics/IndexUtilizationInfoAccumulator.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/Metrics/QueryMetricsAccumulator.cs delete mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/Metrics/QueryPreparationTimes.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/Metrics/QueryPreparationTimesAccumulator.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/Metrics/QueryPreparationTimesInternal.cs delete mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/Metrics/RuntimeExecutionTimes.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/Metrics/RuntimeExecutionTimesAccumulator.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/Metrics/RuntimeExecutionTimesInternal.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideCumulativeMetrics.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideCumulativeMetricsInternal.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideMetrics.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideMetricsInternal.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideMetricsInternalAccumulator.cs rename Microsoft.Azure.Cosmos/src/Query/Core/Metrics/{BackendMetricsParser.cs => ServerSideMetricsParser.cs} (53%) rename Microsoft.Azure.Cosmos/src/Query/Core/Metrics/{BackendMetricsTokenizer.cs => ServerSideMetricsTokenizer.cs} (98%) create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideMetricsUtils.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSidePartitionedMetrics.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSidePartitionedMetricsInternal.cs create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/Metrics/SingleIndexIndexMetrics.cs create mode 100644 Microsoft.Azure.Cosmos/src/RegionNameMapper.cs create mode 100644 Microsoft.Azure.Cosmos/src/Resource/Settings/AccountClientConfiguration.cs create mode 100644 Microsoft.Azure.Cosmos/src/Resource/Settings/ClientTelemetryConfiguration.cs create mode 100644 Microsoft.Azure.Cosmos/src/Telemetry/Collector/ITelemetryCollector.cs create mode 100644 Microsoft.Azure.Cosmos/src/Telemetry/Collector/TelemetryCollector.cs create mode 100644 Microsoft.Azure.Cosmos/src/Telemetry/Collector/TelemetryCollectorNoOp.cs create mode 100644 Microsoft.Azure.Cosmos/src/Telemetry/Collector/TelemetryInformation.cs delete mode 100644 Microsoft.Azure.Cosmos/src/Telemetry/OpenTelemetry/DistributedTracingOptions.cs create mode 100644 Microsoft.Azure.Cosmos/src/Telemetry/TelemetryToServiceHelper.cs create mode 100644 Microsoft.Azure.Cosmos/src/direct/FaultInjection/IChaosInterceptor.cs create mode 100644 Microsoft.Azure.Cosmos/src/direct/IChannelDictionary.cs create mode 100644 Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/BaselineTest/TestBaseline/LinqTranslationBaselineTests.TestRegexMatchFunction.xml create mode 100644 Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/BaselineTest/TestBaseline/LinqTranslationWithCustomSerializerBaseline.TestMemberInitializerDataMember.xml create mode 100644 Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/BaselineTest/TestBaseline/LinqTranslationWithCustomSerializerBaseline.TestMemberInitializerDotNet.xml create mode 100644 Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/BaselineTest/TestBaseline/LinqTranslationWithCustomSerializerBaseline.TestMemberInitializerMultiSerializer.xml create mode 100644 Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/BaselineTest/TestBaseline/LinqTranslationWithCustomSerializerBaseline.TestMemberInitializerNewtonsoft.xml create mode 100644 Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/ClientTelemetryConfigurationTest.cs create mode 100644 Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/ClientTelemetryReleaseTests.cs create mode 100644 Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/ClientTelemetryTestsBase.cs rename Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/{ => Linq}/LinqAggregateFunctionsBaselineTests.cs (98%) rename Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/{ => Linq}/LinqAttributeContractBaselineTests.cs (100%) rename Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/{ => Linq}/LinqConstantFoldingBaselineTests.cs (100%) rename Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/{ => Linq}/LinqGeneralBaselineTests.cs (98%) rename Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/{ => Linq}/LinqSQLTranslationBaselineTests.cs (96%) rename Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/{ => Linq}/LinqTestData.cs (98%) rename Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/{ => Linq}/LinqTestsCommon.cs (84%) rename Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/{ => Linq}/LinqTranslationBaselineTests.cs (96%) create mode 100644 Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/LinqTranslationWithCustomSerializerBaseline.cs create mode 100644 Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/QueryPerfTest/OptimisticDirectExecutionPerformanceTests.cs create mode 100644 Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Performance.Tests/Mocks/HttpHandlerHelper.cs create mode 100644 Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/TestBaseline/ClientDistributionPlanBaselineTests.TestClientDistributionPlanDeserialization.xml create mode 100644 Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/TestBaseline/PartitionKeyHashBaselineTest.Lists.xml create mode 100644 Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/TestBaseline/ScalarExpressionSqlParserBaselineTests.StringLiteral.xml create mode 100644 Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Diagnostics/DiagnosticHandlerHelperTests.cs create mode 100644 Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/ClientDistributionPlanBaselineTests.cs rename Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Metrics/{BackendMetricsTests.cs => ServerSideMetricsTests.cs} (78%) create mode 100644 Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/SplitPartitionQueryTests.cs rename Microsoft.Azure.Cosmos/{src => tests/Microsoft.Azure.Cosmos.Tests}/Routing/PartitionKeyHashRangeSplitterAndMerger.cs (73%) diff --git a/.github/policies/resourceManagement.yml b/.github/policies/resourceManagement.yml index 8207a0708a..7d78118b0e 100644 --- a/.github/policies/resourceManagement.yml +++ b/.github/policies/resourceManagement.yml @@ -38,6 +38,20 @@ configuration: - addLabel: label: needs-investigation description: + - if: + - payloadType: Issues + - isAction: + action: Opened + - not: + or: + - activitySenderHasPermission: + permission: Write + - activitySenderHasPermission: + permission: Admin + then: + - addLabel: + label: customer-reported + description: Identifies issues created by users without write access as customers - if: - payloadType: Pull_Request - hasLabel: diff --git a/Directory.Build.props b/Directory.Build.props index b9171d6307..514e8e7abb 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,11 +1,11 @@ - 3.35.2 - 3.35.2 + 3.36.0 + 3.36.0 preview - 3.31.3 - 2.0.2 - 2.0.2 + 3.31.5 + 2.0.3 + 2.0.3 preview 1.0.0-preview06 1.1.0-preview3 diff --git a/Microsoft.Azure.Cosmos.Encryption/changelog.md b/Microsoft.Azure.Cosmos.Encryption/changelog.md index a8edf3441d..2f50fcbdf3 100644 --- a/Microsoft.Azure.Cosmos.Encryption/changelog.md +++ b/Microsoft.Azure.Cosmos.Encryption/changelog.md @@ -3,6 +3,16 @@ Preview features are treated as a separate branch and will not be included in th The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +### [2.0.3](https://www.nuget.org/packages/Microsoft.Azure.Cosmos.Encryption/2.0.3) - 2023-07-12 + +#### Added +- [#3979](https://github.com/Azure/azure-cosmos-dotnet-v3/pull/3979) Adds fix for supporting Prefix Partition Key (Hierarchical partitioning). + +### [2.0.3-preview](https://www.nuget.org/packages/Microsoft.Azure.Cosmos.Encryption/2.0.3-preview) - 2023-07-12 + +#### Added +- [#3979](https://github.com/Azure/azure-cosmos-dotnet-v3/pull/3979) Adds fix for supporting Prefix Partition Key (Hierarchical partitioning). + ### [2.0.2](https://www.nuget.org/packages/Microsoft.Azure.Cosmos.Encryption/2.0.2) - 2023-06-01 #### Added diff --git a/Microsoft.Azure.Cosmos.Encryption/src/EncryptionContainer.cs b/Microsoft.Azure.Cosmos.Encryption/src/EncryptionContainer.cs index d32bfa1c94..0bd342f0ef 100644 --- a/Microsoft.Azure.Cosmos.Encryption/src/EncryptionContainer.cs +++ b/Microsoft.Azure.Cosmos.Encryption/src/EncryptionContainer.cs @@ -957,15 +957,22 @@ internal async Task CheckIfIdIsEncryptedAndGetEncryptedIdAsync( JArray jArray = JArray.Parse(partitionKey.ToString()); #if ENCRYPTIONPREVIEW - if (jArray.Count > 1) + if (encryptionSettings.PartitionKeyPaths.Count > 1) { - int i = 0; + int counter = 0; PartitionKeyBuilder partitionKeyBuilder = new PartitionKeyBuilder(); + if (jArray.Count() > encryptionSettings.PartitionKeyPaths.Count()) + { + throw new NotSupportedException($"The number of partition keys passed in the query exceeds the number of keys initialized on the container. Container Id : {this.Id}"); + } bool isPkEncrypted = false; + // partitionKeyBuilder expects the paths and values to be in same order. - foreach (string path in encryptionSettings.PartitionKeyPaths) + for(counter = 0; counter < jArray.Count(); counter++) { + string path = encryptionSettings.PartitionKeyPaths[counter]; + // case: partition key path is /a/b/c and the client encryption policy has /a in path. // hence encrypt the partition key value with using its top level path /a since /c would have been encrypted in the document using /a's policy. string partitionKeyPath = path.Split('/')[1]; @@ -975,12 +982,12 @@ internal async Task CheckIfIdIsEncryptedAndGetEncryptedIdAsync( if (encryptionSettingForProperty == null) { - partitionKeyBuilder.Add(jArray[i++].ToString()); + partitionKeyBuilder.Add(jArray[counter].ToString()); continue; } isPkEncrypted = true; - Stream valueStream = EncryptionProcessor.BaseSerializer.ToStream(jArray[i++]); + Stream valueStream = EncryptionProcessor.BaseSerializer.ToStream(jArray[counter]); Stream encryptedPartitionKey = await EncryptionProcessor.EncryptValueStreamAsync( valueStreamToEncrypt: valueStream, diff --git a/Microsoft.Azure.Cosmos.Encryption/src/Microsoft.Azure.Cosmos.Encryption.csproj b/Microsoft.Azure.Cosmos.Encryption/src/Microsoft.Azure.Cosmos.Encryption.csproj index 94e93aa6fe..f7baa75f60 100644 --- a/Microsoft.Azure.Cosmos.Encryption/src/Microsoft.Azure.Cosmos.Encryption.csproj +++ b/Microsoft.Azure.Cosmos.Encryption/src/Microsoft.Azure.Cosmos.Encryption.csproj @@ -28,11 +28,11 @@ - + - + diff --git a/Microsoft.Azure.Cosmos.Encryption/tests/EmulatorTests/MdeEncryptionTests.cs b/Microsoft.Azure.Cosmos.Encryption/tests/EmulatorTests/MdeEncryptionTests.cs index 65efd425aa..3489cdf02e 100644 --- a/Microsoft.Azure.Cosmos.Encryption/tests/EmulatorTests/MdeEncryptionTests.cs +++ b/Microsoft.Azure.Cosmos.Encryption/tests/EmulatorTests/MdeEncryptionTests.cs @@ -189,6 +189,9 @@ public void TestInitialize() { // Reset static cache TTL Microsoft.Data.Encryption.Cryptography.ProtectedDataEncryptionKey.TimeToLive = TimeSpan.FromHours(2); + // flag to disable https://github.com/Azure/azure-cosmos-dotnet-v3/pull/3951 + // need to be removed after the fix + Environment.SetEnvironmentVariable("AZURE_COSMOS_REPLICA_VALIDATION_ENABLED", "False"); } private static async Task CreateClientEncryptionKeyAsync(string cekId, Cosmos.EncryptionKeyWrapMetadata encryptionKeyWrapMetadata) @@ -2303,7 +2306,7 @@ public async Task ValidatePkAndIdEncryptionSupport() VerifyExpectedDocResponse(testDoc, readResponse.Resource); #if ENCRYPTIONTESTPREVIEW - // hierarchical + // hierarchical pk container test cepWithPKIdPath1 = new ClientEncryptionIncludedPath() { Path = "/Sensitive_LongFormat", @@ -2352,9 +2355,320 @@ public async Task ValidatePkAndIdEncryptionSupport() Assert.AreEqual(HttpStatusCode.OK, readResponse.StatusCode); VerifyExpectedDocResponse(testDoc, readResponse.Resource); + + // test to validate query with one partition key (topmost) in hierarchical pk container of 3 keys + QueryRequestOptions queryRequestOptions = new QueryRequestOptions + { + PartitionKey = new PartitionKeyBuilder().Add(testDoc.Sensitive_StringFormat).Build() + }; + + using FeedIterator setIterator = encryptionContainer.GetItemQueryIterator("select * from c", requestOptions: queryRequestOptions); + + while (setIterator.HasMoreResults) + { + FeedResponse response = await setIterator.ReadNextAsync().ConfigureAwait(false); + Assert.AreEqual(HttpStatusCode.OK, response.StatusCode); + VerifyExpectedDocResponse(testDoc, response.First()); + } + + // test to validate query with one partition key (topmost) in hierarchical pk container of 3 keys with where clause on topmost pk + QueryDefinition queryDefinition = encryptionContainer.CreateQueryDefinition("SELECT * FROM c WHERE c.Sensitive_StringFormat = @Sensitive_StringFormat"); + + await queryDefinition.AddParameterAsync("@Sensitive_StringFormat", testDoc.Sensitive_StringFormat, "/Sensitive_StringFormat"); + + FeedIterator setIteratorWithFilter = encryptionContainer.GetItemQueryIterator(queryDefinition, requestOptions: queryRequestOptions); + + while (setIteratorWithFilter.HasMoreResults) + { + FeedResponse response = await setIteratorWithFilter.ReadNextAsync().ConfigureAwait(false); + Assert.AreEqual(HttpStatusCode.OK, response.StatusCode); + VerifyExpectedDocResponse(testDoc, response.First()); + } + + // test to validate query with one partition key (2nd topmost) in hierarchical pk container of 3 keys with where clause on topmost pk + // this shold give 0 items as PK is set wrongly + queryRequestOptions = new QueryRequestOptions + { + PartitionKey = new PartitionKeyBuilder().Add(testDoc.Sensitive_NestedObjectFormatL1.Sensitive_NestedObjectFormatL2.Sensitive_StringFormatL2).Build() + }; + + setIteratorWithFilter = encryptionContainer.GetItemQueryIterator(queryDefinition, requestOptions: queryRequestOptions); + + while (setIteratorWithFilter.HasMoreResults) + { + FeedResponse response = await setIteratorWithFilter.ReadNextAsync().ConfigureAwait(false); + Assert.AreEqual(HttpStatusCode.OK, response.StatusCode); + Assert.AreEqual(0, response.Count()); + } #endif } +#if ENCRYPTIONTESTPREVIEW + [TestMethod] + public async Task TestHirarchicalPkWithFullAndPartialKey() + { + HirarchicalPkTestDoc testDoc = HirarchicalPkTestDoc.Create(); + + ClientEncryptionIncludedPath cepWithPKIdPath1 = new ClientEncryptionIncludedPath() + { + Path = "/State", + ClientEncryptionKeyId = "key1", + EncryptionType = "Deterministic", + EncryptionAlgorithm = "AEAD_AES_256_CBC_HMAC_SHA256", + }; + + ClientEncryptionIncludedPath cepWithPKIdPath2 = new ClientEncryptionIncludedPath() + { + Path = "/City", + ClientEncryptionKeyId = "key1", + EncryptionType = "Deterministic", + EncryptionAlgorithm = "AEAD_AES_256_CBC_HMAC_SHA256", + }; + + ClientEncryptionIncludedPath cepWithPKIdPath3 = new ClientEncryptionIncludedPath() + { + Path = "/ZipCode", + ClientEncryptionKeyId = "key1", + EncryptionType = "Deterministic", + EncryptionAlgorithm = "AEAD_AES_256_CBC_HMAC_SHA256", + }; + + Collection paths = new Collection { cepWithPKIdPath1, cepWithPKIdPath2, cepWithPKIdPath3 }; + + ClientEncryptionPolicy clientEncryptionPolicy= new ClientEncryptionPolicy(paths, 2); + + ContainerProperties containerProperties = new ContainerProperties() + { + Id = "HierarchicalPkContainerWith3Pk", + PartitionKeyPaths = new List { "/State", "/City", "/ZipCode" }, + ClientEncryptionPolicy = clientEncryptionPolicy + }; + + Container encryptionContainer = await database.CreateContainerAsync(containerProperties, 400); + await encryptionContainer.InitializeEncryptionAsync(); + + PartitionKey hirarchicalPk = new PartitionKeyBuilder() + .Add(testDoc.State) + .Add(testDoc.City) + .Add(testDoc.ZipCode) + .Build(); + + ItemResponse createResponse = await encryptionContainer.CreateItemAsync( + testDoc, + partitionKey: hirarchicalPk); + Assert.AreEqual(HttpStatusCode.Created, createResponse.StatusCode); + VerifyExpectedDocResponse(testDoc, createResponse.Resource); + + // read back + ItemResponse readResponse = await encryptionContainer.ReadItemAsync( + testDoc.Id, + hirarchicalPk); + + Assert.AreEqual(HttpStatusCode.OK, readResponse.StatusCode); + VerifyExpectedDocResponse(testDoc, readResponse.Resource); + + PartitionKey partialHirarchicalPk = new PartitionKeyBuilder() + .Add(testDoc.State) + .Add(testDoc.City) + .Build(); + + QueryRequestOptions queryRequestOptions = new QueryRequestOptions + { + PartitionKey = partialHirarchicalPk + }; + + using FeedIterator setIterator = encryptionContainer.GetItemQueryIterator("select * from c", requestOptions: queryRequestOptions); + + while (setIterator.HasMoreResults) + { + FeedResponse response = await setIterator.ReadNextAsync().ConfigureAwait(false); + Assert.AreEqual(HttpStatusCode.OK, response.StatusCode); + VerifyExpectedDocResponse(testDoc, response.First()); + } + + QueryDefinition withEncryptedParameter = encryptionContainer.CreateQueryDefinition( + "SELECT * FROM c WHERE c.City = @cityInput AND c.State = @stateInput"); + + await withEncryptedParameter.AddParameterAsync( + "@cityInput", + testDoc.City, + "/City"); + + await withEncryptedParameter.AddParameterAsync( + "@stateInput", + testDoc.State, + "/State"); + + // query with partial HirarchicalPk state and city + FeedIterator queryResponseIterator; + queryResponseIterator = encryptionContainer.GetItemQueryIterator(withEncryptedParameter, requestOptions: queryRequestOptions); + + while (queryResponseIterator.HasMoreResults) + { + FeedResponse response = await queryResponseIterator.ReadNextAsync().ConfigureAwait(false); + Assert.AreEqual(HttpStatusCode.OK, response.StatusCode); + VerifyExpectedDocResponse(testDoc, response.First()); + } + + partialHirarchicalPk = new PartitionKeyBuilder() + .Add(testDoc.State) + .Build(); + + queryRequestOptions = new QueryRequestOptions + { + PartitionKey = partialHirarchicalPk + }; + + // query with partial HirarchicalPk state + queryResponseIterator = encryptionContainer.GetItemQueryIterator(withEncryptedParameter, requestOptions: queryRequestOptions); + + while (queryResponseIterator.HasMoreResults) + { + FeedResponse response = await queryResponseIterator.ReadNextAsync().ConfigureAwait(false); + Assert.AreEqual(HttpStatusCode.OK, response.StatusCode); + VerifyExpectedDocResponse(testDoc, response.First()); + } + + partialHirarchicalPk = new PartitionKeyBuilder() + .Add(testDoc.ZipCode) + .Build(); + + queryRequestOptions = new QueryRequestOptions + { + PartitionKey = partialHirarchicalPk + }; + + // query with partial HirarchicalPk zipCode. + // Since zipCode is 3rd in HirarchicalPk set. Query will get 0 response. + queryResponseIterator = encryptionContainer.GetItemQueryIterator(withEncryptedParameter, requestOptions: queryRequestOptions); + + while (queryResponseIterator.HasMoreResults) + { + FeedResponse response = await queryResponseIterator.ReadNextAsync().ConfigureAwait(false); + Assert.AreEqual(HttpStatusCode.OK, response.StatusCode); + Assert.AreEqual(0, response.Count()); + } + + // query with no HirarchicalPk set. + queryResponseIterator = encryptionContainer.GetItemQueryIterator(withEncryptedParameter); + + while (queryResponseIterator.HasMoreResults) + { + FeedResponse response = await queryResponseIterator.ReadNextAsync().ConfigureAwait(false); + Assert.AreEqual(HttpStatusCode.OK, response.StatusCode); + VerifyExpectedDocResponse(testDoc, response.First()); + } + + partialHirarchicalPk = new PartitionKeyBuilder() + .Add(testDoc.State) + .Add(testDoc.City) + .Add(testDoc.ZipCode) + .Add("Extra Value") + .Build(); + + queryRequestOptions = new QueryRequestOptions + { + PartitionKey = partialHirarchicalPk + }; + // query with more PKs greater than number of PK feilds set in the container settings. + try + { + queryResponseIterator = encryptionContainer.GetItemQueryIterator(withEncryptedParameter, requestOptions: queryRequestOptions); + while (queryResponseIterator.HasMoreResults) + { + FeedResponse response = await queryResponseIterator.ReadNextAsync().ConfigureAwait(false); + Assert.AreEqual(HttpStatusCode.OK, response.StatusCode); + Assert.AreEqual(0, response.Count()); + } + } + catch (Exception ex) + { + Assert.IsTrue(ex is NotSupportedException); + if (ex is NotSupportedException notSupportedException) + Assert.IsTrue(notSupportedException.Message.Contains("The number of partition keys passed in the query exceeds the number of keys initialized on the container")); + } + } + + [TestMethod] + public async Task TestHirarchicalPkWithOnlyOneKey() + { + HirarchicalPkTestDoc testDoc = HirarchicalPkTestDoc.Create(); + + ClientEncryptionIncludedPath cepWithPKIdPath1 = new ClientEncryptionIncludedPath() + { + Path = "/State", + ClientEncryptionKeyId = "key1", + EncryptionType = "Deterministic", + EncryptionAlgorithm = "AEAD_AES_256_CBC_HMAC_SHA256", + }; + + ClientEncryptionIncludedPath cepWithPKIdPath2 = new ClientEncryptionIncludedPath() + { + Path = "/City", + ClientEncryptionKeyId = "key1", + EncryptionType = "Deterministic", + EncryptionAlgorithm = "AEAD_AES_256_CBC_HMAC_SHA256", + }; + + ClientEncryptionIncludedPath cepWithPKIdPath3 = new ClientEncryptionIncludedPath() + { + Path = "/ZipCode", + ClientEncryptionKeyId = "key1", + EncryptionType = "Deterministic", + EncryptionAlgorithm = "AEAD_AES_256_CBC_HMAC_SHA256", + }; + + Collection paths = new Collection { cepWithPKIdPath1, cepWithPKIdPath2, cepWithPKIdPath3 }; + + ClientEncryptionPolicy clientEncryptionPolicy = new ClientEncryptionPolicy(paths, 2); + + ContainerProperties containerProperties = new ContainerProperties() + { + Id = "HierarchicalPkContainerWithOnePk", + PartitionKeyPaths = new List { "/State" }, + ClientEncryptionPolicy = clientEncryptionPolicy + }; + + Container encryptionContainer = await database.CreateContainerAsync(containerProperties, 400); + await encryptionContainer.InitializeEncryptionAsync(); + + PartitionKey hirarchicalPk = new PartitionKeyBuilder() + .Add(testDoc.State) + .Build(); + + ItemResponse createResponse = await encryptionContainer.CreateItemAsync( + testDoc, + partitionKey: hirarchicalPk); + Assert.AreEqual(HttpStatusCode.Created, createResponse.StatusCode); + VerifyExpectedDocResponse(testDoc, createResponse.Resource); + + // read back + ItemResponse readResponse = await encryptionContainer.ReadItemAsync( + testDoc.Id, + hirarchicalPk); + + Assert.AreEqual(HttpStatusCode.OK, readResponse.StatusCode); + VerifyExpectedDocResponse(testDoc, readResponse.Resource); + + PartitionKey fullHirarchicalPk = new PartitionKeyBuilder() + .Add(testDoc.State) + .Build(); + + QueryRequestOptions queryRequestOptions = new QueryRequestOptions + { + PartitionKey = fullHirarchicalPk + }; + + using FeedIterator setIterator = encryptionContainer.GetItemQueryIterator("select * from c", requestOptions: queryRequestOptions); + + while (setIterator.HasMoreResults) + { + FeedResponse response = await setIterator.ReadNextAsync().ConfigureAwait(false); + Assert.AreEqual(HttpStatusCode.OK, response.StatusCode); + VerifyExpectedDocResponse(testDoc, response.First()); + } + } +#endif [TestMethod] public async Task EncryptionStreamIteratorValidation() { @@ -3204,6 +3518,14 @@ private static async Task> MdeDeleteItemAsync( return deleteResponse; } + private static void VerifyExpectedDocResponse(HirarchicalPkTestDoc expectedDoc, HirarchicalPkTestDoc verifyDoc) + { + Assert.AreEqual(expectedDoc.Id, verifyDoc.Id); + Assert.AreEqual(expectedDoc.State, verifyDoc.State); + Assert.AreEqual(expectedDoc.City, verifyDoc.City); + Assert.AreEqual(expectedDoc.ZipCode, verifyDoc.ZipCode); + } + private static void VerifyExpectedDocResponse(TestDoc expectedDoc, TestDoc verifyDoc) { Assert.AreEqual(expectedDoc.Id, verifyDoc.Id); @@ -3716,6 +4038,70 @@ public Stream ToStream() } } + public class HirarchicalPkTestDoc + { + [JsonProperty("id")] + public string Id { get; set; } + + public string PK { get; set; } + + public string State { get; set; } + + public string City { get; set; } + + public string ZipCode { get; set; } + + public HirarchicalPkTestDoc() + { + } + public HirarchicalPkTestDoc(HirarchicalPkTestDoc other) + { + this.Id = other.Id; + this.PK = other.PK; + this.State = other.State; + this.City = other.City; + this.ZipCode = other.ZipCode; + } + + public override bool Equals(object obj) + { + return obj is HirarchicalPkTestDoc doc + && this.Id == doc.Id + && this.PK == doc.PK + && this.State == doc.State + && this.City == doc.City + && this.ZipCode == doc.ZipCode; + } + + public override int GetHashCode() + { + int hashCode = 1652434776; + hashCode = (hashCode * -1521134295) + EqualityComparer.Default.GetHashCode(this.Id); + hashCode = (hashCode * -1521134295) + EqualityComparer.Default.GetHashCode(this.PK); + hashCode = (hashCode * -1521134295) + EqualityComparer.Default.GetHashCode(this.State); + hashCode = (hashCode * -1521134295) + EqualityComparer.Default.GetHashCode(this.City); + hashCode = (hashCode * -1521134295) + EqualityComparer.Default.GetHashCode(this.ZipCode); + return hashCode; + } + + public static HirarchicalPkTestDoc Create(string partitionKey = null) + { + return new HirarchicalPkTestDoc() + { + Id = Guid.NewGuid().ToString(), + PK = partitionKey ?? Guid.NewGuid().ToString(), + State = Guid.NewGuid().ToString(), + City = Guid.NewGuid().ToString(), + ZipCode = Guid.NewGuid().ToString() + }; + } + + public Stream ToStream() + { + return TestCommon.ToStream(this); + } + } + internal class TestKeyEncryptionKey : IKeyEncryptionKey { private static readonly Dictionary keyinfo = new Dictionary diff --git a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/AzureVmBenchmark/README.md b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/AzureVmBenchmark/README.md new file mode 100644 index 0000000000..cd9ad834fc --- /dev/null +++ b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/AzureVmBenchmark/README.md @@ -0,0 +1,111 @@ +# Running benchmarks on Azure Virtual Machines + +[Azure Arm Template](https://azure.microsoft.com/products/arm-templates/) makes executing the Azure Cosmos DB SDK Benchmark extremely easy. And reaching following abilities: + +- Ability to execute benchmarking on multiple machines with one ARM Template +- Capturing diagnostics data for requests that exceed the latency threshold +- AppInsights: Live metrics (10s) + - Success rate + - Error + - P90, P99, P999, P9999 + +| Parameter name | Description | +| ------------------------------------------------------ | ------------------------------------------------------ | +| projectName | Specifies a name for generating resource names. | +| location | Specifies the location for all resources. | +| adminUsername | Specifies a username for the Virtual Machine. | +| adminPassword | Specifies a password for the Virtual Machine. | +| vmSize | Specifies a Virtual Machine size | +| vNetName | Specifies a Virtual Network name | +| vNetAddressPrefixes | Specifies a Virtual Network Address Prefix | +| vNetSubnetName | Specifies a Virtual Network Subnet name | +| vNetSubnetAddressPrefix | Specifies a Virtual Network Subnet Address Prefix | +| cosmosURI | Specifies the URI of the Cosmos DB account | +| cosmosKey | Specifies the key for the Cosmos DB account | +| throughput | Specifies Collection throughput use | +| operationsCount | Specifies the number of operations to execute | +| parallelism | Specifies the degree of parallelism | +| resultsContainer | Specifies the name of the container to which the results to be saved | +| vmCount | Specifies the number of Virtual Machines that will part of the test bench | +| workloadType | Specifies the workload | +| benchmarkingToolsBranchName | Specifies the GitHub branch for the benchmark tool source code repository | +| diagnosticsLatencyThresholdInMS | Specifies request latency threshold for capturing diagnostic data | +| storageAccountName | Specifies Storage Account Nmae | +| metricsReportingIntervalInSec | Specifies metrics reporting interval in seconds | +| applicationInsightsName | Specifies Application Insights Account Name | +| startDate | Specifies Diagnostic Blob storage container folder prefix | + + [![Deploy to Azure](https://aka.ms/deploytoazurebutton)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2Fazure-cosmos-dotnet-v3%2Fmaster%2FMicrosoft.Azure.Cosmos.Samples%2FTools%2FBenchmark%2FAzureVmBenchmark%2Fazuredeploy.json) + +After benchmark was launched use Shared Dashboard for viewing charts with + +## Workload types + +| Workload Type | Description | +| ------------------------------------------------------ | ------------------------------------------------------ | +| InsertV3BenchmarkOperation | Inserts single document | +| QueryStreamCrossPkDistinctFullDrainV3BenchmarkOperation | Execute a `DISTINCT` query cross partitions and access data using a steram | +| QueryStreamCrossPkDistinctWithPaginationV3BenchmarkOperation | Execute a `DISTINCT` query cross partitions and access data using a steram and pagination | +| QueryStreamCrossPkGroupByFullDrainV3BenchmarkOperation | Execute a `GROUP BY` query cross partitions and access data using a steram | +| QueryStreamCrossPkGroupByWithPaginationV3BenchmarkOperation | Execute a `GROUP BY` query cross partitions and access data using a steram and pagination | +| QueryStreamCrossPkOrderByFullDrainV3BenchmarkOperation | Execute a `ORDER BY` query cross partitions and access data using a steram | +| QueryStreamCrossPkOrderByWithPaginationV3BenchmarkOperation | Execute a `ORDER BY` query cross partitions and access data using a steram and pagination | +| QueryStreamCrossPkV3BenchmarkOperation | Execute `select * from T where T.id = @id` query cross partitions and access data using a steram | +| QueryStreamCrossPkWithPaginationV3BenchmarkOperation | Execute `select * from T where T.id = @id` query cross partitions and access data using a steram and pagination | +| QueryStreamSinglePkDistinctFullDrainV3BenchmarkOperation | Execute a `DISTINCT` query on a single partition and access data using a steram | +| QueryStreamSinglePkDistinctWithPaginationV3BenchmarkOperation | Execute a `DISTINCT` query on a single partition and access data using a steram and pagination | +| QueryStreamSinglePkGroupByFullDrainV3BenchmarkOperation | Execute a `GROUP BY` query on a single partition and access data using a steram | +| QueryStreamSinglePkGroupByWithPaginationV3BenchmarkOperation | Execute a `GROUP BY` query on a single partition and access data using a steram and pagination | +| QueryStreamSinglePkOrderByFullDrainV3BenchmarkOperation | Execute a `ORDER BY` query on a single partition and access data using a stream | +| QueryStreamSinglePkOrderByWithPaginationV3BenchmarkOperation | Execute a `ORDER BY` query on a single partition and access data using a steram and pagination | +| QueryStreamSinglePkV3BenchmarkOperation | Execute `select * from T where T.id = @id` query on a single partition and access data using a steram | +| QueryStreamSinglePkWithPaginationV3BenchmarkOperation | Execute `select * from T where T.id = @id` query on a single partition and access data using a steram and pagination | +| QueryTCrossPkDistinctFullDrainV3BenchmarkOperation | Execute a `DISTINCT` query cross partitions and access data | +| QueryTCrossPkDistinctWithPaginationV3BenchmarkOperation | Execute a `DISTINCT` query cross partitions and access data using a pagination | +| QueryTCrossPkGroupByFullDrainV3BenchmarkOperation | Execute a `GROUP BY` query cross partitions and access data | +| QueryTCrossPkGroupByWithPaginationV3BenchmarkOperation | Execute a `GROUP BY` query cross partitions and access data using a pagination | +| QueryTCrossPkOrderByFullDrainV3BenchmarkOperation | Execute a `ORDER BY` query cross partitions and access data | +| QueryTCrossPkOrderByWithPaginationV3BenchmarkOperation | Execute a `ORDER BY` query cross partitions and access data using a pagination | +| QueryTCrossPkV3BenchmarkOperation | Execute `select * from T where T.id = @id` query cross partitions partition and access data | +| QueryTCrossPkWithPaginationV3BenchmarkOperation | Execute `select * from T where T.id = @id` query cross partitions partition and access data using a pagination | +| QueryTSinglePkDistinctFullDrainV3BenchmarkOperation | Execute a `DISTINCT` query on a single partition and access data | +| QueryTSinglePkDistinctWithPaginationV3BenchmarkOperation | Execute a `DISTINCT` query on a single partition and access data using a pagination | +| QueryTSinglePkGroupByFullDrainV3BenchmarkOperation | Execute a `GROUP BY` query on a single partition and access data | +| QueryTSinglePkGroupByWithPaginationV3BenchmarkOperation | Execute a `GROUP BY` query on a single partition and access data using a pagination | +| QueryTSinglePkOrderByFullDrainV3BenchmarkOperation | Execute a `ORDER BY` query on a single partition and access data | +| QueryTSinglePkOrderByWithPaginationV3BenchmarkOperation | Execute a `ORDER BY` query on a single partition and access data using a pagination | +| QueryTSinglePkV3BenchmarkOperation | Execute `select * from T where T.id = @id` query on a single partition and access data | +| QueryTSinglePkWithPaginationV3BenchmarkOperation | Execute `select * from T where T.id = @id` query on a single partition and access data using a pagination | +| ReadFeedStreamV3BenchmarkOperation | Execute Read Feed query | +| ReadNotExistsV3BenchmarkOperation | Execute query for not existing item | +| ReadStreamExistsV3BenchmarkOperation | Read item stream | +| ReadStreamExistsWithDiagnosticsV3BenchmarkOperation | Read item stream with diagnostics data | +| ReadTExistsV3BenchmarkOperation | Read single item | + + +## Diagnose and troubleshooting +The Benchmark tool output logs may be found on the each Virtual Machine in user home directory. + +- Connect to VM using serial console +- Enter login and password + +```bash +benchmarking@Benchmarking-dotnet-SDK-vm1:~$ ls + +agent.err agent.out +``` + +```bash +benchmarking@Benchmarking-dotnet-SDK-vm1:~$ cat agent.out + +CSC : warning CS8002: Referenced assembly 'MathNet.Numerics, Version=4.15.0.0, Culture=neutral, PublicKeyToken=null' does not have a strong name. [/var/lib/waagent/custom-script/download/2/azure-cosmos-dotnet-v3/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/CosmosBenchmark.csproj] +Azure VM Location:eastus +BenchmarkConfig arguments +IsServerGC: True +--------------------------------------------------------------------- +{ + "WorkloadType": "ReadTExistsV3BenchmarkOperation", + "EndPoint": "https://cosmosdb-benchmark-dotnet-test-thr.documents.azure.com:443/", + "Database": "db", + "Container": "data", +``` diff --git a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/AzureVmBenchmark/azuredeploy.json b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/AzureVmBenchmark/azuredeploy.json new file mode 100644 index 0000000000..594d4c9756 --- /dev/null +++ b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/AzureVmBenchmark/azuredeploy.json @@ -0,0 +1,1161 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "projectName": { + "type": "string", + "defaultValue": "Benchmarking-dotnet-SDK", + "metadata": { + "description": "Specifies a name for generating resource names." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Specifies the location for all resources." + } + }, + "adminUsername": { + "type": "string", + "defaultValue": "benchmarking", + "metadata": { + "description": "Specifies a username for the Virtual Machine." + } + }, + "adminPassword": { + "type": "securestring", + "metadata": { + "description": "Specifies a password for the Virtual Machine." + } + }, + "vmSize": { + "type": "string", + "defaultValue": "Standard_D4s_v3", + "metadata": { + "description": "Specifies a Virtual Machine size" + } + }, + "vNetName": { + "type": "string", + "defaultValue": "Benchmarking-dotnet-SDK-vnet", + "metadata": { + "description": "Specifies a Virtual Network name" + } + }, + "vNetAddressPrefixes": { + "type": "string", + "defaultValue": "10.2.0.0/16", + "metadata": { + "description": "Specifies a Virtual Network Address Prefix" + } + }, + "vNetSubnetName": { + "type": "string", + "defaultValue": "default", + "metadata": { + "description": "Specifies a Virtual Network Subnet name" + } + }, + "vNetSubnetAddressPrefix": { + "type": "string", + "defaultValue": "10.2.0.0/24", + "metadata": { + "description": "Specifies a Virtual Network Subnet Address Prefix " + } + }, + "cosmosURI": { + "type": "string", + "metadata": { + "description": "Specifies the URI of the Cosmos DB account" + } + }, + "cosmosKey": { + "type": "securestring", + "metadata": { + "description": "Specifies the key for the Cosmos DB account" + } + }, + "throughput": { + "type": "int", + "defaultValue": 100000, + "metadata": { + "description": "Specifies Collection throughput use" + } + }, + "operationsCount": { + "type": "int", + "metadata": { + "description": "Specifies the number of operations to execute" + } + }, + "parallelism": { + "type": "int", + "defaultValue": -1, + "metadata": { + "description": "Specifies the degree of parallelism" + } + }, + "resultsContainer": { + "type": "string", + "defaultValue": "BenchmarkResult", + "metadata": { + "description": "Specifies the name of the container to which the results to be saved" + } + }, + "vmCount": { + "type": "int", + "defaultValue": 1, + "metadata": { + "description": "Specifies the number of Virtual Machines that will part of the test bench" + } + }, + "workloadType": { + "type": "string", + "allowedValues": [ + "InsertV3BenchmarkOperation", + "QueryStreamCrossPkDistinctFullDrainV3BenchmarkOperation", + "QueryStreamCrossPkDistinctWithPaginationV3BenchmarkOperation", + "QueryStreamCrossPkGroupByFullDrainV3BenchmarkOperation", + "QueryStreamCrossPkGroupByWithPaginationV3BenchmarkOperation", + "QueryStreamCrossPkOrderByFullDrainV3BenchmarkOperation", + "QueryStreamCrossPkOrderByWithPaginationV3BenchmarkOperation", + "QueryStreamCrossPkV3BenchmarkOperation", + "QueryStreamCrossPkWithPaginationV3BenchmarkOperation", + "QueryStreamSinglePkDistinctFullDrainV3BenchmarkOperation", + "QueryStreamSinglePkDistinctWithPaginationV3BenchmarkOperation", + "QueryStreamSinglePkGroupByFullDrainV3BenchmarkOperation", + "QueryStreamSinglePkGroupByWithPaginationV3BenchmarkOperation", + "QueryStreamSinglePkGroupByWithPaginationV3BenchmarkOperation", + "QueryStreamSinglePkOrderByWithPaginationV3BenchmarkOperation", + "QueryStreamSinglePkV3BenchmarkOperation", + "QueryStreamSinglePkWithPaginationV3BenchmarkOperation", + "QueryTCrossPkDistinctFullDrainV3BenchmarkOperation", + "QueryTCrossPkDistinctWithPaginationV3BenchmarkOperation", + "QueryTCrossPkGroupByFullDrainV3BenchmarkOperation", + "QueryTCrossPkGroupByWithPaginationV3BenchmarkOperation", + "QueryTCrossPkOrderByFullDrainV3BenchmarkOperation", + "QueryTCrossPkOrderByWithPaginationV3BenchmarkOperation", + "QueryTCrossPkV3BenchmarkOperation", + "QueryTCrossPkWithPaginationV3BenchmarkOperation", + "QueryTSinglePkDistinctFullDrainV3BenchmarkOperation", + "QueryTSinglePkDistinctWithPaginationV3BenchmarkOperation", + "QueryTSinglePkGroupByFullDrainV3BenchmarkOperation", + "QueryTSinglePkGroupByWithPaginationV3BenchmarkOperation", + "QueryTSinglePkOrderByFullDrainV3BenchmarkOperation", + "QueryTSinglePkOrderByWithPaginationV3BenchmarkOperation", + "QueryTSinglePkV3BenchmarkOperation", + "QueryTSinglePkWithPaginationV3BenchmarkOperation", + "ReadFeedStreamV3BenchmarkOperation", + "ReadNotExistsV3BenchmarkOperation", + "ReadStreamExistsV3BenchmarkOperation", + "ReadStreamExistsWithDiagnosticsV3BenchmarkOperation", + "ReadTExistsV3BenchmarkOperation" + ], + "defaultValue": "ReadTExistsV3BenchmarkOperation", + "metadata": { + "description": "Specifies the workload" + } + }, + "benchmarkingToolsBranchName": { + "type": "string", + "defaultValue": "master", + "metadata": { + "description": "Specifies the GitHub branch for the benchmark tool source code repository" + } + }, + "diagnosticsLatencyThresholdInMS": { + "type": "int", + "defaultValue": 100 + }, + "storageAccountName": { + "type": "string", + "defaultValue": "dotnetbenchmark", + "metadata": { + "description": "Specifies Storage Account Nmae" + } + }, + "metricsReportingIntervalInSec": { + "type": "int", + "defaultValue": 5 + }, + "applicationInsightsName": { + "type": "string", + "defaultValue": "CosmosDBBenchmarkTestAppInsights", + "metadata": { + "description": "Specifies Application Insights Account Name" + } + }, + "startDate": { + "type": "int", + "defaultValue": "[dateTimeToEpoch(utcNow())]" + }, + "dashboardName": { + "type": "string", + "defaultValue": "Cosmos Benchmark Statistics", + "metadata": { + "description": "Specifies Application Insights Dashboard Name" + } + } + }, + "variables": { + "vmName": "[concat(parameters('projectName'), '-vm')]", + "publicIPAddressName": "[concat(parameters('projectName'), '-ip')]", + "networkInterfaceName": "[concat(parameters('projectName'), '-nic')]", + "networkSecurityGroupName": "[concat(parameters('projectName'), '-nsg')]", + "benchmarkingToolsURL": "https://github.com/Azure/azure-cosmos-dotnet-v3.git", + "cloudInitScriptUrl": "[concat('https://raw.githubusercontent.com/Azure/azure-cosmos-dotnet-v3/',parameters('benchmarkingToolsBranchName'),'/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/AzureVmBenchmark/system/cloud-init.txt')]", + "vmScriptExtensionScriptUrl": "[concat('https://raw.githubusercontent.com/Azure/azure-cosmos-dotnet-v3/',parameters('benchmarkingToolsBranchName'),'/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/AzureVmBenchmark/scripts/execute.sh')]", + "customScriptUrl": "[concat('https://raw.githubusercontent.com/Azure/azure-cosmos-dotnet-v3/',parameters('benchmarkingToolsBranchName'),'/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/AzureVmBenchmark/scripts/custom-script.sh')]", + "vmScriptExtensionScriptName": "execute.sh", + "convertedDatetime": "[dateTimeFromEpoch(parameters('startDate'))]", + "metricsPrefix" : "[if(startsWith(parameters('workloadType'), 'Read'), 'Read', if(startsWith(parameters('workloadType'), 'Query'), 'Query', if(startsWith(parameters('workloadType'), 'Insert'), 'Insert', '')))]", + "appInsightsResourceIds": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', resourceGroup().name, '/providers/microsoft.insights/components/', parameters('applicationInsightsName'))]", + "chart0Expression": "[concat('customMetrics\n| where name == \"', variables('metricsPrefix'), 'OperationLatencyInMs\" and timestamp > ago(1d)\n| summarize\n percentile(value, 50),\n percentile(value, 75),\n percentile(value, 90),\n percentile(value, 95)\n by ts = bin(timestamp, ', parameters('metricsReportingIntervalInSec'), 's)\n| render timechart \n\n')]", + "chart1Expression": "[concat('customMetrics\n| where name == \"', variables('metricsPrefix'), 'OperationLatencyInMs\" and timestamp > ago(1d)\n| summarize\n percentile(value, 99),\n percentile(value, 99.9),\n percentile(value, 99.99)\n by ts = bin(timestamp, ', parameters('metricsReportingIntervalInSec'), 's)\n| render timechart \n\n')]", + "chart2Expression": "[concat('customMetrics\n| where name == \"', variables('metricsPrefix'), 'OperationRps\" and timestamp > ago(1d)\n| summarize\n avg(value)\n by ts = bin(timestamp, ', parameters('metricsReportingIntervalInSec'), 's)\n| render timechart \n\n')]" + + }, + "resources": [ + { + "type": "Microsoft.Storage/storageAccounts", + "apiVersion": "2021-04-01", + "name": "[parameters('storageAccountName')]", + "location": "[resourceGroup().location]", + "sku": { + "name": "Standard_LRS" + }, + "kind": "StorageV2", + "properties": { + "accessTier": "Hot" + } + }, + { + "name": "[parameters('applicationInsightsName')]", + "type": "Microsoft.Insights/components", + "apiVersion": "2015-05-01", + "location": "[resourceGroup().location]", + "properties": { + "ApplicationId": "[parameters('applicationInsightsName')]", + "Application_Type": "web" + } + }, + { + "type": "Microsoft.Network/networkSecurityGroups", + "apiVersion": "2020-11-01", + "name": "[variables('networkSecurityGroupName')]", + "location": "[parameters('location')]", + "properties": { + "securityRules": [] + } + }, + { + "type": "Microsoft.Network/publicIPAddresses", + "apiVersion": "2020-11-01", + "name": "[concat(variables('publicIPAddressName'),copyIndex(1))]", + "location": "[parameters('location')]", + "sku": { + "name": "Basic", + "tier": "Regional" + }, + "properties": { + "publicIPAddressVersion": "IPv4", + "publicIPAllocationMethod": "Dynamic", + "idleTimeoutInMinutes": 4 + }, + "copy": { + "name": "publicIPcopy", + "count": "[parameters('vmCount')]" + } + }, + { + "type": "Microsoft.Network/virtualNetworks", + "apiVersion": "2020-11-01", + "name": "[parameters('vNetName')]", + "location": "[parameters('location')]", + "properties": { + "addressSpace": { + "addressPrefixes": [ + "[parameters('vNetAddressPrefixes')]" + ] + }, + "subnets": [ + { + "name": "[parameters('vNetSubnetName')]", + "properties": { + "addressPrefix": "[parameters('vNetSubnetAddressPrefix')]", + "privateEndpointNetworkPolicies": "Enabled", + "privateLinkServiceNetworkPolicies": "Enabled" + } + } + ], + "enableDdosProtection": false + } + }, + { + "type": "Microsoft.Network/virtualNetworks/subnets", + "apiVersion": "2020-11-01", + "name": "[concat(parameters('vNetName'), '/',parameters('vNetSubnetName'))]", + "dependsOn": [ + "[resourceId('Microsoft.Network/virtualNetworks', parameters('vNetName'))]", + "[resourceId('Microsoft.Network/networkSecurityGroups', variables('networkSecurityGroupName'))]" + ], + "properties": { + "addressPrefix": "[parameters('vNetSubnetAddressPrefix')]", + "privateEndpointNetworkPolicies": "Enabled", + "privateLinkServiceNetworkPolicies": "Enabled", + "networkSecurityGroup": { + "id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('networkSecurityGroupName'))]" + } + } + }, + { + "type": "Microsoft.Network/networkInterfaces", + "apiVersion": "2020-11-01", + "name": "[concat(variables('networkInterfaceName'),copyIndex(1))]", + "location": "[parameters('location')]", + "dependsOn": [ + "[resourceId('Microsoft.Network/publicIPAddresses', concat(variables('publicIPAddressName'),copyIndex(1)))]", + "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('vNetName'), parameters('vNetSubnetName'))]" + ], + "properties": { + "ipConfigurations": [ + { + "name": "ipconfig1", + "properties": { + "privateIPAddress": "10.0.0.4", + "privateIPAllocationMethod": "Dynamic", + "publicIPAddress": { + "id": "[resourceId('Microsoft.Network/publicIPAddresses', concat(variables('publicIPAddressName'),copyIndex(1)))]" + }, + "subnet": { + "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('vNetName'), parameters('vNetSubnetName'))]" + }, + "primary": true, + "privateIPAddressVersion": "IPv4" + } + } + ], + "enableAcceleratedNetworking": true, + "enableIPForwarding": false + }, + "copy": { + "name": "networkInterfacecopy", + "count": "[parameters('vmCount')]" + } + }, + { + "type": "Microsoft.Compute/virtualMachines", + "apiVersion": "2021-11-01", + "name": "[concat(variables('vmName'),copyIndex(1))]", + "location": "[parameters('location')]", + "dependsOn": [ + "[resourceId('Microsoft.Network/networkInterfaces', concat(variables('networkInterfaceName'),copyIndex(1)))]", + "[concat('Microsoft.Storage/storageAccounts/', parameters('storageAccountName'))]", + "[resourceId('Microsoft.Insights/components', parameters('applicationInsightsName'))]" + ], + "tags": { + "azsecpack": "prod", + "platformsettings.host_environment.service.platform_optedin_for_rootcerts": "true" + }, + "properties": { + "hardwareProfile": { + "vmSize": "[parameters('vmSize')]" + }, + "storageProfile": { + "imageReference": { + "publisher": "canonical", + "offer": "0001-com-ubuntu-server-focal", + "sku": "20_04-lts-gen2", + "version": "latest" + }, + "osDisk": { + "osType": "Linux", + "name": "[concat(variables('vmName'),copyIndex(1),'_OsDisk')]", + "createOption": "FromImage", + "caching": "ReadWrite", + "managedDisk": { + "storageAccountType": "Premium_LRS" + }, + "deleteOption": "Delete", + "diskSizeGB": 30 + } + }, + "osProfile": { + "computerName": "[concat(variables('vmName'),copyIndex(1))]", + "adminUsername": "[parameters('adminUsername')]", + "adminPassword": "[parameters('adminPassword')]", + "customData": "[base64(concat('#include\n',variables('cloudInitScriptUrl')))]", + "linuxConfiguration": { + "disablePasswordAuthentication": false, + "provisionVMAgent": true, + "patchSettings": { + "patchMode": "ImageDefault", + "assessmentMode": "ImageDefault" + } + }, + "allowExtensionOperations": true + }, + "networkProfile": { + "networkInterfaces": [ + { + "id": "[resourceId('Microsoft.Network/networkInterfaces', concat(variables('networkInterfaceName'),copyIndex(1)))]", + "properties": { + "deleteOption": "Delete" + } + } + ] + }, + "diagnosticsProfile": { + "bootDiagnostics": { + "enabled": true + } + } + }, + "copy": { + "name": "vmcopy", + "count": "[parameters('vmCount')]" + } + }, + { + "type": "Microsoft.Compute/virtualMachines/extensions", + "apiVersion": "2019-03-01", + "name": "[concat(variables('vmName'),copyIndex(1),'/CustomScript')]", + "location": "[parameters('location')]", + "dependsOn": [ + "[resourceId('Microsoft.Compute/virtualMachines', concat(variables('vmName'),copyIndex(1)))]" + ], + "properties": { + "publisher": "Microsoft.Azure.Extensions", + "type": "CustomScript", + "typeHandlerVersion": "2.1", + "autoUpgradeMinorVersion": true, + "settings": { + }, + "protectedSettings": { + "commandToExecute": "[concat('ADMIN_USER_NAME=',parameters('adminUsername'),' ','BENCHMARKING_TOOLS_URL=',variables('benchmarkingToolsURL'),' ','BENCHMARKING_TOOLS_BRANCH_NAME=',parameters('benchmarkingToolsBranchName'),' ','WORKLOAD_TYPE=',parameters('workloadType'),' ','VM_NAME=',variables('vmName'),copyIndex(1), ' ','DIAGNOSTICS_STORAGE_CONNECTION_STRING=','\"',concat('DefaultEndpointsProtocol=https;AccountName=', parameters('storageAccountName'), ';AccountKey=', listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).keys[0].value),'\"',' ','COSMOS_URI=','\"',parameters('cosmosURI'),'\"', ' ', 'COSMOS_KEY=',parameters('cosmosKey'), ' ', 'THROUGHPUT=',parameters('throughput'), ' ', 'DOCUMENTS=',parameters('operationsCount'), ' ','PARALLELISM=',parameters('parallelism'), ' ','RESULTS_CONTAINER=',parameters('resultsContainer'), ' ','VM_COUNT=',parameters('vmCount'), ' ','DIAGNOSTICS_LATENCY_THRESHOLD_IN_MS=',parameters('diagnosticsLatencyThresholdInMS'),' ','DIAGNOSTICS_STORAGE_CONTAINER_PREFIX=',variables('convertedDatetime'),' ','METRICS_REPORTINT_INTERVAL_SEC=',parameters('metricsReportingIntervalInSec'), ' ','CUSTOM_SCRIPT_URL=',variables('customScriptUrl'), ' ','MACHINE_INDEX=',copyIndex(1), ' ','APP_INSIGHT_CONN_STR=','\"', reference(resourceId('Microsoft.Insights/components', parameters('applicationInsightsName'))).ConnectionString,'\"',' ', 'bash ',variables('vmScriptExtensionScriptName'))]", + "fileUris": [ "[concat(variables('vmScriptExtensionScriptURL'))]" ] + } + }, + "copy": { + "name": "vmextensioncopy", + "count": "[parameters('vmCount')]" + } + }, + { + "name": "CosmosDBBenchmarkDashboard", + "type": "Microsoft.Portal/dashboards", + "location": "[resourceGroup().location]", + "apiVersion": "2015-08-01-preview", + "dependsOn": [ + "[resourceId('Microsoft.Insights/components', parameters('applicationInsightsName'))]" + ], + "tags": { + "hidden-title": "[parameters('dashboardName')]" + }, + + "properties": { + "lenses": { + "0": { + "order": 0, + "parts": { + "0": { + "position": { + "x": 0, + "y": 0, + "colSpan": 10, + "rowSpan": 6 + }, + "metadata": { + "inputs": [ + { + "name": "resourceTypeMode", + "isOptional": true + }, + { + "name": "ComponentId", + "isOptional": true + }, + { + "name": "Scope", + "value": { + "resourceIds": [ + "[variables('appInsightsResourceIds')]" + ] + }, + "isOptional": true + }, + { + "name": "PartId", + "value": "104528fc-0216-49c6-bf70-fffe9d37f93d", + "isOptional": true + }, + { + "name": "Version", + "value": "2.0", + "isOptional": true + }, + { + "name": "TimeRange", + "isOptional": true + }, + { + "name": "DashboardId", + "isOptional": true + }, + { + "name": "DraftRequestParameters", + "isOptional": true + }, + { + "name": "Query", + "value": "[variables('chart0Expression')]", + "isOptional": true + }, + { + "name": "ControlType", + "value": "FrameControlChart", + "isOptional": true + }, + { + "name": "SpecificChart", + "value": "Line", + "isOptional": true + }, + { + "name": "PartTitle", + "value": "Request latencies P50, P75, P90, P95 in ms", + "isOptional": true + }, + { + "name": "PartSubTitle", + "value": "A Latency Percentiles dashboard provides a concise overview of the distribution of response times or latencies for a system or application. It helps monitor and analyze the performance of the system, identify bottlenecks or outliers, and ensure optimal user experience.", + "isOptional": true + }, + { + "name": "Dimensions", + "value": { + "xAxis": { + "name": "ts", + "type": "datetime" + }, + "yAxis": [ + { + "name": "percentile_value_50", + "type": "real" + }, + { + "name": "percentile_value_75", + "type": "real" + }, + { + "name": "percentile_value_90", + "type": "real" + }, + { + "name": "percentile_value_95", + "type": "real" + } + ], + "splitBy": [], + "aggregation": "Sum" + }, + "isOptional": true + }, + { + "name": "LegendOptions", + "value": { + "isEnabled": true, + "position": "Bottom" + }, + "isOptional": true + }, + { + "name": "IsQueryContainTimeRange", + "value": true, + "isOptional": true + } + ], + "type": "Extension/Microsoft_OperationsManagementSuite_Workspace/PartType/LogsDashboardPart", + "settings": { + "content": { + "Dimensions": { + "xAxis": { + "name": "ts", + "type": "datetime" + }, + "yAxis": [ + { + "name": "percentile_value_50", + "type": "real" + }, + { + "name": "percentile_value_75", + "type": "real" + }, + { + "name": "percentile_value_90", + "type": "real" + }, + { + "name": "percentile_value_95", + "type": "real" + } + ], + "splitBy": [], + "aggregation": "Sum" + }, + "IsQueryContainTimeRange": true + } + } + } + }, + "1": { + "position": { + "x": 10, + "y": 0, + "colSpan": 10, + "rowSpan": 6 + }, + "metadata": { + "inputs": [ + { + "name": "resourceTypeMode", + "isOptional": true + }, + { + "name": "ComponentId", + "isOptional": true + }, + { + "name": "Scope", + "value": { + "resourceIds": [ + "[variables('appInsightsResourceIds')]" + ] + }, + "isOptional": true + }, + { + "name": "PartId", + "value": "104528fc-0216-49c6-bf70-fffe9d37f93e", + "isOptional": true + }, + { + "name": "Version", + "value": "2.0", + "isOptional": true + }, + { + "name": "TimeRange", + "isOptional": true + }, + { + "name": "DashboardId", + "isOptional": true + }, + { + "name": "DraftRequestParameters", + "isOptional": true + }, + { + "name": "Query", + "value": "[variables('chart1Expression')]", + "isOptional": true + }, + { + "name": "ControlType", + "value": "FrameControlChart", + "isOptional": true + }, + { + "name": "SpecificChart", + "value": "Line", + "isOptional": true + }, + { + "name": "PartTitle", + "value": "Request latencies P99, P99.9, P99.99 in ms", + "isOptional": true + }, + { + "name": "PartSubTitle", + "value": "A Latency Percentiles dashboard provides a concise overview of the distribution of response times or latencies for a system or application. It helps monitor and analyze the performance of the system, identify bottlenecks or outliers, and ensure optimal user experience.", + "isOptional": true + }, + { + "name": "Dimensions", + "value": { + "xAxis": { + "name": "ts", + "type": "datetime" + }, + "yAxis": [ + { + "name": "percentile_value_99", + "type": "real" + }, + { + "name": "percentile_value_99_9", + "type": "real" + }, + { + "name": "percentile_value_99_99", + "type": "real" + } + ], + "splitBy": [], + "aggregation": "Sum" + }, + "isOptional": true + }, + { + "name": "LegendOptions", + "value": { + "isEnabled": true, + "position": "Bottom" + }, + "isOptional": true + }, + { + "name": "IsQueryContainTimeRange", + "value": true, + "isOptional": true + } + ], + "type": "Extension/Microsoft_OperationsManagementSuite_Workspace/PartType/LogsDashboardPart", + "settings": {} + } + }, + "2": { + "position": { + "x": 0, + "y": 6, + "colSpan": 5, + "rowSpan": 6 + }, + "metadata": { + "inputs": [ + { + "name": "resourceTypeMode", + "isOptional": true + }, + { + "name": "ComponentId", + "isOptional": true + }, + { + "name": "Scope", + "value": { + "resourceIds": [ + "[variables('appInsightsResourceIds')]" + ] + }, + "isOptional": true + }, + { + "name": "PartId", + "value": "104528fc-0216-49c6-bf70-fffe9d37f93e", + "isOptional": true + }, + { + "name": "Version", + "value": "2.0", + "isOptional": true + }, + { + "name": "TimeRange", + "isOptional": true + }, + { + "name": "DashboardId", + "isOptional": true + }, + { + "name": "DraftRequestParameters", + "isOptional": true + }, + { + "name": "Query", + "value": "[concat('customMetrics\n| where name == \"', variables('metricsPrefix'), 'OperationFailure\" and timestamp > ago(1d)\n| summarize\n sum(value)\n by ts = bin(timestamp, 1s)\n | render timechart\n')]", + "isOptional": true + }, + { + "name": "ControlType", + "value": "FrameControlChart", + "isOptional": true + }, + { + "name": "SpecificChart", + "value": "Line", + "isOptional": true + }, + { + "name": "PartTitle", + "value": "Failed operations", + "isOptional": true + }, + { + "name": "PartSubTitle", + "value": "Provides the number of failed operations. (most likely related to some error or inavailability)", + "isOptional": true + }, + { + "name": "Dimensions", + "value": { + "xAxis": { + "name": "ts", + "type": "datetime" + }, + "yAxis": [ + { + "name": "sum_value", + "type": "real" + } + ], + "splitBy": [], + "aggregation": "Sum" + }, + "isOptional": true + }, + { + "name": "LegendOptions", + "value": { + "isEnabled": true, + "position": "Bottom" + }, + "isOptional": true + }, + { + "name": "IsQueryContainTimeRange", + "value": true, + "isOptional": true + } + ], + "type": "Extension/Microsoft_OperationsManagementSuite_Workspace/PartType/LogsDashboardPart", + "settings": { + "content": { + "Query": "[concat('customMetrics\n| where name == \"', variables('metricsPrefix'), 'OperationFailure\" and timestamp > ago(1d)\n| summarize\n sum(value)\n by ts = bin(timestamp, 1s)\n | render timechart\n\n')]", + "Dimensions": { + "xAxis": { + "name": "ts", + "type": "datetime" + }, + "yAxis": [ + { + "name": "sum_value", + "type": "real" + } + ], + "splitBy": [], + "aggregation": "Sum" + } + } + } + } + }, + "3": { + "position": { + "x": 5, + "y": 6, + "colSpan": 5, + "rowSpan": 6 + }, + "metadata": { + "inputs": [ + { + "name": "resourceTypeMode", + "isOptional": true + }, + { + "name": "ComponentId", + "isOptional": true + }, + { + "name": "Scope", + "value": { + "resourceIds": [ + "[variables('appInsightsResourceIds')]" + ] + }, + "isOptional": true + }, + { + "name": "PartId", + "value": "104528fc-0216-49c6-bf70-fffe9d37f93e", + "isOptional": true + }, + { + "name": "Version", + "value": "2.0", + "isOptional": true + }, + { + "name": "TimeRange", + "isOptional": true + }, + { + "name": "DashboardId", + "isOptional": true + }, + { + "name": "DraftRequestParameters", + "isOptional": true + }, + { + "name": "Query", + "value": "[concat('customMetrics\n| where name == \"', variables('metricsPrefix'), 'OperationSuccess\" and timestamp > ago(1d)\n| summarize\n sum(value)\n by ts = bin(timestamp, 1s)\n | render timechart\n')]", + "isOptional": true + }, + { + "name": "ControlType", + "value": "FrameControlChart", + "isOptional": true + }, + { + "name": "SpecificChart", + "value": "Line", + "isOptional": true + }, + { + "name": "PartTitle", + "value": "Success operations", + "isOptional": true + }, + { + "name": "PartSubTitle", + "value": "Provides the number of successful operations.", + "isOptional": true + }, + { + "name": "Dimensions", + "value": { + "xAxis": { + "name": "ts", + "type": "datetime" + }, + "yAxis": [ + { + "name": "sum_value", + "type": "real" + } + ], + "splitBy": [], + "aggregation": "Sum" + }, + "isOptional": true + }, + { + "name": "LegendOptions", + "value": { + "isEnabled": true, + "position": "Bottom" + }, + "isOptional": true + }, + { + "name": "IsQueryContainTimeRange", + "value": true, + "isOptional": true + } + ], + "type": "Extension/Microsoft_OperationsManagementSuite_Workspace/PartType/LogsDashboardPart", + "settings": { + "content": { + "Query": "[concat('customMetrics\n| where name == \"', variables('metricsPrefix'), 'OperationSuccess\" and timestamp > ago(1d)\n| summarize\n sum(value)\n by ts = bin(timestamp, 1s)\n | render timechart\n\n')]", + "Dimensions": { + "xAxis": { + "name": "ts", + "type": "datetime" + }, + "yAxis": [ + { + "name": "sum_value", + "type": "real" + } + ], + "splitBy": [], + "aggregation": "Sum" + } + } + } + } + }, + "4": { + "position": { + "x": 10, + "y": 6, + "colSpan": 10, + "rowSpan": 6 + }, + "metadata": { + "inputs": [ + { + "name": "resourceTypeMode", + "isOptional": true + }, + { + "name": "ComponentId", + "isOptional": true + }, + { + "name": "Scope", + "value": { + "resourceIds": [ + "[variables('appInsightsResourceIds')]" + ] + }, + "isOptional": true + }, + { + "name": "PartId", + "value": "104528fc-0216-49c6-bf70-fffe9d37f93e", + "isOptional": true + }, + { + "name": "Version", + "value": "2.0", + "isOptional": true + }, + { + "name": "TimeRange", + "isOptional": true + }, + { + "name": "DashboardId", + "isOptional": true + }, + { + "name": "DraftRequestParameters", + "isOptional": true + }, + { + "name": "Query", + "value": "[variables('chart2Expression')]", + "isOptional": true + }, + { + "name": "ControlType", + "value": "FrameControlChart", + "isOptional": true + }, + { + "name": "SpecificChart", + "value": "Line", + "isOptional": true + }, + { + "name": "PartTitle", + "value": "Requests per Second (RPS)", + "isOptional": true + }, + { + "name": "PartSubTitle", + "value": "A Requests per Second (RPS) dashboard provides a concise overview of the number of requests being processed by a system or application per second.", + "isOptional": true + }, + { + "name": "Dimensions", + "value": { + "xAxis": { + "name": "ts", + "type": "datetime" + }, + "yAxis": [ + { + "name": "RPs", + "type": "real" + } + ], + "splitBy": [], + "aggregation": "Sum" + }, + "isOptional": true + }, + { + "name": "LegendOptions", + "value": { + "isEnabled": true, + "position": "Bottom" + }, + "isOptional": true + }, + { + "name": "IsQueryContainTimeRange", + "value": true, + "isOptional": true + } + ], + "type": "Extension/Microsoft_OperationsManagementSuite_Workspace/PartType/LogsDashboardPart", + "settings": { + "content": { + "Dimensions": { + "xAxis": { + "name": "ts", + "type": "datetime" + }, + "yAxis": [ + { + "name": "avg_value", + "type": "real" + } + ], + "splitBy": [], + "aggregation": "Sum" + }, + "IsQueryContainTimeRange": false + } + } + } + } + } + } + }, + "metadata": { + "model": { + "timeRange": { + "value": { + "relative": { + "duration": 24, + "timeUnit": 1 + } + }, + "type": "MsPortalFx.Composition.Configuration.ValueTypes.TimeRange" + }, + "filterLocale": { + "value": "en-us" + }, + "filters": { + "value": { + "MsPortalFx_TimeRange": { + "model": { + "format": "utc", + "granularity": "auto", + "relative": "24h" + }, + "displayCache": { + "name": "UTC Time", + "value": "Past 24 hours" + }, + "filteredPartIds": [ + "StartboardPart-LogsDashboardPart-6d2eff36-636b-406d-8390-12e2135e700a", + "StartboardPart-LogsDashboardPart-6d2eff36-636b-406d-8390-12e2135e700c", + "StartboardPart-LogsDashboardPart-6d2eff36-636b-406d-8390-12e2135e700d", + "StartboardPart-LogsDashboardPart-6d2eff36-636b-406d-8390-12e2135e700e", + "StartboardPart-LogsDashboardPart-6d2eff36-636b-406d-8390-12e2135e700f" + ] + } + } + } + } + } + } + } + ], + "outputs": { + "results": { + "type": "string", + "value": "The Benchmarking job has been triggered successfully. Please check the storage account you provided for Job Status and Results. The jobs status will be available in a storage table within a few minutes and results will be available once the job finishes." + } + } +} diff --git a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/AzureVmBenchmark/scripts/custom-script.sh b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/AzureVmBenchmark/scripts/custom-script.sh new file mode 100644 index 0000000000..8ae5662144 --- /dev/null +++ b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/AzureVmBenchmark/scripts/custom-script.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +#Cloning Test Bench Repo +echo "########## Cloning Test Bench repository ##########" +git clone https://github.com/Azure/azure-cosmos-dotnet-v3.git + +# Build Benchmark Project +cd 'azure-cosmos-dotnet-v3/' +git checkout ${BENCHMARKING_TOOLS_BRANCH_NAME} + +cd 'Microsoft.Azure.Cosmos.Samples/Tools/Benchmark' + +echo "########## Build benckmark tool ##########" +dotnet build --configuration Release -p:"OSSProjectRef=true" + +echo "########## Run benchmark ##########" +nohup dotnet run -c Release -p:"OSSProjectRef=true" -e ${COSMOS_URI} -k ${COSMOS_KEY} -t ${THROUGHPUT} -n ${DOCUMENTS} --pl ${PARALLELISM} \ +--enablelatencypercentiles true --resultscontainer ${RESULTS_CONTAINER} --resultspartitionkeyvalue "pk" \ +--DiagnosticsStorageConnectionString ${DIAGNOSTICS_STORAGE_CONNECTION_STRING} \ +--DiagnosticLatencyThresholdInMs ${DIAGNOSTICS_LATENCY_THRESHOLD_IN_MS} \ +--DiagnosticsStorageContainerPrefix ${DIAGNOSTICS_STORAGE_CONTAINER_PREFIX} \ +--MetricsReportingIntervalInSec ${METRICS_REPORTINT_INTERVAL_SEC} \ +--AppInsightsConnectionString ${APP_INSIGHT_CONN_STR} \ +-w ${WORKLOAD_TYPE} \ +> "/home/${ADMIN_USER_NAME}/agent.out" 2> "/home/${ADMIN_USER_NAME}/agent.err" & diff --git a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/AzureVmBenchmark/scripts/execute.sh b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/AzureVmBenchmark/scripts/execute.sh new file mode 100644 index 0000000000..cf86202002 --- /dev/null +++ b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/AzureVmBenchmark/scripts/execute.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +export DOTNET_CLI_HOME=/temp + +cloud-init status --wait +curl -o custom-script.sh $CUSTOM_SCRIPT_URL +bash -x custom-script.sh \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/AzureVmBenchmark/system/cloud-init.txt b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/AzureVmBenchmark/system/cloud-init.txt new file mode 100644 index 0000000000..b6a0419fd5 --- /dev/null +++ b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/AzureVmBenchmark/system/cloud-init.txt @@ -0,0 +1,13 @@ +#cloud-config +package_upgrade: true +packages: + - azure-cli + +runcmd: + - wget https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb + - sudo dpkg -i packages-microsoft-prod.deb + - sudo apt update + - sudo apt install apt-transport-https -y + - sudo apt install dotnet-sdk-6.0 -y + - sudo apt install dotnet-runtime-6.0 + - sudo apt-get install git \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/BenchmarkConfig.cs b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/BenchmarkConfig.cs index 6f89776370..4b7123eb36 100644 --- a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/BenchmarkConfig.cs +++ b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/BenchmarkConfig.cs @@ -6,12 +6,17 @@ namespace CosmosBenchmark { using System; using System.Collections.Generic; + using System.Diagnostics; using System.Linq; using System.Runtime; using CommandLine; + using Microsoft.Azure.Cosmos.Telemetry; using Microsoft.Azure.Documents.Client; using Newtonsoft.Json; + /// + /// Represents Benchmark Configuration + /// public class BenchmarkConfig { private static readonly string UserAgentSuffix = "cosmosdbdotnetbenchmark"; @@ -98,8 +103,8 @@ public class BenchmarkConfig [Option(Required = false, HelpText = "Disable core SDK logging")] public bool DisableCoreSdkLogging { get; set; } - [Option(Required = false, HelpText = "Enable Client Telemetry")] - public bool EnableTelemetry { get; set; } + [Option(Required = false, HelpText = "Enable Distributed Tracing")] + public bool EnableDistributedTracing { get; set; } = false; [Option(Required = false, HelpText = "Enable Distributed Tracing")] public bool EnableDistributedTracing { get; set; } @@ -107,9 +112,6 @@ public class BenchmarkConfig [Option(Required = false, HelpText = "Client Telemetry Schedule in Seconds")] public int TelemetryScheduleInSec { get; set; } - [Option(Required = false, HelpText = "Client Telemetry Endpoint")] - public string TelemetryEndpoint { get; set; } - [Option(Required = false, HelpText = "Endpoint to publish results to")] public string ResultsEndpoint { get; set; } @@ -122,6 +124,25 @@ public class BenchmarkConfig [Option(Required = false, HelpText = "Container to publish results to")] public string ResultsContainer { get; set; } = "runsummary"; + + [Option(Required = false, HelpText = "Request latency threshold for capturing diagnostic data")] + public int DiagnosticLatencyThresholdInMs { get; set; } = 100; + + [Option(Required = false, HelpText = "Blob storage account connection string")] + [JsonIgnore] + public string DiagnosticsStorageConnectionString { get; set; } + + [Option(Required = false, HelpText = "Blob storage container folder prefix")] + public string DiagnosticsStorageContainerPrefix { get; set; } + + [Option(Required = false, HelpText = "Metrics reporting interval in seconds")] + public int MetricsReportingIntervalInSec { get; set; } = 5; + + [Option(Required = false, HelpText = "Application Insights connection string")] + public string AppInsightsConnectionString { get; set; } + + [Option(Required = false, HelpText = "Enable Client Telemetry Feature in SDK. Make sure you enable it from the portal also.")] + public bool EnableTelemetry { get; set; } = false; internal int GetTaskCount(int containerThroughput) { @@ -190,34 +211,24 @@ private string GetUserAgentPrefix() internal Microsoft.Azure.Cosmos.CosmosClient CreateCosmosClient(string accountKey) { + // Overwrite the default timespan if configured + if(this.TelemetryScheduleInSec > 0) + { + ClientTelemetryOptions.DefaultIntervalForTelemetryJob = TimeSpan.FromSeconds(this.TelemetryScheduleInSec); + } + Microsoft.Azure.Cosmos.CosmosClientOptions clientOptions = new Microsoft.Azure.Cosmos.CosmosClientOptions() { ApplicationName = this.GetUserAgentPrefix(), MaxRetryAttemptsOnRateLimitedRequests = 0, MaxRequestsPerTcpConnection = this.MaxRequestsPerTcpConnection, - MaxTcpConnectionsPerEndpoint = this.MaxTcpConnectionsPerEndpoint - }; - - if (this.EnableTelemetry) - { - Environment.SetEnvironmentVariable( - Microsoft.Azure.Cosmos.Telemetry.ClientTelemetryOptions.EnvPropsClientTelemetryEnabled, - "true"); - - if (this.TelemetryScheduleInSec > 0) + MaxTcpConnectionsPerEndpoint = this.MaxTcpConnectionsPerEndpoint, + CosmosClientTelemetryOptions = new Microsoft.Azure.Cosmos.CosmosClientTelemetryOptions() { - Environment.SetEnvironmentVariable( - Microsoft.Azure.Cosmos.Telemetry.ClientTelemetryOptions.EnvPropsClientTelemetrySchedulingInSeconds, - Convert.ToString(this.TelemetryScheduleInSec)); + DisableSendingMetricsToService = !this.EnableTelemetry, + DisableDistributedTracing = !this.EnableDistributedTracing } - - if (!string.IsNullOrEmpty(this.TelemetryEndpoint)) - { - Environment.SetEnvironmentVariable( - Microsoft.Azure.Cosmos.Telemetry.ClientTelemetryOptions.EnvPropsClientTelemetryEndpoint, - this.TelemetryEndpoint); - } - } + }; if (!string.IsNullOrWhiteSpace(this.ConsistencyLevel)) { @@ -263,11 +274,11 @@ private static void HandleParseError(IEnumerable errors) { foreach (Error e in errors) { - Console.WriteLine(e.ToString()); + Trace.TraceInformation(e.ToString()); } } Environment.Exit(errors.Count()); } } -} +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/BenchmarkLatencyEventSource.cs b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/BenchmarkLatencyEventSource.cs index 309eb58c15..6b1b6d03d7 100644 --- a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/BenchmarkLatencyEventSource.cs +++ b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/BenchmarkLatencyEventSource.cs @@ -36,13 +36,26 @@ public void LatencyDiagnostics( string dbName, string containerName, int durationInMs, - Func lazyDiagnostics) + Func lazyDiagnostics, + int latencyThreshold) { - if (durationInMs > BenchmarkLatencyEventSource.TraceLatencyThreshold + if (durationInMs > latencyThreshold && this.IsEnabled()) { this.WriteEvent(1, dbName, containerName, durationInMs, lazyDiagnostics()); } } + + [Event(2, Level = EventLevel.Informational)] + public void OnOperationSuccess(int operationType, double durationInMs) + { + this.WriteEvent(2, operationType, durationInMs); + } + + [Event(3, Level = EventLevel.Informational)] + public void OnOperationFailure(int operationType, double durationInMs) + { + this.WriteEvent(3, operationType, durationInMs); + } } } diff --git a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/BenchmarkProgress.cs b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/BenchmarkProgress.cs new file mode 100644 index 0000000000..584f9e7a29 --- /dev/null +++ b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/BenchmarkProgress.cs @@ -0,0 +1,55 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ +namespace CosmosBenchmark +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using System.Threading.Tasks; + using Newtonsoft.Json; + + /// + /// Represents a class that is used as an item in CosmosDB to track benchmark progress. + /// + public class BenchmarkProgress + { + /// + /// Record item id + /// + [JsonProperty] + public string id { get; set; } + + /// + /// Record item pk + /// + [JsonProperty] + public string pk { get; set; } + + /// + /// Machine name + /// + [JsonProperty] + public string MachineName { get; set; } + + /// + /// Job status STARTED|COMPLETED + /// + [JsonProperty] + public string JobStatus { get; set; } + + /// + /// Job start time . + /// + [JsonProperty] + public DateTime JobStartTime { get; set; } + + /// + /// Job end time . + /// + [JsonProperty] + public DateTime JobEndTime { get; set; } + + } +} diff --git a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/CosmosBenchmark.csproj b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/CosmosBenchmark.csproj index c8ac26f5aa..073e8daa7a 100644 --- a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/CosmosBenchmark.csproj +++ b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/CosmosBenchmark.csproj @@ -17,6 +17,8 @@ + + diff --git a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/CosmosBenchmarkEventListener.cs b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/CosmosBenchmarkEventListener.cs new file mode 100644 index 0000000000..d12cb6c476 --- /dev/null +++ b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/CosmosBenchmarkEventListener.cs @@ -0,0 +1,92 @@ +namespace CosmosBenchmark +{ + using System; + using System.Diagnostics.Tracing; + using System.Threading; + using System.Threading.Tasks; + using OpenTelemetry.Metrics; + + internal class CosmosBenchmarkEventListener : EventListener + { + static readonly string CosmosBenchmarkEventSourceName = "Azure.Cosmos.Benchmark"; + + private readonly MeterProvider meterProvider; + private readonly MetricsCollector[] metricsCollectors; + private readonly MetricCollectionWindow metricCollectionWindow; + private const int WindowCheckInterval = 10; + + public CosmosBenchmarkEventListener(MeterProvider meterProvider, BenchmarkConfig config) + { + this.meterProvider = meterProvider; + this.metricCollectionWindow ??= new MetricCollectionWindow(config.MetricsReportingIntervalInSec); + + this.metricsCollectors = new MetricsCollector[Enum.GetValues().Length]; + foreach (BenchmarkOperationType entry in Enum.GetValues()) + { + this.metricsCollectors[(int)entry] = new MetricsCollector(entry); + } + + /// + /// Flush metrics every + /// + ThreadPool.QueueUserWorkItem(async state => + { + while (true) + { + // Reset metricCollectionWindow and flush. + if (this.metricCollectionWindow.IsInvalid()) + { + this.meterProvider.ForceFlush(); + this.metricCollectionWindow.Reset(); + } + await Task.Delay(TimeSpan.FromMilliseconds(CosmosBenchmarkEventListener.WindowCheckInterval)); + } + }); + } + + + + /// + /// Override this method to get a list of all the eventSources that exist. + /// + protected override void OnEventSourceCreated(EventSource eventSource) + { + // Because we want to turn on every EventSource, we subscribe to a callback that triggers + // when new EventSources are created. It is also fired when the EventListener is created + // for all pre-existing EventSources. Thus this callback get called once for every + // EventSource regardless of the order of EventSource and EventListener creation. + + // For any EventSource we learn about, turn it on. + if (eventSource.Name == CosmosBenchmarkEventSourceName) + { + this.EnableEvents(eventSource, EventLevel.Informational, EventKeywords.All); + } + } + + /// + /// We override this method to get a callback on every event we subscribed to with EnableEvents + /// + /// + protected override void OnEventWritten(EventWrittenEventArgs eventData) + { + if (eventData.EventId == 2 // Successful + || eventData.EventId == 3) // Failure + { + int operationTypeIndex = (int)eventData.Payload[0]; + double durationInMs = (double)eventData.Payload[1]; + + switch (eventData.EventId) + { + case 2: + this.metricsCollectors[operationTypeIndex].OnOperationSuccess(durationInMs); + break; + case 3: + this.metricsCollectors[operationTypeIndex].OnOperationFailure(durationInMs); + break; + default: + break; + } + } + } + } +} diff --git a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/Fx/DiagnosticDataListener.cs b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/Fx/DiagnosticDataListener.cs new file mode 100644 index 0000000000..fe7da4a2e2 --- /dev/null +++ b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/Fx/DiagnosticDataListener.cs @@ -0,0 +1,227 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace CosmosBenchmark.Fx +{ + using System; + using System.Collections.Generic; + using System.Diagnostics.Tracing; + using System.IO; + using System.Threading; + using System.Threading.Tasks; + using Azure.Storage.Blobs; + + public class DiagnosticDataListener : EventListener + { + /// + /// A constant string representing the container name in Azure Blob Storage. + /// + private const string BlobContainerName = "diagnostics"; + + /// + /// A constant string representing the diagnostics file path. + /// + public const string DiagnosticsFileName = "BenchmarkDiagnostics.out"; + + /// + /// A constant int representing the maximum file size. + /// + private readonly int MaxDIagnosticFileSize = 100_000_000; + + /// + /// A constant int representing the interval at which the file size is checked. + /// + private readonly TimeSpan FileSizeCheckInterval = TimeSpan.FromSeconds(5); + + /// + /// string representing filename prefix in blob storage + /// + private readonly string BlobPrefix = $"{Environment.MachineName}/{Environment.MachineName}"; + + /// + /// Number of files + /// + private int filesCount = 0; + + /// + /// Represents a Blob storage container client instance + /// + private readonly Lazy BlobContainerClient; + + /// + /// Represents a Benchmark Configs + /// + private readonly BenchmarkConfig config; + + /// + /// Current diagnostics optput StreamWriter + /// + private volatile TextWriter Writer; + + /// + /// Current diagnostics optput filename + /// + public volatile string WriterFileName; + + /// + /// List of all previously opened StreamWriters + /// should be stored for later closing, as they may be + /// concurrently accessed by other threads for appending to a file. + /// + private readonly List TextWriters = new List(); + + /// + /// Represents a class that performs writing diagnostic data to a file and uploading it to Azure Blob Storage + /// + public DiagnosticDataListener(BenchmarkConfig config) + { + this.config = config; + this.EnableEvents(BenchmarkLatencyEventSource.Instance, EventLevel.Informational); + this.BlobContainerClient = new Lazy(() => this.GetBlobServiceClient()); + this.Writer = TextWriter.Synchronized(File.AppendText(DiagnosticsFileName)); + this.WriterFileName = DiagnosticsFileName; + + /// + /// Checks the file size every milliseconds for diagnostics and creates a new one if the maximum limit is exceeded. + /// + ThreadPool.QueueUserWorkItem(async state => + { + while (true) + { + try + { + if (File.Exists(this.WriterFileName)) + { + FileInfo fileInfo = new FileInfo(this.WriterFileName); + long fileSize = fileInfo.Length; + + if (fileSize > this.MaxDIagnosticFileSize) + { + string newFilePath = Path.Combine(fileInfo.DirectoryName, $"{DiagnosticsFileName}-{this.filesCount}"); + + File.Create(newFilePath).Close(); + + this.TextWriters.Add(this.Writer); + + this.Writer = TextWriter.Synchronized(File.AppendText($"{newFilePath}")); + this.WriterFileName = newFilePath; + this.filesCount++; + + Utility.TeeTraceInformation("File size exceeded 100MB. Created a new one."); + } + } + + await Task.Delay(this.FileSizeCheckInterval); + + this.CloseStreamWriters(); + } + catch (Exception ex) + { + Utility.TraceError("Exception in file size check loop", ex); + } + } + }); + } + + + /// + /// Listening for events generated by BenchmarkLatencyEventSource + /// + /// An instance of containing the request latency and diagnostics. + protected override void OnEventWritten(EventWrittenEventArgs eventData) + { + if (eventData.EventId == 1) + { + try + { + this.Writer.WriteLine($"{eventData.Payload[2]} ; {eventData.Payload[3]}"); + } + catch (Exception ex) + { + Utility.TraceError("An exception ocured while writing diagnostic data to the file", ex); + } + } + } + + /// + /// Uploading all files with diagnostic data to blob storage + /// + public void UploadDiagnostcs() + { + Utility.TeeTraceInformation("Uploading diagnostics"); + string[] diagnosticFiles = Directory.GetFiles(".", $"{DiagnosticsFileName}*"); + string containerPrefix = this.config.DiagnosticsStorageContainerPrefix; + + this.CloseStreamWriters(); + this.SafeCloseCurrentStreamWriter(); + + BlobContainerClient blobContainerClient = this.BlobContainerClient.Value; + for (int i = 0; i < diagnosticFiles.Length; i++) + { + try + { + string diagnosticFile = diagnosticFiles[i]; + Utility.TeeTraceInformation($"Uploading {i + 1} of {diagnosticFiles.Length} file: {diagnosticFile} "); + + string blobName = string.IsNullOrEmpty(containerPrefix) ? + $"{this.BlobPrefix}-{i}.out" : $"{containerPrefix}/{this.BlobPrefix}-{i}.out"; + + BlobClient blobClient = blobContainerClient.GetBlobClient(blobName); + + blobClient.Upload(diagnosticFile, overwrite: true); + } + catch (Exception ex) + { + Utility.TraceError($"An exception ocured while uploading file {this.WriterFileName} to the blob storage", ex); + } + } + } + + /// + /// Closes all unclosed StreamWriters + /// + private void CloseStreamWriters() + { + + this.TextWriters.ForEach(t => + { + try + { + t.Close(); + } + catch (Exception ex) + { + Utility.TraceError("An exception ocured while closing StreamWriters", ex); + } + }); + } + + /// + /// Safe close current StreamWriter + /// + private void SafeCloseCurrentStreamWriter() + { + try + { + this.Writer.Close(); + } + catch (Exception ex) + { + Utility.TraceError("An exception ocured while closing StreamWriters.", ex); + } + } + + /// + /// Creating an instance of BlobClient using configs + /// + private BlobContainerClient GetBlobServiceClient() + { + BlobContainerClient blobContainerClient = new BlobContainerClient( + this.config.DiagnosticsStorageConnectionString, + BlobContainerName); + blobContainerClient.CreateIfNotExists(); + return blobContainerClient; + } + } +} diff --git a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/Fx/IExecutionStrategy.cs b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/Fx/IExecutionStrategy.cs index b18fc34dc7..e517439419 100644 --- a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/Fx/IExecutionStrategy.cs +++ b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/Fx/IExecutionStrategy.cs @@ -6,6 +6,7 @@ namespace CosmosBenchmark { using System; using System.Threading.Tasks; + using OpenTelemetry.Metrics; internal interface IExecutionStrategy { @@ -20,6 +21,5 @@ public Task ExecuteAsync( int serialExecutorConcurrency, int serialExecutorIterationCount, double warmupFraction); - } } diff --git a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/Fx/IExecutor.cs b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/Fx/IExecutor.cs index be2ee2e761..c4d1c765e7 100644 --- a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/Fx/IExecutor.cs +++ b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/Fx/IExecutor.cs @@ -17,6 +17,7 @@ public Task ExecuteAsync( int iterationCount, bool isWarmup, bool traceFailures, - Action completionCallback); + Action completionCallback, + BenchmarkConfig benchmarkConfig); } } diff --git a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/Fx/IMetricsCollector.cs b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/Fx/IMetricsCollector.cs new file mode 100644 index 0000000000..fa5558c31b --- /dev/null +++ b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/Fx/IMetricsCollector.cs @@ -0,0 +1,24 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace CosmosBenchmark +{ + using System; + + /// + /// Represents the metrics collector. + /// + public interface IMetricsCollector + { + /// + /// Successful operation with latency + /// + void OnOperationSuccess(double operationLatencyInMs); + + /// + /// Failed operation with latency + /// + void OnOperationFailure(double operationLatencyInMs); + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/Fx/MetricsCollector.cs b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/Fx/MetricsCollector.cs new file mode 100644 index 0000000000..4f1fc68257 --- /dev/null +++ b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/Fx/MetricsCollector.cs @@ -0,0 +1,177 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace CosmosBenchmark +{ + using System; + using System.Collections.Generic; + using System.Diagnostics.Metrics; + + /// + /// Represents the metrics collector. + /// + internal class MetricsCollector : IMetricsCollector + { + /// + /// Represents the meter to collect metrics. + /// + private readonly Meter meter; + + /// + /// Represents the histogram for operation latency. + /// + private readonly Histogram operationLatencyHistogram; + + /// + /// Represents the histogram for records per second metric. + /// + private readonly Histogram rpsMetricNameHistogram; + + /// + /// Represents the histogram for failed operation latency. + /// + private readonly Histogram operationFailedLatencyHistogram; + + /// + /// Represents the histogram failed operations for records per second metric. + /// + private readonly Histogram rpsFailedMetricNameHistogram; + + /// + /// Represents the success operation counter. + /// + private readonly Counter successOperationCounter; + + /// + /// Represents the failure operation counter. + /// + private readonly Counter failureOperationCounter; + + /// + /// Represents latency in milliseconds metric gauge. + /// + /// Please do not remove this as it used when collecting metrics.. + private readonly ObservableGauge latencyInMsMetricNameGauge; + + /// + /// Represents records per second metric gauge. + /// + /// Please do not remove this as it used when collecting metrics.. + private readonly ObservableGauge rpsNameGauge; + + + /// + /// Represents latency in milliseconds metric gauge for failed operations. + /// + /// Please do not remove this as it used when collecting metrics.. + private readonly ObservableGauge latencyInMsFailedMetricNameGauge; + + /// + /// Represents records per second metric gauge for failed operations. + /// + /// Please do not remove this as it used when collecting metrics.. + private readonly ObservableGauge rpsFailedNameGauge; + + /// + /// Latency in milliseconds. + /// + private double latencyInMs; + + /// + /// Records per second. + /// + private double rps; + + /// + /// Latency in milliseconds. + /// + private double latencyFailedInMs; + + /// + /// Records per second. + /// + private double rpsFailed; + + /// + /// Initialize new instance of . + /// + /// OpenTelemetry meter. + public MetricsCollector(BenchmarkOperationType operationType) + { + this.meter = new Meter($"CosmosBenchmark{operationType}OperationMeter"); + this.rpsMetricNameHistogram = this.meter.CreateHistogram($"{operationType}OperationRpsHistogram"); + this.operationLatencyHistogram = this.meter.CreateHistogram($"{operationType}OperationLatencyInMsHistogram"); + + this.rpsFailedMetricNameHistogram = this.meter.CreateHistogram($"{operationType}FailedOperationRpsHistogram"); + this.operationFailedLatencyHistogram = this.meter.CreateHistogram($"{operationType}FailedOperationLatencyInMsHistogram"); + + this.successOperationCounter = this.meter.CreateCounter($"{operationType}OperationSuccess"); + this.failureOperationCounter = this.meter.CreateCounter($"{operationType}OperationFailure"); + + this.latencyInMsMetricNameGauge = this.meter.CreateObservableGauge($"{operationType}OperationLatencyInMs", + () => new Measurement(this.latencyInMs)); + + this.rpsNameGauge = this.meter.CreateObservableGauge($"{operationType}OperationRps", + () => new Measurement(this.rps)); + + this.latencyInMsFailedMetricNameGauge = this.meter.CreateObservableGauge($"{operationType}FailedOperationLatencyInMs", + () => new Measurement(this.latencyFailedInMs)); + + this.rpsFailedNameGauge = this.meter.CreateObservableGauge($"{operationType}FailedOperationRps", + () => new Measurement(this.rpsFailed)); + } + + internal static IEnumerable GetBenchmarkMeterNames() + { + foreach (BenchmarkOperationType entry in Enum.GetValues()) + { + yield return $"CosmosBenchmark{entry}OperationMeter"; + } + } + + /// + /// Successful operation with latency + /// + public void OnOperationSuccess(double operationLatencyInMs) + { + this.successOperationCounter.Add(1); + this.RecordSuccessOpLatencyAndRps(operationLatencyInMs); + } + + /// + /// Failed operation with latency + /// + public void OnOperationFailure(double operationLatencyInMs) + { + this.failureOperationCounter.Add(1); + this.RecordFailedOpLatencyAndRps(operationLatencyInMs); + } + + /// + /// Records success operation latency in milliseconds. + /// + /// The number of milliseconds to record. + public void RecordSuccessOpLatencyAndRps( + double operationLatencyInMs) + { + this.rps = operationLatencyInMs != 0 ? 1000 / operationLatencyInMs : 0; + this.latencyInMs = operationLatencyInMs; + this.rpsMetricNameHistogram.Record(this.rps); + this.operationLatencyHistogram.Record(this.latencyInMs); + } + + /// + /// Records failed operation latency in milliseconds. + /// + /// The number of milliseconds to record. + public void RecordFailedOpLatencyAndRps( + double operationLatencyInMs) + { + this.rpsFailed = operationLatencyInMs != 0 ? 1000 / operationLatencyInMs : 0; + this.latencyFailedInMs = operationLatencyInMs; + this.rpsFailedMetricNameHistogram.Record(this.rpsFailed); + this.operationFailedLatencyHistogram.Record(this.latencyFailedInMs); + } + } +} diff --git a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/Fx/OperationResult.cs b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/Fx/OperationResult.cs index 0e87c33b35..a7f34b8bb0 100644 --- a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/Fx/OperationResult.cs +++ b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/Fx/OperationResult.cs @@ -7,6 +7,7 @@ internal struct OperationResult { public string DatabseName { get; set; } public string ContainerName { get; set; } + public BenchmarkOperationType OperationType { get; set; } public double RuCharges { get; set; } public Func LazyDiagnostics { get; set; } public CosmosDiagnostics CosmosDiagnostics { get; set; } diff --git a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/Fx/ParallelExecutionStrategy.cs b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/Fx/ParallelExecutionStrategy.cs index e5dc7bb58d..018f7f1615 100644 --- a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/Fx/ParallelExecutionStrategy.cs +++ b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/Fx/ParallelExecutionStrategy.cs @@ -11,6 +11,7 @@ namespace CosmosBenchmark using System.Threading; using System.Threading.Tasks; using Newtonsoft.Json; + using OpenTelemetry.Metrics; internal class ParallelExecutionStrategy : IExecutionStrategy { @@ -37,8 +38,10 @@ await warmupExecutor.ExecuteAsync( (int)(serialExecutorIterationCount * warmupFraction), isWarmup: true, traceFailures: benchmarkConfig.TraceFailures, - completionCallback: () => { }); + completionCallback: () => { }, + benchmarkConfig); + Utility.TeePrint("Starting execution {0} tasks", serialExecutorConcurrency); IExecutor[] executors = new IExecutor[serialExecutorConcurrency]; for (int i = 0; i < serialExecutorConcurrency; i++) { @@ -54,11 +57,12 @@ await warmupExecutor.ExecuteAsync( iterationCount: serialExecutorIterationCount, isWarmup: false, traceFailures: benchmarkConfig.TraceFailures, - completionCallback: () => Interlocked.Decrement(ref this.pendingExecutorCount)); + completionCallback: () => Interlocked.Decrement(ref this.pendingExecutorCount), + benchmarkConfig); } return await this.LogOutputStats( - benchmarkConfig, + benchmarkConfig, executors); } @@ -107,9 +111,8 @@ private async Task LogOutputStats( using (ConsoleColorContext ct = new ConsoleColorContext(ConsoleColor.Green)) { - Console.WriteLine(); - Console.WriteLine("Summary:"); - Console.WriteLine("--------------------------------------------------------------------- "); + Utility.TeeTraceInformation("Summary:"); + Utility.TeeTraceInformation("--------------------------------------------------------------------- "); lastSummary.Print(lastSummary.failedOpsCount + lastSummary.successfulOpsCount); // Skip first 5 and last 5 counters as outliers @@ -122,7 +125,6 @@ private async Task LogOutputStats( if (summaryCounters.Length > 10) { - Console.WriteLine(); Utility.TeeTraceInformation("After Excluding outliers"); runSummary.Top10PercentAverageRps = Math.Round(summaryCounters.Take((int)(0.1 * summaryCounters.Length)).Average(), 0); @@ -154,10 +156,10 @@ private async Task LogOutputStats( Utility.TeeTraceInformation("Please adjust ItemCount high to run of at-least 1M"); } - Console.WriteLine("--------------------------------------------------------------------- "); + Utility.TeeTraceInformation("--------------------------------------------------------------------- "); return runSummary; } } } -} +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/Fx/SerialOperationExecutor.cs b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/Fx/SerialOperationExecutor.cs index 1086c31bd5..200a647e77 100644 --- a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/Fx/SerialOperationExecutor.cs +++ b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/Fx/SerialOperationExecutor.cs @@ -8,6 +8,7 @@ namespace CosmosBenchmark using System.Diagnostics; using System.Threading.Tasks; using Microsoft.Azure.Cosmos; + using static CosmosBenchmark.TelemetrySpan; internal class SerialOperationExecutor : IExecutor { @@ -34,7 +35,8 @@ public async Task ExecuteAsync( int iterationCount, bool isWarmup, bool traceFailures, - Action completionCallback) + Action completionCallback, + BenchmarkConfig benchmarkConfig) { Trace.TraceInformation($"Executor {this.executorId} started"); @@ -47,13 +49,15 @@ public async Task ExecuteAsync( await this.operation.PrepareAsync(); - using (IDisposable telemetrySpan = TelemetrySpan.StartNew( + using (ITelemetrySpan telemetrySpan = TelemetrySpan.StartNew( + benchmarkConfig, () => operationResult.Value, disableTelemetry: isWarmup)) { try { operationResult = await this.operation.ExecuteOnceAsync(); + telemetrySpan.MarkSuccess(); // Success case this.SuccessOperationCount++; @@ -66,9 +70,10 @@ public async Task ExecuteAsync( } catch (Exception ex) { + telemetrySpan.MarkFailed(); if (traceFailures) { - Console.WriteLine(ex.ToString()); + Trace.TraceInformation(ex.ToString()); } // failure case @@ -96,6 +101,11 @@ public async Task ExecuteAsync( Trace.TraceInformation($"Executor {this.executorId} completed"); } + catch (Exception e) + { + Utility.TraceError("Error:", e); + + } finally { completionCallback(); diff --git a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/Fx/TelemetrySpan.cs b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/Fx/TelemetrySpan.cs index 13d971aa2a..ae03edcfa3 100644 --- a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/Fx/TelemetrySpan.cs +++ b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/Fx/TelemetrySpan.cs @@ -8,8 +8,9 @@ namespace CosmosBenchmark using System.Diagnostics; using System.Linq; using System.Threading; + using static CosmosBenchmark.TelemetrySpan; - internal struct TelemetrySpan : IDisposable + internal class TelemetrySpan : ITelemetrySpan { private static double[] latencyHistogram; private static int latencyIndex = -1; @@ -19,8 +20,11 @@ internal struct TelemetrySpan : IDisposable private Stopwatch stopwatch; private Func lazyOperationResult; private bool disableTelemetry; + private bool isFailed = false; + private BenchmarkConfig benchmarkConfig; - public static IDisposable StartNew( + public static ITelemetrySpan StartNew( + BenchmarkConfig benchmarkConfig, Func lazyOperationResult, bool disableTelemetry) { @@ -31,15 +35,28 @@ public static IDisposable StartNew( return new TelemetrySpan { + benchmarkConfig = benchmarkConfig, stopwatch = Stopwatch.StartNew(), lazyOperationResult = lazyOperationResult, disableTelemetry = disableTelemetry }; } - public void Dispose() + public void MarkFailed() + { + this.isFailed = true; + this.stopwatch.Stop(); + } + + public void MarkSuccess() { + this.isFailed = false; this.stopwatch.Stop(); + } + + public void Dispose() + { + this.stopwatch.Stop(); // No-op in-case of MarkFailed or MarkSuccess prior call if (!this.disableTelemetry) { OperationResult operationResult = this.lazyOperationResult(); @@ -47,13 +64,23 @@ public void Dispose() if (TelemetrySpan.IncludePercentile) { RecordLatency(this.stopwatch.Elapsed.TotalMilliseconds); + + if (this.isFailed) + { + BenchmarkLatencyEventSource.Instance.OnOperationFailure((int)operationResult.OperationType, this.stopwatch.Elapsed.TotalMilliseconds); + } + else + { + BenchmarkLatencyEventSource.Instance.OnOperationSuccess((int)operationResult.OperationType, this.stopwatch.Elapsed.TotalMilliseconds); + } } BenchmarkLatencyEventSource.Instance.LatencyDiagnostics( operationResult.DatabseName, operationResult.ContainerName, (int)this.stopwatch.ElapsedMilliseconds, - operationResult.LazyDiagnostics); + operationResult.LazyDiagnostics, + this.benchmarkConfig.DiagnosticLatencyThresholdInMs); } } @@ -65,13 +92,13 @@ private static void RecordLatency(double elapsedMilliseoncds) internal static void ResetLatencyHistogram(int totalNumberOfIterations) { - latencyHistogram = new double[totalNumberOfIterations]; + TelemetrySpan.latencyHistogram = new double[totalNumberOfIterations]; latencyIndex = -1; } internal static double? GetLatencyPercentile(int percentile) { - if (latencyHistogram == null) + if (TelemetrySpan.latencyHistogram == null) { return null; } @@ -79,13 +106,27 @@ internal static void ResetLatencyHistogram(int totalNumberOfIterations) return MathNet.Numerics.Statistics.Statistics.Percentile(latencyHistogram.Take(latencyIndex + 1), percentile); } - private class NoOpDisposable : IDisposable + private class NoOpDisposable : ITelemetrySpan { public static readonly NoOpDisposable Instance = new NoOpDisposable(); public void Dispose() { } + + public void MarkSuccess() + { + } + + public void MarkFailed() + { + } + } + + public interface ITelemetrySpan : IDisposable + { + void MarkSuccess(); + void MarkFailed(); } } -} +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/MetricCollectionWindow.cs b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/MetricCollectionWindow.cs new file mode 100644 index 0000000000..fabdcfc75d --- /dev/null +++ b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/MetricCollectionWindow.cs @@ -0,0 +1,45 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace CosmosBenchmark +{ + using System; + + /// + /// Represents the metric collection window (time span while accumulating and granulating the data) + /// + internal class MetricCollectionWindow + { + private DateTime ValidTill { get; set; } + + private int MetricsReportingIntervalInSec { get; set; } + + /// + /// Creates the instance of . + /// + /// Cosmos Benchmark configuration. + public MetricCollectionWindow(int metricsReportingIntervalInSec) + { + this.MetricsReportingIntervalInSec = metricsReportingIntervalInSec; + this.Reset(); + } + + /// + /// Indicates whether the current window is valid. + /// + public bool IsInvalid() + { + return DateTime.UtcNow > this.ValidTill; + } + + /// + /// Resets the started timestamp and valid till timespan. + /// + /// + public void Reset() + { + this.ValidTill = DateTime.UtcNow.AddSeconds(this.MetricsReportingIntervalInSec); + } + } +} diff --git a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/Program.cs b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/Program.cs index 65ee51dfe2..a3f2f2dfa9 100644 --- a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/Program.cs +++ b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/Program.cs @@ -9,13 +9,17 @@ namespace CosmosBenchmark using System.Diagnostics; using System.IO; using System.Linq; - using System.Net; using System.Net.Http; using System.Reflection; using System.Threading; using System.Threading.Tasks; + using Azure.Monitor.OpenTelemetry.Exporter; + using CosmosBenchmark.Fx; using Microsoft.Azure.Cosmos; using Newtonsoft.Json.Linq; + using OpenTelemetry; + using OpenTelemetry.Metrics; + using Container = Microsoft.Azure.Cosmos.Container; /// /// This sample demonstrates how to achieve high performance writes using Azure Comsos DB. @@ -31,10 +35,19 @@ public static async Task Main(string[] args) try { BenchmarkConfig config = BenchmarkConfig.From(args); - await Program.AddAzureInfoToRunSummary(); - + await AddAzureInfoToRunSummary(); + + MeterProvider meterProvider = BuildMeterProvider(config); + CosmosBenchmarkEventListener listener = new CosmosBenchmarkEventListener(meterProvider, config); + ThreadPool.SetMinThreads(config.MinThreadPoolSize, config.MinThreadPoolSize); + DiagnosticDataListener diagnosticDataListener = null; + if (!string.IsNullOrEmpty(config.DiagnosticsStorageConnectionString)) + { + diagnosticDataListener = new DiagnosticDataListener(config); + } + if (config.EnableLatencyPercentiles) { TelemetrySpan.IncludePercentile = true; @@ -46,18 +59,61 @@ public static async Task Main(string[] args) Program program = new Program(); RunSummary runSummary = await program.ExecuteAsync(config); + + if (!string.IsNullOrEmpty(config.DiagnosticsStorageConnectionString)) + { + diagnosticDataListener.UploadDiagnostcs(); + } + } + catch (Exception e) + { + Utility.TeeTraceInformation("Exception ocured:" + e.ToString()); } finally { - Console.WriteLine($"{nameof(CosmosBenchmark)} completed successfully."); + Utility.TeeTraceInformation($"{nameof(CosmosBenchmark)} completed successfully."); if (Debugger.IsAttached) { - Console.WriteLine("Press any key to exit..."); + Utility.TeeTraceInformation("Press any key to exit..."); Console.ReadLine(); } } } + /// + /// Create a MeterProvider. If the App Insights connection string is not set, do not create an AppInsights Exporter. + /// + /// + private static MeterProvider BuildMeterProvider(BenchmarkConfig config) + { + MeterProviderBuilder meterProviderBuilder = Sdk.CreateMeterProviderBuilder(); + if (string.IsNullOrWhiteSpace(config.AppInsightsConnectionString)) + { + foreach(string benchmarkName in MetricsCollector.GetBenchmarkMeterNames()) + { + meterProviderBuilder = meterProviderBuilder.AddMeter(benchmarkName); + }; + + return meterProviderBuilder.Build(); + } + + OpenTelemetry.Trace.TracerProviderBuilder tracerProviderBuilder = Sdk.CreateTracerProviderBuilder() + .AddAzureMonitorTraceExporter(); + + meterProviderBuilder = meterProviderBuilder.AddAzureMonitorMetricExporter(configure: new Action( + (options) => options.ConnectionString = config.AppInsightsConnectionString)); + foreach (string benchmarkName in MetricsCollector.GetBenchmarkMeterNames()) + { + meterProviderBuilder = meterProviderBuilder.AddMeter(benchmarkName); + }; + + return meterProviderBuilder.Build(); + } + + /// + /// Adds Azure VM information to run summary. + /// + /// private static async Task AddAzureInfoToRunSummary() { using HttpClient httpClient = new HttpClient(); @@ -73,11 +129,11 @@ private static async Task AddAzureInfoToRunSummary() JObject jObject = JObject.Parse(jsonVmInfo); RunSummary.AzureVmInfo = jObject; RunSummary.Location = jObject["compute"]["location"].ToString(); - Console.WriteLine($"Azure VM Location:{RunSummary.Location}"); + Utility.TeeTraceInformation($"Azure VM Location:{RunSummary.Location}"); } - catch(Exception e) + catch (Exception e) { - Console.WriteLine("Failed to get Azure VM info:" + e.ToString()); + Utility.TeeTraceInformation("Failed to get Azure VM info:" + e.ToString()); } } @@ -109,11 +165,14 @@ private async Task ExecuteAsync(BenchmarkConfig config) $"Container {config.Container} must have a configured throughput."); } - Console.WriteLine($"Using container {config.Container} with {currentContainerThroughput} RU/s"); + Container resultContainer = await GetResultContainer(config, cosmosClient); + + BenchmarkProgress benchmarkProgressItem = await CreateBenchmarkProgressItem(resultContainer); + + Utility.TeeTraceInformation($"Using container {config.Container} with {currentContainerThroughput} RU/s"); int taskCount = config.GetTaskCount(currentContainerThroughput.Value); - Console.WriteLine("Starting Inserts with {0} tasks", taskCount); - Console.WriteLine(); + Utility.TeePrint("Starting Inserts with {0} tasks", taskCount); string partitionKeyPath = containerResponse.Resource.PartitionKeyPath; int opsPerTask = config.ItemCount / taskCount; @@ -137,12 +196,12 @@ private async Task ExecuteAsync(BenchmarkConfig config) } IExecutionStrategy execution = IExecutionStrategy.StartNew(benchmarkOperationFactory); - runSummary = await execution.ExecuteAsync(config, taskCount, opsPerTask, 0.01); + runSummary = await execution.ExecuteAsync(config, taskCount, opsPerTask, 0.01); } if (config.CleanupOnFinish) { - Console.WriteLine($"Deleting Database {config.Database}"); + Utility.TeeTraceInformation($"Deleting Database {config.Database}"); await database.DeleteStreamAsync(); } @@ -154,9 +213,10 @@ private async Task ExecuteAsync(BenchmarkConfig config) } runSummary.ConsistencyLevel = consistencyLevel; - + BenchmarkProgress benchmarkProgress = await CompleteBenchmarkProgressStatus(benchmarkProgressItem, resultContainer); if (config.PublishResults) { + Utility.TeeTraceInformation("Publishing results"); runSummary.Diagnostics = CosmosDiagnosticsLogger.GetDiagnostics(); await this.PublishResults( config, @@ -187,6 +247,7 @@ private async Task PublishResults( Container resultContainer = cosmosClient.GetContainer(config.ResultsDatabase, config.ResultsContainer); await resultContainer.CreateItemAsync(runSummary, new PartitionKey(runSummary.pk)); } + } private Func GetBenchmarkFactory( @@ -259,25 +320,58 @@ private static Type[] AvailableBenchmarks() private static async Task CreatePartitionedContainerAsync(BenchmarkConfig options, CosmosClient cosmosClient) { Microsoft.Azure.Cosmos.Database database = await cosmosClient.CreateDatabaseIfNotExistsAsync(options.Database); + + string partitionKeyPath = options.PartitionKeyPath; + return await database.CreateContainerIfNotExistsAsync(options.Container, partitionKeyPath, options.Throughput); + } - Container container = database.GetContainer(options.Container); - - try + /// + /// Creating a progress item in ComsosDb when the benchmark start + /// + /// An instance of that represents operations performed on a database container. + private static async Task CreateBenchmarkProgressItem(Container resultContainer) + { + BenchmarkProgress benchmarkProgress = new BenchmarkProgress { - return await container.ReadContainerAsync(); - } - catch(CosmosException ex) when (ex.StatusCode == HttpStatusCode.NotFound) - { - // Show user cost of running this test - double estimatedCostPerMonth = 0.06 * options.Throughput; - double estimatedCostPerHour = estimatedCostPerMonth / (24 * 30); - Console.WriteLine($"The container will cost an estimated ${Math.Round(estimatedCostPerHour, 2)} per hour (${Math.Round(estimatedCostPerMonth, 2)} per month)"); - Console.WriteLine("Press enter to continue ..."); - Console.ReadLine(); - - string partitionKeyPath = options.PartitionKeyPath; - return await database.CreateContainerAsync(options.Container, partitionKeyPath, options.Throughput); - } + id = Environment.MachineName, + MachineName = Environment.MachineName, + JobStatus = "STARTED", + JobStartTime = DateTime.Now, + pk = Environment.MachineName + }; + + ItemResponse itemResponse = await resultContainer.UpsertItemAsync( + benchmarkProgress, new PartitionKey(benchmarkProgress.pk)); + + return itemResponse.Resource; + } + + /// + /// Change a progress item status to Complete in ComsosDb when the benchmark compleated + /// + /// An instance of that represents operations performed on a database container. + /// An instance of that represents the document to be modified. + public static async Task CompleteBenchmarkProgressStatus(BenchmarkProgress benchmarkProgress, Container resultContainer) + { + benchmarkProgress.JobStatus = "COMPLETED"; + benchmarkProgress.JobEndTime = DateTime.Now; + ItemResponse itemResponse = await resultContainer.UpsertItemAsync(benchmarkProgress); + return itemResponse.Resource; + } + + /// + /// Configure and prepare the Cosmos DB Container instance for the result container. + /// + /// An instance of containing the benchmark tool input parameters. + /// An instance of that represents operations performed on a CosmosDb database. + private static async Task GetResultContainer(BenchmarkConfig config, CosmosClient cosmosClient) + { + Database database = cosmosClient.GetDatabase(config.ResultsDatabase ?? config.Database); + ContainerResponse containerResponse = await database + .CreateContainerIfNotExistsAsync( + id: config.ResultsContainer, + partitionKeyPath: "/pk"); + return containerResponse.Container; } private static void ClearCoreSdkListeners() diff --git a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/README.md b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/README.md index 8aac52daad..afbaf84bc6 100644 --- a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/README.md +++ b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/README.md @@ -54,6 +54,7 @@ cd 'azure-cosmos-dotnet-v3/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark' dotnet build --configuration Release -p:"OSSProjectRef=true;ShouldUnsetParentConfigurationAndPlatform=false" ``` + For PerfRuns with reports (INTERNAL) ``` @@ -113,9 +114,9 @@ Copyright (C) 2019 CosmosBenchmark --branchname Branch name, only for publish --resultspartitionkeyvalue Partitionkey, only for publish --disablecoresdklogging Disable core SDK logging - --enabletelemetry Enable Telemetry + --enabletelemetry Enable Telemetry Feature --telemetryscheduleinsec Telemetry Schedule in Seconds - --telemetryendpoint Telemetry Endpoint + --enableDistributedTracing Enable Distributed Tracing Feature --resultsendpoint Endpoint to publish results to --resultskey Key to publish results to --resultsdatabase Database to publish results to @@ -127,3 +128,7 @@ Copyright (C) 2019 CosmosBenchmark ## Running on Azure If you want to quickly get results, you can use our [guide to leverage Azure Container Instances](./AzureContainerInstances/README.md) to execute the benchmarks in any number of Azure regions with very little setup required. + +## Running on Azure VM + +If you want to execute benchmarking on multiple machines with one ARM Template, you can use our [guide to leverage Azure Virtual Machines](./AzureVmBenchmark/README.md). diff --git a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/Utility.cs b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/Utility.cs index d743bd391d..6d278f3d3a 100644 --- a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/Utility.cs +++ b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/Utility.cs @@ -16,6 +16,12 @@ public static void TeeTraceInformation(string payload) Trace.TraceInformation(payload); } + public static void TraceError(string payload, Exception e) + { + Console.WriteLine($"{payload}: {e.Message} {e.StackTrace}"); + Trace.TraceError(payload); + } + public static void TeePrint(string format, params object[] arg) { string payload = string.Format(format, arg); diff --git a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/loop.sh b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/loop.sh index 845f1c0022..11ff4ebf8a 100644 --- a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/loop.sh +++ b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/loop.sh @@ -7,7 +7,6 @@ export PL=18 #These must be configured export ACCOUNT_ENDPOINT= export ACCOUNT_KEY= -export TELEMETRY_ENDPOINT= #Loop forever i=0 diff --git a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v2/InsertV2BenchmarkOperation.cs b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v2/InsertV2BenchmarkOperation.cs index 124c841085..aafe6d4d4e 100644 --- a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v2/InsertV2BenchmarkOperation.cs +++ b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v2/InsertV2BenchmarkOperation.cs @@ -55,6 +55,7 @@ public async Task ExecuteOnceAsync() { DatabseName = databsaeName, ContainerName = containerName, + OperationType = this.OperationType, RuCharges = ruCharges, LazyDiagnostics = () => itemResponse.RequestDiagnosticsString, }; diff --git a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v2/QueryStreamSinglePkV2BenchmarkOperation.cs b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v2/QueryStreamSinglePkV2BenchmarkOperation.cs index b0f071f6de..222fa5fa3f 100644 --- a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v2/QueryStreamSinglePkV2BenchmarkOperation.cs +++ b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v2/QueryStreamSinglePkV2BenchmarkOperation.cs @@ -82,6 +82,7 @@ public async Task ExecuteOnceAsync() { DatabseName = databsaeName, ContainerName = containerName, + OperationType = this.OperationType, RuCharges = totalCharge, LazyDiagnostics = lastDiagnostics, }; diff --git a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v2/QueryTSinglePkV2BenchmarkOperation.cs b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v2/QueryTSinglePkV2BenchmarkOperation.cs index cd50a789b8..7abb881ba1 100644 --- a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v2/QueryTSinglePkV2BenchmarkOperation.cs +++ b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v2/QueryTSinglePkV2BenchmarkOperation.cs @@ -90,6 +90,7 @@ public async Task ExecuteOnceAsync() { DatabseName = databsaeName, ContainerName = containerName, + OperationType = this.OperationType, RuCharges = totalCharge, LazyDiagnostics = lastDiagnostics, }; diff --git a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v2/ReadFeedStreamV2BenchmarkOperation.cs b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v2/ReadFeedStreamV2BenchmarkOperation.cs index 0a9b9e3d7f..49e92195ce 100644 --- a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v2/ReadFeedStreamV2BenchmarkOperation.cs +++ b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v2/ReadFeedStreamV2BenchmarkOperation.cs @@ -54,6 +54,7 @@ public async Task ExecuteOnceAsync() { DatabseName = databsaeName, ContainerName = containerName, + OperationType = this.OperationType, RuCharges = ruCharges, LazyDiagnostics = () => feedResponse.QueryMetrics.ToString(), }; diff --git a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v2/ReadNotExistsV2BenchmarkOperation.cs b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v2/ReadNotExistsV2BenchmarkOperation.cs index 1d8b99449e..825d10ab60 100644 --- a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v2/ReadNotExistsV2BenchmarkOperation.cs +++ b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v2/ReadNotExistsV2BenchmarkOperation.cs @@ -61,6 +61,7 @@ public async Task ExecuteOnceAsync() { DatabseName = databsaeName, ContainerName = containerName, + OperationType = this.OperationType, RuCharges = dce.RequestCharge, LazyDiagnostics = () => dce.ToString(), }; diff --git a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v2/ReadStreamExistsV2BenchmarkOperation.cs b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v2/ReadStreamExistsV2BenchmarkOperation.cs index c7419db811..041d9e4ffd 100644 --- a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v2/ReadStreamExistsV2BenchmarkOperation.cs +++ b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v2/ReadStreamExistsV2BenchmarkOperation.cs @@ -58,6 +58,7 @@ public async Task ExecuteOnceAsync() { DatabseName = databsaeName, ContainerName = containerName, + OperationType = this.OperationType, RuCharges = ruCharges, LazyDiagnostics = () => itemResponse.RequestDiagnosticsString, }; diff --git a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v2/ReadTExistsV2BenchmarkOperation.cs b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v2/ReadTExistsV2BenchmarkOperation.cs index 7e161f8ffc..7058f07f66 100644 --- a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v2/ReadTExistsV2BenchmarkOperation.cs +++ b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v2/ReadTExistsV2BenchmarkOperation.cs @@ -59,6 +59,7 @@ public async Task ExecuteOnceAsync() { DatabseName = databsaeName, ContainerName = containerName, + OperationType = this.OperationType, RuCharges = ruCharges, LazyDiagnostics = () => itemResponse.RequestDiagnosticsString, }; diff --git a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v3/InsertV3BenchmarkOperation.cs b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v3/InsertV3BenchmarkOperation.cs index 504148bfda..cb3acc5d7b 100644 --- a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v3/InsertV3BenchmarkOperation.cs +++ b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v3/InsertV3BenchmarkOperation.cs @@ -55,6 +55,7 @@ public async Task ExecuteOnceAsync() { DatabseName = databaseName, ContainerName = containerName, + OperationType = this.OperationType, RuCharges = ruCharges, CosmosDiagnostics = itemResponse.Diagnostics, LazyDiagnostics = () => itemResponse.Diagnostics.ToString(), diff --git a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v3/QueryTV3BenchmarkOperation.cs b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v3/QueryTV3BenchmarkOperation.cs index f78153034b..a40a8d0834 100644 --- a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v3/QueryTV3BenchmarkOperation.cs +++ b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v3/QueryTV3BenchmarkOperation.cs @@ -108,6 +108,7 @@ private async Task ExecuteOnceAsyncDefault() { DatabseName = databaseName, ContainerName = containerName, + OperationType = this.OperationType, RuCharges = totalCharge, CosmosDiagnostics = lastDiagnostics, LazyDiagnostics = () => lastDiagnostics?.ToString(), diff --git a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v3/ReadFeedStreamV3BenchmarkOperation.cs b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v3/ReadFeedStreamV3BenchmarkOperation.cs index 3b9c5cd800..cc69305450 100644 --- a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v3/ReadFeedStreamV3BenchmarkOperation.cs +++ b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v3/ReadFeedStreamV3BenchmarkOperation.cs @@ -59,6 +59,7 @@ public async Task ExecuteOnceAsync() { DatabseName = databsaeName, ContainerName = containerName, + OperationType = this.OperationType, RuCharges = feedResponse.Headers.RequestCharge, CosmosDiagnostics = feedResponse.Diagnostics, LazyDiagnostics = () => feedResponse.Diagnostics.ToString(), diff --git a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v3/ReadNotExistsV3BenchmarkOperation.cs b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v3/ReadNotExistsV3BenchmarkOperation.cs index 1804ea9852..c3a24f8dcd 100644 --- a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v3/ReadNotExistsV3BenchmarkOperation.cs +++ b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v3/ReadNotExistsV3BenchmarkOperation.cs @@ -49,6 +49,7 @@ public async Task ExecuteOnceAsync() { DatabseName = databsaeName, ContainerName = containerName, + OperationType = this.OperationType, RuCharges = itemResponse.Headers.RequestCharge, CosmosDiagnostics = itemResponse.Diagnostics, LazyDiagnostics = () => itemResponse.Diagnostics.ToString(), diff --git a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v3/ReadStreamExistsV3BenchmarkOperation.cs b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v3/ReadStreamExistsV3BenchmarkOperation.cs index fabe8f20bd..752a773bdc 100644 --- a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v3/ReadStreamExistsV3BenchmarkOperation.cs +++ b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v3/ReadStreamExistsV3BenchmarkOperation.cs @@ -56,6 +56,7 @@ public async Task ExecuteOnceAsync() { DatabseName = databsaeName, ContainerName = containerName, + OperationType = this.OperationType, RuCharges = itemResponse.Headers.RequestCharge, CosmosDiagnostics = itemResponse.Diagnostics, LazyDiagnostics = () => itemResponse.Diagnostics.ToString(), diff --git a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v3/ReadStreamExistsWithDiagnosticsV3BenchmarkOperation.cs b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v3/ReadStreamExistsWithDiagnosticsV3BenchmarkOperation.cs index 74f2ac67f7..5963f04c3a 100644 --- a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v3/ReadStreamExistsWithDiagnosticsV3BenchmarkOperation.cs +++ b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v3/ReadStreamExistsWithDiagnosticsV3BenchmarkOperation.cs @@ -62,6 +62,7 @@ public async Task ExecuteOnceAsync() { DatabseName = databsaeName, ContainerName = containerName, + OperationType = this.OperationType, RuCharges = itemResponse.Headers.RequestCharge, CosmosDiagnostics = itemResponse.Diagnostics, LazyDiagnostics = () => itemResponse.Diagnostics.ToString(), diff --git a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v3/ReadTExistsV3BenchmarkOperation.cs b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v3/ReadTExistsV3BenchmarkOperation.cs index bb6295356e..1a1feccb82 100644 --- a/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v3/ReadTExistsV3BenchmarkOperation.cs +++ b/Microsoft.Azure.Cosmos.Samples/Tools/Benchmark/v3/ReadTExistsV3BenchmarkOperation.cs @@ -55,6 +55,7 @@ public async Task ExecuteOnceAsync() { DatabseName = databsaeName, ContainerName = containerName, + OperationType = this.OperationType, RuCharges = itemResponse.Headers.RequestCharge, CosmosDiagnostics = itemResponse.Diagnostics, LazyDiagnostics = () => itemResponse.Diagnostics.ToString(), diff --git a/Microsoft.Azure.Cosmos.Samples/Tools/CTL/CTLConfig.cs b/Microsoft.Azure.Cosmos.Samples/Tools/CTL/CTLConfig.cs index 05064003ce..6eb27c52de 100644 --- a/Microsoft.Azure.Cosmos.Samples/Tools/CTL/CTLConfig.cs +++ b/Microsoft.Azure.Cosmos.Samples/Tools/CTL/CTLConfig.cs @@ -97,11 +97,14 @@ public string DiagnosticsThresholdDuration [Option("ctl_logging_context", Required = false, HelpText = "Defines a custom context to use on metrics")] public string LogginContext { get; set; } = string.Empty; - [Option("ctl_telemetry_endpoint", Required = false, HelpText = "telemetry juno end point")] - public string TelemetryEndpoint { get; set; } + [Option("ctl_reservoir_type", Required = false, HelpText = "Defines the reservoir type. Valid values are: Uniform, SlidingWindow and ExponentialDecay. The default value is SlidingWindow.")] + public ReservoirTypes ReservoirType { get; set; } = ReservoirTypes.SlidingWindow; + + [Option("ctl_reservoir_sample_size", Required = false, HelpText = "The reservoir sample size.")] + public int ReservoirSampleSize { get; set; } = 1028; - [Option("ctl_telemetry_schedule_in_sec", Required = false, HelpText = "telemetry task schedule time in sec")] - public string TelemetryScheduleInSeconds { get; set; } + [Option("ctl_disable_client_telemetry", Required = false, HelpText = "Disable Client Telemetry Feature in SDK. Make sure you enable it from the portal also.")] + public bool DisableClientTelemetry { get; set; } = false; [Option("ctl_reservoir_type", Required = false, HelpText = "Defines the reservoir type. Valid values are: Uniform, SlidingWindow and ExponentialDecay. The default value is SlidingWindow.")] public ReservoirTypes ReservoirType { get; set; } = ReservoirTypes.SlidingWindow; @@ -133,12 +136,19 @@ internal CosmosClient CreateCosmosClient() CosmosClientOptions clientOptions = new CosmosClientOptions() { ApplicationName = CTLConfig.UserAgentSuffix, - EnableClientTelemetry = true + CosmosClientTelemetryOptions = new CosmosClientTelemetryOptions() + { + DisableSendingMetricsToService = this.DisableClientTelemetry, + } }; + Console.WriteLine("ApplicationName = " + CTLConfig.UserAgentSuffix); + Console.WriteLine("DisableSendingMetricsToService = " + this.DisableClientTelemetry); + if (this.UseGatewayMode) { clientOptions.ConnectionMode = ConnectionMode.Gateway; + Console.WriteLine("ConnectionMode = " + ConnectionMode.Gateway); } if (!string.IsNullOrWhiteSpace(this.ConsistencyLevel)) @@ -146,6 +156,7 @@ internal CosmosClient CreateCosmosClient() if (Enum.TryParse(this.ConsistencyLevel, out ConsistencyLevel consistencyLevel)) { clientOptions.ConsistencyLevel = consistencyLevel; + Console.WriteLine("ConsistencyLevel = " + consistencyLevel); } else { diff --git a/Microsoft.Azure.Cosmos.Samples/Tools/CTL/Program.cs b/Microsoft.Azure.Cosmos.Samples/Tools/CTL/Program.cs index 62f1eb913f..b42f651df1 100644 --- a/Microsoft.Azure.Cosmos.Samples/Tools/CTL/Program.cs +++ b/Microsoft.Azure.Cosmos.Samples/Tools/CTL/Program.cs @@ -29,8 +29,6 @@ public static async Task Main(string[] args) { CTLConfig config = CTLConfig.From(args); - SetEnvironmentVariables(config); - if (config.OutputEventTraces) { EnableTraceSourcesToConsole(); @@ -54,12 +52,6 @@ await scenario.InitializeAsync( logger.LogInformation("Initialization completed."); - if(client.ClientOptions.EnableClientTelemetry.GetValueOrDefault()) { - logger.LogInformation("Telemetry is enabled for CTL."); - } else { - logger.LogInformation("Telemetry is disabled for CTL."); - } - List tasks = new List { scenario.RunAsync( @@ -148,12 +140,6 @@ await scenario.InitializeAsync( } } - private static void SetEnvironmentVariables(CTLConfig config) - { - Environment.SetEnvironmentVariable(ClientTelemetryOptions.EnvPropsClientTelemetryEndpoint, config.TelemetryEndpoint); - Environment.SetEnvironmentVariable(ClientTelemetryOptions.EnvPropsClientTelemetrySchedulingInSeconds, config.TelemetryScheduleInSeconds); - } - private static IMetricsRoot ConfigureReporting( CTLConfig config, ILogger logger) diff --git a/Microsoft.Azure.Cosmos.Samples/Tools/CosmosBenchmarkTests/CosmosBenchmarkTests.csproj b/Microsoft.Azure.Cosmos.Samples/Tools/CosmosBenchmarkTests/CosmosBenchmarkTests.csproj new file mode 100644 index 0000000000..7da26827a5 --- /dev/null +++ b/Microsoft.Azure.Cosmos.Samples/Tools/CosmosBenchmarkTests/CosmosBenchmarkTests.csproj @@ -0,0 +1,23 @@ + + + + net6.0 + enable + enable + + false + true + + + + + + + + + + + + + + diff --git a/Microsoft.Azure.Cosmos.Samples/Tools/CosmosBenchmarkTests/Fx/DiagnosticDataListenerTests.cs b/Microsoft.Azure.Cosmos.Samples/Tools/CosmosBenchmarkTests/Fx/DiagnosticDataListenerTests.cs new file mode 100644 index 0000000000..9c453cf2e6 --- /dev/null +++ b/Microsoft.Azure.Cosmos.Samples/Tools/CosmosBenchmarkTests/Fx/DiagnosticDataListenerTests.cs @@ -0,0 +1,54 @@ +namespace CosmosBenchmark.Fx.Tests +{ + using CosmosBenchmark.Fx; + using Microsoft.VisualStudio.TestTools.UnitTesting; + using System.IO; + using Moq; + using Azure.Storage.Blobs; + + [TestClass] + public class DiagnosticDataListenerTests + { + private DiagnosticDataListener listener; + + [TestInitialize] + public void Setup() + { + this.listener = new DiagnosticDataListener(); + } + + [TestCleanup] + public void Cleanup() + { + string[] diagnosticFiles = Directory.GetFiles(".", "BenchmarkDiagnostics.out*"); + foreach (string file in diagnosticFiles) + { + File.Delete(file); + } + } + + + /// + /// The scenario tested here is to ensure + /// that all created files with captured diagnostic + /// data are successfully uploaded to the Blob storage + /// + [TestMethod] + public void UploadDiagnostics_WhenFilesExist_ShouldUploadFilesToBlobStorage() + { + for (int i = 0; i < 10; i++) + { + string fileName = $"BenchmarkDiagnostics.out-{i}"; + File.Create(fileName).Close(); + } + int filesCount = Directory.GetFiles(".", $"{DiagnosticDataListener.DiagnosticsFileName}*").Length; + + Mock mockContainer = new Mock(); + Mock mockClient = new Mock(); + mockContainer.Setup(mock => mock.GetBlobClient(It.IsAny())).Returns(mockClient.Object); + + this.listener.UploadDiagnostcs(mockContainer.Object, "prefix"); + mockClient.Verify(mock => mock.Upload(It.IsAny(), true, default), Times.Exactly(filesCount)); + } + } +} diff --git a/Microsoft.Azure.Cosmos.Samples/Usage/Cosmos.Samples.Usage.sln b/Microsoft.Azure.Cosmos.Samples/Usage/Cosmos.Samples.Usage.sln index 999b48d928..5e23b5c075 100644 --- a/Microsoft.Azure.Cosmos.Samples/Usage/Cosmos.Samples.Usage.sln +++ b/Microsoft.Azure.Cosmos.Samples/Usage/Cosmos.Samples.Usage.sln @@ -53,7 +53,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CFPullModelLatestVersionMod EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry", "OpenTelemetry\OpenTelemetry.csproj", "{C6EF6948-C085-4013-A21F-99303ECBA7A9}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ApplicationInsights", "ApplicationInsights\ApplicationInsights.csproj", "{55149A3C-A263-4EE5-AD2D-02FE9AC4D291}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ApplicationInsights", "ApplicationInsights\ApplicationInsights.csproj", "{55149A3C-A263-4EE5-AD2D-02FE9AC4D291}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CustomDiagnosticAndEventListener", "CustomDiagnosticAndEventListener\CustomDiagnosticAndEventListener.csproj", "{9BE3551E-31A1-4186-9D2F-DC325411A39D}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -165,6 +167,10 @@ Global {55149A3C-A263-4EE5-AD2D-02FE9AC4D291}.Debug|Any CPU.Build.0 = Debug|Any CPU {55149A3C-A263-4EE5-AD2D-02FE9AC4D291}.Release|Any CPU.ActiveCfg = Release|Any CPU {55149A3C-A263-4EE5-AD2D-02FE9AC4D291}.Release|Any CPU.Build.0 = Release|Any CPU + {9BE3551E-31A1-4186-9D2F-DC325411A39D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9BE3551E-31A1-4186-9D2F-DC325411A39D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9BE3551E-31A1-4186-9D2F-DC325411A39D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9BE3551E-31A1-4186-9D2F-DC325411A39D}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Microsoft.Azure.Cosmos.Samples/Usage/CustomDiagnosticAndEventListener/CustomDiagnosticAndEventListener.cs b/Microsoft.Azure.Cosmos.Samples/Usage/CustomDiagnosticAndEventListener/CustomDiagnosticAndEventListener.cs new file mode 100644 index 0000000000..17348d9a22 --- /dev/null +++ b/Microsoft.Azure.Cosmos.Samples/Usage/CustomDiagnosticAndEventListener/CustomDiagnosticAndEventListener.cs @@ -0,0 +1,167 @@ +namespace Sample.Listeners +{ + using System.Diagnostics.Tracing; + using System.Diagnostics; + using System.Collections.Concurrent; + + /// + /// This listener can cover following aspects: + /// 1. Write its own monitoring library with the custom implementation of aggregation or whatever you want to do with this data. + /// 2. Support an APM tool which is not open telemetry compliant. + /// + /// It is a simple sample. Anybody can get as creative as they want to make it better in terms of usability and performance. + internal class CustomDiagnosticAndEventListener : + EventListener, // Override Event Listener to capture Event source events + IObserver>, // Override IObserver to capture Activity events + IObserver, + IDisposable + { + private readonly string diagnosticSourceName; + private readonly string eventSourceName; + + private ConcurrentBag? Subscriptions = new(); + private ConcurrentBag Activities { get; } = new(); + + public CustomDiagnosticAndEventListener(string diagnosticSourceName, string eventSourceName) + { + this.diagnosticSourceName = diagnosticSourceName; + this.eventSourceName = eventSourceName; + + DiagnosticListener.AllListeners.Subscribe(this); + } + + /// + /// IObserver Override + /// + public void OnCompleted() { + Console.WriteLine("OnCompleted"); + } + + /// + /// IObserver Override + /// + public void OnError(Exception error) { + Console.WriteLine($"OnError : {error}"); + } + + /// + /// IObserver Override + /// + public void OnNext(KeyValuePair value) + { + lock (this.Activities) + { + // Check for disposal + if (this.Subscriptions == null) return; + + string startSuffix = ".Start"; + string stopSuffix = ".Stop"; + string exceptionSuffix = ".Exception"; + + if (Activity.Current == null) + { + return; + } + + if (value.Key.EndsWith(startSuffix)) + { + this.Activities.Add(Activity.Current); + } + else if (value.Key.EndsWith(stopSuffix) || value.Key.EndsWith(exceptionSuffix)) + { + foreach (Activity activity in this.Activities) + { + if (activity.Id == Activity.Current.Id) + { + Console.WriteLine($" Activity Name: {activity.DisplayName}"); + Console.WriteLine($" Activity Operation Name: {activity.OperationName}"); + foreach (KeyValuePair actualTag in activity.Tags) + { + Console.WriteLine($" {actualTag.Key} ==> {actualTag.Value}"); + } + Console.WriteLine(); + return; + } + } + } + } + } + + /// + /// IObserver Override + /// + public void OnNext(DiagnosticListener value) + { + if (value.Name == this.diagnosticSourceName && this.Subscriptions != null) + { + Console.WriteLine($"CustomDiagnosticAndEventListener : OnNext : {value.Name}"); + lock (this.Activities) + { + this.Subscriptions?.Add(value.Subscribe(this)); + } + } + } + + /// + /// EventListener Override + /// + protected override void OnEventSourceCreated(EventSource eventSource) + { + if (eventSource != null && eventSource.Name.Equals(this.eventSourceName)) + { + Console.WriteLine($"CustomDiagnosticAndEventListener : OnEventSourceCreated : {eventSource.Name}"); + this.EnableEvents(eventSource, EventLevel.Informational); // Enable information level events + } + } + + /// + /// EventListener Override + /// + protected override void OnEventWritten(EventWrittenEventArgs eventData) + { + Console.WriteLine($" Event Name: {eventData.EventName}"); + Console.WriteLine($" Event Level: {eventData.Level}"); + if(eventData.Payload != null) + { + int counter = 0; + foreach (object? payload in eventData.Payload) + { + Console.WriteLine($" Event Payload {counter++}: {payload}"); + } + } + else + { + Console.WriteLine($" Event Payload: NULL"); + } + Console.WriteLine(); + } + + public override void Dispose() + { + Console.WriteLine("CustomDiagnosticAndEventListener : Dispose"); + base.Dispose(); + + if (this.Subscriptions == null) + { + return; + } + + ConcurrentBag subscriptions; + lock (this.Activities) + { + subscriptions = this.Subscriptions; + this.Subscriptions = null; + } + + foreach (IDisposable subscription in subscriptions) + { + subscription.Dispose(); // Dispose of DiagnosticListener subscription + } + + foreach (Activity activity in this.Activities) + { + activity.Dispose(); // Dispose of Activity + } + } + } +} diff --git a/Microsoft.Azure.Cosmos.Samples/Usage/CustomDiagnosticAndEventListener/CustomDiagnosticAndEventListener.csproj b/Microsoft.Azure.Cosmos.Samples/Usage/CustomDiagnosticAndEventListener/CustomDiagnosticAndEventListener.csproj new file mode 100644 index 0000000000..eeb17eb145 --- /dev/null +++ b/Microsoft.Azure.Cosmos.Samples/Usage/CustomDiagnosticAndEventListener/CustomDiagnosticAndEventListener.csproj @@ -0,0 +1,20 @@ + + + + Exe + net6.0 + enable + enable + + + + + + + + + + PreserveNewest + + + diff --git a/Microsoft.Azure.Cosmos.Samples/Usage/CustomDiagnosticAndEventListener/Program.cs b/Microsoft.Azure.Cosmos.Samples/Usage/CustomDiagnosticAndEventListener/Program.cs new file mode 100644 index 0000000000..77580936f7 --- /dev/null +++ b/Microsoft.Azure.Cosmos.Samples/Usage/CustomDiagnosticAndEventListener/Program.cs @@ -0,0 +1,90 @@ +namespace Cosmos.Samples.ApplicationInsights +{ + using Microsoft.Azure.Cosmos; + using Microsoft.Extensions.Configuration; + using Newtonsoft.Json; + using Sample.Listeners; + + internal class Program + { + private static readonly string databaseName = "samples"; + private static readonly string containerName = "custom-listener-sample"; + + static async Task Main() + { + IConfigurationRoot configuration = new ConfigurationBuilder() + .AddJsonFile("AppSettings.json") + .Build(); + + string endpoint = configuration["EndPointUrl"]; + if (string.IsNullOrEmpty(endpoint)) + { + throw new ArgumentNullException("Please specify a valid CosmosDBEndPointUrl in the appSettings.json"); + } + + string authKey = configuration["AuthorizationKey"]; + if (string.IsNullOrEmpty(authKey) || string.Equals(authKey, "Super secret key")) + { + throw new ArgumentException("Please specify a valid CosmosDBAuthorizationKey in the appSettings.json"); + } + + using CustomDiagnosticAndEventListener listener + = new CustomDiagnosticAndEventListener( + diagnosticSourceName: "Azure.Cosmos.Operation", + eventSourceName: "Azure-Cosmos-Operation-Request-Diagnostics"); + + CosmosClientOptions options = new CosmosClientOptions() + { + IsDistributedTracingEnabled = true // Defaults to true, set to false to disable + }; + using (CosmosClient client = new CosmosClient(endpoint, authKey, options)) + { + Console.WriteLine($"Getting container reference for {containerName}."); + + ContainerProperties properties = new ContainerProperties(containerName, partitionKeyPath: "/id"); + + await client.CreateDatabaseIfNotExistsAsync(databaseName); + Container container = await client.GetDatabase(databaseName).CreateContainerIfNotExistsAsync(properties); + + await Program.RunCrudDemo(container); + } + } + + public static async Task RunCrudDemo(Container container) + { + // Any operations will automatically generate telemetry + + for (int i = 1; i <= 5; i++) + { + await container.CreateItemAsync(new Item { Id = $"{i}", Status = "new" }, new PartitionKey($"{i}")); + Console.WriteLine($"Created document with id: {i}"); + } + + for (int i = 1; i <= 5; i++) + { + await container.ReadItemAsync($"{i}", new PartitionKey($"{i}")); + Console.WriteLine($"Read document with id: {i}"); + } + + for (int i = 1; i <= 5; i++) + { + await container.ReplaceItemAsync(new Item { Id = $"{i}", Status = "updated" }, $"{i}", new PartitionKey($"{i}")); + Console.WriteLine($"Updated document with id: {i}"); + } + + for (int i = 1; i <= 5; i++) + { + await container.DeleteItemAsync($"{i}", new PartitionKey($"{i}")); + Console.WriteLine($"Deleted document with id: {i}"); + } + } + } + + internal class Item + { + [JsonProperty("id")] + public string Id { get; set; } + + public string Status { get; set; } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/contracts/API_3.35.3-preview.txt b/Microsoft.Azure.Cosmos/contracts/API_3.35.3-preview.txt new file mode 100644 index 0000000000..6c989053fd --- /dev/null +++ b/Microsoft.Azure.Cosmos/contracts/API_3.35.3-preview.txt @@ -0,0 +1,1563 @@ +namespace Microsoft.Azure.Cosmos +{ + public class AccountConsistency + { + public AccountConsistency(); + public ConsistencyLevel DefaultConsistencyLevel { get; } + public int MaxStalenessIntervalInSeconds { get; } + public int MaxStalenessPrefix { get; } + } + public class AccountProperties + { + public AccountConsistency Consistency { get; } + public string ETag { get; } + public string Id { get; } + public IEnumerable ReadableRegions { get; } + public IEnumerable WritableRegions { get; } + } + public class AccountRegion + { + public AccountRegion(); + public string Endpoint { get; } + public string Name { get; } + } + public sealed class BoundingBoxProperties + { + public BoundingBoxProperties(); + public double Xmax { get; set; } + public double Xmin { get; set; } + public double Ymax { get; set; } + public double Ymin { get; set; } + } + public abstract class ChangeFeedEstimator + { + protected ChangeFeedEstimator(); + public abstract FeedIterator GetCurrentStateIterator(ChangeFeedEstimatorRequestOptions changeFeedEstimatorRequestOptions=null); + } + public sealed class ChangeFeedEstimatorRequestOptions + { + public ChangeFeedEstimatorRequestOptions(); + public Nullable MaxItemCount { get; set; } + } + public class ChangeFeedItemChange + { + public ChangeFeedItemChange(); + public T Current { get; set; } + public ChangeFeedMetadata Metadata { get; set; } + public T Previous { get; set; } + } + public class ChangeFeedMetadata + { + public ChangeFeedMetadata(DateTime conflictResolutionTimestamp, long lsn, ChangeFeedOperationType operationType, long previousLsn); + public DateTime ConflictResolutionTimestamp { get; } + public bool IsTimeToLiveExpired { get; } + public long Lsn { get; } + public ChangeFeedOperationType OperationType { get; } + public long PreviousLsn { get; } + } + public abstract class ChangeFeedMode + { + public static ChangeFeedMode AllVersionsAndDeletes { get; } + public static ChangeFeedMode Incremental { get; } + public static ChangeFeedMode LatestVersion { get; } + } + public enum ChangeFeedOperationType + { + Create = 0, + Delete = 2, + Replace = 1, + } + public sealed class ChangeFeedPolicy + { + public ChangeFeedPolicy(); + public static TimeSpan FullFidelityNoRetention { get; } + public TimeSpan FullFidelityRetention { get; set; } + } + public abstract class ChangeFeedProcessor + { + protected ChangeFeedProcessor(); + public abstract Task StartAsync(); + public abstract Task StopAsync(); + } + public class ChangeFeedProcessorBuilder + { + public ChangeFeedProcessor Build(); + public ChangeFeedProcessorBuilder WithErrorNotification(Container.ChangeFeedMonitorErrorDelegate errorDelegate); + public ChangeFeedProcessorBuilder WithInstanceName(string instanceName); + public ChangeFeedProcessorBuilder WithLeaseAcquireNotification(Container.ChangeFeedMonitorLeaseAcquireDelegate acquireDelegate); + public ChangeFeedProcessorBuilder WithLeaseConfiguration(Nullable acquireInterval=default(Nullable), Nullable expirationInterval=default(Nullable), Nullable renewInterval=default(Nullable)); + public ChangeFeedProcessorBuilder WithLeaseContainer(Container leaseContainer); + public ChangeFeedProcessorBuilder WithLeaseReleaseNotification(Container.ChangeFeedMonitorLeaseReleaseDelegate releaseDelegate); + public ChangeFeedProcessorBuilder WithMaxItems(int maxItemCount); + public ChangeFeedProcessorBuilder WithPollInterval(TimeSpan pollInterval); + public ChangeFeedProcessorBuilder WithStartTime(DateTime startTime); + } + public abstract class ChangeFeedProcessorContext + { + protected ChangeFeedProcessorContext(); + public abstract CosmosDiagnostics Diagnostics { get; } + public abstract Headers Headers { get; } + public abstract string LeaseToken { get; } + } + public sealed class ChangeFeedProcessorState + { + public ChangeFeedProcessorState(string leaseToken, long estimatedLag, string instanceName); + public long EstimatedLag { get; } + public string InstanceName { get; } + public string LeaseToken { get; } + } + public class ChangeFeedProcessorUserException : Exception + { + public ChangeFeedProcessorUserException(Exception originalException, ChangeFeedProcessorContext context); + protected ChangeFeedProcessorUserException(SerializationInfo info, StreamingContext context); + public ChangeFeedProcessorContext ChangeFeedProcessorContext { get; } + public override void GetObjectData(SerializationInfo info, StreamingContext context); + } + public sealed class ChangeFeedRequestOptions : RequestOptions + { + public ChangeFeedRequestOptions(); + public new string IfMatchEtag { get; set; } + public new string IfNoneMatchEtag { get; set; } + public Nullable PageSizeHint { get; set; } + } + public abstract class ChangeFeedStartFrom + { + public static ChangeFeedStartFrom Beginning(); + public static ChangeFeedStartFrom Beginning(FeedRange feedRange); + public static ChangeFeedStartFrom ContinuationToken(string continuationToken); + public static ChangeFeedStartFrom Now(); + public static ChangeFeedStartFrom Now(FeedRange feedRange); + public static ChangeFeedStartFrom Time(DateTime dateTimeUtc); + public static ChangeFeedStartFrom Time(DateTime dateTimeUtc, FeedRange feedRange); + } + public sealed class ClientEncryptionIncludedPath + { + public ClientEncryptionIncludedPath(); + public string ClientEncryptionKeyId { get; set; } + public string EncryptionAlgorithm { get; set; } + public string EncryptionType { get; set; } + public string Path { get; set; } + } + public abstract class ClientEncryptionKey + { + protected ClientEncryptionKey(); + public abstract string Id { get; } + public abstract Task ReadAsync(RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceAsync(ClientEncryptionKeyProperties clientEncryptionKeyProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + } + public class ClientEncryptionKeyProperties : IEquatable + { + protected ClientEncryptionKeyProperties(); + public ClientEncryptionKeyProperties(string id, string encryptionAlgorithm, byte[] wrappedDataEncryptionKey, EncryptionKeyWrapMetadata encryptionKeyWrapMetadata); + public Nullable CreatedTime { get; } + public string EncryptionAlgorithm { get; } + public EncryptionKeyWrapMetadata EncryptionKeyWrapMetadata { get; } + public string ETag { get; } + public string Id { get; } + public Nullable LastModified { get; } + public virtual string SelfLink { get; } + public byte[] WrappedDataEncryptionKey { get; } + public bool Equals(ClientEncryptionKeyProperties other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public class ClientEncryptionKeyResponse : Response + { + protected ClientEncryptionKeyResponse(); + public override string ActivityId { get; } + public virtual ClientEncryptionKey ClientEncryptionKey { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public override double RequestCharge { get; } + public override ClientEncryptionKeyProperties Resource { get; } + public override HttpStatusCode StatusCode { get; } + public static implicit operator ClientEncryptionKey (ClientEncryptionKeyResponse response); + } + public sealed class ClientEncryptionPolicy + { + public ClientEncryptionPolicy(IEnumerable includedPaths); + public ClientEncryptionPolicy(IEnumerable includedPaths, int policyFormatVersion); + public IEnumerable IncludedPaths { get; } + public int PolicyFormatVersion { get; } + } + public sealed class CompositePath + { + public CompositePath(); + public CompositePathSortOrder Order { get; set; } + public string Path { get; set; } + } + public enum CompositePathSortOrder + { + Ascending = 0, + Descending = 1, + } + public sealed class ComputedProperty + { + public ComputedProperty(); + public string Name { get; set; } + public string Query { get; set; } + } + public class ConflictProperties + { + public ConflictProperties(); + public string Id { get; } + public OperationKind OperationKind { get; } + public string SelfLink { get; } + } + public enum ConflictResolutionMode + { + Custom = 1, + LastWriterWins = 0, + } + public class ConflictResolutionPolicy + { + public ConflictResolutionPolicy(); + public ConflictResolutionMode Mode { get; set; } + public string ResolutionPath { get; set; } + public string ResolutionProcedure { get; set; } + } + public abstract class Conflicts + { + protected Conflicts(); + public abstract Task DeleteAsync(ConflictProperties conflict, PartitionKey partitionKey, CancellationToken cancellationToken=default(CancellationToken)); + public abstract FeedIterator GetConflictQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetConflictQueryIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetConflictQueryStreamIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetConflictQueryStreamIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract T ReadConflictContent(ConflictProperties conflict); + public abstract Task> ReadCurrentAsync(ConflictProperties conflict, PartitionKey partitionKey, CancellationToken cancellationToken=default(CancellationToken)); + } + public enum ConnectionMode + { + Direct = 1, + Gateway = 0, + } + public enum ConsistencyLevel + { + BoundedStaleness = 1, + ConsistentPrefix = 4, + Eventual = 3, + Session = 2, + Strong = 0, + } + public abstract class Container + { + protected Container(); + public abstract Conflicts Conflicts { get; } + public abstract Database Database { get; } + public abstract string Id { get; } + public abstract Scripts Scripts { get; } + public abstract Task> CreateItemAsync(T item, Nullable partitionKey=default(Nullable), ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateItemStreamAsync(Stream streamPayload, PartitionKey partitionKey, ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract TransactionalBatch CreateTransactionalBatch(PartitionKey partitionKey); + public abstract Task DeleteAllItemsByPartitionKeyStreamAsync(PartitionKey partitionKey, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task DeleteContainerAsync(ContainerRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task DeleteContainerStreamAsync(ContainerRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task> DeleteItemAsync(string id, PartitionKey partitionKey, ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task DeleteItemStreamAsync(string id, PartitionKey partitionKey, ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract ChangeFeedEstimator GetChangeFeedEstimator(string processorName, Container leaseContainer); + public abstract ChangeFeedProcessorBuilder GetChangeFeedEstimatorBuilder(string processorName, Container.ChangesEstimationHandler estimationDelegate, Nullable estimationPeriod=default(Nullable)); + public abstract FeedIterator GetChangeFeedIterator(ChangeFeedStartFrom changeFeedStartFrom, ChangeFeedMode changeFeedMode, ChangeFeedRequestOptions changeFeedRequestOptions=null); + public abstract ChangeFeedProcessorBuilder GetChangeFeedProcessorBuilder(string processorName, Container.ChangeFeedStreamHandler onChangesDelegate); + public abstract ChangeFeedProcessorBuilder GetChangeFeedProcessorBuilderWithManualCheckpoint(string processorName, Container.ChangeFeedStreamHandlerWithManualCheckpoint onChangesDelegate); + public abstract ChangeFeedProcessorBuilder GetChangeFeedProcessorBuilderWithManualCheckpoint(string processorName, Container.ChangeFeedHandlerWithManualCheckpoint onChangesDelegate); + public abstract ChangeFeedProcessorBuilder GetChangeFeedProcessorBuilder(string processorName, Container.ChangeFeedHandler onChangesDelegate); + public abstract ChangeFeedProcessorBuilder GetChangeFeedProcessorBuilder(string processorName, Container.ChangesHandler onChangesDelegate); + public abstract FeedIterator GetChangeFeedStreamIterator(ChangeFeedStartFrom changeFeedStartFrom, ChangeFeedMode changeFeedMode, ChangeFeedRequestOptions changeFeedRequestOptions=null); + public abstract Task> GetFeedRangesAsync(CancellationToken cancellationToken=default(CancellationToken)); + public abstract IOrderedQueryable GetItemLinqQueryable(bool allowSynchronousQueryExecution=false, string continuationToken=null, QueryRequestOptions requestOptions=null, CosmosLinqSerializerOptions linqSerializerOptions=null); + public abstract FeedIterator GetItemQueryIterator(FeedRange feedRange, QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetItemQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetItemQueryIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetItemQueryStreamIterator(FeedRange feedRange, QueryDefinition queryDefinition, string continuationToken, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetItemQueryStreamIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetItemQueryStreamIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract Task> GetPartitionKeyRangesAsync(FeedRange feedRange, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task> PatchItemAsync(string id, PartitionKey partitionKey, IReadOnlyList patchOperations, PatchItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task PatchItemStreamAsync(string id, PartitionKey partitionKey, IReadOnlyList patchOperations, PatchItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadContainerAsync(ContainerRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadContainerStreamAsync(ContainerRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task> ReadItemAsync(string id, PartitionKey partitionKey, ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadItemStreamAsync(string id, PartitionKey partitionKey, ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task> ReadManyItemsAsync(IReadOnlyList> items, ReadManyRequestOptions readManyRequestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadManyItemsStreamAsync(IReadOnlyList> items, ReadManyRequestOptions readManyRequestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadThroughputAsync(RequestOptions requestOptions, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task> ReadThroughputAsync(CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceContainerAsync(ContainerProperties containerProperties, ContainerRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceContainerStreamAsync(ContainerProperties containerProperties, ContainerRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task> ReplaceItemAsync(T item, string id, Nullable partitionKey=default(Nullable), ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceItemStreamAsync(Stream streamPayload, string id, PartitionKey partitionKey, ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceThroughputAsync(ThroughputProperties throughputProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceThroughputAsync(int throughput, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task> UpsertItemAsync(T item, Nullable partitionKey=default(Nullable), ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task UpsertItemStreamAsync(Stream streamPayload, PartitionKey partitionKey, ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public delegate Task ChangeFeedHandlerWithManualCheckpoint(ChangeFeedProcessorContext context, IReadOnlyCollection changes, Func checkpointAsync, CancellationToken cancellationToken); + public delegate Task ChangeFeedHandler(ChangeFeedProcessorContext context, IReadOnlyCollection changes, CancellationToken cancellationToken); + public delegate Task ChangeFeedMonitorErrorDelegate(string leaseToken, Exception exception); + public delegate Task ChangeFeedMonitorLeaseAcquireDelegate(string leaseToken); + public delegate Task ChangeFeedMonitorLeaseReleaseDelegate(string leaseToken); + public delegate Task ChangeFeedStreamHandler(ChangeFeedProcessorContext context, Stream changes, CancellationToken cancellationToken); + public delegate Task ChangeFeedStreamHandlerWithManualCheckpoint(ChangeFeedProcessorContext context, Stream changes, Func checkpointAsync, CancellationToken cancellationToken); + public delegate Task ChangesEstimationHandler(long estimatedPendingChanges, CancellationToken cancellationToken); + public delegate Task ChangesHandler(IReadOnlyCollection changes, CancellationToken cancellationToken); + } + public class ContainerProperties + { + public ContainerProperties(); + public ContainerProperties(string id, IReadOnlyList partitionKeyPaths); + public ContainerProperties(string id, string partitionKeyPath); + public Nullable AnalyticalStoreTimeToLiveInSeconds { get; set; } + public ChangeFeedPolicy ChangeFeedPolicy { get; set; } + public ClientEncryptionPolicy ClientEncryptionPolicy { get; set; } + public Collection ComputedProperties { get; set; } + public ConflictResolutionPolicy ConflictResolutionPolicy { get; set; } + public Nullable DefaultTimeToLive { get; set; } + public string ETag { get; } + public GeospatialConfig GeospatialConfig { get; set; } + public string Id { get; set; } + public IndexingPolicy IndexingPolicy { get; set; } + public Nullable LastModified { get; } + public Nullable PartitionKeyDefinitionVersion { get; set; } + public string PartitionKeyPath { get; set; } + public IReadOnlyList PartitionKeyPaths { get; set; } + public string SelfLink { get; } + public string TimeToLivePropertyPath { get; set; } + public UniqueKeyPolicy UniqueKeyPolicy { get; set; } + } + public class ContainerRequestOptions : RequestOptions + { + public ContainerRequestOptions(); + public bool PopulateQuotaInfo { get; set; } + } + public class ContainerResponse : Response + { + protected ContainerResponse(); + public override string ActivityId { get; } + public virtual Container Container { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public override double RequestCharge { get; } + public override ContainerProperties Resource { get; } + public override HttpStatusCode StatusCode { get; } + public static implicit operator Container (ContainerResponse response); + } + public class CosmosClient : IDisposable + { + protected CosmosClient(); + public CosmosClient(string accountEndpoint, AzureKeyCredential authKeyOrResourceTokenCredential, CosmosClientOptions clientOptions=null); + public CosmosClient(string accountEndpoint, TokenCredential tokenCredential, CosmosClientOptions clientOptions=null); + public CosmosClient(string connectionString, CosmosClientOptions clientOptions=null); + public CosmosClient(string accountEndpoint, string authKeyOrResourceToken, CosmosClientOptions clientOptions=null); + public virtual CosmosClientOptions ClientOptions { get; } + public virtual Uri Endpoint { get; } + public virtual CosmosResponseFactory ResponseFactory { get; } + public static Task CreateAndInitializeAsync(string accountEndpoint, AzureKeyCredential authKeyOrResourceTokenCredential, IReadOnlyList> containers, CosmosClientOptions cosmosClientOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public static Task CreateAndInitializeAsync(string accountEndpoint, TokenCredential tokenCredential, IReadOnlyList> containers, CosmosClientOptions cosmosClientOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public static Task CreateAndInitializeAsync(string connectionString, IReadOnlyList> containers, CosmosClientOptions cosmosClientOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public static Task CreateAndInitializeAsync(string accountEndpoint, string authKeyOrResourceToken, IReadOnlyList> containers, CosmosClientOptions cosmosClientOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public virtual Task CreateDatabaseAsync(string id, ThroughputProperties throughputProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public virtual Task CreateDatabaseAsync(string id, Nullable throughput=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public virtual Task CreateDatabaseIfNotExistsAsync(string id, ThroughputProperties throughputProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public virtual Task CreateDatabaseIfNotExistsAsync(string id, Nullable throughput=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public virtual Task CreateDatabaseStreamAsync(DatabaseProperties databaseProperties, Nullable throughput=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public void Dispose(); + protected virtual void Dispose(bool disposing); + public virtual Container GetContainer(string databaseId, string containerId); + public virtual Database GetDatabase(string id); + public virtual FeedIterator GetDatabaseQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public virtual FeedIterator GetDatabaseQueryIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public virtual FeedIterator GetDatabaseQueryStreamIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public virtual FeedIterator GetDatabaseQueryStreamIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public virtual Task ReadAccountAsync(); + } + public class CosmosClientOptions + { + public CosmosClientOptions(); + public bool AllowBulkExecution { get; set; } + public string ApplicationName { get; set; } + public IReadOnlyList ApplicationPreferredRegions { get; set; } + public string ApplicationRegion { get; set; } + public ConnectionMode ConnectionMode { get; set; } + public Nullable ConsistencyLevel { get; set; } + public Collection CustomHandlers { get; } + public Nullable EnableContentResponseOnWrite { get; set; } + public bool EnableTcpConnectionEndpointRediscovery { get; set; } + public int GatewayModeMaxConnectionLimit { get; set; } + public Func HttpClientFactory { get; set; } + public Nullable IdleTcpConnectionTimeout { get; set; } + public bool IsDistributedTracingEnabled { get; set; } + public bool LimitToEndpoint { get; set; } + public Nullable MaxRequestsPerTcpConnection { get; set; } + public Nullable MaxRetryAttemptsOnRateLimitedRequests { get; set; } + public Nullable MaxRetryWaitTimeOnRateLimitedRequests { get; set; } + public Nullable MaxTcpConnectionsPerEndpoint { get; set; } + public Nullable OpenTcpConnectionTimeout { get; set; } + public Nullable PortReuseMode { get; set; } + public TimeSpan RequestTimeout { get; set; } + public CosmosSerializer Serializer { get; set; } + public CosmosSerializationOptions SerializerOptions { get; set; } + public Func ServerCertificateCustomValidationCallback { get; set; } + public Nullable TokenCredentialBackgroundRefreshInterval { get; set; } + public IWebProxy WebProxy { get; set; } + } + public abstract class CosmosDiagnostics + { + protected CosmosDiagnostics(); + public virtual TimeSpan GetClientElapsedTime(); + public abstract IReadOnlyList> GetContactedRegions(); + public virtual int GetFailedRequestCount(); + public virtual Nullable GetStartTimeUtc(); + public abstract override string ToString(); + } + public class CosmosException : Exception + { + public CosmosException(string message, HttpStatusCode statusCode, int subStatusCode, string activityId, double requestCharge); + public virtual string ActivityId { get; } + public virtual CosmosDiagnostics Diagnostics { get; } + public virtual Headers Headers { get; } + public override string Message { get; } + public virtual double RequestCharge { get; } + public virtual string ResponseBody { get; } + public virtual Nullable RetryAfter { get; } + public override string StackTrace { get; } + public virtual HttpStatusCode StatusCode { get; } + public virtual int SubStatusCode { get; } + public override string ToString(); + public virtual bool TryGetHeader(string headerName, out string value); + } + public sealed class CosmosLinqSerializerOptions + { + public CosmosLinqSerializerOptions(); + public CosmosPropertyNamingPolicy PropertyNamingPolicy { get; set; } + } + public class CosmosOperationCanceledException : OperationCanceledException + { + public CosmosOperationCanceledException(OperationCanceledException originalException, CosmosDiagnostics diagnostics); + protected CosmosOperationCanceledException(SerializationInfo info, StreamingContext context); + public override IDictionary Data { get; } + public CosmosDiagnostics Diagnostics { get; } + public override string HelpLink { get; set; } + public override string Message { get; } + public override string Source { get; set; } + public override string StackTrace { get; } + public override Exception GetBaseException(); + public override void GetObjectData(SerializationInfo info, StreamingContext context); + public override string ToString(); + } + public enum CosmosPropertyNamingPolicy + { + CamelCase = 1, + Default = 0, + } + public abstract class CosmosResponseFactory + { + protected CosmosResponseFactory(); + public abstract FeedResponse CreateItemFeedResponse(ResponseMessage responseMessage); + public abstract ItemResponse CreateItemResponse(ResponseMessage responseMessage); + public abstract StoredProcedureExecuteResponse CreateStoredProcedureExecuteResponse(ResponseMessage responseMessage); + } + public sealed class CosmosSerializationOptions + { + public CosmosSerializationOptions(); + public bool IgnoreNullValues { get; set; } + public bool Indented { get; set; } + public CosmosPropertyNamingPolicy PropertyNamingPolicy { get; set; } + } + public abstract class CosmosSerializer + { + protected CosmosSerializer(); + public abstract T FromStream(Stream stream); + public abstract Stream ToStream(T input); + } + public abstract class Database + { + protected Database(); + public abstract CosmosClient Client { get; } + public abstract string Id { get; } + public abstract Task CreateClientEncryptionKeyAsync(ClientEncryptionKeyProperties clientEncryptionKeyProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateContainerAsync(ContainerProperties containerProperties, ThroughputProperties throughputProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateContainerAsync(ContainerProperties containerProperties, Nullable throughput=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateContainerAsync(string id, string partitionKeyPath, Nullable throughput=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateContainerIfNotExistsAsync(ContainerProperties containerProperties, ThroughputProperties throughputProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateContainerIfNotExistsAsync(ContainerProperties containerProperties, Nullable throughput=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateContainerIfNotExistsAsync(string id, string partitionKeyPath, Nullable throughput=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateContainerStreamAsync(ContainerProperties containerProperties, ThroughputProperties throughputProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateContainerStreamAsync(ContainerProperties containerProperties, Nullable throughput=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateUserAsync(string id, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract ContainerBuilder DefineContainer(string name, string partitionKeyPath); + public abstract Task DeleteAsync(RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task DeleteStreamAsync(RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract ClientEncryptionKey GetClientEncryptionKey(string id); + public abstract FeedIterator GetClientEncryptionKeyQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract Container GetContainer(string id); + public abstract FeedIterator GetContainerQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetContainerQueryIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetContainerQueryStreamIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetContainerQueryStreamIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract User GetUser(string id); + public abstract FeedIterator GetUserQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetUserQueryIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract Task ReadAsync(RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadStreamAsync(RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadThroughputAsync(RequestOptions requestOptions, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task> ReadThroughputAsync(CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceThroughputAsync(ThroughputProperties throughputProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceThroughputAsync(int throughput, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task UpsertUserAsync(string id, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + } + public class DatabaseProperties + { + public DatabaseProperties(); + public DatabaseProperties(string id); + public string ETag { get; } + public string Id { get; set; } + public Nullable LastModified { get; } + public string SelfLink { get; } + } + public class DatabaseResponse : Response + { + protected DatabaseResponse(); + public override string ActivityId { get; } + public virtual Database Database { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public override double RequestCharge { get; } + public override DatabaseProperties Resource { get; } + public override HttpStatusCode StatusCode { get; } + public static implicit operator Database (DatabaseResponse response); + } + public enum DataType + { + LineString = 3, + MultiPolygon = 5, + Number = 0, + Point = 2, + Polygon = 4, + String = 1, + } + public class DedicatedGatewayRequestOptions + { + public DedicatedGatewayRequestOptions(); + public Nullable BypassIntegratedCache { get; set; } + public Nullable MaxIntegratedCacheStaleness { get; set; } + } + public class EncryptionKeyWrapMetadata : IEquatable + { + public EncryptionKeyWrapMetadata(EncryptionKeyWrapMetadata source); + public EncryptionKeyWrapMetadata(string type, string name, string value, string algorithm); + public string Algorithm { get; } + public string Name { get; } + public string Type { get; } + public string Value { get; } + public bool Equals(EncryptionKeyWrapMetadata other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public sealed class ExcludedPath + { + public ExcludedPath(); + public string Path { get; set; } + } + public abstract class FeedIterator : IDisposable + { + protected FeedIterator(); + public abstract bool HasMoreResults { get; } + public void Dispose(); + protected virtual void Dispose(bool disposing); + public abstract Task ReadNextAsync(CancellationToken cancellationToken=default(CancellationToken)); + } + public abstract class FeedIterator : IDisposable + { + protected FeedIterator(); + public abstract bool HasMoreResults { get; } + public void Dispose(); + protected virtual void Dispose(bool disposing); + public abstract Task> ReadNextAsync(CancellationToken cancellationToken=default(CancellationToken)); + } + public abstract class FeedRange + { + protected FeedRange(); + public static FeedRange FromJsonString(string toStringValue); + public static FeedRange FromPartitionKey(PartitionKey partitionKey); + public abstract string ToJsonString(); + } + public abstract class FeedResponse : IEnumerable, IEnumerable + { + protected FeedResponse(); + public override string ActivityId { get; } + public abstract string ContinuationToken { get; } + public abstract int Count { get; } + public override string ETag { get; } + public abstract string IndexMetrics { get; } + public override double RequestCharge { get; } + public abstract IEnumerator GetEnumerator(); + IEnumerator System.Collections.IEnumerable.GetEnumerator(); + } + public sealed class GeospatialConfig + { + public GeospatialConfig(); + public GeospatialConfig(GeospatialType geospatialType); + public GeospatialType GeospatialType { get; set; } + } + public enum GeospatialType + { + Geography = 0, + Geometry = 1, + } + public class Headers : IEnumerable + { + public Headers(); + public virtual string ActivityId { get; } + public virtual string ContentLength { get; set; } + public virtual string ContentType { get; } + public virtual string ContinuationToken { get; } + public virtual string ETag { get; } + public virtual string this[string headerName] { get; set; } + public virtual string Location { get; } + public virtual double RequestCharge { get; } + public virtual string Session { get; } + public virtual void Add(string headerName, IEnumerable values); + public virtual void Add(string headerName, string value); + public virtual string[] AllKeys(); + public virtual string Get(string headerName); + public virtual IEnumerator GetEnumerator(); + public virtual T GetHeaderValue(string headerName); + public virtual string GetValueOrDefault(string headerName); + public virtual void Remove(string headerName); + public virtual void Set(string headerName, string value); + IEnumerator System.Collections.IEnumerable.GetEnumerator(); + public virtual bool TryGetValue(string headerName, out string value); + } + public sealed class IncludedPath + { + public IncludedPath(); + public string Path { get; set; } + } + public enum IndexingDirective + { + Default = 0, + Exclude = 2, + Include = 1, + } + public enum IndexingMode + { + Consistent = 0, + Lazy = 1, + None = 2, + } + public sealed class IndexingPolicy + { + public IndexingPolicy(); + public bool Automatic { get; set; } + public Collection> CompositeIndexes { get; } + public Collection ExcludedPaths { get; } + public Collection IncludedPaths { get; } + public IndexingMode IndexingMode { get; set; } + public Collection SpatialIndexes { get; } + } + public enum IndexKind + { + Hash = 0, + Range = 1, + Spatial = 2, + } + public class ItemRequestOptions : RequestOptions + { + public ItemRequestOptions(); + public Nullable ConsistencyLevel { get; set; } + public DedicatedGatewayRequestOptions DedicatedGatewayRequestOptions { get; set; } + public Nullable EnableContentResponseOnWrite { get; set; } + public Nullable IndexingDirective { get; set; } + public IEnumerable PostTriggers { get; set; } + public IEnumerable PreTriggers { get; set; } + public string SessionToken { get; set; } + } + public class ItemResponse : Response + { + protected ItemResponse(); + public override string ActivityId { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public override double RequestCharge { get; } + public override T Resource { get; } + public override HttpStatusCode StatusCode { get; } + } + public enum OperationKind + { + Create = 1, + Delete = 3, + Invalid = 0, + Read = 4, + Replace = 2, + } + public struct PartitionKey : IEquatable + { + public static readonly PartitionKey None; + public static readonly PartitionKey Null; + public static readonly string SystemKeyName; + public static readonly string SystemKeyPath; + public PartitionKey(bool partitionKeyValue); + public PartitionKey(double partitionKeyValue); + public PartitionKey(string partitionKeyValue); + public bool Equals(PartitionKey other); + public override bool Equals(object obj); + public override int GetHashCode(); + public static bool operator ==(PartitionKey left, PartitionKey right); + public static bool operator !=(PartitionKey left, PartitionKey right); + public override string ToString(); + } + public sealed class PartitionKeyBuilder + { + public PartitionKeyBuilder(); + public PartitionKeyBuilder Add(bool val); + public PartitionKeyBuilder Add(double val); + public PartitionKeyBuilder Add(string val); + public PartitionKeyBuilder AddNoneType(); + public PartitionKeyBuilder AddNullValue(); + public PartitionKey Build(); + } + public enum PartitionKeyDefinitionVersion + { + V1 = 1, + V2 = 2, + } + public sealed class PatchItemRequestOptions : ItemRequestOptions + { + public PatchItemRequestOptions(); + public string FilterPredicate { get; set; } + } + public abstract class PatchOperation + { + protected PatchOperation(); + public virtual string From { get; set; } + public abstract PatchOperationType OperationType { get; } + public abstract string Path { get; } + public static PatchOperation Add(string path, T value); + public static PatchOperation Increment(string path, double value); + public static PatchOperation Increment(string path, long value); + public static PatchOperation Move(string from, string path); + public static PatchOperation Remove(string path); + public static PatchOperation Replace(string path, T value); + public static PatchOperation Set(string path, T value); + public virtual bool TrySerializeValueParameter(CosmosSerializer cosmosSerializer, out Stream valueParam); + } + public enum PatchOperationType + { + Add = 0, + Increment = 4, + Move = 5, + Remove = 1, + Replace = 2, + Set = 3, + } + public abstract class PatchOperation : PatchOperation + { + protected PatchOperation(); + public abstract T Value { get; } + } + public abstract class Permission + { + protected Permission(); + public abstract string Id { get; } + public abstract Task DeleteAsync(RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadAsync(Nullable tokenExpiryInSeconds=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceAsync(PermissionProperties permissionProperties, Nullable tokenExpiryInSeconds=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + } + public enum PermissionMode : byte + { + All = (byte)2, + Read = (byte)1, + } + public class PermissionProperties + { + public PermissionProperties(string id, PermissionMode permissionMode, Container container, PartitionKey resourcePartitionKey, string itemId); + public PermissionProperties(string id, PermissionMode permissionMode, Container container, Nullable resourcePartitionKey=default(Nullable)); + public string ETag { get; } + public string Id { get; } + public Nullable LastModified { get; } + public PermissionMode PermissionMode { get; } + public Nullable ResourcePartitionKey { get; set; } + public string ResourceUri { get; } + public string SelfLink { get; } + public string Token { get; } + } + public class PermissionResponse : Response + { + protected PermissionResponse(); + public override string ActivityId { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public virtual Permission Permission { get; } + public override double RequestCharge { get; } + public override PermissionProperties Resource { get; } + public override HttpStatusCode StatusCode { get; } + public static implicit operator Permission (PermissionResponse response); + } + public enum PortReuseMode + { + PrivatePortPool = 1, + ReuseUnicastPort = 0, + } + public enum PriorityLevel + { + High = 1, + Low = 2, + } + public class QueryDefinition + { + public QueryDefinition(string query); + public string QueryText { get; } + public IReadOnlyList> GetQueryParameters(); + public QueryDefinition WithParameter(string name, object value); + public QueryDefinition WithParameterStream(string name, Stream valueStream); + } + public class QueryRequestOptions : RequestOptions + { + public QueryRequestOptions(); + public Nullable ConsistencyLevel { get; set; } + public DedicatedGatewayRequestOptions DedicatedGatewayRequestOptions { get; set; } + public Nullable EnableLowPrecisionOrderBy { get; set; } + public bool EnableOptimisticDirectExecution { get; set; } + public Nullable EnableScanInQuery { get; set; } + public Nullable MaxBufferedItemCount { get; set; } + public Nullable MaxConcurrency { get; set; } + public Nullable MaxItemCount { get; set; } + public Nullable PartitionKey { get; set; } + public Nullable PopulateIndexMetrics { get; set; } + public Nullable ResponseContinuationTokenLimitInKb { get; set; } + public string SessionToken { get; set; } + } + public class ReadManyRequestOptions : RequestOptions + { + public ReadManyRequestOptions(); + public Nullable ConsistencyLevel { get; set; } + public string SessionToken { get; set; } + } + public static class Regions + { + public const string AustraliaCentral = "Australia Central"; + public const string AustraliaCentral2 = "Australia Central 2"; + public const string AustraliaEast = "Australia East"; + public const string AustraliaSoutheast = "Australia Southeast"; + public const string BrazilSouth = "Brazil South"; + public const string BrazilSoutheast = "Brazil Southeast"; + public const string CanadaCentral = "Canada Central"; + public const string CanadaEast = "Canada East"; + public const string CentralIndia = "Central India"; + public const string CentralUS = "Central US"; + public const string CentralUSEUAP = "Central US EUAP"; + public const string ChinaEast = "China East"; + public const string ChinaEast2 = "China East 2"; + public const string ChinaEast3 = "China East 3"; + public const string ChinaNorth = "China North"; + public const string ChinaNorth2 = "China North 2"; + public const string ChinaNorth3 = "China North 3"; + public const string EastAsia = "East Asia"; + public const string EastUS = "East US"; + public const string EastUS2 = "East US 2"; + public const string EastUS2EUAP = "East US 2 EUAP"; + public const string EastUSSLV = "East US SLV"; + public const string FranceCentral = "France Central"; + public const string FranceSouth = "France South"; + public const string GermanyCentral = "Germany Central"; + public const string GermanyNorth = "Germany North"; + public const string GermanyNortheast = "Germany Northeast"; + public const string GermanyWestCentral = "Germany West Central"; + public const string IsraelCentral = "Israel Central"; + public const string ItalyNorth = "Italy North"; + public const string JapanEast = "Japan East"; + public const string JapanWest = "Japan West"; + public const string JioIndiaCentral = "Jio India Central"; + public const string JioIndiaWest = "Jio India West"; + public const string KoreaCentral = "Korea Central"; + public const string KoreaSouth = "Korea South"; + public const string MalaysiaSouth = "Malaysia South"; + public const string NorthCentralUS = "North Central US"; + public const string NorthEurope = "North Europe"; + public const string NorwayEast = "Norway East"; + public const string NorwayWest = "Norway West"; + public const string PolandCentral = "Poland Central"; + public const string QatarCentral = "Qatar Central"; + public const string SouthAfricaNorth = "South Africa North"; + public const string SouthAfricaWest = "South Africa West"; + public const string SouthCentralUS = "South Central US"; + public const string SoutheastAsia = "Southeast Asia"; + public const string SouthIndia = "South India"; + public const string SwedenCentral = "Sweden Central"; + public const string SwedenSouth = "Sweden South"; + public const string SwitzerlandNorth = "Switzerland North"; + public const string SwitzerlandWest = "Switzerland West"; + public const string UAECentral = "UAE Central"; + public const string UAENorth = "UAE North"; + public const string UKSouth = "UK South"; + public const string UKWest = "UK West"; + public const string USDoDCentral = "USDoD Central"; + public const string USDoDEast = "USDoD East"; + public const string USGovArizona = "USGov Arizona"; + public const string USGovTexas = "USGov Texas"; + public const string USGovVirginia = "USGov Virginia"; + public const string USNatEast = "USNat East"; + public const string USNatWest = "USNat West"; + public const string USSecEast = "USSec East"; + public const string USSecWest = "USSec West"; + public const string WestCentralUS = "West Central US"; + public const string WestEurope = "West Europe"; + public const string WestIndia = "West India"; + public const string WestUS = "West US"; + public const string WestUS2 = "West US 2"; + public const string WestUS3 = "West US 3"; + } + public abstract class RequestHandler + { + protected RequestHandler(); + public RequestHandler InnerHandler { get; set; } + public virtual Task SendAsync(RequestMessage request, CancellationToken cancellationToken); + } + public class RequestMessage : IDisposable + { + public RequestMessage(); + public RequestMessage(HttpMethod method, Uri requestUri); + public virtual Stream Content { get; set; } + public virtual Headers Headers { get; } + public virtual HttpMethod Method { get; } + public virtual Dictionary Properties { get; } + public virtual Uri RequestUri { get; } + public void Dispose(); + protected virtual void Dispose(bool disposing); + } + public class RequestOptions + { + public RequestOptions(); + public Action AddRequestHeaders { get; set; } + public string IfMatchEtag { get; set; } + public string IfNoneMatchEtag { get; set; } + public Nullable PriorityLevel { get; set; } + public IReadOnlyDictionary Properties { get; set; } + public RequestOptions ShallowCopy(); + } + public class ResponseMessage : IDisposable + { + public ResponseMessage(); + public ResponseMessage(HttpStatusCode statusCode, RequestMessage requestMessage=null, string errorMessage=null); + public virtual Stream Content { get; set; } + public virtual string ContinuationToken { get; } + public virtual CosmosDiagnostics Diagnostics { get; set; } + public virtual string ErrorMessage { get; } + public virtual Headers Headers { get; } + public string IndexMetrics { get; } + public virtual bool IsSuccessStatusCode { get; } + public virtual RequestMessage RequestMessage { get; } + public virtual HttpStatusCode StatusCode { get; } + public void Dispose(); + protected virtual void Dispose(bool disposing); + public virtual ResponseMessage EnsureSuccessStatusCode(); + } + public abstract class Response + { + protected Response(); + public abstract string ActivityId { get; } + public abstract CosmosDiagnostics Diagnostics { get; } + public abstract string ETag { get; } + public abstract Headers Headers { get; } + public abstract double RequestCharge { get; } + public abstract T Resource { get; } + public abstract HttpStatusCode StatusCode { get; } + public static implicit operator T (Response response); + } + public sealed class SpatialPath + { + public SpatialPath(); + public BoundingBoxProperties BoundingBox { get; set; } + public string Path { get; set; } + public Collection SpatialTypes { get; } + } + public enum SpatialType + { + LineString = 1, + MultiPolygon = 3, + Point = 0, + Polygon = 2, + } + public class ThroughputProperties + { + public Nullable AutoscaleMaxThroughput { get; } + public string ETag { get; } + public Nullable LastModified { get; } + public string SelfLink { get; } + public Nullable Throughput { get; } + public static ThroughputProperties CreateAutoscaleThroughput(int autoscaleMaxThroughput); + public static ThroughputProperties CreateManualThroughput(int throughput); + } + public class ThroughputResponse : Response + { + protected ThroughputResponse(); + public override string ActivityId { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public Nullable IsReplacePending { get; } + public Nullable MinThroughput { get; } + public override double RequestCharge { get; } + public override ThroughputProperties Resource { get; } + public override HttpStatusCode StatusCode { get; } + public static implicit operator ThroughputProperties (ThroughputResponse response); + } + public abstract class TransactionalBatch + { + protected TransactionalBatch(); + public abstract TransactionalBatch CreateItemStream(Stream streamPayload, TransactionalBatchItemRequestOptions requestOptions=null); + public abstract TransactionalBatch CreateItem(T item, TransactionalBatchItemRequestOptions requestOptions=null); + public abstract TransactionalBatch DeleteItem(string id, TransactionalBatchItemRequestOptions requestOptions=null); + public abstract Task ExecuteAsync(TransactionalBatchRequestOptions requestOptions, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ExecuteAsync(CancellationToken cancellationToken=default(CancellationToken)); + public abstract TransactionalBatch PatchItem(string id, IReadOnlyList patchOperations, TransactionalBatchPatchItemRequestOptions requestOptions=null); + public abstract TransactionalBatch ReadItem(string id, TransactionalBatchItemRequestOptions requestOptions=null); + public abstract TransactionalBatch ReplaceItemStream(string id, Stream streamPayload, TransactionalBatchItemRequestOptions requestOptions=null); + public abstract TransactionalBatch ReplaceItem(string id, T item, TransactionalBatchItemRequestOptions requestOptions=null); + public abstract TransactionalBatch UpsertItemStream(Stream streamPayload, TransactionalBatchItemRequestOptions requestOptions=null); + public abstract TransactionalBatch UpsertItem(T item, TransactionalBatchItemRequestOptions requestOptions=null); + } + public class TransactionalBatchItemRequestOptions : RequestOptions + { + public TransactionalBatchItemRequestOptions(); + public Nullable EnableContentResponseOnWrite { get; set; } + public Nullable IndexingDirective { get; set; } + } + public class TransactionalBatchOperationResult + { + protected TransactionalBatchOperationResult(); + public virtual string ETag { get; } + public virtual bool IsSuccessStatusCode { get; } + public virtual Stream ResourceStream { get; } + public virtual TimeSpan RetryAfter { get; } + public virtual HttpStatusCode StatusCode { get; } + } + public class TransactionalBatchOperationResult : TransactionalBatchOperationResult + { + protected TransactionalBatchOperationResult(); + public virtual T Resource { get; set; } + } + public class TransactionalBatchPatchItemRequestOptions : TransactionalBatchItemRequestOptions + { + public TransactionalBatchPatchItemRequestOptions(); + public string FilterPredicate { get; set; } + } + public class TransactionalBatchRequestOptions : RequestOptions + { + public TransactionalBatchRequestOptions(); + public Nullable ConsistencyLevel { get; set; } + public string SessionToken { get; set; } + } + public class TransactionalBatchResponse : IDisposable, IEnumerable, IEnumerable, IReadOnlyCollection, IReadOnlyList + { + protected TransactionalBatchResponse(); + public virtual string ActivityId { get; } + public virtual int Count { get; } + public virtual CosmosDiagnostics Diagnostics { get; } + public virtual string ErrorMessage { get; } + public virtual Headers Headers { get; } + public virtual bool IsSuccessStatusCode { get; } + public virtual TransactionalBatchOperationResult this[int index] { get; } + public virtual double RequestCharge { get; } + public virtual Nullable RetryAfter { get; } + public virtual HttpStatusCode StatusCode { get; } + public void Dispose(); + protected virtual void Dispose(bool disposing); + public virtual IEnumerator GetEnumerator(); + public virtual TransactionalBatchOperationResult GetOperationResultAtIndex(int index); + IEnumerator System.Collections.IEnumerable.GetEnumerator(); + } + public class UniqueKey + { + public UniqueKey(); + public Collection Paths { get; } + } + public sealed class UniqueKeyPolicy + { + public UniqueKeyPolicy(); + public Collection UniqueKeys { get; } + } + public abstract class User + { + protected User(); + public abstract string Id { get; } + public abstract Task CreatePermissionAsync(PermissionProperties permissionProperties, Nullable tokenExpiryInSeconds=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task DeleteAsync(RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Permission GetPermission(string id); + public abstract FeedIterator GetPermissionQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetPermissionQueryIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract Task ReadAsync(RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceAsync(UserProperties userProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task UpsertPermissionAsync(PermissionProperties permissionProperties, Nullable tokenExpiryInSeconds=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + } + public class UserProperties + { + protected UserProperties(); + public UserProperties(string id); + public string ETag { get; } + public string Id { get; set; } + public Nullable LastModified { get; } + public string SelfLink { get; } + } + public class UserResponse : Response + { + protected UserResponse(); + public override string ActivityId { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public override double RequestCharge { get; } + public override UserProperties Resource { get; } + public override HttpStatusCode StatusCode { get; } + public virtual User User { get; } + public static implicit operator User (UserResponse response); + } +} +namespace Microsoft.Azure.Cosmos.Fluent +{ + public class ChangeFeedPolicyDefinition + { + public ContainerBuilder Attach(); + } + public sealed class ClientEncryptionPolicyDefinition + { + public ContainerBuilder Attach(); + public ClientEncryptionPolicyDefinition WithIncludedPath(ClientEncryptionIncludedPath path); + } + public class CompositeIndexDefinition + { + public T Attach(); + public CompositeIndexDefinition Path(string path); + public CompositeIndexDefinition Path(string path, CompositePathSortOrder sortOrder); + } + public class ComputedPropertiesDefinition + { + public T Attach(); + public ComputedPropertiesDefinition WithComputedProperty(string name, string query); + } + public class ConflictResolutionDefinition + { + public ContainerBuilder Attach(); + public ConflictResolutionDefinition WithCustomStoredProcedureResolution(string conflictResolutionProcedure); + public ConflictResolutionDefinition WithLastWriterWinsResolution(string conflictResolutionPath); + } + public class ContainerBuilder : ContainerDefinition + { + protected ContainerBuilder(); + public ContainerBuilder(Database database, string name, string partitionKeyPath); + public new ContainerProperties Build(); + public Task CreateAsync(ThroughputProperties throughputProperties, CancellationToken cancellationToken=default(CancellationToken)); + public Task CreateAsync(Nullable throughput=default(Nullable), CancellationToken cancellationToken=default(CancellationToken)); + public Task CreateIfNotExistsAsync(ThroughputProperties throughputProperties, CancellationToken cancellationToken=default(CancellationToken)); + public Task CreateIfNotExistsAsync(Nullable throughput=default(Nullable), CancellationToken cancellationToken=default(CancellationToken)); + public ChangeFeedPolicyDefinition WithChangeFeedPolicy(TimeSpan retention); + public ClientEncryptionPolicyDefinition WithClientEncryptionPolicy(); + public ClientEncryptionPolicyDefinition WithClientEncryptionPolicy(int policyFormatVersion); + public ConflictResolutionDefinition WithConflictResolution(); + public UniqueKeyDefinition WithUniqueKey(); + } + public abstract class ContainerDefinition where T : ContainerDefinition + { + public ContainerDefinition(); + public ContainerProperties Build(); + public ComputedPropertiesDefinition WithComputedProperties(); + public T WithDefaultTimeToLive(int defaultTtlInSeconds); + public T WithDefaultTimeToLive(TimeSpan defaultTtlTimeSpan); + public IndexingPolicyDefinition WithIndexingPolicy(); + public T WithPartitionKeyDefinitionVersion(PartitionKeyDefinitionVersion partitionKeyDefinitionVersion); + public T WithTimeToLivePropertyPath(string propertyPath); + } + public class CosmosClientBuilder + { + public CosmosClientBuilder(string connectionString); + public CosmosClientBuilder(string accountEndpoint, AzureKeyCredential authKeyOrResourceTokenCredential); + public CosmosClientBuilder(string accountEndpoint, TokenCredential tokenCredential); + public CosmosClientBuilder(string accountEndpoint, string authKeyOrResourceToken); + public CosmosClientBuilder AddCustomHandlers(params RequestHandler[] customHandlers); + public CosmosClient Build(); + public Task BuildAndInitializeAsync(IReadOnlyList> containers, CancellationToken cancellationToken=default(CancellationToken)); + public CosmosClientBuilder WithApplicationName(string applicationName); + public CosmosClientBuilder WithApplicationPreferredRegions(IReadOnlyList applicationPreferredRegions); + public CosmosClientBuilder WithApplicationRegion(string applicationRegion); + public CosmosClientBuilder WithBulkExecution(bool enabled); + public CosmosClientBuilder WithConnectionModeDirect(); + public CosmosClientBuilder WithConnectionModeDirect(Nullable idleTcpConnectionTimeout=default(Nullable), Nullable openTcpConnectionTimeout=default(Nullable), Nullable maxRequestsPerTcpConnection=default(Nullable), Nullable maxTcpConnectionsPerEndpoint=default(Nullable), Nullable portReuseMode=default(Nullable), Nullable enableTcpConnectionEndpointRediscovery=default(Nullable)); + public CosmosClientBuilder WithConnectionModeGateway(Nullable maxConnectionLimit=default(Nullable), IWebProxy webProxy=null); + public CosmosClientBuilder WithConsistencyLevel(ConsistencyLevel consistencyLevel); + public CosmosClientBuilder WithContentResponseOnWrite(bool contentResponseOnWrite); + public CosmosClientBuilder WithCustomSerializer(CosmosSerializer cosmosJsonSerializer); + public CosmosClientBuilder WithDistributedTracing(bool isEnabled=true); + public CosmosClientBuilder WithHttpClientFactory(Func httpClientFactory); + public CosmosClientBuilder WithLimitToEndpoint(bool limitToEndpoint); + public CosmosClientBuilder WithRequestTimeout(TimeSpan requestTimeout); + public CosmosClientBuilder WithSerializerOptions(CosmosSerializationOptions cosmosSerializerOptions); + public CosmosClientBuilder WithThrottlingRetryOptions(TimeSpan maxRetryWaitTimeOnThrottledRequests, int maxRetryAttemptsOnThrottledRequests); + } + public class IndexingPolicyDefinition + { + public IndexingPolicyDefinition(); + public T Attach(); + public IndexingPolicyDefinition WithAutomaticIndexing(bool enabled); + public CompositeIndexDefinition> WithCompositeIndex(); + public PathsDefinition> WithExcludedPaths(); + public PathsDefinition> WithIncludedPaths(); + public IndexingPolicyDefinition WithIndexingMode(IndexingMode indexingMode); + public SpatialIndexDefinition> WithSpatialIndex(); + } + public class PathsDefinition + { + public T Attach(); + public PathsDefinition Path(string path); + } + public class SpatialIndexDefinition + { + public T Attach(); + public SpatialIndexDefinition Path(string path); + public SpatialIndexDefinition Path(string path, params SpatialType[] spatialTypes); + } + public class UniqueKeyDefinition + { + public ContainerBuilder Attach(); + public UniqueKeyDefinition Path(string path); + } +} +namespace Microsoft.Azure.Cosmos.Linq +{ + public static class CosmosLinq + { + public static object InvokeUserDefinedFunction(string udfName, params object[] arguments); + } + public static class CosmosLinqExtensions + { + public static Task> AverageAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> AverageAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> AverageAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> AverageAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> AverageAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> AverageAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> AverageAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> AverageAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> AverageAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> AverageAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> CountAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static bool IsArray(this object obj); + public static bool IsBool(this object obj); + public static bool IsDefined(this object obj); + public static bool IsNull(this object obj); + public static bool IsNumber(this object obj); + public static bool IsObject(this object obj); + public static bool IsPrimitive(this object obj); + public static bool IsString(this object obj); + public static Task> MaxAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> MinAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> SumAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> SumAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> SumAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> SumAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> SumAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> SumAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> SumAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> SumAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> SumAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> SumAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static FeedIterator ToFeedIterator(this IQueryable query); + public static QueryDefinition ToQueryDefinition(this IQueryable query); + public static QueryDefinition ToQueryDefinition(this IQueryable query, IDictionary namedParameters); + public static FeedIterator ToStreamIterator(this IQueryable query); + } +} +namespace Microsoft.Azure.Cosmos.Scripts +{ + public abstract class Scripts + { + protected Scripts(); + public abstract Task CreateStoredProcedureAsync(StoredProcedureProperties storedProcedureProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateTriggerAsync(TriggerProperties triggerProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateUserDefinedFunctionAsync(UserDefinedFunctionProperties userDefinedFunctionProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task DeleteStoredProcedureAsync(string id, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task DeleteTriggerAsync(string id, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task DeleteUserDefinedFunctionAsync(string id, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task> ExecuteStoredProcedureAsync(string storedProcedureId, PartitionKey partitionKey, dynamic parameters, StoredProcedureRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ExecuteStoredProcedureStreamAsync(string storedProcedureId, PartitionKey partitionKey, dynamic parameters, StoredProcedureRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ExecuteStoredProcedureStreamAsync(string storedProcedureId, Stream streamPayload, PartitionKey partitionKey, StoredProcedureRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract FeedIterator GetStoredProcedureQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetStoredProcedureQueryIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetStoredProcedureQueryStreamIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetStoredProcedureQueryStreamIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetTriggerQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetTriggerQueryIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetTriggerQueryStreamIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetTriggerQueryStreamIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetUserDefinedFunctionQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetUserDefinedFunctionQueryIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetUserDefinedFunctionQueryStreamIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetUserDefinedFunctionQueryStreamIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract Task ReadStoredProcedureAsync(string id, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadTriggerAsync(string id, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadUserDefinedFunctionAsync(string id, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceStoredProcedureAsync(StoredProcedureProperties storedProcedureProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceTriggerAsync(TriggerProperties triggerProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceUserDefinedFunctionAsync(UserDefinedFunctionProperties userDefinedFunctionProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + } + public class StoredProcedureExecuteResponse : Response + { + protected StoredProcedureExecuteResponse(); + public override string ActivityId { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public override double RequestCharge { get; } + public override T Resource { get; } + public virtual string ScriptLog { get; } + public virtual string SessionToken { get; } + public override HttpStatusCode StatusCode { get; } + } + public class StoredProcedureProperties + { + public StoredProcedureProperties(); + public StoredProcedureProperties(string id, string body); + public string Body { get; set; } + public string ETag { get; } + public string Id { get; set; } + public Nullable LastModified { get; } + public string SelfLink { get; } + } + public class StoredProcedureRequestOptions : RequestOptions + { + public StoredProcedureRequestOptions(); + public Nullable ConsistencyLevel { get; set; } + public bool EnableScriptLogging { get; set; } + public string SessionToken { get; set; } + } + public class StoredProcedureResponse : Response + { + protected StoredProcedureResponse(); + public override string ActivityId { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public override double RequestCharge { get; } + public override StoredProcedureProperties Resource { get; } + public virtual string SessionToken { get; } + public override HttpStatusCode StatusCode { get; } + public static implicit operator StoredProcedureProperties (StoredProcedureResponse response); + } + public enum TriggerOperation : short + { + All = (short)0, + Create = (short)1, + Delete = (short)3, + Replace = (short)4, + Update = (short)2, + } + public class TriggerProperties + { + public TriggerProperties(); + public string Body { get; set; } + public string ETag { get; } + public string Id { get; set; } + public string SelfLink { get; } + public TriggerOperation TriggerOperation { get; set; } + public TriggerType TriggerType { get; set; } + } + public class TriggerResponse : Response + { + protected TriggerResponse(); + public override string ActivityId { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public override double RequestCharge { get; } + public override TriggerProperties Resource { get; } + public override HttpStatusCode StatusCode { get; } + public static implicit operator TriggerProperties (TriggerResponse response); + } + public enum TriggerType : byte + { + Post = (byte)1, + Pre = (byte)0, + } + public class UserDefinedFunctionProperties + { + public UserDefinedFunctionProperties(); + public string Body { get; set; } + public string ETag { get; } + public string Id { get; set; } + public string SelfLink { get; } + } + public class UserDefinedFunctionResponse : Response + { + protected UserDefinedFunctionResponse(); + public override string ActivityId { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public override double RequestCharge { get; } + public override UserDefinedFunctionProperties Resource { get; } + public override HttpStatusCode StatusCode { get; } + public static implicit operator UserDefinedFunctionProperties (UserDefinedFunctionResponse response); + } +} +namespace Microsoft.Azure.Cosmos.Spatial +{ + public sealed class BoundingBox : IEquatable + { + public BoundingBox(Position min, Position max); + public Position Max { get; } + public Position Min { get; } + public bool Equals(BoundingBox other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public abstract class Crs + { + protected Crs(CrsType type); + public static Crs Default { get; } + public CrsType Type { get; } + public static Crs Unspecified { get; } + public static LinkedCrs Linked(string href); + public static LinkedCrs Linked(string href, string type); + public static NamedCrs Named(string name); + } + public enum CrsType + { + Linked = 1, + Named = 0, + Unspecified = 2, + } + public abstract class Geometry + { + protected Geometry(GeometryType type, GeometryParams geometryParams); + public IDictionary AdditionalProperties { get; } + public BoundingBox BoundingBox { get; } + public Crs Crs { get; } + public GeometryType Type { get; } + public double Distance(Geometry to); + public override bool Equals(object obj); + public override int GetHashCode(); + public bool Intersects(Geometry geometry2); + public bool IsValid(); + public GeometryValidationResult IsValidDetailed(); + public bool Within(Geometry outer); + } + public class GeometryParams + { + public GeometryParams(); + public IDictionary AdditionalProperties { get; set; } + public BoundingBox BoundingBox { get; set; } + public Crs Crs { get; set; } + } + public enum GeometryShape + { + GeometryCollection = 6, + LineString = 2, + MultiLineString = 3, + MultiPoint = 1, + MultiPolygon = 5, + Point = 0, + Polygon = 4, + } + public enum GeometryType + { + GeometryCollection = 6, + LineString = 2, + MultiLineString = 3, + MultiPoint = 1, + MultiPolygon = 5, + Point = 0, + Polygon = 4, + } + public class GeometryValidationResult + { + public GeometryValidationResult(); + public bool IsValid { get; } + public string Reason { get; } + } + public sealed class LinearRing : IEquatable + { + public LinearRing(IList coordinates); + public ReadOnlyCollection Positions { get; } + public bool Equals(LinearRing other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public sealed class LineString : Geometry, IEquatable + { + public LineString(IList coordinates); + public LineString(IList coordinates, GeometryParams geometryParams); + public ReadOnlyCollection Positions { get; } + public bool Equals(LineString other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public sealed class LinkedCrs : Crs, IEquatable + { + public string Href { get; } + public string HrefType { get; } + public bool Equals(LinkedCrs other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public sealed class MultiPolygon : Geometry, IEquatable + { + public MultiPolygon(IList polygons); + public MultiPolygon(IList polygons, GeometryParams geometryParams); + public ReadOnlyCollection Polygons { get; } + public bool Equals(MultiPolygon other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public sealed class NamedCrs : Crs, IEquatable + { + public string Name { get; } + public bool Equals(NamedCrs other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public sealed class Point : Geometry, IEquatable + { + public Point(Position position); + public Point(Position position, GeometryParams geometryParams); + public Point(double longitude, double latitude); + public Position Position { get; } + public bool Equals(Point other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public sealed class Polygon : Geometry, IEquatable + { + public Polygon(IList rings); + public Polygon(IList rings, GeometryParams geometryParams); + public Polygon(IList externalRingPositions); + public ReadOnlyCollection Rings { get; } + public bool Equals(Polygon other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public sealed class PolygonCoordinates : IEquatable + { + public PolygonCoordinates(IList rings); + public ReadOnlyCollection Rings { get; } + public bool Equals(PolygonCoordinates other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public sealed class Position : IEquatable + { + public Position(IList coordinates); + public Position(double longitude, double latitude); + public Position(double longitude, double latitude, Nullable altitude); + public Nullable Altitude { get; } + public ReadOnlyCollection Coordinates { get; } + public double Latitude { get; } + public double Longitude { get; } + public bool Equals(Position other); + public override bool Equals(object obj); + public override int GetHashCode(); + } +} diff --git a/Microsoft.Azure.Cosmos/contracts/API_3.35.3.txt b/Microsoft.Azure.Cosmos/contracts/API_3.35.3.txt new file mode 100644 index 0000000000..c0dc3e280f --- /dev/null +++ b/Microsoft.Azure.Cosmos/contracts/API_3.35.3.txt @@ -0,0 +1,1502 @@ +namespace Microsoft.Azure.Cosmos +{ + public class AccountConsistency + { + public AccountConsistency(); + public ConsistencyLevel DefaultConsistencyLevel { get; } + public int MaxStalenessIntervalInSeconds { get; } + public int MaxStalenessPrefix { get; } + } + public class AccountProperties + { + public AccountConsistency Consistency { get; } + public string ETag { get; } + public string Id { get; } + public IEnumerable ReadableRegions { get; } + public IEnumerable WritableRegions { get; } + } + public class AccountRegion + { + public AccountRegion(); + public string Endpoint { get; } + public string Name { get; } + } + public sealed class BoundingBoxProperties + { + public BoundingBoxProperties(); + public double Xmax { get; set; } + public double Xmin { get; set; } + public double Ymax { get; set; } + public double Ymin { get; set; } + } + public abstract class ChangeFeedEstimator + { + protected ChangeFeedEstimator(); + public abstract FeedIterator GetCurrentStateIterator(ChangeFeedEstimatorRequestOptions changeFeedEstimatorRequestOptions=null); + } + public sealed class ChangeFeedEstimatorRequestOptions + { + public ChangeFeedEstimatorRequestOptions(); + public Nullable MaxItemCount { get; set; } + } + public abstract class ChangeFeedMode + { + public static ChangeFeedMode Incremental { get; } + public static ChangeFeedMode LatestVersion { get; } + } + public abstract class ChangeFeedProcessor + { + protected ChangeFeedProcessor(); + public abstract Task StartAsync(); + public abstract Task StopAsync(); + } + public class ChangeFeedProcessorBuilder + { + public ChangeFeedProcessor Build(); + public ChangeFeedProcessorBuilder WithErrorNotification(Container.ChangeFeedMonitorErrorDelegate errorDelegate); + public ChangeFeedProcessorBuilder WithInstanceName(string instanceName); + public ChangeFeedProcessorBuilder WithLeaseAcquireNotification(Container.ChangeFeedMonitorLeaseAcquireDelegate acquireDelegate); + public ChangeFeedProcessorBuilder WithLeaseConfiguration(Nullable acquireInterval=default(Nullable), Nullable expirationInterval=default(Nullable), Nullable renewInterval=default(Nullable)); + public ChangeFeedProcessorBuilder WithLeaseContainer(Container leaseContainer); + public ChangeFeedProcessorBuilder WithLeaseReleaseNotification(Container.ChangeFeedMonitorLeaseReleaseDelegate releaseDelegate); + public ChangeFeedProcessorBuilder WithMaxItems(int maxItemCount); + public ChangeFeedProcessorBuilder WithPollInterval(TimeSpan pollInterval); + public ChangeFeedProcessorBuilder WithStartTime(DateTime startTime); + } + public abstract class ChangeFeedProcessorContext + { + protected ChangeFeedProcessorContext(); + public abstract CosmosDiagnostics Diagnostics { get; } + public abstract Headers Headers { get; } + public abstract string LeaseToken { get; } + } + public sealed class ChangeFeedProcessorState + { + public ChangeFeedProcessorState(string leaseToken, long estimatedLag, string instanceName); + public long EstimatedLag { get; } + public string InstanceName { get; } + public string LeaseToken { get; } + } + public class ChangeFeedProcessorUserException : Exception + { + public ChangeFeedProcessorUserException(Exception originalException, ChangeFeedProcessorContext context); + protected ChangeFeedProcessorUserException(SerializationInfo info, StreamingContext context); + public ChangeFeedProcessorContext ChangeFeedProcessorContext { get; } + public override void GetObjectData(SerializationInfo info, StreamingContext context); + } + public sealed class ChangeFeedRequestOptions : RequestOptions + { + public ChangeFeedRequestOptions(); + public new string IfMatchEtag { get; set; } + public new string IfNoneMatchEtag { get; set; } + public Nullable PageSizeHint { get; set; } + } + public abstract class ChangeFeedStartFrom + { + public static ChangeFeedStartFrom Beginning(); + public static ChangeFeedStartFrom Beginning(FeedRange feedRange); + public static ChangeFeedStartFrom ContinuationToken(string continuationToken); + public static ChangeFeedStartFrom Now(); + public static ChangeFeedStartFrom Now(FeedRange feedRange); + public static ChangeFeedStartFrom Time(DateTime dateTimeUtc); + public static ChangeFeedStartFrom Time(DateTime dateTimeUtc, FeedRange feedRange); + } + public sealed class ClientEncryptionIncludedPath + { + public ClientEncryptionIncludedPath(); + public string ClientEncryptionKeyId { get; set; } + public string EncryptionAlgorithm { get; set; } + public string EncryptionType { get; set; } + public string Path { get; set; } + } + public abstract class ClientEncryptionKey + { + protected ClientEncryptionKey(); + public abstract string Id { get; } + public abstract Task ReadAsync(RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceAsync(ClientEncryptionKeyProperties clientEncryptionKeyProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + } + public class ClientEncryptionKeyProperties : IEquatable + { + protected ClientEncryptionKeyProperties(); + public ClientEncryptionKeyProperties(string id, string encryptionAlgorithm, byte[] wrappedDataEncryptionKey, EncryptionKeyWrapMetadata encryptionKeyWrapMetadata); + public Nullable CreatedTime { get; } + public string EncryptionAlgorithm { get; } + public EncryptionKeyWrapMetadata EncryptionKeyWrapMetadata { get; } + public string ETag { get; } + public string Id { get; } + public Nullable LastModified { get; } + public virtual string SelfLink { get; } + public byte[] WrappedDataEncryptionKey { get; } + public bool Equals(ClientEncryptionKeyProperties other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public class ClientEncryptionKeyResponse : Response + { + protected ClientEncryptionKeyResponse(); + public override string ActivityId { get; } + public virtual ClientEncryptionKey ClientEncryptionKey { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public override double RequestCharge { get; } + public override ClientEncryptionKeyProperties Resource { get; } + public override HttpStatusCode StatusCode { get; } + public static implicit operator ClientEncryptionKey (ClientEncryptionKeyResponse response); + } + public sealed class ClientEncryptionPolicy + { + public ClientEncryptionPolicy(IEnumerable includedPaths); + public ClientEncryptionPolicy(IEnumerable includedPaths, int policyFormatVersion); + public IEnumerable IncludedPaths { get; } + public int PolicyFormatVersion { get; } + } + public sealed class CompositePath + { + public CompositePath(); + public CompositePathSortOrder Order { get; set; } + public string Path { get; set; } + } + public enum CompositePathSortOrder + { + Ascending = 0, + Descending = 1, + } + public class ConflictProperties + { + public ConflictProperties(); + public string Id { get; } + public OperationKind OperationKind { get; } + public string SelfLink { get; } + } + public enum ConflictResolutionMode + { + Custom = 1, + LastWriterWins = 0, + } + public class ConflictResolutionPolicy + { + public ConflictResolutionPolicy(); + public ConflictResolutionMode Mode { get; set; } + public string ResolutionPath { get; set; } + public string ResolutionProcedure { get; set; } + } + public abstract class Conflicts + { + protected Conflicts(); + public abstract Task DeleteAsync(ConflictProperties conflict, PartitionKey partitionKey, CancellationToken cancellationToken=default(CancellationToken)); + public abstract FeedIterator GetConflictQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetConflictQueryIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetConflictQueryStreamIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetConflictQueryStreamIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract T ReadConflictContent(ConflictProperties conflict); + public abstract Task> ReadCurrentAsync(ConflictProperties conflict, PartitionKey partitionKey, CancellationToken cancellationToken=default(CancellationToken)); + } + public enum ConnectionMode + { + Direct = 1, + Gateway = 0, + } + public enum ConsistencyLevel + { + BoundedStaleness = 1, + ConsistentPrefix = 4, + Eventual = 3, + Session = 2, + Strong = 0, + } + public abstract class Container + { + protected Container(); + public abstract Conflicts Conflicts { get; } + public abstract Database Database { get; } + public abstract string Id { get; } + public abstract Scripts Scripts { get; } + public abstract Task> CreateItemAsync(T item, Nullable partitionKey=default(Nullable), ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateItemStreamAsync(Stream streamPayload, PartitionKey partitionKey, ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract TransactionalBatch CreateTransactionalBatch(PartitionKey partitionKey); + public abstract Task DeleteContainerAsync(ContainerRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task DeleteContainerStreamAsync(ContainerRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task> DeleteItemAsync(string id, PartitionKey partitionKey, ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task DeleteItemStreamAsync(string id, PartitionKey partitionKey, ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract ChangeFeedEstimator GetChangeFeedEstimator(string processorName, Container leaseContainer); + public abstract ChangeFeedProcessorBuilder GetChangeFeedEstimatorBuilder(string processorName, Container.ChangesEstimationHandler estimationDelegate, Nullable estimationPeriod=default(Nullable)); + public abstract FeedIterator GetChangeFeedIterator(ChangeFeedStartFrom changeFeedStartFrom, ChangeFeedMode changeFeedMode, ChangeFeedRequestOptions changeFeedRequestOptions=null); + public abstract ChangeFeedProcessorBuilder GetChangeFeedProcessorBuilder(string processorName, Container.ChangeFeedStreamHandler onChangesDelegate); + public abstract ChangeFeedProcessorBuilder GetChangeFeedProcessorBuilderWithManualCheckpoint(string processorName, Container.ChangeFeedStreamHandlerWithManualCheckpoint onChangesDelegate); + public abstract ChangeFeedProcessorBuilder GetChangeFeedProcessorBuilderWithManualCheckpoint(string processorName, Container.ChangeFeedHandlerWithManualCheckpoint onChangesDelegate); + public abstract ChangeFeedProcessorBuilder GetChangeFeedProcessorBuilder(string processorName, Container.ChangeFeedHandler onChangesDelegate); + public abstract ChangeFeedProcessorBuilder GetChangeFeedProcessorBuilder(string processorName, Container.ChangesHandler onChangesDelegate); + public abstract FeedIterator GetChangeFeedStreamIterator(ChangeFeedStartFrom changeFeedStartFrom, ChangeFeedMode changeFeedMode, ChangeFeedRequestOptions changeFeedRequestOptions=null); + public abstract Task> GetFeedRangesAsync(CancellationToken cancellationToken=default(CancellationToken)); + public abstract IOrderedQueryable GetItemLinqQueryable(bool allowSynchronousQueryExecution=false, string continuationToken=null, QueryRequestOptions requestOptions=null, CosmosLinqSerializerOptions linqSerializerOptions=null); + public abstract FeedIterator GetItemQueryIterator(FeedRange feedRange, QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetItemQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetItemQueryIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetItemQueryStreamIterator(FeedRange feedRange, QueryDefinition queryDefinition, string continuationToken, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetItemQueryStreamIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetItemQueryStreamIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract Task> PatchItemAsync(string id, PartitionKey partitionKey, IReadOnlyList patchOperations, PatchItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task PatchItemStreamAsync(string id, PartitionKey partitionKey, IReadOnlyList patchOperations, PatchItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadContainerAsync(ContainerRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadContainerStreamAsync(ContainerRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task> ReadItemAsync(string id, PartitionKey partitionKey, ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadItemStreamAsync(string id, PartitionKey partitionKey, ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task> ReadManyItemsAsync(IReadOnlyList> items, ReadManyRequestOptions readManyRequestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadManyItemsStreamAsync(IReadOnlyList> items, ReadManyRequestOptions readManyRequestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadThroughputAsync(RequestOptions requestOptions, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task> ReadThroughputAsync(CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceContainerAsync(ContainerProperties containerProperties, ContainerRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceContainerStreamAsync(ContainerProperties containerProperties, ContainerRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task> ReplaceItemAsync(T item, string id, Nullable partitionKey=default(Nullable), ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceItemStreamAsync(Stream streamPayload, string id, PartitionKey partitionKey, ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceThroughputAsync(ThroughputProperties throughputProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceThroughputAsync(int throughput, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task> UpsertItemAsync(T item, Nullable partitionKey=default(Nullable), ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task UpsertItemStreamAsync(Stream streamPayload, PartitionKey partitionKey, ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public delegate Task ChangeFeedHandlerWithManualCheckpoint(ChangeFeedProcessorContext context, IReadOnlyCollection changes, Func checkpointAsync, CancellationToken cancellationToken); + public delegate Task ChangeFeedHandler(ChangeFeedProcessorContext context, IReadOnlyCollection changes, CancellationToken cancellationToken); + public delegate Task ChangeFeedMonitorErrorDelegate(string leaseToken, Exception exception); + public delegate Task ChangeFeedMonitorLeaseAcquireDelegate(string leaseToken); + public delegate Task ChangeFeedMonitorLeaseReleaseDelegate(string leaseToken); + public delegate Task ChangeFeedStreamHandler(ChangeFeedProcessorContext context, Stream changes, CancellationToken cancellationToken); + public delegate Task ChangeFeedStreamHandlerWithManualCheckpoint(ChangeFeedProcessorContext context, Stream changes, Func checkpointAsync, CancellationToken cancellationToken); + public delegate Task ChangesEstimationHandler(long estimatedPendingChanges, CancellationToken cancellationToken); + public delegate Task ChangesHandler(IReadOnlyCollection changes, CancellationToken cancellationToken); + } + public class ContainerProperties + { + public ContainerProperties(); + public ContainerProperties(string id, IReadOnlyList partitionKeyPaths); + public ContainerProperties(string id, string partitionKeyPath); + public Nullable AnalyticalStoreTimeToLiveInSeconds { get; set; } + public ClientEncryptionPolicy ClientEncryptionPolicy { get; set; } + public ConflictResolutionPolicy ConflictResolutionPolicy { get; set; } + public Nullable DefaultTimeToLive { get; set; } + public string ETag { get; } + public GeospatialConfig GeospatialConfig { get; set; } + public string Id { get; set; } + public IndexingPolicy IndexingPolicy { get; set; } + public Nullable LastModified { get; } + public Nullable PartitionKeyDefinitionVersion { get; set; } + public string PartitionKeyPath { get; set; } + public IReadOnlyList PartitionKeyPaths { get; set; } + public string SelfLink { get; } + public string TimeToLivePropertyPath { get; set; } + public UniqueKeyPolicy UniqueKeyPolicy { get; set; } + } + public class ContainerRequestOptions : RequestOptions + { + public ContainerRequestOptions(); + public bool PopulateQuotaInfo { get; set; } + } + public class ContainerResponse : Response + { + protected ContainerResponse(); + public override string ActivityId { get; } + public virtual Container Container { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public override double RequestCharge { get; } + public override ContainerProperties Resource { get; } + public override HttpStatusCode StatusCode { get; } + public static implicit operator Container (ContainerResponse response); + } + public class CosmosClient : IDisposable + { + protected CosmosClient(); + public CosmosClient(string accountEndpoint, AzureKeyCredential authKeyOrResourceTokenCredential, CosmosClientOptions clientOptions=null); + public CosmosClient(string accountEndpoint, TokenCredential tokenCredential, CosmosClientOptions clientOptions=null); + public CosmosClient(string connectionString, CosmosClientOptions clientOptions=null); + public CosmosClient(string accountEndpoint, string authKeyOrResourceToken, CosmosClientOptions clientOptions=null); + public virtual CosmosClientOptions ClientOptions { get; } + public virtual Uri Endpoint { get; } + public virtual CosmosResponseFactory ResponseFactory { get; } + public static Task CreateAndInitializeAsync(string accountEndpoint, AzureKeyCredential authKeyOrResourceTokenCredential, IReadOnlyList> containers, CosmosClientOptions cosmosClientOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public static Task CreateAndInitializeAsync(string accountEndpoint, TokenCredential tokenCredential, IReadOnlyList> containers, CosmosClientOptions cosmosClientOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public static Task CreateAndInitializeAsync(string connectionString, IReadOnlyList> containers, CosmosClientOptions cosmosClientOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public static Task CreateAndInitializeAsync(string accountEndpoint, string authKeyOrResourceToken, IReadOnlyList> containers, CosmosClientOptions cosmosClientOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public virtual Task CreateDatabaseAsync(string id, ThroughputProperties throughputProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public virtual Task CreateDatabaseAsync(string id, Nullable throughput=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public virtual Task CreateDatabaseIfNotExistsAsync(string id, ThroughputProperties throughputProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public virtual Task CreateDatabaseIfNotExistsAsync(string id, Nullable throughput=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public virtual Task CreateDatabaseStreamAsync(DatabaseProperties databaseProperties, Nullable throughput=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public void Dispose(); + protected virtual void Dispose(bool disposing); + public virtual Container GetContainer(string databaseId, string containerId); + public virtual Database GetDatabase(string id); + public virtual FeedIterator GetDatabaseQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public virtual FeedIterator GetDatabaseQueryIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public virtual FeedIterator GetDatabaseQueryStreamIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public virtual FeedIterator GetDatabaseQueryStreamIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public virtual Task ReadAccountAsync(); + } + public class CosmosClientOptions + { + public CosmosClientOptions(); + public bool AllowBulkExecution { get; set; } + public string ApplicationName { get; set; } + public IReadOnlyList ApplicationPreferredRegions { get; set; } + public string ApplicationRegion { get; set; } + public ConnectionMode ConnectionMode { get; set; } + public Nullable ConsistencyLevel { get; set; } + public Collection CustomHandlers { get; } + public Nullable EnableContentResponseOnWrite { get; set; } + public bool EnableTcpConnectionEndpointRediscovery { get; set; } + public int GatewayModeMaxConnectionLimit { get; set; } + public Func HttpClientFactory { get; set; } + public Nullable IdleTcpConnectionTimeout { get; set; } + public bool LimitToEndpoint { get; set; } + public Nullable MaxRequestsPerTcpConnection { get; set; } + public Nullable MaxRetryAttemptsOnRateLimitedRequests { get; set; } + public Nullable MaxRetryWaitTimeOnRateLimitedRequests { get; set; } + public Nullable MaxTcpConnectionsPerEndpoint { get; set; } + public Nullable OpenTcpConnectionTimeout { get; set; } + public Nullable PortReuseMode { get; set; } + public TimeSpan RequestTimeout { get; set; } + public CosmosSerializer Serializer { get; set; } + public CosmosSerializationOptions SerializerOptions { get; set; } + public Func ServerCertificateCustomValidationCallback { get; set; } + public Nullable TokenCredentialBackgroundRefreshInterval { get; set; } + public IWebProxy WebProxy { get; set; } + } + public abstract class CosmosDiagnostics + { + protected CosmosDiagnostics(); + public virtual TimeSpan GetClientElapsedTime(); + public abstract IReadOnlyList> GetContactedRegions(); + public virtual int GetFailedRequestCount(); + public virtual Nullable GetStartTimeUtc(); + public abstract override string ToString(); + } + public class CosmosException : Exception + { + public CosmosException(string message, HttpStatusCode statusCode, int subStatusCode, string activityId, double requestCharge); + public virtual string ActivityId { get; } + public virtual CosmosDiagnostics Diagnostics { get; } + public virtual Headers Headers { get; } + public override string Message { get; } + public virtual double RequestCharge { get; } + public virtual string ResponseBody { get; } + public virtual Nullable RetryAfter { get; } + public override string StackTrace { get; } + public virtual HttpStatusCode StatusCode { get; } + public virtual int SubStatusCode { get; } + public override string ToString(); + public virtual bool TryGetHeader(string headerName, out string value); + } + public sealed class CosmosLinqSerializerOptions + { + public CosmosLinqSerializerOptions(); + public CosmosPropertyNamingPolicy PropertyNamingPolicy { get; set; } + } + public class CosmosOperationCanceledException : OperationCanceledException + { + public CosmosOperationCanceledException(OperationCanceledException originalException, CosmosDiagnostics diagnostics); + protected CosmosOperationCanceledException(SerializationInfo info, StreamingContext context); + public override IDictionary Data { get; } + public CosmosDiagnostics Diagnostics { get; } + public override string HelpLink { get; set; } + public override string Message { get; } + public override string Source { get; set; } + public override string StackTrace { get; } + public override Exception GetBaseException(); + public override void GetObjectData(SerializationInfo info, StreamingContext context); + public override string ToString(); + } + public enum CosmosPropertyNamingPolicy + { + CamelCase = 1, + Default = 0, + } + public abstract class CosmosResponseFactory + { + protected CosmosResponseFactory(); + public abstract FeedResponse CreateItemFeedResponse(ResponseMessage responseMessage); + public abstract ItemResponse CreateItemResponse(ResponseMessage responseMessage); + public abstract StoredProcedureExecuteResponse CreateStoredProcedureExecuteResponse(ResponseMessage responseMessage); + } + public sealed class CosmosSerializationOptions + { + public CosmosSerializationOptions(); + public bool IgnoreNullValues { get; set; } + public bool Indented { get; set; } + public CosmosPropertyNamingPolicy PropertyNamingPolicy { get; set; } + } + public abstract class CosmosSerializer + { + protected CosmosSerializer(); + public abstract T FromStream(Stream stream); + public abstract Stream ToStream(T input); + } + public abstract class Database + { + protected Database(); + public abstract CosmosClient Client { get; } + public abstract string Id { get; } + public abstract Task CreateClientEncryptionKeyAsync(ClientEncryptionKeyProperties clientEncryptionKeyProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateContainerAsync(ContainerProperties containerProperties, ThroughputProperties throughputProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateContainerAsync(ContainerProperties containerProperties, Nullable throughput=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateContainerAsync(string id, string partitionKeyPath, Nullable throughput=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateContainerIfNotExistsAsync(ContainerProperties containerProperties, ThroughputProperties throughputProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateContainerIfNotExistsAsync(ContainerProperties containerProperties, Nullable throughput=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateContainerIfNotExistsAsync(string id, string partitionKeyPath, Nullable throughput=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateContainerStreamAsync(ContainerProperties containerProperties, ThroughputProperties throughputProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateContainerStreamAsync(ContainerProperties containerProperties, Nullable throughput=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateUserAsync(string id, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract ContainerBuilder DefineContainer(string name, string partitionKeyPath); + public abstract Task DeleteAsync(RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task DeleteStreamAsync(RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract ClientEncryptionKey GetClientEncryptionKey(string id); + public abstract FeedIterator GetClientEncryptionKeyQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract Container GetContainer(string id); + public abstract FeedIterator GetContainerQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetContainerQueryIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetContainerQueryStreamIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetContainerQueryStreamIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract User GetUser(string id); + public abstract FeedIterator GetUserQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetUserQueryIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract Task ReadAsync(RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadStreamAsync(RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadThroughputAsync(RequestOptions requestOptions, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task> ReadThroughputAsync(CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceThroughputAsync(ThroughputProperties throughputProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceThroughputAsync(int throughput, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task UpsertUserAsync(string id, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + } + public class DatabaseProperties + { + public DatabaseProperties(); + public DatabaseProperties(string id); + public string ETag { get; } + public string Id { get; set; } + public Nullable LastModified { get; } + public string SelfLink { get; } + } + public class DatabaseResponse : Response + { + protected DatabaseResponse(); + public override string ActivityId { get; } + public virtual Database Database { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public override double RequestCharge { get; } + public override DatabaseProperties Resource { get; } + public override HttpStatusCode StatusCode { get; } + public static implicit operator Database (DatabaseResponse response); + } + public enum DataType + { + LineString = 3, + MultiPolygon = 5, + Number = 0, + Point = 2, + Polygon = 4, + String = 1, + } + public class DedicatedGatewayRequestOptions + { + public DedicatedGatewayRequestOptions(); + public Nullable MaxIntegratedCacheStaleness { get; set; } + } + public class EncryptionKeyWrapMetadata : IEquatable + { + public EncryptionKeyWrapMetadata(EncryptionKeyWrapMetadata source); + public EncryptionKeyWrapMetadata(string type, string name, string value, string algorithm); + public string Algorithm { get; } + public string Name { get; } + public string Type { get; } + public string Value { get; } + public bool Equals(EncryptionKeyWrapMetadata other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public sealed class ExcludedPath + { + public ExcludedPath(); + public string Path { get; set; } + } + public abstract class FeedIterator : IDisposable + { + protected FeedIterator(); + public abstract bool HasMoreResults { get; } + public void Dispose(); + protected virtual void Dispose(bool disposing); + public abstract Task ReadNextAsync(CancellationToken cancellationToken=default(CancellationToken)); + } + public abstract class FeedIterator : IDisposable + { + protected FeedIterator(); + public abstract bool HasMoreResults { get; } + public void Dispose(); + protected virtual void Dispose(bool disposing); + public abstract Task> ReadNextAsync(CancellationToken cancellationToken=default(CancellationToken)); + } + public abstract class FeedRange + { + protected FeedRange(); + public static FeedRange FromJsonString(string toStringValue); + public static FeedRange FromPartitionKey(PartitionKey partitionKey); + public abstract string ToJsonString(); + } + public abstract class FeedResponse : IEnumerable, IEnumerable + { + protected FeedResponse(); + public override string ActivityId { get; } + public abstract string ContinuationToken { get; } + public abstract int Count { get; } + public override string ETag { get; } + public abstract string IndexMetrics { get; } + public override double RequestCharge { get; } + public abstract IEnumerator GetEnumerator(); + IEnumerator System.Collections.IEnumerable.GetEnumerator(); + } + public sealed class GeospatialConfig + { + public GeospatialConfig(); + public GeospatialConfig(GeospatialType geospatialType); + public GeospatialType GeospatialType { get; set; } + } + public enum GeospatialType + { + Geography = 0, + Geometry = 1, + } + public class Headers : IEnumerable + { + public Headers(); + public virtual string ActivityId { get; } + public virtual string ContentLength { get; set; } + public virtual string ContentType { get; } + public virtual string ContinuationToken { get; } + public virtual string ETag { get; } + public virtual string this[string headerName] { get; set; } + public virtual string Location { get; } + public virtual double RequestCharge { get; } + public virtual string Session { get; } + public virtual void Add(string headerName, IEnumerable values); + public virtual void Add(string headerName, string value); + public virtual string[] AllKeys(); + public virtual string Get(string headerName); + public virtual IEnumerator GetEnumerator(); + public virtual T GetHeaderValue(string headerName); + public virtual string GetValueOrDefault(string headerName); + public virtual void Remove(string headerName); + public virtual void Set(string headerName, string value); + IEnumerator System.Collections.IEnumerable.GetEnumerator(); + public virtual bool TryGetValue(string headerName, out string value); + } + public sealed class IncludedPath + { + public IncludedPath(); + public string Path { get; set; } + } + public enum IndexingDirective + { + Default = 0, + Exclude = 2, + Include = 1, + } + public enum IndexingMode + { + Consistent = 0, + Lazy = 1, + None = 2, + } + public sealed class IndexingPolicy + { + public IndexingPolicy(); + public bool Automatic { get; set; } + public Collection> CompositeIndexes { get; } + public Collection ExcludedPaths { get; } + public Collection IncludedPaths { get; } + public IndexingMode IndexingMode { get; set; } + public Collection SpatialIndexes { get; } + } + public enum IndexKind + { + Hash = 0, + Range = 1, + Spatial = 2, + } + public class ItemRequestOptions : RequestOptions + { + public ItemRequestOptions(); + public Nullable ConsistencyLevel { get; set; } + public DedicatedGatewayRequestOptions DedicatedGatewayRequestOptions { get; set; } + public Nullable EnableContentResponseOnWrite { get; set; } + public Nullable IndexingDirective { get; set; } + public IEnumerable PostTriggers { get; set; } + public IEnumerable PreTriggers { get; set; } + public string SessionToken { get; set; } + } + public class ItemResponse : Response + { + protected ItemResponse(); + public override string ActivityId { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public override double RequestCharge { get; } + public override T Resource { get; } + public override HttpStatusCode StatusCode { get; } + } + public enum OperationKind + { + Create = 1, + Delete = 3, + Invalid = 0, + Read = 4, + Replace = 2, + } + public struct PartitionKey : IEquatable + { + public static readonly PartitionKey None; + public static readonly PartitionKey Null; + public static readonly string SystemKeyName; + public static readonly string SystemKeyPath; + public PartitionKey(bool partitionKeyValue); + public PartitionKey(double partitionKeyValue); + public PartitionKey(string partitionKeyValue); + public bool Equals(PartitionKey other); + public override bool Equals(object obj); + public override int GetHashCode(); + public static bool operator ==(PartitionKey left, PartitionKey right); + public static bool operator !=(PartitionKey left, PartitionKey right); + public override string ToString(); + } + public sealed class PartitionKeyBuilder + { + public PartitionKeyBuilder(); + public PartitionKeyBuilder Add(bool val); + public PartitionKeyBuilder Add(double val); + public PartitionKeyBuilder Add(string val); + public PartitionKeyBuilder AddNoneType(); + public PartitionKeyBuilder AddNullValue(); + public PartitionKey Build(); + } + public enum PartitionKeyDefinitionVersion + { + V1 = 1, + V2 = 2, + } + public sealed class PatchItemRequestOptions : ItemRequestOptions + { + public PatchItemRequestOptions(); + public string FilterPredicate { get; set; } + } + public abstract class PatchOperation + { + protected PatchOperation(); + public virtual string From { get; set; } + public abstract PatchOperationType OperationType { get; } + public abstract string Path { get; } + public static PatchOperation Add(string path, T value); + public static PatchOperation Increment(string path, double value); + public static PatchOperation Increment(string path, long value); + public static PatchOperation Move(string from, string path); + public static PatchOperation Remove(string path); + public static PatchOperation Replace(string path, T value); + public static PatchOperation Set(string path, T value); + public virtual bool TrySerializeValueParameter(CosmosSerializer cosmosSerializer, out Stream valueParam); + } + public enum PatchOperationType + { + Add = 0, + Increment = 4, + Move = 5, + Remove = 1, + Replace = 2, + Set = 3, + } + public abstract class PatchOperation : PatchOperation + { + protected PatchOperation(); + public abstract T Value { get; } + } + public abstract class Permission + { + protected Permission(); + public abstract string Id { get; } + public abstract Task DeleteAsync(RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadAsync(Nullable tokenExpiryInSeconds=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceAsync(PermissionProperties permissionProperties, Nullable tokenExpiryInSeconds=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + } + public enum PermissionMode : byte + { + All = (byte)2, + Read = (byte)1, + } + public class PermissionProperties + { + public PermissionProperties(string id, PermissionMode permissionMode, Container container, PartitionKey resourcePartitionKey, string itemId); + public PermissionProperties(string id, PermissionMode permissionMode, Container container, Nullable resourcePartitionKey=default(Nullable)); + public string ETag { get; } + public string Id { get; } + public Nullable LastModified { get; } + public PermissionMode PermissionMode { get; } + public Nullable ResourcePartitionKey { get; set; } + public string ResourceUri { get; } + public string SelfLink { get; } + public string Token { get; } + } + public class PermissionResponse : Response + { + protected PermissionResponse(); + public override string ActivityId { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public virtual Permission Permission { get; } + public override double RequestCharge { get; } + public override PermissionProperties Resource { get; } + public override HttpStatusCode StatusCode { get; } + public static implicit operator Permission (PermissionResponse response); + } + public enum PortReuseMode + { + PrivatePortPool = 1, + ReuseUnicastPort = 0, + } + public class QueryDefinition + { + public QueryDefinition(string query); + public string QueryText { get; } + public IReadOnlyList> GetQueryParameters(); + public QueryDefinition WithParameter(string name, object value); + public QueryDefinition WithParameterStream(string name, Stream valueStream); + } + public class QueryRequestOptions : RequestOptions + { + public QueryRequestOptions(); + public Nullable ConsistencyLevel { get; set; } + public DedicatedGatewayRequestOptions DedicatedGatewayRequestOptions { get; set; } + public Nullable EnableLowPrecisionOrderBy { get; set; } + public Nullable EnableScanInQuery { get; set; } + public Nullable MaxBufferedItemCount { get; set; } + public Nullable MaxConcurrency { get; set; } + public Nullable MaxItemCount { get; set; } + public Nullable PartitionKey { get; set; } + public Nullable PopulateIndexMetrics { get; set; } + public Nullable ResponseContinuationTokenLimitInKb { get; set; } + public string SessionToken { get; set; } + } + public class ReadManyRequestOptions : RequestOptions + { + public ReadManyRequestOptions(); + public Nullable ConsistencyLevel { get; set; } + public string SessionToken { get; set; } + } + public static class Regions + { + public const string AustraliaCentral = "Australia Central"; + public const string AustraliaCentral2 = "Australia Central 2"; + public const string AustraliaEast = "Australia East"; + public const string AustraliaSoutheast = "Australia Southeast"; + public const string BrazilSouth = "Brazil South"; + public const string BrazilSoutheast = "Brazil Southeast"; + public const string CanadaCentral = "Canada Central"; + public const string CanadaEast = "Canada East"; + public const string CentralIndia = "Central India"; + public const string CentralUS = "Central US"; + public const string CentralUSEUAP = "Central US EUAP"; + public const string ChinaEast = "China East"; + public const string ChinaEast2 = "China East 2"; + public const string ChinaEast3 = "China East 3"; + public const string ChinaNorth = "China North"; + public const string ChinaNorth2 = "China North 2"; + public const string ChinaNorth3 = "China North 3"; + public const string EastAsia = "East Asia"; + public const string EastUS = "East US"; + public const string EastUS2 = "East US 2"; + public const string EastUS2EUAP = "East US 2 EUAP"; + public const string EastUSSLV = "East US SLV"; + public const string FranceCentral = "France Central"; + public const string FranceSouth = "France South"; + public const string GermanyCentral = "Germany Central"; + public const string GermanyNorth = "Germany North"; + public const string GermanyNortheast = "Germany Northeast"; + public const string GermanyWestCentral = "Germany West Central"; + public const string IsraelCentral = "Israel Central"; + public const string ItalyNorth = "Italy North"; + public const string JapanEast = "Japan East"; + public const string JapanWest = "Japan West"; + public const string JioIndiaCentral = "Jio India Central"; + public const string JioIndiaWest = "Jio India West"; + public const string KoreaCentral = "Korea Central"; + public const string KoreaSouth = "Korea South"; + public const string MalaysiaSouth = "Malaysia South"; + public const string NorthCentralUS = "North Central US"; + public const string NorthEurope = "North Europe"; + public const string NorwayEast = "Norway East"; + public const string NorwayWest = "Norway West"; + public const string PolandCentral = "Poland Central"; + public const string QatarCentral = "Qatar Central"; + public const string SouthAfricaNorth = "South Africa North"; + public const string SouthAfricaWest = "South Africa West"; + public const string SouthCentralUS = "South Central US"; + public const string SoutheastAsia = "Southeast Asia"; + public const string SouthIndia = "South India"; + public const string SwedenCentral = "Sweden Central"; + public const string SwedenSouth = "Sweden South"; + public const string SwitzerlandNorth = "Switzerland North"; + public const string SwitzerlandWest = "Switzerland West"; + public const string UAECentral = "UAE Central"; + public const string UAENorth = "UAE North"; + public const string UKSouth = "UK South"; + public const string UKWest = "UK West"; + public const string USDoDCentral = "USDoD Central"; + public const string USDoDEast = "USDoD East"; + public const string USGovArizona = "USGov Arizona"; + public const string USGovTexas = "USGov Texas"; + public const string USGovVirginia = "USGov Virginia"; + public const string USNatEast = "USNat East"; + public const string USNatWest = "USNat West"; + public const string USSecEast = "USSec East"; + public const string USSecWest = "USSec West"; + public const string WestCentralUS = "West Central US"; + public const string WestEurope = "West Europe"; + public const string WestIndia = "West India"; + public const string WestUS = "West US"; + public const string WestUS2 = "West US 2"; + public const string WestUS3 = "West US 3"; + } + public abstract class RequestHandler + { + protected RequestHandler(); + public RequestHandler InnerHandler { get; set; } + public virtual Task SendAsync(RequestMessage request, CancellationToken cancellationToken); + } + public class RequestMessage : IDisposable + { + public RequestMessage(); + public RequestMessage(HttpMethod method, Uri requestUri); + public virtual Stream Content { get; set; } + public virtual Headers Headers { get; } + public virtual HttpMethod Method { get; } + public virtual Dictionary Properties { get; } + public virtual Uri RequestUri { get; } + public void Dispose(); + protected virtual void Dispose(bool disposing); + } + public class RequestOptions + { + public RequestOptions(); + public Action AddRequestHeaders { get; set; } + public string IfMatchEtag { get; set; } + public string IfNoneMatchEtag { get; set; } + public IReadOnlyDictionary Properties { get; set; } + public RequestOptions ShallowCopy(); + } + public class ResponseMessage : IDisposable + { + public ResponseMessage(); + public ResponseMessage(HttpStatusCode statusCode, RequestMessage requestMessage=null, string errorMessage=null); + public virtual Stream Content { get; set; } + public virtual string ContinuationToken { get; } + public virtual CosmosDiagnostics Diagnostics { get; set; } + public virtual string ErrorMessage { get; } + public virtual Headers Headers { get; } + public string IndexMetrics { get; } + public virtual bool IsSuccessStatusCode { get; } + public virtual RequestMessage RequestMessage { get; } + public virtual HttpStatusCode StatusCode { get; } + public void Dispose(); + protected virtual void Dispose(bool disposing); + public virtual ResponseMessage EnsureSuccessStatusCode(); + } + public abstract class Response + { + protected Response(); + public abstract string ActivityId { get; } + public abstract CosmosDiagnostics Diagnostics { get; } + public abstract string ETag { get; } + public abstract Headers Headers { get; } + public abstract double RequestCharge { get; } + public abstract T Resource { get; } + public abstract HttpStatusCode StatusCode { get; } + public static implicit operator T (Response response); + } + public sealed class SpatialPath + { + public SpatialPath(); + public BoundingBoxProperties BoundingBox { get; set; } + public string Path { get; set; } + public Collection SpatialTypes { get; } + } + public enum SpatialType + { + LineString = 1, + MultiPolygon = 3, + Point = 0, + Polygon = 2, + } + public class ThroughputProperties + { + public Nullable AutoscaleMaxThroughput { get; } + public string ETag { get; } + public Nullable LastModified { get; } + public string SelfLink { get; } + public Nullable Throughput { get; } + public static ThroughputProperties CreateAutoscaleThroughput(int autoscaleMaxThroughput); + public static ThroughputProperties CreateManualThroughput(int throughput); + } + public class ThroughputResponse : Response + { + protected ThroughputResponse(); + public override string ActivityId { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public Nullable IsReplacePending { get; } + public Nullable MinThroughput { get; } + public override double RequestCharge { get; } + public override ThroughputProperties Resource { get; } + public override HttpStatusCode StatusCode { get; } + public static implicit operator ThroughputProperties (ThroughputResponse response); + } + public abstract class TransactionalBatch + { + protected TransactionalBatch(); + public abstract TransactionalBatch CreateItemStream(Stream streamPayload, TransactionalBatchItemRequestOptions requestOptions=null); + public abstract TransactionalBatch CreateItem(T item, TransactionalBatchItemRequestOptions requestOptions=null); + public abstract TransactionalBatch DeleteItem(string id, TransactionalBatchItemRequestOptions requestOptions=null); + public abstract Task ExecuteAsync(TransactionalBatchRequestOptions requestOptions, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ExecuteAsync(CancellationToken cancellationToken=default(CancellationToken)); + public abstract TransactionalBatch PatchItem(string id, IReadOnlyList patchOperations, TransactionalBatchPatchItemRequestOptions requestOptions=null); + public abstract TransactionalBatch ReadItem(string id, TransactionalBatchItemRequestOptions requestOptions=null); + public abstract TransactionalBatch ReplaceItemStream(string id, Stream streamPayload, TransactionalBatchItemRequestOptions requestOptions=null); + public abstract TransactionalBatch ReplaceItem(string id, T item, TransactionalBatchItemRequestOptions requestOptions=null); + public abstract TransactionalBatch UpsertItemStream(Stream streamPayload, TransactionalBatchItemRequestOptions requestOptions=null); + public abstract TransactionalBatch UpsertItem(T item, TransactionalBatchItemRequestOptions requestOptions=null); + } + public class TransactionalBatchItemRequestOptions : RequestOptions + { + public TransactionalBatchItemRequestOptions(); + public Nullable EnableContentResponseOnWrite { get; set; } + public Nullable IndexingDirective { get; set; } + } + public class TransactionalBatchOperationResult + { + protected TransactionalBatchOperationResult(); + public virtual string ETag { get; } + public virtual bool IsSuccessStatusCode { get; } + public virtual Stream ResourceStream { get; } + public virtual TimeSpan RetryAfter { get; } + public virtual HttpStatusCode StatusCode { get; } + } + public class TransactionalBatchOperationResult : TransactionalBatchOperationResult + { + protected TransactionalBatchOperationResult(); + public virtual T Resource { get; set; } + } + public class TransactionalBatchPatchItemRequestOptions : TransactionalBatchItemRequestOptions + { + public TransactionalBatchPatchItemRequestOptions(); + public string FilterPredicate { get; set; } + } + public class TransactionalBatchRequestOptions : RequestOptions + { + public TransactionalBatchRequestOptions(); + public Nullable ConsistencyLevel { get; set; } + public string SessionToken { get; set; } + } + public class TransactionalBatchResponse : IDisposable, IEnumerable, IEnumerable, IReadOnlyCollection, IReadOnlyList + { + protected TransactionalBatchResponse(); + public virtual string ActivityId { get; } + public virtual int Count { get; } + public virtual CosmosDiagnostics Diagnostics { get; } + public virtual string ErrorMessage { get; } + public virtual Headers Headers { get; } + public virtual bool IsSuccessStatusCode { get; } + public virtual TransactionalBatchOperationResult this[int index] { get; } + public virtual double RequestCharge { get; } + public virtual Nullable RetryAfter { get; } + public virtual HttpStatusCode StatusCode { get; } + public void Dispose(); + protected virtual void Dispose(bool disposing); + public virtual IEnumerator GetEnumerator(); + public virtual TransactionalBatchOperationResult GetOperationResultAtIndex(int index); + IEnumerator System.Collections.IEnumerable.GetEnumerator(); + } + public class UniqueKey + { + public UniqueKey(); + public Collection Paths { get; } + } + public sealed class UniqueKeyPolicy + { + public UniqueKeyPolicy(); + public Collection UniqueKeys { get; } + } + public abstract class User + { + protected User(); + public abstract string Id { get; } + public abstract Task CreatePermissionAsync(PermissionProperties permissionProperties, Nullable tokenExpiryInSeconds=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task DeleteAsync(RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Permission GetPermission(string id); + public abstract FeedIterator GetPermissionQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetPermissionQueryIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract Task ReadAsync(RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceAsync(UserProperties userProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task UpsertPermissionAsync(PermissionProperties permissionProperties, Nullable tokenExpiryInSeconds=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + } + public class UserProperties + { + protected UserProperties(); + public UserProperties(string id); + public string ETag { get; } + public string Id { get; set; } + public Nullable LastModified { get; } + public string SelfLink { get; } + } + public class UserResponse : Response + { + protected UserResponse(); + public override string ActivityId { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public override double RequestCharge { get; } + public override UserProperties Resource { get; } + public override HttpStatusCode StatusCode { get; } + public virtual User User { get; } + public static implicit operator User (UserResponse response); + } +} +namespace Microsoft.Azure.Cosmos.Fluent +{ + public sealed class ClientEncryptionPolicyDefinition + { + public ContainerBuilder Attach(); + public ClientEncryptionPolicyDefinition WithIncludedPath(ClientEncryptionIncludedPath path); + } + public class CompositeIndexDefinition + { + public T Attach(); + public CompositeIndexDefinition Path(string path); + public CompositeIndexDefinition Path(string path, CompositePathSortOrder sortOrder); + } + public class ConflictResolutionDefinition + { + public ContainerBuilder Attach(); + public ConflictResolutionDefinition WithCustomStoredProcedureResolution(string conflictResolutionProcedure); + public ConflictResolutionDefinition WithLastWriterWinsResolution(string conflictResolutionPath); + } + public class ContainerBuilder : ContainerDefinition + { + protected ContainerBuilder(); + public ContainerBuilder(Database database, string name, string partitionKeyPath); + public new ContainerProperties Build(); + public Task CreateAsync(ThroughputProperties throughputProperties, CancellationToken cancellationToken=default(CancellationToken)); + public Task CreateAsync(Nullable throughput=default(Nullable), CancellationToken cancellationToken=default(CancellationToken)); + public Task CreateIfNotExistsAsync(ThroughputProperties throughputProperties, CancellationToken cancellationToken=default(CancellationToken)); + public Task CreateIfNotExistsAsync(Nullable throughput=default(Nullable), CancellationToken cancellationToken=default(CancellationToken)); + public ClientEncryptionPolicyDefinition WithClientEncryptionPolicy(); + public ClientEncryptionPolicyDefinition WithClientEncryptionPolicy(int policyFormatVersion); + public ConflictResolutionDefinition WithConflictResolution(); + public UniqueKeyDefinition WithUniqueKey(); + } + public abstract class ContainerDefinition where T : ContainerDefinition + { + public ContainerDefinition(); + public ContainerProperties Build(); + public T WithDefaultTimeToLive(int defaultTtlInSeconds); + public T WithDefaultTimeToLive(TimeSpan defaultTtlTimeSpan); + public IndexingPolicyDefinition WithIndexingPolicy(); + public T WithPartitionKeyDefinitionVersion(PartitionKeyDefinitionVersion partitionKeyDefinitionVersion); + public T WithTimeToLivePropertyPath(string propertyPath); + } + public class CosmosClientBuilder + { + public CosmosClientBuilder(string connectionString); + public CosmosClientBuilder(string accountEndpoint, AzureKeyCredential authKeyOrResourceTokenCredential); + public CosmosClientBuilder(string accountEndpoint, TokenCredential tokenCredential); + public CosmosClientBuilder(string accountEndpoint, string authKeyOrResourceToken); + public CosmosClientBuilder AddCustomHandlers(params RequestHandler[] customHandlers); + public CosmosClient Build(); + public Task BuildAndInitializeAsync(IReadOnlyList> containers, CancellationToken cancellationToken=default(CancellationToken)); + public CosmosClientBuilder WithApplicationName(string applicationName); + public CosmosClientBuilder WithApplicationPreferredRegions(IReadOnlyList applicationPreferredRegions); + public CosmosClientBuilder WithApplicationRegion(string applicationRegion); + public CosmosClientBuilder WithBulkExecution(bool enabled); + public CosmosClientBuilder WithConnectionModeDirect(); + public CosmosClientBuilder WithConnectionModeDirect(Nullable idleTcpConnectionTimeout=default(Nullable), Nullable openTcpConnectionTimeout=default(Nullable), Nullable maxRequestsPerTcpConnection=default(Nullable), Nullable maxTcpConnectionsPerEndpoint=default(Nullable), Nullable portReuseMode=default(Nullable), Nullable enableTcpConnectionEndpointRediscovery=default(Nullable)); + public CosmosClientBuilder WithConnectionModeGateway(Nullable maxConnectionLimit=default(Nullable), IWebProxy webProxy=null); + public CosmosClientBuilder WithConsistencyLevel(ConsistencyLevel consistencyLevel); + public CosmosClientBuilder WithContentResponseOnWrite(bool contentResponseOnWrite); + public CosmosClientBuilder WithCustomSerializer(CosmosSerializer cosmosJsonSerializer); + public CosmosClientBuilder WithHttpClientFactory(Func httpClientFactory); + public CosmosClientBuilder WithLimitToEndpoint(bool limitToEndpoint); + public CosmosClientBuilder WithRequestTimeout(TimeSpan requestTimeout); + public CosmosClientBuilder WithSerializerOptions(CosmosSerializationOptions cosmosSerializerOptions); + public CosmosClientBuilder WithThrottlingRetryOptions(TimeSpan maxRetryWaitTimeOnThrottledRequests, int maxRetryAttemptsOnThrottledRequests); + } + public class IndexingPolicyDefinition + { + public IndexingPolicyDefinition(); + public T Attach(); + public IndexingPolicyDefinition WithAutomaticIndexing(bool enabled); + public CompositeIndexDefinition> WithCompositeIndex(); + public PathsDefinition> WithExcludedPaths(); + public PathsDefinition> WithIncludedPaths(); + public IndexingPolicyDefinition WithIndexingMode(IndexingMode indexingMode); + public SpatialIndexDefinition> WithSpatialIndex(); + } + public class PathsDefinition + { + public T Attach(); + public PathsDefinition Path(string path); + } + public class SpatialIndexDefinition + { + public T Attach(); + public SpatialIndexDefinition Path(string path); + public SpatialIndexDefinition Path(string path, params SpatialType[] spatialTypes); + } + public class UniqueKeyDefinition + { + public ContainerBuilder Attach(); + public UniqueKeyDefinition Path(string path); + } +} +namespace Microsoft.Azure.Cosmos.Linq +{ + public static class CosmosLinq + { + public static object InvokeUserDefinedFunction(string udfName, params object[] arguments); + } + public static class CosmosLinqExtensions + { + public static Task> AverageAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> AverageAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> AverageAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> AverageAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> AverageAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> AverageAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> AverageAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> AverageAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> AverageAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> AverageAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> CountAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static bool IsArray(this object obj); + public static bool IsBool(this object obj); + public static bool IsDefined(this object obj); + public static bool IsNull(this object obj); + public static bool IsNumber(this object obj); + public static bool IsObject(this object obj); + public static bool IsPrimitive(this object obj); + public static bool IsString(this object obj); + public static Task> MaxAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> MinAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> SumAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> SumAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> SumAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> SumAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> SumAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> SumAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> SumAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> SumAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> SumAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> SumAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static FeedIterator ToFeedIterator(this IQueryable query); + public static QueryDefinition ToQueryDefinition(this IQueryable query); + public static FeedIterator ToStreamIterator(this IQueryable query); + } +} +namespace Microsoft.Azure.Cosmos.Scripts +{ + public abstract class Scripts + { + protected Scripts(); + public abstract Task CreateStoredProcedureAsync(StoredProcedureProperties storedProcedureProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateTriggerAsync(TriggerProperties triggerProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateUserDefinedFunctionAsync(UserDefinedFunctionProperties userDefinedFunctionProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task DeleteStoredProcedureAsync(string id, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task DeleteTriggerAsync(string id, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task DeleteUserDefinedFunctionAsync(string id, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task> ExecuteStoredProcedureAsync(string storedProcedureId, PartitionKey partitionKey, dynamic parameters, StoredProcedureRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ExecuteStoredProcedureStreamAsync(string storedProcedureId, PartitionKey partitionKey, dynamic parameters, StoredProcedureRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ExecuteStoredProcedureStreamAsync(string storedProcedureId, Stream streamPayload, PartitionKey partitionKey, StoredProcedureRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract FeedIterator GetStoredProcedureQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetStoredProcedureQueryIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetStoredProcedureQueryStreamIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetStoredProcedureQueryStreamIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetTriggerQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetTriggerQueryIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetTriggerQueryStreamIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetTriggerQueryStreamIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetUserDefinedFunctionQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetUserDefinedFunctionQueryIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetUserDefinedFunctionQueryStreamIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetUserDefinedFunctionQueryStreamIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract Task ReadStoredProcedureAsync(string id, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadTriggerAsync(string id, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadUserDefinedFunctionAsync(string id, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceStoredProcedureAsync(StoredProcedureProperties storedProcedureProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceTriggerAsync(TriggerProperties triggerProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceUserDefinedFunctionAsync(UserDefinedFunctionProperties userDefinedFunctionProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + } + public class StoredProcedureExecuteResponse : Response + { + protected StoredProcedureExecuteResponse(); + public override string ActivityId { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public override double RequestCharge { get; } + public override T Resource { get; } + public virtual string ScriptLog { get; } + public virtual string SessionToken { get; } + public override HttpStatusCode StatusCode { get; } + } + public class StoredProcedureProperties + { + public StoredProcedureProperties(); + public StoredProcedureProperties(string id, string body); + public string Body { get; set; } + public string ETag { get; } + public string Id { get; set; } + public Nullable LastModified { get; } + public string SelfLink { get; } + } + public class StoredProcedureRequestOptions : RequestOptions + { + public StoredProcedureRequestOptions(); + public Nullable ConsistencyLevel { get; set; } + public bool EnableScriptLogging { get; set; } + public string SessionToken { get; set; } + } + public class StoredProcedureResponse : Response + { + protected StoredProcedureResponse(); + public override string ActivityId { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public override double RequestCharge { get; } + public override StoredProcedureProperties Resource { get; } + public virtual string SessionToken { get; } + public override HttpStatusCode StatusCode { get; } + public static implicit operator StoredProcedureProperties (StoredProcedureResponse response); + } + public enum TriggerOperation : short + { + All = (short)0, + Create = (short)1, + Delete = (short)3, + Replace = (short)4, + Update = (short)2, + } + public class TriggerProperties + { + public TriggerProperties(); + public string Body { get; set; } + public string ETag { get; } + public string Id { get; set; } + public string SelfLink { get; } + public TriggerOperation TriggerOperation { get; set; } + public TriggerType TriggerType { get; set; } + } + public class TriggerResponse : Response + { + protected TriggerResponse(); + public override string ActivityId { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public override double RequestCharge { get; } + public override TriggerProperties Resource { get; } + public override HttpStatusCode StatusCode { get; } + public static implicit operator TriggerProperties (TriggerResponse response); + } + public enum TriggerType : byte + { + Post = (byte)1, + Pre = (byte)0, + } + public class UserDefinedFunctionProperties + { + public UserDefinedFunctionProperties(); + public string Body { get; set; } + public string ETag { get; } + public string Id { get; set; } + public string SelfLink { get; } + } + public class UserDefinedFunctionResponse : Response + { + protected UserDefinedFunctionResponse(); + public override string ActivityId { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public override double RequestCharge { get; } + public override UserDefinedFunctionProperties Resource { get; } + public override HttpStatusCode StatusCode { get; } + public static implicit operator UserDefinedFunctionProperties (UserDefinedFunctionResponse response); + } +} +namespace Microsoft.Azure.Cosmos.Spatial +{ + public sealed class BoundingBox : IEquatable + { + public BoundingBox(Position min, Position max); + public Position Max { get; } + public Position Min { get; } + public bool Equals(BoundingBox other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public abstract class Crs + { + protected Crs(CrsType type); + public static Crs Default { get; } + public CrsType Type { get; } + public static Crs Unspecified { get; } + public static LinkedCrs Linked(string href); + public static LinkedCrs Linked(string href, string type); + public static NamedCrs Named(string name); + } + public enum CrsType + { + Linked = 1, + Named = 0, + Unspecified = 2, + } + public abstract class Geometry + { + protected Geometry(GeometryType type, GeometryParams geometryParams); + public IDictionary AdditionalProperties { get; } + public BoundingBox BoundingBox { get; } + public Crs Crs { get; } + public GeometryType Type { get; } + public double Distance(Geometry to); + public override bool Equals(object obj); + public override int GetHashCode(); + public bool Intersects(Geometry geometry2); + public bool IsValid(); + public GeometryValidationResult IsValidDetailed(); + public bool Within(Geometry outer); + } + public class GeometryParams + { + public GeometryParams(); + public IDictionary AdditionalProperties { get; set; } + public BoundingBox BoundingBox { get; set; } + public Crs Crs { get; set; } + } + public enum GeometryShape + { + GeometryCollection = 6, + LineString = 2, + MultiLineString = 3, + MultiPoint = 1, + MultiPolygon = 5, + Point = 0, + Polygon = 4, + } + public enum GeometryType + { + GeometryCollection = 6, + LineString = 2, + MultiLineString = 3, + MultiPoint = 1, + MultiPolygon = 5, + Point = 0, + Polygon = 4, + } + public class GeometryValidationResult + { + public GeometryValidationResult(); + public bool IsValid { get; } + public string Reason { get; } + } + public sealed class LinearRing : IEquatable + { + public LinearRing(IList coordinates); + public ReadOnlyCollection Positions { get; } + public bool Equals(LinearRing other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public sealed class LineString : Geometry, IEquatable + { + public LineString(IList coordinates); + public LineString(IList coordinates, GeometryParams geometryParams); + public ReadOnlyCollection Positions { get; } + public bool Equals(LineString other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public sealed class LinkedCrs : Crs, IEquatable + { + public string Href { get; } + public string HrefType { get; } + public bool Equals(LinkedCrs other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public sealed class MultiPolygon : Geometry, IEquatable + { + public MultiPolygon(IList polygons); + public MultiPolygon(IList polygons, GeometryParams geometryParams); + public ReadOnlyCollection Polygons { get; } + public bool Equals(MultiPolygon other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public sealed class NamedCrs : Crs, IEquatable + { + public string Name { get; } + public bool Equals(NamedCrs other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public sealed class Point : Geometry, IEquatable + { + public Point(Position position); + public Point(Position position, GeometryParams geometryParams); + public Point(double longitude, double latitude); + public Position Position { get; } + public bool Equals(Point other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public sealed class Polygon : Geometry, IEquatable + { + public Polygon(IList rings); + public Polygon(IList rings, GeometryParams geometryParams); + public Polygon(IList externalRingPositions); + public ReadOnlyCollection Rings { get; } + public bool Equals(Polygon other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public sealed class PolygonCoordinates : IEquatable + { + public PolygonCoordinates(IList rings); + public ReadOnlyCollection Rings { get; } + public bool Equals(PolygonCoordinates other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public sealed class Position : IEquatable + { + public Position(IList coordinates); + public Position(double longitude, double latitude); + public Position(double longitude, double latitude, Nullable altitude); + public Nullable Altitude { get; } + public ReadOnlyCollection Coordinates { get; } + public double Latitude { get; } + public double Longitude { get; } + public bool Equals(Position other); + public override bool Equals(object obj); + public override int GetHashCode(); + } +} diff --git a/Microsoft.Azure.Cosmos/contracts/API_3.35.4-preview.txt b/Microsoft.Azure.Cosmos/contracts/API_3.35.4-preview.txt new file mode 100644 index 0000000000..6c989053fd --- /dev/null +++ b/Microsoft.Azure.Cosmos/contracts/API_3.35.4-preview.txt @@ -0,0 +1,1563 @@ +namespace Microsoft.Azure.Cosmos +{ + public class AccountConsistency + { + public AccountConsistency(); + public ConsistencyLevel DefaultConsistencyLevel { get; } + public int MaxStalenessIntervalInSeconds { get; } + public int MaxStalenessPrefix { get; } + } + public class AccountProperties + { + public AccountConsistency Consistency { get; } + public string ETag { get; } + public string Id { get; } + public IEnumerable ReadableRegions { get; } + public IEnumerable WritableRegions { get; } + } + public class AccountRegion + { + public AccountRegion(); + public string Endpoint { get; } + public string Name { get; } + } + public sealed class BoundingBoxProperties + { + public BoundingBoxProperties(); + public double Xmax { get; set; } + public double Xmin { get; set; } + public double Ymax { get; set; } + public double Ymin { get; set; } + } + public abstract class ChangeFeedEstimator + { + protected ChangeFeedEstimator(); + public abstract FeedIterator GetCurrentStateIterator(ChangeFeedEstimatorRequestOptions changeFeedEstimatorRequestOptions=null); + } + public sealed class ChangeFeedEstimatorRequestOptions + { + public ChangeFeedEstimatorRequestOptions(); + public Nullable MaxItemCount { get; set; } + } + public class ChangeFeedItemChange + { + public ChangeFeedItemChange(); + public T Current { get; set; } + public ChangeFeedMetadata Metadata { get; set; } + public T Previous { get; set; } + } + public class ChangeFeedMetadata + { + public ChangeFeedMetadata(DateTime conflictResolutionTimestamp, long lsn, ChangeFeedOperationType operationType, long previousLsn); + public DateTime ConflictResolutionTimestamp { get; } + public bool IsTimeToLiveExpired { get; } + public long Lsn { get; } + public ChangeFeedOperationType OperationType { get; } + public long PreviousLsn { get; } + } + public abstract class ChangeFeedMode + { + public static ChangeFeedMode AllVersionsAndDeletes { get; } + public static ChangeFeedMode Incremental { get; } + public static ChangeFeedMode LatestVersion { get; } + } + public enum ChangeFeedOperationType + { + Create = 0, + Delete = 2, + Replace = 1, + } + public sealed class ChangeFeedPolicy + { + public ChangeFeedPolicy(); + public static TimeSpan FullFidelityNoRetention { get; } + public TimeSpan FullFidelityRetention { get; set; } + } + public abstract class ChangeFeedProcessor + { + protected ChangeFeedProcessor(); + public abstract Task StartAsync(); + public abstract Task StopAsync(); + } + public class ChangeFeedProcessorBuilder + { + public ChangeFeedProcessor Build(); + public ChangeFeedProcessorBuilder WithErrorNotification(Container.ChangeFeedMonitorErrorDelegate errorDelegate); + public ChangeFeedProcessorBuilder WithInstanceName(string instanceName); + public ChangeFeedProcessorBuilder WithLeaseAcquireNotification(Container.ChangeFeedMonitorLeaseAcquireDelegate acquireDelegate); + public ChangeFeedProcessorBuilder WithLeaseConfiguration(Nullable acquireInterval=default(Nullable), Nullable expirationInterval=default(Nullable), Nullable renewInterval=default(Nullable)); + public ChangeFeedProcessorBuilder WithLeaseContainer(Container leaseContainer); + public ChangeFeedProcessorBuilder WithLeaseReleaseNotification(Container.ChangeFeedMonitorLeaseReleaseDelegate releaseDelegate); + public ChangeFeedProcessorBuilder WithMaxItems(int maxItemCount); + public ChangeFeedProcessorBuilder WithPollInterval(TimeSpan pollInterval); + public ChangeFeedProcessorBuilder WithStartTime(DateTime startTime); + } + public abstract class ChangeFeedProcessorContext + { + protected ChangeFeedProcessorContext(); + public abstract CosmosDiagnostics Diagnostics { get; } + public abstract Headers Headers { get; } + public abstract string LeaseToken { get; } + } + public sealed class ChangeFeedProcessorState + { + public ChangeFeedProcessorState(string leaseToken, long estimatedLag, string instanceName); + public long EstimatedLag { get; } + public string InstanceName { get; } + public string LeaseToken { get; } + } + public class ChangeFeedProcessorUserException : Exception + { + public ChangeFeedProcessorUserException(Exception originalException, ChangeFeedProcessorContext context); + protected ChangeFeedProcessorUserException(SerializationInfo info, StreamingContext context); + public ChangeFeedProcessorContext ChangeFeedProcessorContext { get; } + public override void GetObjectData(SerializationInfo info, StreamingContext context); + } + public sealed class ChangeFeedRequestOptions : RequestOptions + { + public ChangeFeedRequestOptions(); + public new string IfMatchEtag { get; set; } + public new string IfNoneMatchEtag { get; set; } + public Nullable PageSizeHint { get; set; } + } + public abstract class ChangeFeedStartFrom + { + public static ChangeFeedStartFrom Beginning(); + public static ChangeFeedStartFrom Beginning(FeedRange feedRange); + public static ChangeFeedStartFrom ContinuationToken(string continuationToken); + public static ChangeFeedStartFrom Now(); + public static ChangeFeedStartFrom Now(FeedRange feedRange); + public static ChangeFeedStartFrom Time(DateTime dateTimeUtc); + public static ChangeFeedStartFrom Time(DateTime dateTimeUtc, FeedRange feedRange); + } + public sealed class ClientEncryptionIncludedPath + { + public ClientEncryptionIncludedPath(); + public string ClientEncryptionKeyId { get; set; } + public string EncryptionAlgorithm { get; set; } + public string EncryptionType { get; set; } + public string Path { get; set; } + } + public abstract class ClientEncryptionKey + { + protected ClientEncryptionKey(); + public abstract string Id { get; } + public abstract Task ReadAsync(RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceAsync(ClientEncryptionKeyProperties clientEncryptionKeyProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + } + public class ClientEncryptionKeyProperties : IEquatable + { + protected ClientEncryptionKeyProperties(); + public ClientEncryptionKeyProperties(string id, string encryptionAlgorithm, byte[] wrappedDataEncryptionKey, EncryptionKeyWrapMetadata encryptionKeyWrapMetadata); + public Nullable CreatedTime { get; } + public string EncryptionAlgorithm { get; } + public EncryptionKeyWrapMetadata EncryptionKeyWrapMetadata { get; } + public string ETag { get; } + public string Id { get; } + public Nullable LastModified { get; } + public virtual string SelfLink { get; } + public byte[] WrappedDataEncryptionKey { get; } + public bool Equals(ClientEncryptionKeyProperties other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public class ClientEncryptionKeyResponse : Response + { + protected ClientEncryptionKeyResponse(); + public override string ActivityId { get; } + public virtual ClientEncryptionKey ClientEncryptionKey { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public override double RequestCharge { get; } + public override ClientEncryptionKeyProperties Resource { get; } + public override HttpStatusCode StatusCode { get; } + public static implicit operator ClientEncryptionKey (ClientEncryptionKeyResponse response); + } + public sealed class ClientEncryptionPolicy + { + public ClientEncryptionPolicy(IEnumerable includedPaths); + public ClientEncryptionPolicy(IEnumerable includedPaths, int policyFormatVersion); + public IEnumerable IncludedPaths { get; } + public int PolicyFormatVersion { get; } + } + public sealed class CompositePath + { + public CompositePath(); + public CompositePathSortOrder Order { get; set; } + public string Path { get; set; } + } + public enum CompositePathSortOrder + { + Ascending = 0, + Descending = 1, + } + public sealed class ComputedProperty + { + public ComputedProperty(); + public string Name { get; set; } + public string Query { get; set; } + } + public class ConflictProperties + { + public ConflictProperties(); + public string Id { get; } + public OperationKind OperationKind { get; } + public string SelfLink { get; } + } + public enum ConflictResolutionMode + { + Custom = 1, + LastWriterWins = 0, + } + public class ConflictResolutionPolicy + { + public ConflictResolutionPolicy(); + public ConflictResolutionMode Mode { get; set; } + public string ResolutionPath { get; set; } + public string ResolutionProcedure { get; set; } + } + public abstract class Conflicts + { + protected Conflicts(); + public abstract Task DeleteAsync(ConflictProperties conflict, PartitionKey partitionKey, CancellationToken cancellationToken=default(CancellationToken)); + public abstract FeedIterator GetConflictQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetConflictQueryIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetConflictQueryStreamIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetConflictQueryStreamIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract T ReadConflictContent(ConflictProperties conflict); + public abstract Task> ReadCurrentAsync(ConflictProperties conflict, PartitionKey partitionKey, CancellationToken cancellationToken=default(CancellationToken)); + } + public enum ConnectionMode + { + Direct = 1, + Gateway = 0, + } + public enum ConsistencyLevel + { + BoundedStaleness = 1, + ConsistentPrefix = 4, + Eventual = 3, + Session = 2, + Strong = 0, + } + public abstract class Container + { + protected Container(); + public abstract Conflicts Conflicts { get; } + public abstract Database Database { get; } + public abstract string Id { get; } + public abstract Scripts Scripts { get; } + public abstract Task> CreateItemAsync(T item, Nullable partitionKey=default(Nullable), ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateItemStreamAsync(Stream streamPayload, PartitionKey partitionKey, ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract TransactionalBatch CreateTransactionalBatch(PartitionKey partitionKey); + public abstract Task DeleteAllItemsByPartitionKeyStreamAsync(PartitionKey partitionKey, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task DeleteContainerAsync(ContainerRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task DeleteContainerStreamAsync(ContainerRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task> DeleteItemAsync(string id, PartitionKey partitionKey, ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task DeleteItemStreamAsync(string id, PartitionKey partitionKey, ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract ChangeFeedEstimator GetChangeFeedEstimator(string processorName, Container leaseContainer); + public abstract ChangeFeedProcessorBuilder GetChangeFeedEstimatorBuilder(string processorName, Container.ChangesEstimationHandler estimationDelegate, Nullable estimationPeriod=default(Nullable)); + public abstract FeedIterator GetChangeFeedIterator(ChangeFeedStartFrom changeFeedStartFrom, ChangeFeedMode changeFeedMode, ChangeFeedRequestOptions changeFeedRequestOptions=null); + public abstract ChangeFeedProcessorBuilder GetChangeFeedProcessorBuilder(string processorName, Container.ChangeFeedStreamHandler onChangesDelegate); + public abstract ChangeFeedProcessorBuilder GetChangeFeedProcessorBuilderWithManualCheckpoint(string processorName, Container.ChangeFeedStreamHandlerWithManualCheckpoint onChangesDelegate); + public abstract ChangeFeedProcessorBuilder GetChangeFeedProcessorBuilderWithManualCheckpoint(string processorName, Container.ChangeFeedHandlerWithManualCheckpoint onChangesDelegate); + public abstract ChangeFeedProcessorBuilder GetChangeFeedProcessorBuilder(string processorName, Container.ChangeFeedHandler onChangesDelegate); + public abstract ChangeFeedProcessorBuilder GetChangeFeedProcessorBuilder(string processorName, Container.ChangesHandler onChangesDelegate); + public abstract FeedIterator GetChangeFeedStreamIterator(ChangeFeedStartFrom changeFeedStartFrom, ChangeFeedMode changeFeedMode, ChangeFeedRequestOptions changeFeedRequestOptions=null); + public abstract Task> GetFeedRangesAsync(CancellationToken cancellationToken=default(CancellationToken)); + public abstract IOrderedQueryable GetItemLinqQueryable(bool allowSynchronousQueryExecution=false, string continuationToken=null, QueryRequestOptions requestOptions=null, CosmosLinqSerializerOptions linqSerializerOptions=null); + public abstract FeedIterator GetItemQueryIterator(FeedRange feedRange, QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetItemQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetItemQueryIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetItemQueryStreamIterator(FeedRange feedRange, QueryDefinition queryDefinition, string continuationToken, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetItemQueryStreamIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetItemQueryStreamIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract Task> GetPartitionKeyRangesAsync(FeedRange feedRange, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task> PatchItemAsync(string id, PartitionKey partitionKey, IReadOnlyList patchOperations, PatchItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task PatchItemStreamAsync(string id, PartitionKey partitionKey, IReadOnlyList patchOperations, PatchItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadContainerAsync(ContainerRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadContainerStreamAsync(ContainerRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task> ReadItemAsync(string id, PartitionKey partitionKey, ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadItemStreamAsync(string id, PartitionKey partitionKey, ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task> ReadManyItemsAsync(IReadOnlyList> items, ReadManyRequestOptions readManyRequestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadManyItemsStreamAsync(IReadOnlyList> items, ReadManyRequestOptions readManyRequestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadThroughputAsync(RequestOptions requestOptions, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task> ReadThroughputAsync(CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceContainerAsync(ContainerProperties containerProperties, ContainerRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceContainerStreamAsync(ContainerProperties containerProperties, ContainerRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task> ReplaceItemAsync(T item, string id, Nullable partitionKey=default(Nullable), ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceItemStreamAsync(Stream streamPayload, string id, PartitionKey partitionKey, ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceThroughputAsync(ThroughputProperties throughputProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceThroughputAsync(int throughput, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task> UpsertItemAsync(T item, Nullable partitionKey=default(Nullable), ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task UpsertItemStreamAsync(Stream streamPayload, PartitionKey partitionKey, ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public delegate Task ChangeFeedHandlerWithManualCheckpoint(ChangeFeedProcessorContext context, IReadOnlyCollection changes, Func checkpointAsync, CancellationToken cancellationToken); + public delegate Task ChangeFeedHandler(ChangeFeedProcessorContext context, IReadOnlyCollection changes, CancellationToken cancellationToken); + public delegate Task ChangeFeedMonitorErrorDelegate(string leaseToken, Exception exception); + public delegate Task ChangeFeedMonitorLeaseAcquireDelegate(string leaseToken); + public delegate Task ChangeFeedMonitorLeaseReleaseDelegate(string leaseToken); + public delegate Task ChangeFeedStreamHandler(ChangeFeedProcessorContext context, Stream changes, CancellationToken cancellationToken); + public delegate Task ChangeFeedStreamHandlerWithManualCheckpoint(ChangeFeedProcessorContext context, Stream changes, Func checkpointAsync, CancellationToken cancellationToken); + public delegate Task ChangesEstimationHandler(long estimatedPendingChanges, CancellationToken cancellationToken); + public delegate Task ChangesHandler(IReadOnlyCollection changes, CancellationToken cancellationToken); + } + public class ContainerProperties + { + public ContainerProperties(); + public ContainerProperties(string id, IReadOnlyList partitionKeyPaths); + public ContainerProperties(string id, string partitionKeyPath); + public Nullable AnalyticalStoreTimeToLiveInSeconds { get; set; } + public ChangeFeedPolicy ChangeFeedPolicy { get; set; } + public ClientEncryptionPolicy ClientEncryptionPolicy { get; set; } + public Collection ComputedProperties { get; set; } + public ConflictResolutionPolicy ConflictResolutionPolicy { get; set; } + public Nullable DefaultTimeToLive { get; set; } + public string ETag { get; } + public GeospatialConfig GeospatialConfig { get; set; } + public string Id { get; set; } + public IndexingPolicy IndexingPolicy { get; set; } + public Nullable LastModified { get; } + public Nullable PartitionKeyDefinitionVersion { get; set; } + public string PartitionKeyPath { get; set; } + public IReadOnlyList PartitionKeyPaths { get; set; } + public string SelfLink { get; } + public string TimeToLivePropertyPath { get; set; } + public UniqueKeyPolicy UniqueKeyPolicy { get; set; } + } + public class ContainerRequestOptions : RequestOptions + { + public ContainerRequestOptions(); + public bool PopulateQuotaInfo { get; set; } + } + public class ContainerResponse : Response + { + protected ContainerResponse(); + public override string ActivityId { get; } + public virtual Container Container { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public override double RequestCharge { get; } + public override ContainerProperties Resource { get; } + public override HttpStatusCode StatusCode { get; } + public static implicit operator Container (ContainerResponse response); + } + public class CosmosClient : IDisposable + { + protected CosmosClient(); + public CosmosClient(string accountEndpoint, AzureKeyCredential authKeyOrResourceTokenCredential, CosmosClientOptions clientOptions=null); + public CosmosClient(string accountEndpoint, TokenCredential tokenCredential, CosmosClientOptions clientOptions=null); + public CosmosClient(string connectionString, CosmosClientOptions clientOptions=null); + public CosmosClient(string accountEndpoint, string authKeyOrResourceToken, CosmosClientOptions clientOptions=null); + public virtual CosmosClientOptions ClientOptions { get; } + public virtual Uri Endpoint { get; } + public virtual CosmosResponseFactory ResponseFactory { get; } + public static Task CreateAndInitializeAsync(string accountEndpoint, AzureKeyCredential authKeyOrResourceTokenCredential, IReadOnlyList> containers, CosmosClientOptions cosmosClientOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public static Task CreateAndInitializeAsync(string accountEndpoint, TokenCredential tokenCredential, IReadOnlyList> containers, CosmosClientOptions cosmosClientOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public static Task CreateAndInitializeAsync(string connectionString, IReadOnlyList> containers, CosmosClientOptions cosmosClientOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public static Task CreateAndInitializeAsync(string accountEndpoint, string authKeyOrResourceToken, IReadOnlyList> containers, CosmosClientOptions cosmosClientOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public virtual Task CreateDatabaseAsync(string id, ThroughputProperties throughputProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public virtual Task CreateDatabaseAsync(string id, Nullable throughput=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public virtual Task CreateDatabaseIfNotExistsAsync(string id, ThroughputProperties throughputProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public virtual Task CreateDatabaseIfNotExistsAsync(string id, Nullable throughput=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public virtual Task CreateDatabaseStreamAsync(DatabaseProperties databaseProperties, Nullable throughput=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public void Dispose(); + protected virtual void Dispose(bool disposing); + public virtual Container GetContainer(string databaseId, string containerId); + public virtual Database GetDatabase(string id); + public virtual FeedIterator GetDatabaseQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public virtual FeedIterator GetDatabaseQueryIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public virtual FeedIterator GetDatabaseQueryStreamIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public virtual FeedIterator GetDatabaseQueryStreamIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public virtual Task ReadAccountAsync(); + } + public class CosmosClientOptions + { + public CosmosClientOptions(); + public bool AllowBulkExecution { get; set; } + public string ApplicationName { get; set; } + public IReadOnlyList ApplicationPreferredRegions { get; set; } + public string ApplicationRegion { get; set; } + public ConnectionMode ConnectionMode { get; set; } + public Nullable ConsistencyLevel { get; set; } + public Collection CustomHandlers { get; } + public Nullable EnableContentResponseOnWrite { get; set; } + public bool EnableTcpConnectionEndpointRediscovery { get; set; } + public int GatewayModeMaxConnectionLimit { get; set; } + public Func HttpClientFactory { get; set; } + public Nullable IdleTcpConnectionTimeout { get; set; } + public bool IsDistributedTracingEnabled { get; set; } + public bool LimitToEndpoint { get; set; } + public Nullable MaxRequestsPerTcpConnection { get; set; } + public Nullable MaxRetryAttemptsOnRateLimitedRequests { get; set; } + public Nullable MaxRetryWaitTimeOnRateLimitedRequests { get; set; } + public Nullable MaxTcpConnectionsPerEndpoint { get; set; } + public Nullable OpenTcpConnectionTimeout { get; set; } + public Nullable PortReuseMode { get; set; } + public TimeSpan RequestTimeout { get; set; } + public CosmosSerializer Serializer { get; set; } + public CosmosSerializationOptions SerializerOptions { get; set; } + public Func ServerCertificateCustomValidationCallback { get; set; } + public Nullable TokenCredentialBackgroundRefreshInterval { get; set; } + public IWebProxy WebProxy { get; set; } + } + public abstract class CosmosDiagnostics + { + protected CosmosDiagnostics(); + public virtual TimeSpan GetClientElapsedTime(); + public abstract IReadOnlyList> GetContactedRegions(); + public virtual int GetFailedRequestCount(); + public virtual Nullable GetStartTimeUtc(); + public abstract override string ToString(); + } + public class CosmosException : Exception + { + public CosmosException(string message, HttpStatusCode statusCode, int subStatusCode, string activityId, double requestCharge); + public virtual string ActivityId { get; } + public virtual CosmosDiagnostics Diagnostics { get; } + public virtual Headers Headers { get; } + public override string Message { get; } + public virtual double RequestCharge { get; } + public virtual string ResponseBody { get; } + public virtual Nullable RetryAfter { get; } + public override string StackTrace { get; } + public virtual HttpStatusCode StatusCode { get; } + public virtual int SubStatusCode { get; } + public override string ToString(); + public virtual bool TryGetHeader(string headerName, out string value); + } + public sealed class CosmosLinqSerializerOptions + { + public CosmosLinqSerializerOptions(); + public CosmosPropertyNamingPolicy PropertyNamingPolicy { get; set; } + } + public class CosmosOperationCanceledException : OperationCanceledException + { + public CosmosOperationCanceledException(OperationCanceledException originalException, CosmosDiagnostics diagnostics); + protected CosmosOperationCanceledException(SerializationInfo info, StreamingContext context); + public override IDictionary Data { get; } + public CosmosDiagnostics Diagnostics { get; } + public override string HelpLink { get; set; } + public override string Message { get; } + public override string Source { get; set; } + public override string StackTrace { get; } + public override Exception GetBaseException(); + public override void GetObjectData(SerializationInfo info, StreamingContext context); + public override string ToString(); + } + public enum CosmosPropertyNamingPolicy + { + CamelCase = 1, + Default = 0, + } + public abstract class CosmosResponseFactory + { + protected CosmosResponseFactory(); + public abstract FeedResponse CreateItemFeedResponse(ResponseMessage responseMessage); + public abstract ItemResponse CreateItemResponse(ResponseMessage responseMessage); + public abstract StoredProcedureExecuteResponse CreateStoredProcedureExecuteResponse(ResponseMessage responseMessage); + } + public sealed class CosmosSerializationOptions + { + public CosmosSerializationOptions(); + public bool IgnoreNullValues { get; set; } + public bool Indented { get; set; } + public CosmosPropertyNamingPolicy PropertyNamingPolicy { get; set; } + } + public abstract class CosmosSerializer + { + protected CosmosSerializer(); + public abstract T FromStream(Stream stream); + public abstract Stream ToStream(T input); + } + public abstract class Database + { + protected Database(); + public abstract CosmosClient Client { get; } + public abstract string Id { get; } + public abstract Task CreateClientEncryptionKeyAsync(ClientEncryptionKeyProperties clientEncryptionKeyProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateContainerAsync(ContainerProperties containerProperties, ThroughputProperties throughputProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateContainerAsync(ContainerProperties containerProperties, Nullable throughput=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateContainerAsync(string id, string partitionKeyPath, Nullable throughput=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateContainerIfNotExistsAsync(ContainerProperties containerProperties, ThroughputProperties throughputProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateContainerIfNotExistsAsync(ContainerProperties containerProperties, Nullable throughput=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateContainerIfNotExistsAsync(string id, string partitionKeyPath, Nullable throughput=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateContainerStreamAsync(ContainerProperties containerProperties, ThroughputProperties throughputProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateContainerStreamAsync(ContainerProperties containerProperties, Nullable throughput=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateUserAsync(string id, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract ContainerBuilder DefineContainer(string name, string partitionKeyPath); + public abstract Task DeleteAsync(RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task DeleteStreamAsync(RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract ClientEncryptionKey GetClientEncryptionKey(string id); + public abstract FeedIterator GetClientEncryptionKeyQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract Container GetContainer(string id); + public abstract FeedIterator GetContainerQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetContainerQueryIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetContainerQueryStreamIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetContainerQueryStreamIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract User GetUser(string id); + public abstract FeedIterator GetUserQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetUserQueryIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract Task ReadAsync(RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadStreamAsync(RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadThroughputAsync(RequestOptions requestOptions, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task> ReadThroughputAsync(CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceThroughputAsync(ThroughputProperties throughputProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceThroughputAsync(int throughput, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task UpsertUserAsync(string id, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + } + public class DatabaseProperties + { + public DatabaseProperties(); + public DatabaseProperties(string id); + public string ETag { get; } + public string Id { get; set; } + public Nullable LastModified { get; } + public string SelfLink { get; } + } + public class DatabaseResponse : Response + { + protected DatabaseResponse(); + public override string ActivityId { get; } + public virtual Database Database { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public override double RequestCharge { get; } + public override DatabaseProperties Resource { get; } + public override HttpStatusCode StatusCode { get; } + public static implicit operator Database (DatabaseResponse response); + } + public enum DataType + { + LineString = 3, + MultiPolygon = 5, + Number = 0, + Point = 2, + Polygon = 4, + String = 1, + } + public class DedicatedGatewayRequestOptions + { + public DedicatedGatewayRequestOptions(); + public Nullable BypassIntegratedCache { get; set; } + public Nullable MaxIntegratedCacheStaleness { get; set; } + } + public class EncryptionKeyWrapMetadata : IEquatable + { + public EncryptionKeyWrapMetadata(EncryptionKeyWrapMetadata source); + public EncryptionKeyWrapMetadata(string type, string name, string value, string algorithm); + public string Algorithm { get; } + public string Name { get; } + public string Type { get; } + public string Value { get; } + public bool Equals(EncryptionKeyWrapMetadata other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public sealed class ExcludedPath + { + public ExcludedPath(); + public string Path { get; set; } + } + public abstract class FeedIterator : IDisposable + { + protected FeedIterator(); + public abstract bool HasMoreResults { get; } + public void Dispose(); + protected virtual void Dispose(bool disposing); + public abstract Task ReadNextAsync(CancellationToken cancellationToken=default(CancellationToken)); + } + public abstract class FeedIterator : IDisposable + { + protected FeedIterator(); + public abstract bool HasMoreResults { get; } + public void Dispose(); + protected virtual void Dispose(bool disposing); + public abstract Task> ReadNextAsync(CancellationToken cancellationToken=default(CancellationToken)); + } + public abstract class FeedRange + { + protected FeedRange(); + public static FeedRange FromJsonString(string toStringValue); + public static FeedRange FromPartitionKey(PartitionKey partitionKey); + public abstract string ToJsonString(); + } + public abstract class FeedResponse : IEnumerable, IEnumerable + { + protected FeedResponse(); + public override string ActivityId { get; } + public abstract string ContinuationToken { get; } + public abstract int Count { get; } + public override string ETag { get; } + public abstract string IndexMetrics { get; } + public override double RequestCharge { get; } + public abstract IEnumerator GetEnumerator(); + IEnumerator System.Collections.IEnumerable.GetEnumerator(); + } + public sealed class GeospatialConfig + { + public GeospatialConfig(); + public GeospatialConfig(GeospatialType geospatialType); + public GeospatialType GeospatialType { get; set; } + } + public enum GeospatialType + { + Geography = 0, + Geometry = 1, + } + public class Headers : IEnumerable + { + public Headers(); + public virtual string ActivityId { get; } + public virtual string ContentLength { get; set; } + public virtual string ContentType { get; } + public virtual string ContinuationToken { get; } + public virtual string ETag { get; } + public virtual string this[string headerName] { get; set; } + public virtual string Location { get; } + public virtual double RequestCharge { get; } + public virtual string Session { get; } + public virtual void Add(string headerName, IEnumerable values); + public virtual void Add(string headerName, string value); + public virtual string[] AllKeys(); + public virtual string Get(string headerName); + public virtual IEnumerator GetEnumerator(); + public virtual T GetHeaderValue(string headerName); + public virtual string GetValueOrDefault(string headerName); + public virtual void Remove(string headerName); + public virtual void Set(string headerName, string value); + IEnumerator System.Collections.IEnumerable.GetEnumerator(); + public virtual bool TryGetValue(string headerName, out string value); + } + public sealed class IncludedPath + { + public IncludedPath(); + public string Path { get; set; } + } + public enum IndexingDirective + { + Default = 0, + Exclude = 2, + Include = 1, + } + public enum IndexingMode + { + Consistent = 0, + Lazy = 1, + None = 2, + } + public sealed class IndexingPolicy + { + public IndexingPolicy(); + public bool Automatic { get; set; } + public Collection> CompositeIndexes { get; } + public Collection ExcludedPaths { get; } + public Collection IncludedPaths { get; } + public IndexingMode IndexingMode { get; set; } + public Collection SpatialIndexes { get; } + } + public enum IndexKind + { + Hash = 0, + Range = 1, + Spatial = 2, + } + public class ItemRequestOptions : RequestOptions + { + public ItemRequestOptions(); + public Nullable ConsistencyLevel { get; set; } + public DedicatedGatewayRequestOptions DedicatedGatewayRequestOptions { get; set; } + public Nullable EnableContentResponseOnWrite { get; set; } + public Nullable IndexingDirective { get; set; } + public IEnumerable PostTriggers { get; set; } + public IEnumerable PreTriggers { get; set; } + public string SessionToken { get; set; } + } + public class ItemResponse : Response + { + protected ItemResponse(); + public override string ActivityId { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public override double RequestCharge { get; } + public override T Resource { get; } + public override HttpStatusCode StatusCode { get; } + } + public enum OperationKind + { + Create = 1, + Delete = 3, + Invalid = 0, + Read = 4, + Replace = 2, + } + public struct PartitionKey : IEquatable + { + public static readonly PartitionKey None; + public static readonly PartitionKey Null; + public static readonly string SystemKeyName; + public static readonly string SystemKeyPath; + public PartitionKey(bool partitionKeyValue); + public PartitionKey(double partitionKeyValue); + public PartitionKey(string partitionKeyValue); + public bool Equals(PartitionKey other); + public override bool Equals(object obj); + public override int GetHashCode(); + public static bool operator ==(PartitionKey left, PartitionKey right); + public static bool operator !=(PartitionKey left, PartitionKey right); + public override string ToString(); + } + public sealed class PartitionKeyBuilder + { + public PartitionKeyBuilder(); + public PartitionKeyBuilder Add(bool val); + public PartitionKeyBuilder Add(double val); + public PartitionKeyBuilder Add(string val); + public PartitionKeyBuilder AddNoneType(); + public PartitionKeyBuilder AddNullValue(); + public PartitionKey Build(); + } + public enum PartitionKeyDefinitionVersion + { + V1 = 1, + V2 = 2, + } + public sealed class PatchItemRequestOptions : ItemRequestOptions + { + public PatchItemRequestOptions(); + public string FilterPredicate { get; set; } + } + public abstract class PatchOperation + { + protected PatchOperation(); + public virtual string From { get; set; } + public abstract PatchOperationType OperationType { get; } + public abstract string Path { get; } + public static PatchOperation Add(string path, T value); + public static PatchOperation Increment(string path, double value); + public static PatchOperation Increment(string path, long value); + public static PatchOperation Move(string from, string path); + public static PatchOperation Remove(string path); + public static PatchOperation Replace(string path, T value); + public static PatchOperation Set(string path, T value); + public virtual bool TrySerializeValueParameter(CosmosSerializer cosmosSerializer, out Stream valueParam); + } + public enum PatchOperationType + { + Add = 0, + Increment = 4, + Move = 5, + Remove = 1, + Replace = 2, + Set = 3, + } + public abstract class PatchOperation : PatchOperation + { + protected PatchOperation(); + public abstract T Value { get; } + } + public abstract class Permission + { + protected Permission(); + public abstract string Id { get; } + public abstract Task DeleteAsync(RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadAsync(Nullable tokenExpiryInSeconds=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceAsync(PermissionProperties permissionProperties, Nullable tokenExpiryInSeconds=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + } + public enum PermissionMode : byte + { + All = (byte)2, + Read = (byte)1, + } + public class PermissionProperties + { + public PermissionProperties(string id, PermissionMode permissionMode, Container container, PartitionKey resourcePartitionKey, string itemId); + public PermissionProperties(string id, PermissionMode permissionMode, Container container, Nullable resourcePartitionKey=default(Nullable)); + public string ETag { get; } + public string Id { get; } + public Nullable LastModified { get; } + public PermissionMode PermissionMode { get; } + public Nullable ResourcePartitionKey { get; set; } + public string ResourceUri { get; } + public string SelfLink { get; } + public string Token { get; } + } + public class PermissionResponse : Response + { + protected PermissionResponse(); + public override string ActivityId { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public virtual Permission Permission { get; } + public override double RequestCharge { get; } + public override PermissionProperties Resource { get; } + public override HttpStatusCode StatusCode { get; } + public static implicit operator Permission (PermissionResponse response); + } + public enum PortReuseMode + { + PrivatePortPool = 1, + ReuseUnicastPort = 0, + } + public enum PriorityLevel + { + High = 1, + Low = 2, + } + public class QueryDefinition + { + public QueryDefinition(string query); + public string QueryText { get; } + public IReadOnlyList> GetQueryParameters(); + public QueryDefinition WithParameter(string name, object value); + public QueryDefinition WithParameterStream(string name, Stream valueStream); + } + public class QueryRequestOptions : RequestOptions + { + public QueryRequestOptions(); + public Nullable ConsistencyLevel { get; set; } + public DedicatedGatewayRequestOptions DedicatedGatewayRequestOptions { get; set; } + public Nullable EnableLowPrecisionOrderBy { get; set; } + public bool EnableOptimisticDirectExecution { get; set; } + public Nullable EnableScanInQuery { get; set; } + public Nullable MaxBufferedItemCount { get; set; } + public Nullable MaxConcurrency { get; set; } + public Nullable MaxItemCount { get; set; } + public Nullable PartitionKey { get; set; } + public Nullable PopulateIndexMetrics { get; set; } + public Nullable ResponseContinuationTokenLimitInKb { get; set; } + public string SessionToken { get; set; } + } + public class ReadManyRequestOptions : RequestOptions + { + public ReadManyRequestOptions(); + public Nullable ConsistencyLevel { get; set; } + public string SessionToken { get; set; } + } + public static class Regions + { + public const string AustraliaCentral = "Australia Central"; + public const string AustraliaCentral2 = "Australia Central 2"; + public const string AustraliaEast = "Australia East"; + public const string AustraliaSoutheast = "Australia Southeast"; + public const string BrazilSouth = "Brazil South"; + public const string BrazilSoutheast = "Brazil Southeast"; + public const string CanadaCentral = "Canada Central"; + public const string CanadaEast = "Canada East"; + public const string CentralIndia = "Central India"; + public const string CentralUS = "Central US"; + public const string CentralUSEUAP = "Central US EUAP"; + public const string ChinaEast = "China East"; + public const string ChinaEast2 = "China East 2"; + public const string ChinaEast3 = "China East 3"; + public const string ChinaNorth = "China North"; + public const string ChinaNorth2 = "China North 2"; + public const string ChinaNorth3 = "China North 3"; + public const string EastAsia = "East Asia"; + public const string EastUS = "East US"; + public const string EastUS2 = "East US 2"; + public const string EastUS2EUAP = "East US 2 EUAP"; + public const string EastUSSLV = "East US SLV"; + public const string FranceCentral = "France Central"; + public const string FranceSouth = "France South"; + public const string GermanyCentral = "Germany Central"; + public const string GermanyNorth = "Germany North"; + public const string GermanyNortheast = "Germany Northeast"; + public const string GermanyWestCentral = "Germany West Central"; + public const string IsraelCentral = "Israel Central"; + public const string ItalyNorth = "Italy North"; + public const string JapanEast = "Japan East"; + public const string JapanWest = "Japan West"; + public const string JioIndiaCentral = "Jio India Central"; + public const string JioIndiaWest = "Jio India West"; + public const string KoreaCentral = "Korea Central"; + public const string KoreaSouth = "Korea South"; + public const string MalaysiaSouth = "Malaysia South"; + public const string NorthCentralUS = "North Central US"; + public const string NorthEurope = "North Europe"; + public const string NorwayEast = "Norway East"; + public const string NorwayWest = "Norway West"; + public const string PolandCentral = "Poland Central"; + public const string QatarCentral = "Qatar Central"; + public const string SouthAfricaNorth = "South Africa North"; + public const string SouthAfricaWest = "South Africa West"; + public const string SouthCentralUS = "South Central US"; + public const string SoutheastAsia = "Southeast Asia"; + public const string SouthIndia = "South India"; + public const string SwedenCentral = "Sweden Central"; + public const string SwedenSouth = "Sweden South"; + public const string SwitzerlandNorth = "Switzerland North"; + public const string SwitzerlandWest = "Switzerland West"; + public const string UAECentral = "UAE Central"; + public const string UAENorth = "UAE North"; + public const string UKSouth = "UK South"; + public const string UKWest = "UK West"; + public const string USDoDCentral = "USDoD Central"; + public const string USDoDEast = "USDoD East"; + public const string USGovArizona = "USGov Arizona"; + public const string USGovTexas = "USGov Texas"; + public const string USGovVirginia = "USGov Virginia"; + public const string USNatEast = "USNat East"; + public const string USNatWest = "USNat West"; + public const string USSecEast = "USSec East"; + public const string USSecWest = "USSec West"; + public const string WestCentralUS = "West Central US"; + public const string WestEurope = "West Europe"; + public const string WestIndia = "West India"; + public const string WestUS = "West US"; + public const string WestUS2 = "West US 2"; + public const string WestUS3 = "West US 3"; + } + public abstract class RequestHandler + { + protected RequestHandler(); + public RequestHandler InnerHandler { get; set; } + public virtual Task SendAsync(RequestMessage request, CancellationToken cancellationToken); + } + public class RequestMessage : IDisposable + { + public RequestMessage(); + public RequestMessage(HttpMethod method, Uri requestUri); + public virtual Stream Content { get; set; } + public virtual Headers Headers { get; } + public virtual HttpMethod Method { get; } + public virtual Dictionary Properties { get; } + public virtual Uri RequestUri { get; } + public void Dispose(); + protected virtual void Dispose(bool disposing); + } + public class RequestOptions + { + public RequestOptions(); + public Action AddRequestHeaders { get; set; } + public string IfMatchEtag { get; set; } + public string IfNoneMatchEtag { get; set; } + public Nullable PriorityLevel { get; set; } + public IReadOnlyDictionary Properties { get; set; } + public RequestOptions ShallowCopy(); + } + public class ResponseMessage : IDisposable + { + public ResponseMessage(); + public ResponseMessage(HttpStatusCode statusCode, RequestMessage requestMessage=null, string errorMessage=null); + public virtual Stream Content { get; set; } + public virtual string ContinuationToken { get; } + public virtual CosmosDiagnostics Diagnostics { get; set; } + public virtual string ErrorMessage { get; } + public virtual Headers Headers { get; } + public string IndexMetrics { get; } + public virtual bool IsSuccessStatusCode { get; } + public virtual RequestMessage RequestMessage { get; } + public virtual HttpStatusCode StatusCode { get; } + public void Dispose(); + protected virtual void Dispose(bool disposing); + public virtual ResponseMessage EnsureSuccessStatusCode(); + } + public abstract class Response + { + protected Response(); + public abstract string ActivityId { get; } + public abstract CosmosDiagnostics Diagnostics { get; } + public abstract string ETag { get; } + public abstract Headers Headers { get; } + public abstract double RequestCharge { get; } + public abstract T Resource { get; } + public abstract HttpStatusCode StatusCode { get; } + public static implicit operator T (Response response); + } + public sealed class SpatialPath + { + public SpatialPath(); + public BoundingBoxProperties BoundingBox { get; set; } + public string Path { get; set; } + public Collection SpatialTypes { get; } + } + public enum SpatialType + { + LineString = 1, + MultiPolygon = 3, + Point = 0, + Polygon = 2, + } + public class ThroughputProperties + { + public Nullable AutoscaleMaxThroughput { get; } + public string ETag { get; } + public Nullable LastModified { get; } + public string SelfLink { get; } + public Nullable Throughput { get; } + public static ThroughputProperties CreateAutoscaleThroughput(int autoscaleMaxThroughput); + public static ThroughputProperties CreateManualThroughput(int throughput); + } + public class ThroughputResponse : Response + { + protected ThroughputResponse(); + public override string ActivityId { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public Nullable IsReplacePending { get; } + public Nullable MinThroughput { get; } + public override double RequestCharge { get; } + public override ThroughputProperties Resource { get; } + public override HttpStatusCode StatusCode { get; } + public static implicit operator ThroughputProperties (ThroughputResponse response); + } + public abstract class TransactionalBatch + { + protected TransactionalBatch(); + public abstract TransactionalBatch CreateItemStream(Stream streamPayload, TransactionalBatchItemRequestOptions requestOptions=null); + public abstract TransactionalBatch CreateItem(T item, TransactionalBatchItemRequestOptions requestOptions=null); + public abstract TransactionalBatch DeleteItem(string id, TransactionalBatchItemRequestOptions requestOptions=null); + public abstract Task ExecuteAsync(TransactionalBatchRequestOptions requestOptions, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ExecuteAsync(CancellationToken cancellationToken=default(CancellationToken)); + public abstract TransactionalBatch PatchItem(string id, IReadOnlyList patchOperations, TransactionalBatchPatchItemRequestOptions requestOptions=null); + public abstract TransactionalBatch ReadItem(string id, TransactionalBatchItemRequestOptions requestOptions=null); + public abstract TransactionalBatch ReplaceItemStream(string id, Stream streamPayload, TransactionalBatchItemRequestOptions requestOptions=null); + public abstract TransactionalBatch ReplaceItem(string id, T item, TransactionalBatchItemRequestOptions requestOptions=null); + public abstract TransactionalBatch UpsertItemStream(Stream streamPayload, TransactionalBatchItemRequestOptions requestOptions=null); + public abstract TransactionalBatch UpsertItem(T item, TransactionalBatchItemRequestOptions requestOptions=null); + } + public class TransactionalBatchItemRequestOptions : RequestOptions + { + public TransactionalBatchItemRequestOptions(); + public Nullable EnableContentResponseOnWrite { get; set; } + public Nullable IndexingDirective { get; set; } + } + public class TransactionalBatchOperationResult + { + protected TransactionalBatchOperationResult(); + public virtual string ETag { get; } + public virtual bool IsSuccessStatusCode { get; } + public virtual Stream ResourceStream { get; } + public virtual TimeSpan RetryAfter { get; } + public virtual HttpStatusCode StatusCode { get; } + } + public class TransactionalBatchOperationResult : TransactionalBatchOperationResult + { + protected TransactionalBatchOperationResult(); + public virtual T Resource { get; set; } + } + public class TransactionalBatchPatchItemRequestOptions : TransactionalBatchItemRequestOptions + { + public TransactionalBatchPatchItemRequestOptions(); + public string FilterPredicate { get; set; } + } + public class TransactionalBatchRequestOptions : RequestOptions + { + public TransactionalBatchRequestOptions(); + public Nullable ConsistencyLevel { get; set; } + public string SessionToken { get; set; } + } + public class TransactionalBatchResponse : IDisposable, IEnumerable, IEnumerable, IReadOnlyCollection, IReadOnlyList + { + protected TransactionalBatchResponse(); + public virtual string ActivityId { get; } + public virtual int Count { get; } + public virtual CosmosDiagnostics Diagnostics { get; } + public virtual string ErrorMessage { get; } + public virtual Headers Headers { get; } + public virtual bool IsSuccessStatusCode { get; } + public virtual TransactionalBatchOperationResult this[int index] { get; } + public virtual double RequestCharge { get; } + public virtual Nullable RetryAfter { get; } + public virtual HttpStatusCode StatusCode { get; } + public void Dispose(); + protected virtual void Dispose(bool disposing); + public virtual IEnumerator GetEnumerator(); + public virtual TransactionalBatchOperationResult GetOperationResultAtIndex(int index); + IEnumerator System.Collections.IEnumerable.GetEnumerator(); + } + public class UniqueKey + { + public UniqueKey(); + public Collection Paths { get; } + } + public sealed class UniqueKeyPolicy + { + public UniqueKeyPolicy(); + public Collection UniqueKeys { get; } + } + public abstract class User + { + protected User(); + public abstract string Id { get; } + public abstract Task CreatePermissionAsync(PermissionProperties permissionProperties, Nullable tokenExpiryInSeconds=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task DeleteAsync(RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Permission GetPermission(string id); + public abstract FeedIterator GetPermissionQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetPermissionQueryIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract Task ReadAsync(RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceAsync(UserProperties userProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task UpsertPermissionAsync(PermissionProperties permissionProperties, Nullable tokenExpiryInSeconds=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + } + public class UserProperties + { + protected UserProperties(); + public UserProperties(string id); + public string ETag { get; } + public string Id { get; set; } + public Nullable LastModified { get; } + public string SelfLink { get; } + } + public class UserResponse : Response + { + protected UserResponse(); + public override string ActivityId { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public override double RequestCharge { get; } + public override UserProperties Resource { get; } + public override HttpStatusCode StatusCode { get; } + public virtual User User { get; } + public static implicit operator User (UserResponse response); + } +} +namespace Microsoft.Azure.Cosmos.Fluent +{ + public class ChangeFeedPolicyDefinition + { + public ContainerBuilder Attach(); + } + public sealed class ClientEncryptionPolicyDefinition + { + public ContainerBuilder Attach(); + public ClientEncryptionPolicyDefinition WithIncludedPath(ClientEncryptionIncludedPath path); + } + public class CompositeIndexDefinition + { + public T Attach(); + public CompositeIndexDefinition Path(string path); + public CompositeIndexDefinition Path(string path, CompositePathSortOrder sortOrder); + } + public class ComputedPropertiesDefinition + { + public T Attach(); + public ComputedPropertiesDefinition WithComputedProperty(string name, string query); + } + public class ConflictResolutionDefinition + { + public ContainerBuilder Attach(); + public ConflictResolutionDefinition WithCustomStoredProcedureResolution(string conflictResolutionProcedure); + public ConflictResolutionDefinition WithLastWriterWinsResolution(string conflictResolutionPath); + } + public class ContainerBuilder : ContainerDefinition + { + protected ContainerBuilder(); + public ContainerBuilder(Database database, string name, string partitionKeyPath); + public new ContainerProperties Build(); + public Task CreateAsync(ThroughputProperties throughputProperties, CancellationToken cancellationToken=default(CancellationToken)); + public Task CreateAsync(Nullable throughput=default(Nullable), CancellationToken cancellationToken=default(CancellationToken)); + public Task CreateIfNotExistsAsync(ThroughputProperties throughputProperties, CancellationToken cancellationToken=default(CancellationToken)); + public Task CreateIfNotExistsAsync(Nullable throughput=default(Nullable), CancellationToken cancellationToken=default(CancellationToken)); + public ChangeFeedPolicyDefinition WithChangeFeedPolicy(TimeSpan retention); + public ClientEncryptionPolicyDefinition WithClientEncryptionPolicy(); + public ClientEncryptionPolicyDefinition WithClientEncryptionPolicy(int policyFormatVersion); + public ConflictResolutionDefinition WithConflictResolution(); + public UniqueKeyDefinition WithUniqueKey(); + } + public abstract class ContainerDefinition where T : ContainerDefinition + { + public ContainerDefinition(); + public ContainerProperties Build(); + public ComputedPropertiesDefinition WithComputedProperties(); + public T WithDefaultTimeToLive(int defaultTtlInSeconds); + public T WithDefaultTimeToLive(TimeSpan defaultTtlTimeSpan); + public IndexingPolicyDefinition WithIndexingPolicy(); + public T WithPartitionKeyDefinitionVersion(PartitionKeyDefinitionVersion partitionKeyDefinitionVersion); + public T WithTimeToLivePropertyPath(string propertyPath); + } + public class CosmosClientBuilder + { + public CosmosClientBuilder(string connectionString); + public CosmosClientBuilder(string accountEndpoint, AzureKeyCredential authKeyOrResourceTokenCredential); + public CosmosClientBuilder(string accountEndpoint, TokenCredential tokenCredential); + public CosmosClientBuilder(string accountEndpoint, string authKeyOrResourceToken); + public CosmosClientBuilder AddCustomHandlers(params RequestHandler[] customHandlers); + public CosmosClient Build(); + public Task BuildAndInitializeAsync(IReadOnlyList> containers, CancellationToken cancellationToken=default(CancellationToken)); + public CosmosClientBuilder WithApplicationName(string applicationName); + public CosmosClientBuilder WithApplicationPreferredRegions(IReadOnlyList applicationPreferredRegions); + public CosmosClientBuilder WithApplicationRegion(string applicationRegion); + public CosmosClientBuilder WithBulkExecution(bool enabled); + public CosmosClientBuilder WithConnectionModeDirect(); + public CosmosClientBuilder WithConnectionModeDirect(Nullable idleTcpConnectionTimeout=default(Nullable), Nullable openTcpConnectionTimeout=default(Nullable), Nullable maxRequestsPerTcpConnection=default(Nullable), Nullable maxTcpConnectionsPerEndpoint=default(Nullable), Nullable portReuseMode=default(Nullable), Nullable enableTcpConnectionEndpointRediscovery=default(Nullable)); + public CosmosClientBuilder WithConnectionModeGateway(Nullable maxConnectionLimit=default(Nullable), IWebProxy webProxy=null); + public CosmosClientBuilder WithConsistencyLevel(ConsistencyLevel consistencyLevel); + public CosmosClientBuilder WithContentResponseOnWrite(bool contentResponseOnWrite); + public CosmosClientBuilder WithCustomSerializer(CosmosSerializer cosmosJsonSerializer); + public CosmosClientBuilder WithDistributedTracing(bool isEnabled=true); + public CosmosClientBuilder WithHttpClientFactory(Func httpClientFactory); + public CosmosClientBuilder WithLimitToEndpoint(bool limitToEndpoint); + public CosmosClientBuilder WithRequestTimeout(TimeSpan requestTimeout); + public CosmosClientBuilder WithSerializerOptions(CosmosSerializationOptions cosmosSerializerOptions); + public CosmosClientBuilder WithThrottlingRetryOptions(TimeSpan maxRetryWaitTimeOnThrottledRequests, int maxRetryAttemptsOnThrottledRequests); + } + public class IndexingPolicyDefinition + { + public IndexingPolicyDefinition(); + public T Attach(); + public IndexingPolicyDefinition WithAutomaticIndexing(bool enabled); + public CompositeIndexDefinition> WithCompositeIndex(); + public PathsDefinition> WithExcludedPaths(); + public PathsDefinition> WithIncludedPaths(); + public IndexingPolicyDefinition WithIndexingMode(IndexingMode indexingMode); + public SpatialIndexDefinition> WithSpatialIndex(); + } + public class PathsDefinition + { + public T Attach(); + public PathsDefinition Path(string path); + } + public class SpatialIndexDefinition + { + public T Attach(); + public SpatialIndexDefinition Path(string path); + public SpatialIndexDefinition Path(string path, params SpatialType[] spatialTypes); + } + public class UniqueKeyDefinition + { + public ContainerBuilder Attach(); + public UniqueKeyDefinition Path(string path); + } +} +namespace Microsoft.Azure.Cosmos.Linq +{ + public static class CosmosLinq + { + public static object InvokeUserDefinedFunction(string udfName, params object[] arguments); + } + public static class CosmosLinqExtensions + { + public static Task> AverageAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> AverageAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> AverageAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> AverageAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> AverageAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> AverageAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> AverageAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> AverageAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> AverageAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> AverageAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> CountAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static bool IsArray(this object obj); + public static bool IsBool(this object obj); + public static bool IsDefined(this object obj); + public static bool IsNull(this object obj); + public static bool IsNumber(this object obj); + public static bool IsObject(this object obj); + public static bool IsPrimitive(this object obj); + public static bool IsString(this object obj); + public static Task> MaxAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> MinAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> SumAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> SumAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> SumAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> SumAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> SumAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> SumAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> SumAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> SumAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> SumAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> SumAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static FeedIterator ToFeedIterator(this IQueryable query); + public static QueryDefinition ToQueryDefinition(this IQueryable query); + public static QueryDefinition ToQueryDefinition(this IQueryable query, IDictionary namedParameters); + public static FeedIterator ToStreamIterator(this IQueryable query); + } +} +namespace Microsoft.Azure.Cosmos.Scripts +{ + public abstract class Scripts + { + protected Scripts(); + public abstract Task CreateStoredProcedureAsync(StoredProcedureProperties storedProcedureProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateTriggerAsync(TriggerProperties triggerProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateUserDefinedFunctionAsync(UserDefinedFunctionProperties userDefinedFunctionProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task DeleteStoredProcedureAsync(string id, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task DeleteTriggerAsync(string id, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task DeleteUserDefinedFunctionAsync(string id, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task> ExecuteStoredProcedureAsync(string storedProcedureId, PartitionKey partitionKey, dynamic parameters, StoredProcedureRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ExecuteStoredProcedureStreamAsync(string storedProcedureId, PartitionKey partitionKey, dynamic parameters, StoredProcedureRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ExecuteStoredProcedureStreamAsync(string storedProcedureId, Stream streamPayload, PartitionKey partitionKey, StoredProcedureRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract FeedIterator GetStoredProcedureQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetStoredProcedureQueryIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetStoredProcedureQueryStreamIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetStoredProcedureQueryStreamIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetTriggerQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetTriggerQueryIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetTriggerQueryStreamIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetTriggerQueryStreamIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetUserDefinedFunctionQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetUserDefinedFunctionQueryIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetUserDefinedFunctionQueryStreamIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetUserDefinedFunctionQueryStreamIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract Task ReadStoredProcedureAsync(string id, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadTriggerAsync(string id, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadUserDefinedFunctionAsync(string id, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceStoredProcedureAsync(StoredProcedureProperties storedProcedureProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceTriggerAsync(TriggerProperties triggerProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceUserDefinedFunctionAsync(UserDefinedFunctionProperties userDefinedFunctionProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + } + public class StoredProcedureExecuteResponse : Response + { + protected StoredProcedureExecuteResponse(); + public override string ActivityId { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public override double RequestCharge { get; } + public override T Resource { get; } + public virtual string ScriptLog { get; } + public virtual string SessionToken { get; } + public override HttpStatusCode StatusCode { get; } + } + public class StoredProcedureProperties + { + public StoredProcedureProperties(); + public StoredProcedureProperties(string id, string body); + public string Body { get; set; } + public string ETag { get; } + public string Id { get; set; } + public Nullable LastModified { get; } + public string SelfLink { get; } + } + public class StoredProcedureRequestOptions : RequestOptions + { + public StoredProcedureRequestOptions(); + public Nullable ConsistencyLevel { get; set; } + public bool EnableScriptLogging { get; set; } + public string SessionToken { get; set; } + } + public class StoredProcedureResponse : Response + { + protected StoredProcedureResponse(); + public override string ActivityId { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public override double RequestCharge { get; } + public override StoredProcedureProperties Resource { get; } + public virtual string SessionToken { get; } + public override HttpStatusCode StatusCode { get; } + public static implicit operator StoredProcedureProperties (StoredProcedureResponse response); + } + public enum TriggerOperation : short + { + All = (short)0, + Create = (short)1, + Delete = (short)3, + Replace = (short)4, + Update = (short)2, + } + public class TriggerProperties + { + public TriggerProperties(); + public string Body { get; set; } + public string ETag { get; } + public string Id { get; set; } + public string SelfLink { get; } + public TriggerOperation TriggerOperation { get; set; } + public TriggerType TriggerType { get; set; } + } + public class TriggerResponse : Response + { + protected TriggerResponse(); + public override string ActivityId { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public override double RequestCharge { get; } + public override TriggerProperties Resource { get; } + public override HttpStatusCode StatusCode { get; } + public static implicit operator TriggerProperties (TriggerResponse response); + } + public enum TriggerType : byte + { + Post = (byte)1, + Pre = (byte)0, + } + public class UserDefinedFunctionProperties + { + public UserDefinedFunctionProperties(); + public string Body { get; set; } + public string ETag { get; } + public string Id { get; set; } + public string SelfLink { get; } + } + public class UserDefinedFunctionResponse : Response + { + protected UserDefinedFunctionResponse(); + public override string ActivityId { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public override double RequestCharge { get; } + public override UserDefinedFunctionProperties Resource { get; } + public override HttpStatusCode StatusCode { get; } + public static implicit operator UserDefinedFunctionProperties (UserDefinedFunctionResponse response); + } +} +namespace Microsoft.Azure.Cosmos.Spatial +{ + public sealed class BoundingBox : IEquatable + { + public BoundingBox(Position min, Position max); + public Position Max { get; } + public Position Min { get; } + public bool Equals(BoundingBox other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public abstract class Crs + { + protected Crs(CrsType type); + public static Crs Default { get; } + public CrsType Type { get; } + public static Crs Unspecified { get; } + public static LinkedCrs Linked(string href); + public static LinkedCrs Linked(string href, string type); + public static NamedCrs Named(string name); + } + public enum CrsType + { + Linked = 1, + Named = 0, + Unspecified = 2, + } + public abstract class Geometry + { + protected Geometry(GeometryType type, GeometryParams geometryParams); + public IDictionary AdditionalProperties { get; } + public BoundingBox BoundingBox { get; } + public Crs Crs { get; } + public GeometryType Type { get; } + public double Distance(Geometry to); + public override bool Equals(object obj); + public override int GetHashCode(); + public bool Intersects(Geometry geometry2); + public bool IsValid(); + public GeometryValidationResult IsValidDetailed(); + public bool Within(Geometry outer); + } + public class GeometryParams + { + public GeometryParams(); + public IDictionary AdditionalProperties { get; set; } + public BoundingBox BoundingBox { get; set; } + public Crs Crs { get; set; } + } + public enum GeometryShape + { + GeometryCollection = 6, + LineString = 2, + MultiLineString = 3, + MultiPoint = 1, + MultiPolygon = 5, + Point = 0, + Polygon = 4, + } + public enum GeometryType + { + GeometryCollection = 6, + LineString = 2, + MultiLineString = 3, + MultiPoint = 1, + MultiPolygon = 5, + Point = 0, + Polygon = 4, + } + public class GeometryValidationResult + { + public GeometryValidationResult(); + public bool IsValid { get; } + public string Reason { get; } + } + public sealed class LinearRing : IEquatable + { + public LinearRing(IList coordinates); + public ReadOnlyCollection Positions { get; } + public bool Equals(LinearRing other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public sealed class LineString : Geometry, IEquatable + { + public LineString(IList coordinates); + public LineString(IList coordinates, GeometryParams geometryParams); + public ReadOnlyCollection Positions { get; } + public bool Equals(LineString other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public sealed class LinkedCrs : Crs, IEquatable + { + public string Href { get; } + public string HrefType { get; } + public bool Equals(LinkedCrs other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public sealed class MultiPolygon : Geometry, IEquatable + { + public MultiPolygon(IList polygons); + public MultiPolygon(IList polygons, GeometryParams geometryParams); + public ReadOnlyCollection Polygons { get; } + public bool Equals(MultiPolygon other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public sealed class NamedCrs : Crs, IEquatable + { + public string Name { get; } + public bool Equals(NamedCrs other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public sealed class Point : Geometry, IEquatable + { + public Point(Position position); + public Point(Position position, GeometryParams geometryParams); + public Point(double longitude, double latitude); + public Position Position { get; } + public bool Equals(Point other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public sealed class Polygon : Geometry, IEquatable + { + public Polygon(IList rings); + public Polygon(IList rings, GeometryParams geometryParams); + public Polygon(IList externalRingPositions); + public ReadOnlyCollection Rings { get; } + public bool Equals(Polygon other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public sealed class PolygonCoordinates : IEquatable + { + public PolygonCoordinates(IList rings); + public ReadOnlyCollection Rings { get; } + public bool Equals(PolygonCoordinates other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public sealed class Position : IEquatable + { + public Position(IList coordinates); + public Position(double longitude, double latitude); + public Position(double longitude, double latitude, Nullable altitude); + public Nullable Altitude { get; } + public ReadOnlyCollection Coordinates { get; } + public double Latitude { get; } + public double Longitude { get; } + public bool Equals(Position other); + public override bool Equals(object obj); + public override int GetHashCode(); + } +} diff --git a/Microsoft.Azure.Cosmos/contracts/API_3.35.4.txt b/Microsoft.Azure.Cosmos/contracts/API_3.35.4.txt new file mode 100644 index 0000000000..c0dc3e280f --- /dev/null +++ b/Microsoft.Azure.Cosmos/contracts/API_3.35.4.txt @@ -0,0 +1,1502 @@ +namespace Microsoft.Azure.Cosmos +{ + public class AccountConsistency + { + public AccountConsistency(); + public ConsistencyLevel DefaultConsistencyLevel { get; } + public int MaxStalenessIntervalInSeconds { get; } + public int MaxStalenessPrefix { get; } + } + public class AccountProperties + { + public AccountConsistency Consistency { get; } + public string ETag { get; } + public string Id { get; } + public IEnumerable ReadableRegions { get; } + public IEnumerable WritableRegions { get; } + } + public class AccountRegion + { + public AccountRegion(); + public string Endpoint { get; } + public string Name { get; } + } + public sealed class BoundingBoxProperties + { + public BoundingBoxProperties(); + public double Xmax { get; set; } + public double Xmin { get; set; } + public double Ymax { get; set; } + public double Ymin { get; set; } + } + public abstract class ChangeFeedEstimator + { + protected ChangeFeedEstimator(); + public abstract FeedIterator GetCurrentStateIterator(ChangeFeedEstimatorRequestOptions changeFeedEstimatorRequestOptions=null); + } + public sealed class ChangeFeedEstimatorRequestOptions + { + public ChangeFeedEstimatorRequestOptions(); + public Nullable MaxItemCount { get; set; } + } + public abstract class ChangeFeedMode + { + public static ChangeFeedMode Incremental { get; } + public static ChangeFeedMode LatestVersion { get; } + } + public abstract class ChangeFeedProcessor + { + protected ChangeFeedProcessor(); + public abstract Task StartAsync(); + public abstract Task StopAsync(); + } + public class ChangeFeedProcessorBuilder + { + public ChangeFeedProcessor Build(); + public ChangeFeedProcessorBuilder WithErrorNotification(Container.ChangeFeedMonitorErrorDelegate errorDelegate); + public ChangeFeedProcessorBuilder WithInstanceName(string instanceName); + public ChangeFeedProcessorBuilder WithLeaseAcquireNotification(Container.ChangeFeedMonitorLeaseAcquireDelegate acquireDelegate); + public ChangeFeedProcessorBuilder WithLeaseConfiguration(Nullable acquireInterval=default(Nullable), Nullable expirationInterval=default(Nullable), Nullable renewInterval=default(Nullable)); + public ChangeFeedProcessorBuilder WithLeaseContainer(Container leaseContainer); + public ChangeFeedProcessorBuilder WithLeaseReleaseNotification(Container.ChangeFeedMonitorLeaseReleaseDelegate releaseDelegate); + public ChangeFeedProcessorBuilder WithMaxItems(int maxItemCount); + public ChangeFeedProcessorBuilder WithPollInterval(TimeSpan pollInterval); + public ChangeFeedProcessorBuilder WithStartTime(DateTime startTime); + } + public abstract class ChangeFeedProcessorContext + { + protected ChangeFeedProcessorContext(); + public abstract CosmosDiagnostics Diagnostics { get; } + public abstract Headers Headers { get; } + public abstract string LeaseToken { get; } + } + public sealed class ChangeFeedProcessorState + { + public ChangeFeedProcessorState(string leaseToken, long estimatedLag, string instanceName); + public long EstimatedLag { get; } + public string InstanceName { get; } + public string LeaseToken { get; } + } + public class ChangeFeedProcessorUserException : Exception + { + public ChangeFeedProcessorUserException(Exception originalException, ChangeFeedProcessorContext context); + protected ChangeFeedProcessorUserException(SerializationInfo info, StreamingContext context); + public ChangeFeedProcessorContext ChangeFeedProcessorContext { get; } + public override void GetObjectData(SerializationInfo info, StreamingContext context); + } + public sealed class ChangeFeedRequestOptions : RequestOptions + { + public ChangeFeedRequestOptions(); + public new string IfMatchEtag { get; set; } + public new string IfNoneMatchEtag { get; set; } + public Nullable PageSizeHint { get; set; } + } + public abstract class ChangeFeedStartFrom + { + public static ChangeFeedStartFrom Beginning(); + public static ChangeFeedStartFrom Beginning(FeedRange feedRange); + public static ChangeFeedStartFrom ContinuationToken(string continuationToken); + public static ChangeFeedStartFrom Now(); + public static ChangeFeedStartFrom Now(FeedRange feedRange); + public static ChangeFeedStartFrom Time(DateTime dateTimeUtc); + public static ChangeFeedStartFrom Time(DateTime dateTimeUtc, FeedRange feedRange); + } + public sealed class ClientEncryptionIncludedPath + { + public ClientEncryptionIncludedPath(); + public string ClientEncryptionKeyId { get; set; } + public string EncryptionAlgorithm { get; set; } + public string EncryptionType { get; set; } + public string Path { get; set; } + } + public abstract class ClientEncryptionKey + { + protected ClientEncryptionKey(); + public abstract string Id { get; } + public abstract Task ReadAsync(RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceAsync(ClientEncryptionKeyProperties clientEncryptionKeyProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + } + public class ClientEncryptionKeyProperties : IEquatable + { + protected ClientEncryptionKeyProperties(); + public ClientEncryptionKeyProperties(string id, string encryptionAlgorithm, byte[] wrappedDataEncryptionKey, EncryptionKeyWrapMetadata encryptionKeyWrapMetadata); + public Nullable CreatedTime { get; } + public string EncryptionAlgorithm { get; } + public EncryptionKeyWrapMetadata EncryptionKeyWrapMetadata { get; } + public string ETag { get; } + public string Id { get; } + public Nullable LastModified { get; } + public virtual string SelfLink { get; } + public byte[] WrappedDataEncryptionKey { get; } + public bool Equals(ClientEncryptionKeyProperties other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public class ClientEncryptionKeyResponse : Response + { + protected ClientEncryptionKeyResponse(); + public override string ActivityId { get; } + public virtual ClientEncryptionKey ClientEncryptionKey { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public override double RequestCharge { get; } + public override ClientEncryptionKeyProperties Resource { get; } + public override HttpStatusCode StatusCode { get; } + public static implicit operator ClientEncryptionKey (ClientEncryptionKeyResponse response); + } + public sealed class ClientEncryptionPolicy + { + public ClientEncryptionPolicy(IEnumerable includedPaths); + public ClientEncryptionPolicy(IEnumerable includedPaths, int policyFormatVersion); + public IEnumerable IncludedPaths { get; } + public int PolicyFormatVersion { get; } + } + public sealed class CompositePath + { + public CompositePath(); + public CompositePathSortOrder Order { get; set; } + public string Path { get; set; } + } + public enum CompositePathSortOrder + { + Ascending = 0, + Descending = 1, + } + public class ConflictProperties + { + public ConflictProperties(); + public string Id { get; } + public OperationKind OperationKind { get; } + public string SelfLink { get; } + } + public enum ConflictResolutionMode + { + Custom = 1, + LastWriterWins = 0, + } + public class ConflictResolutionPolicy + { + public ConflictResolutionPolicy(); + public ConflictResolutionMode Mode { get; set; } + public string ResolutionPath { get; set; } + public string ResolutionProcedure { get; set; } + } + public abstract class Conflicts + { + protected Conflicts(); + public abstract Task DeleteAsync(ConflictProperties conflict, PartitionKey partitionKey, CancellationToken cancellationToken=default(CancellationToken)); + public abstract FeedIterator GetConflictQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetConflictQueryIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetConflictQueryStreamIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetConflictQueryStreamIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract T ReadConflictContent(ConflictProperties conflict); + public abstract Task> ReadCurrentAsync(ConflictProperties conflict, PartitionKey partitionKey, CancellationToken cancellationToken=default(CancellationToken)); + } + public enum ConnectionMode + { + Direct = 1, + Gateway = 0, + } + public enum ConsistencyLevel + { + BoundedStaleness = 1, + ConsistentPrefix = 4, + Eventual = 3, + Session = 2, + Strong = 0, + } + public abstract class Container + { + protected Container(); + public abstract Conflicts Conflicts { get; } + public abstract Database Database { get; } + public abstract string Id { get; } + public abstract Scripts Scripts { get; } + public abstract Task> CreateItemAsync(T item, Nullable partitionKey=default(Nullable), ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateItemStreamAsync(Stream streamPayload, PartitionKey partitionKey, ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract TransactionalBatch CreateTransactionalBatch(PartitionKey partitionKey); + public abstract Task DeleteContainerAsync(ContainerRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task DeleteContainerStreamAsync(ContainerRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task> DeleteItemAsync(string id, PartitionKey partitionKey, ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task DeleteItemStreamAsync(string id, PartitionKey partitionKey, ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract ChangeFeedEstimator GetChangeFeedEstimator(string processorName, Container leaseContainer); + public abstract ChangeFeedProcessorBuilder GetChangeFeedEstimatorBuilder(string processorName, Container.ChangesEstimationHandler estimationDelegate, Nullable estimationPeriod=default(Nullable)); + public abstract FeedIterator GetChangeFeedIterator(ChangeFeedStartFrom changeFeedStartFrom, ChangeFeedMode changeFeedMode, ChangeFeedRequestOptions changeFeedRequestOptions=null); + public abstract ChangeFeedProcessorBuilder GetChangeFeedProcessorBuilder(string processorName, Container.ChangeFeedStreamHandler onChangesDelegate); + public abstract ChangeFeedProcessorBuilder GetChangeFeedProcessorBuilderWithManualCheckpoint(string processorName, Container.ChangeFeedStreamHandlerWithManualCheckpoint onChangesDelegate); + public abstract ChangeFeedProcessorBuilder GetChangeFeedProcessorBuilderWithManualCheckpoint(string processorName, Container.ChangeFeedHandlerWithManualCheckpoint onChangesDelegate); + public abstract ChangeFeedProcessorBuilder GetChangeFeedProcessorBuilder(string processorName, Container.ChangeFeedHandler onChangesDelegate); + public abstract ChangeFeedProcessorBuilder GetChangeFeedProcessorBuilder(string processorName, Container.ChangesHandler onChangesDelegate); + public abstract FeedIterator GetChangeFeedStreamIterator(ChangeFeedStartFrom changeFeedStartFrom, ChangeFeedMode changeFeedMode, ChangeFeedRequestOptions changeFeedRequestOptions=null); + public abstract Task> GetFeedRangesAsync(CancellationToken cancellationToken=default(CancellationToken)); + public abstract IOrderedQueryable GetItemLinqQueryable(bool allowSynchronousQueryExecution=false, string continuationToken=null, QueryRequestOptions requestOptions=null, CosmosLinqSerializerOptions linqSerializerOptions=null); + public abstract FeedIterator GetItemQueryIterator(FeedRange feedRange, QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetItemQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetItemQueryIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetItemQueryStreamIterator(FeedRange feedRange, QueryDefinition queryDefinition, string continuationToken, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetItemQueryStreamIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetItemQueryStreamIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract Task> PatchItemAsync(string id, PartitionKey partitionKey, IReadOnlyList patchOperations, PatchItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task PatchItemStreamAsync(string id, PartitionKey partitionKey, IReadOnlyList patchOperations, PatchItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadContainerAsync(ContainerRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadContainerStreamAsync(ContainerRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task> ReadItemAsync(string id, PartitionKey partitionKey, ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadItemStreamAsync(string id, PartitionKey partitionKey, ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task> ReadManyItemsAsync(IReadOnlyList> items, ReadManyRequestOptions readManyRequestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadManyItemsStreamAsync(IReadOnlyList> items, ReadManyRequestOptions readManyRequestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadThroughputAsync(RequestOptions requestOptions, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task> ReadThroughputAsync(CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceContainerAsync(ContainerProperties containerProperties, ContainerRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceContainerStreamAsync(ContainerProperties containerProperties, ContainerRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task> ReplaceItemAsync(T item, string id, Nullable partitionKey=default(Nullable), ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceItemStreamAsync(Stream streamPayload, string id, PartitionKey partitionKey, ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceThroughputAsync(ThroughputProperties throughputProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceThroughputAsync(int throughput, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task> UpsertItemAsync(T item, Nullable partitionKey=default(Nullable), ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task UpsertItemStreamAsync(Stream streamPayload, PartitionKey partitionKey, ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public delegate Task ChangeFeedHandlerWithManualCheckpoint(ChangeFeedProcessorContext context, IReadOnlyCollection changes, Func checkpointAsync, CancellationToken cancellationToken); + public delegate Task ChangeFeedHandler(ChangeFeedProcessorContext context, IReadOnlyCollection changes, CancellationToken cancellationToken); + public delegate Task ChangeFeedMonitorErrorDelegate(string leaseToken, Exception exception); + public delegate Task ChangeFeedMonitorLeaseAcquireDelegate(string leaseToken); + public delegate Task ChangeFeedMonitorLeaseReleaseDelegate(string leaseToken); + public delegate Task ChangeFeedStreamHandler(ChangeFeedProcessorContext context, Stream changes, CancellationToken cancellationToken); + public delegate Task ChangeFeedStreamHandlerWithManualCheckpoint(ChangeFeedProcessorContext context, Stream changes, Func checkpointAsync, CancellationToken cancellationToken); + public delegate Task ChangesEstimationHandler(long estimatedPendingChanges, CancellationToken cancellationToken); + public delegate Task ChangesHandler(IReadOnlyCollection changes, CancellationToken cancellationToken); + } + public class ContainerProperties + { + public ContainerProperties(); + public ContainerProperties(string id, IReadOnlyList partitionKeyPaths); + public ContainerProperties(string id, string partitionKeyPath); + public Nullable AnalyticalStoreTimeToLiveInSeconds { get; set; } + public ClientEncryptionPolicy ClientEncryptionPolicy { get; set; } + public ConflictResolutionPolicy ConflictResolutionPolicy { get; set; } + public Nullable DefaultTimeToLive { get; set; } + public string ETag { get; } + public GeospatialConfig GeospatialConfig { get; set; } + public string Id { get; set; } + public IndexingPolicy IndexingPolicy { get; set; } + public Nullable LastModified { get; } + public Nullable PartitionKeyDefinitionVersion { get; set; } + public string PartitionKeyPath { get; set; } + public IReadOnlyList PartitionKeyPaths { get; set; } + public string SelfLink { get; } + public string TimeToLivePropertyPath { get; set; } + public UniqueKeyPolicy UniqueKeyPolicy { get; set; } + } + public class ContainerRequestOptions : RequestOptions + { + public ContainerRequestOptions(); + public bool PopulateQuotaInfo { get; set; } + } + public class ContainerResponse : Response + { + protected ContainerResponse(); + public override string ActivityId { get; } + public virtual Container Container { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public override double RequestCharge { get; } + public override ContainerProperties Resource { get; } + public override HttpStatusCode StatusCode { get; } + public static implicit operator Container (ContainerResponse response); + } + public class CosmosClient : IDisposable + { + protected CosmosClient(); + public CosmosClient(string accountEndpoint, AzureKeyCredential authKeyOrResourceTokenCredential, CosmosClientOptions clientOptions=null); + public CosmosClient(string accountEndpoint, TokenCredential tokenCredential, CosmosClientOptions clientOptions=null); + public CosmosClient(string connectionString, CosmosClientOptions clientOptions=null); + public CosmosClient(string accountEndpoint, string authKeyOrResourceToken, CosmosClientOptions clientOptions=null); + public virtual CosmosClientOptions ClientOptions { get; } + public virtual Uri Endpoint { get; } + public virtual CosmosResponseFactory ResponseFactory { get; } + public static Task CreateAndInitializeAsync(string accountEndpoint, AzureKeyCredential authKeyOrResourceTokenCredential, IReadOnlyList> containers, CosmosClientOptions cosmosClientOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public static Task CreateAndInitializeAsync(string accountEndpoint, TokenCredential tokenCredential, IReadOnlyList> containers, CosmosClientOptions cosmosClientOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public static Task CreateAndInitializeAsync(string connectionString, IReadOnlyList> containers, CosmosClientOptions cosmosClientOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public static Task CreateAndInitializeAsync(string accountEndpoint, string authKeyOrResourceToken, IReadOnlyList> containers, CosmosClientOptions cosmosClientOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public virtual Task CreateDatabaseAsync(string id, ThroughputProperties throughputProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public virtual Task CreateDatabaseAsync(string id, Nullable throughput=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public virtual Task CreateDatabaseIfNotExistsAsync(string id, ThroughputProperties throughputProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public virtual Task CreateDatabaseIfNotExistsAsync(string id, Nullable throughput=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public virtual Task CreateDatabaseStreamAsync(DatabaseProperties databaseProperties, Nullable throughput=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public void Dispose(); + protected virtual void Dispose(bool disposing); + public virtual Container GetContainer(string databaseId, string containerId); + public virtual Database GetDatabase(string id); + public virtual FeedIterator GetDatabaseQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public virtual FeedIterator GetDatabaseQueryIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public virtual FeedIterator GetDatabaseQueryStreamIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public virtual FeedIterator GetDatabaseQueryStreamIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public virtual Task ReadAccountAsync(); + } + public class CosmosClientOptions + { + public CosmosClientOptions(); + public bool AllowBulkExecution { get; set; } + public string ApplicationName { get; set; } + public IReadOnlyList ApplicationPreferredRegions { get; set; } + public string ApplicationRegion { get; set; } + public ConnectionMode ConnectionMode { get; set; } + public Nullable ConsistencyLevel { get; set; } + public Collection CustomHandlers { get; } + public Nullable EnableContentResponseOnWrite { get; set; } + public bool EnableTcpConnectionEndpointRediscovery { get; set; } + public int GatewayModeMaxConnectionLimit { get; set; } + public Func HttpClientFactory { get; set; } + public Nullable IdleTcpConnectionTimeout { get; set; } + public bool LimitToEndpoint { get; set; } + public Nullable MaxRequestsPerTcpConnection { get; set; } + public Nullable MaxRetryAttemptsOnRateLimitedRequests { get; set; } + public Nullable MaxRetryWaitTimeOnRateLimitedRequests { get; set; } + public Nullable MaxTcpConnectionsPerEndpoint { get; set; } + public Nullable OpenTcpConnectionTimeout { get; set; } + public Nullable PortReuseMode { get; set; } + public TimeSpan RequestTimeout { get; set; } + public CosmosSerializer Serializer { get; set; } + public CosmosSerializationOptions SerializerOptions { get; set; } + public Func ServerCertificateCustomValidationCallback { get; set; } + public Nullable TokenCredentialBackgroundRefreshInterval { get; set; } + public IWebProxy WebProxy { get; set; } + } + public abstract class CosmosDiagnostics + { + protected CosmosDiagnostics(); + public virtual TimeSpan GetClientElapsedTime(); + public abstract IReadOnlyList> GetContactedRegions(); + public virtual int GetFailedRequestCount(); + public virtual Nullable GetStartTimeUtc(); + public abstract override string ToString(); + } + public class CosmosException : Exception + { + public CosmosException(string message, HttpStatusCode statusCode, int subStatusCode, string activityId, double requestCharge); + public virtual string ActivityId { get; } + public virtual CosmosDiagnostics Diagnostics { get; } + public virtual Headers Headers { get; } + public override string Message { get; } + public virtual double RequestCharge { get; } + public virtual string ResponseBody { get; } + public virtual Nullable RetryAfter { get; } + public override string StackTrace { get; } + public virtual HttpStatusCode StatusCode { get; } + public virtual int SubStatusCode { get; } + public override string ToString(); + public virtual bool TryGetHeader(string headerName, out string value); + } + public sealed class CosmosLinqSerializerOptions + { + public CosmosLinqSerializerOptions(); + public CosmosPropertyNamingPolicy PropertyNamingPolicy { get; set; } + } + public class CosmosOperationCanceledException : OperationCanceledException + { + public CosmosOperationCanceledException(OperationCanceledException originalException, CosmosDiagnostics diagnostics); + protected CosmosOperationCanceledException(SerializationInfo info, StreamingContext context); + public override IDictionary Data { get; } + public CosmosDiagnostics Diagnostics { get; } + public override string HelpLink { get; set; } + public override string Message { get; } + public override string Source { get; set; } + public override string StackTrace { get; } + public override Exception GetBaseException(); + public override void GetObjectData(SerializationInfo info, StreamingContext context); + public override string ToString(); + } + public enum CosmosPropertyNamingPolicy + { + CamelCase = 1, + Default = 0, + } + public abstract class CosmosResponseFactory + { + protected CosmosResponseFactory(); + public abstract FeedResponse CreateItemFeedResponse(ResponseMessage responseMessage); + public abstract ItemResponse CreateItemResponse(ResponseMessage responseMessage); + public abstract StoredProcedureExecuteResponse CreateStoredProcedureExecuteResponse(ResponseMessage responseMessage); + } + public sealed class CosmosSerializationOptions + { + public CosmosSerializationOptions(); + public bool IgnoreNullValues { get; set; } + public bool Indented { get; set; } + public CosmosPropertyNamingPolicy PropertyNamingPolicy { get; set; } + } + public abstract class CosmosSerializer + { + protected CosmosSerializer(); + public abstract T FromStream(Stream stream); + public abstract Stream ToStream(T input); + } + public abstract class Database + { + protected Database(); + public abstract CosmosClient Client { get; } + public abstract string Id { get; } + public abstract Task CreateClientEncryptionKeyAsync(ClientEncryptionKeyProperties clientEncryptionKeyProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateContainerAsync(ContainerProperties containerProperties, ThroughputProperties throughputProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateContainerAsync(ContainerProperties containerProperties, Nullable throughput=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateContainerAsync(string id, string partitionKeyPath, Nullable throughput=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateContainerIfNotExistsAsync(ContainerProperties containerProperties, ThroughputProperties throughputProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateContainerIfNotExistsAsync(ContainerProperties containerProperties, Nullable throughput=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateContainerIfNotExistsAsync(string id, string partitionKeyPath, Nullable throughput=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateContainerStreamAsync(ContainerProperties containerProperties, ThroughputProperties throughputProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateContainerStreamAsync(ContainerProperties containerProperties, Nullable throughput=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateUserAsync(string id, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract ContainerBuilder DefineContainer(string name, string partitionKeyPath); + public abstract Task DeleteAsync(RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task DeleteStreamAsync(RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract ClientEncryptionKey GetClientEncryptionKey(string id); + public abstract FeedIterator GetClientEncryptionKeyQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract Container GetContainer(string id); + public abstract FeedIterator GetContainerQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetContainerQueryIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetContainerQueryStreamIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetContainerQueryStreamIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract User GetUser(string id); + public abstract FeedIterator GetUserQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetUserQueryIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract Task ReadAsync(RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadStreamAsync(RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadThroughputAsync(RequestOptions requestOptions, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task> ReadThroughputAsync(CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceThroughputAsync(ThroughputProperties throughputProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceThroughputAsync(int throughput, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task UpsertUserAsync(string id, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + } + public class DatabaseProperties + { + public DatabaseProperties(); + public DatabaseProperties(string id); + public string ETag { get; } + public string Id { get; set; } + public Nullable LastModified { get; } + public string SelfLink { get; } + } + public class DatabaseResponse : Response + { + protected DatabaseResponse(); + public override string ActivityId { get; } + public virtual Database Database { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public override double RequestCharge { get; } + public override DatabaseProperties Resource { get; } + public override HttpStatusCode StatusCode { get; } + public static implicit operator Database (DatabaseResponse response); + } + public enum DataType + { + LineString = 3, + MultiPolygon = 5, + Number = 0, + Point = 2, + Polygon = 4, + String = 1, + } + public class DedicatedGatewayRequestOptions + { + public DedicatedGatewayRequestOptions(); + public Nullable MaxIntegratedCacheStaleness { get; set; } + } + public class EncryptionKeyWrapMetadata : IEquatable + { + public EncryptionKeyWrapMetadata(EncryptionKeyWrapMetadata source); + public EncryptionKeyWrapMetadata(string type, string name, string value, string algorithm); + public string Algorithm { get; } + public string Name { get; } + public string Type { get; } + public string Value { get; } + public bool Equals(EncryptionKeyWrapMetadata other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public sealed class ExcludedPath + { + public ExcludedPath(); + public string Path { get; set; } + } + public abstract class FeedIterator : IDisposable + { + protected FeedIterator(); + public abstract bool HasMoreResults { get; } + public void Dispose(); + protected virtual void Dispose(bool disposing); + public abstract Task ReadNextAsync(CancellationToken cancellationToken=default(CancellationToken)); + } + public abstract class FeedIterator : IDisposable + { + protected FeedIterator(); + public abstract bool HasMoreResults { get; } + public void Dispose(); + protected virtual void Dispose(bool disposing); + public abstract Task> ReadNextAsync(CancellationToken cancellationToken=default(CancellationToken)); + } + public abstract class FeedRange + { + protected FeedRange(); + public static FeedRange FromJsonString(string toStringValue); + public static FeedRange FromPartitionKey(PartitionKey partitionKey); + public abstract string ToJsonString(); + } + public abstract class FeedResponse : IEnumerable, IEnumerable + { + protected FeedResponse(); + public override string ActivityId { get; } + public abstract string ContinuationToken { get; } + public abstract int Count { get; } + public override string ETag { get; } + public abstract string IndexMetrics { get; } + public override double RequestCharge { get; } + public abstract IEnumerator GetEnumerator(); + IEnumerator System.Collections.IEnumerable.GetEnumerator(); + } + public sealed class GeospatialConfig + { + public GeospatialConfig(); + public GeospatialConfig(GeospatialType geospatialType); + public GeospatialType GeospatialType { get; set; } + } + public enum GeospatialType + { + Geography = 0, + Geometry = 1, + } + public class Headers : IEnumerable + { + public Headers(); + public virtual string ActivityId { get; } + public virtual string ContentLength { get; set; } + public virtual string ContentType { get; } + public virtual string ContinuationToken { get; } + public virtual string ETag { get; } + public virtual string this[string headerName] { get; set; } + public virtual string Location { get; } + public virtual double RequestCharge { get; } + public virtual string Session { get; } + public virtual void Add(string headerName, IEnumerable values); + public virtual void Add(string headerName, string value); + public virtual string[] AllKeys(); + public virtual string Get(string headerName); + public virtual IEnumerator GetEnumerator(); + public virtual T GetHeaderValue(string headerName); + public virtual string GetValueOrDefault(string headerName); + public virtual void Remove(string headerName); + public virtual void Set(string headerName, string value); + IEnumerator System.Collections.IEnumerable.GetEnumerator(); + public virtual bool TryGetValue(string headerName, out string value); + } + public sealed class IncludedPath + { + public IncludedPath(); + public string Path { get; set; } + } + public enum IndexingDirective + { + Default = 0, + Exclude = 2, + Include = 1, + } + public enum IndexingMode + { + Consistent = 0, + Lazy = 1, + None = 2, + } + public sealed class IndexingPolicy + { + public IndexingPolicy(); + public bool Automatic { get; set; } + public Collection> CompositeIndexes { get; } + public Collection ExcludedPaths { get; } + public Collection IncludedPaths { get; } + public IndexingMode IndexingMode { get; set; } + public Collection SpatialIndexes { get; } + } + public enum IndexKind + { + Hash = 0, + Range = 1, + Spatial = 2, + } + public class ItemRequestOptions : RequestOptions + { + public ItemRequestOptions(); + public Nullable ConsistencyLevel { get; set; } + public DedicatedGatewayRequestOptions DedicatedGatewayRequestOptions { get; set; } + public Nullable EnableContentResponseOnWrite { get; set; } + public Nullable IndexingDirective { get; set; } + public IEnumerable PostTriggers { get; set; } + public IEnumerable PreTriggers { get; set; } + public string SessionToken { get; set; } + } + public class ItemResponse : Response + { + protected ItemResponse(); + public override string ActivityId { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public override double RequestCharge { get; } + public override T Resource { get; } + public override HttpStatusCode StatusCode { get; } + } + public enum OperationKind + { + Create = 1, + Delete = 3, + Invalid = 0, + Read = 4, + Replace = 2, + } + public struct PartitionKey : IEquatable + { + public static readonly PartitionKey None; + public static readonly PartitionKey Null; + public static readonly string SystemKeyName; + public static readonly string SystemKeyPath; + public PartitionKey(bool partitionKeyValue); + public PartitionKey(double partitionKeyValue); + public PartitionKey(string partitionKeyValue); + public bool Equals(PartitionKey other); + public override bool Equals(object obj); + public override int GetHashCode(); + public static bool operator ==(PartitionKey left, PartitionKey right); + public static bool operator !=(PartitionKey left, PartitionKey right); + public override string ToString(); + } + public sealed class PartitionKeyBuilder + { + public PartitionKeyBuilder(); + public PartitionKeyBuilder Add(bool val); + public PartitionKeyBuilder Add(double val); + public PartitionKeyBuilder Add(string val); + public PartitionKeyBuilder AddNoneType(); + public PartitionKeyBuilder AddNullValue(); + public PartitionKey Build(); + } + public enum PartitionKeyDefinitionVersion + { + V1 = 1, + V2 = 2, + } + public sealed class PatchItemRequestOptions : ItemRequestOptions + { + public PatchItemRequestOptions(); + public string FilterPredicate { get; set; } + } + public abstract class PatchOperation + { + protected PatchOperation(); + public virtual string From { get; set; } + public abstract PatchOperationType OperationType { get; } + public abstract string Path { get; } + public static PatchOperation Add(string path, T value); + public static PatchOperation Increment(string path, double value); + public static PatchOperation Increment(string path, long value); + public static PatchOperation Move(string from, string path); + public static PatchOperation Remove(string path); + public static PatchOperation Replace(string path, T value); + public static PatchOperation Set(string path, T value); + public virtual bool TrySerializeValueParameter(CosmosSerializer cosmosSerializer, out Stream valueParam); + } + public enum PatchOperationType + { + Add = 0, + Increment = 4, + Move = 5, + Remove = 1, + Replace = 2, + Set = 3, + } + public abstract class PatchOperation : PatchOperation + { + protected PatchOperation(); + public abstract T Value { get; } + } + public abstract class Permission + { + protected Permission(); + public abstract string Id { get; } + public abstract Task DeleteAsync(RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadAsync(Nullable tokenExpiryInSeconds=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceAsync(PermissionProperties permissionProperties, Nullable tokenExpiryInSeconds=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + } + public enum PermissionMode : byte + { + All = (byte)2, + Read = (byte)1, + } + public class PermissionProperties + { + public PermissionProperties(string id, PermissionMode permissionMode, Container container, PartitionKey resourcePartitionKey, string itemId); + public PermissionProperties(string id, PermissionMode permissionMode, Container container, Nullable resourcePartitionKey=default(Nullable)); + public string ETag { get; } + public string Id { get; } + public Nullable LastModified { get; } + public PermissionMode PermissionMode { get; } + public Nullable ResourcePartitionKey { get; set; } + public string ResourceUri { get; } + public string SelfLink { get; } + public string Token { get; } + } + public class PermissionResponse : Response + { + protected PermissionResponse(); + public override string ActivityId { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public virtual Permission Permission { get; } + public override double RequestCharge { get; } + public override PermissionProperties Resource { get; } + public override HttpStatusCode StatusCode { get; } + public static implicit operator Permission (PermissionResponse response); + } + public enum PortReuseMode + { + PrivatePortPool = 1, + ReuseUnicastPort = 0, + } + public class QueryDefinition + { + public QueryDefinition(string query); + public string QueryText { get; } + public IReadOnlyList> GetQueryParameters(); + public QueryDefinition WithParameter(string name, object value); + public QueryDefinition WithParameterStream(string name, Stream valueStream); + } + public class QueryRequestOptions : RequestOptions + { + public QueryRequestOptions(); + public Nullable ConsistencyLevel { get; set; } + public DedicatedGatewayRequestOptions DedicatedGatewayRequestOptions { get; set; } + public Nullable EnableLowPrecisionOrderBy { get; set; } + public Nullable EnableScanInQuery { get; set; } + public Nullable MaxBufferedItemCount { get; set; } + public Nullable MaxConcurrency { get; set; } + public Nullable MaxItemCount { get; set; } + public Nullable PartitionKey { get; set; } + public Nullable PopulateIndexMetrics { get; set; } + public Nullable ResponseContinuationTokenLimitInKb { get; set; } + public string SessionToken { get; set; } + } + public class ReadManyRequestOptions : RequestOptions + { + public ReadManyRequestOptions(); + public Nullable ConsistencyLevel { get; set; } + public string SessionToken { get; set; } + } + public static class Regions + { + public const string AustraliaCentral = "Australia Central"; + public const string AustraliaCentral2 = "Australia Central 2"; + public const string AustraliaEast = "Australia East"; + public const string AustraliaSoutheast = "Australia Southeast"; + public const string BrazilSouth = "Brazil South"; + public const string BrazilSoutheast = "Brazil Southeast"; + public const string CanadaCentral = "Canada Central"; + public const string CanadaEast = "Canada East"; + public const string CentralIndia = "Central India"; + public const string CentralUS = "Central US"; + public const string CentralUSEUAP = "Central US EUAP"; + public const string ChinaEast = "China East"; + public const string ChinaEast2 = "China East 2"; + public const string ChinaEast3 = "China East 3"; + public const string ChinaNorth = "China North"; + public const string ChinaNorth2 = "China North 2"; + public const string ChinaNorth3 = "China North 3"; + public const string EastAsia = "East Asia"; + public const string EastUS = "East US"; + public const string EastUS2 = "East US 2"; + public const string EastUS2EUAP = "East US 2 EUAP"; + public const string EastUSSLV = "East US SLV"; + public const string FranceCentral = "France Central"; + public const string FranceSouth = "France South"; + public const string GermanyCentral = "Germany Central"; + public const string GermanyNorth = "Germany North"; + public const string GermanyNortheast = "Germany Northeast"; + public const string GermanyWestCentral = "Germany West Central"; + public const string IsraelCentral = "Israel Central"; + public const string ItalyNorth = "Italy North"; + public const string JapanEast = "Japan East"; + public const string JapanWest = "Japan West"; + public const string JioIndiaCentral = "Jio India Central"; + public const string JioIndiaWest = "Jio India West"; + public const string KoreaCentral = "Korea Central"; + public const string KoreaSouth = "Korea South"; + public const string MalaysiaSouth = "Malaysia South"; + public const string NorthCentralUS = "North Central US"; + public const string NorthEurope = "North Europe"; + public const string NorwayEast = "Norway East"; + public const string NorwayWest = "Norway West"; + public const string PolandCentral = "Poland Central"; + public const string QatarCentral = "Qatar Central"; + public const string SouthAfricaNorth = "South Africa North"; + public const string SouthAfricaWest = "South Africa West"; + public const string SouthCentralUS = "South Central US"; + public const string SoutheastAsia = "Southeast Asia"; + public const string SouthIndia = "South India"; + public const string SwedenCentral = "Sweden Central"; + public const string SwedenSouth = "Sweden South"; + public const string SwitzerlandNorth = "Switzerland North"; + public const string SwitzerlandWest = "Switzerland West"; + public const string UAECentral = "UAE Central"; + public const string UAENorth = "UAE North"; + public const string UKSouth = "UK South"; + public const string UKWest = "UK West"; + public const string USDoDCentral = "USDoD Central"; + public const string USDoDEast = "USDoD East"; + public const string USGovArizona = "USGov Arizona"; + public const string USGovTexas = "USGov Texas"; + public const string USGovVirginia = "USGov Virginia"; + public const string USNatEast = "USNat East"; + public const string USNatWest = "USNat West"; + public const string USSecEast = "USSec East"; + public const string USSecWest = "USSec West"; + public const string WestCentralUS = "West Central US"; + public const string WestEurope = "West Europe"; + public const string WestIndia = "West India"; + public const string WestUS = "West US"; + public const string WestUS2 = "West US 2"; + public const string WestUS3 = "West US 3"; + } + public abstract class RequestHandler + { + protected RequestHandler(); + public RequestHandler InnerHandler { get; set; } + public virtual Task SendAsync(RequestMessage request, CancellationToken cancellationToken); + } + public class RequestMessage : IDisposable + { + public RequestMessage(); + public RequestMessage(HttpMethod method, Uri requestUri); + public virtual Stream Content { get; set; } + public virtual Headers Headers { get; } + public virtual HttpMethod Method { get; } + public virtual Dictionary Properties { get; } + public virtual Uri RequestUri { get; } + public void Dispose(); + protected virtual void Dispose(bool disposing); + } + public class RequestOptions + { + public RequestOptions(); + public Action AddRequestHeaders { get; set; } + public string IfMatchEtag { get; set; } + public string IfNoneMatchEtag { get; set; } + public IReadOnlyDictionary Properties { get; set; } + public RequestOptions ShallowCopy(); + } + public class ResponseMessage : IDisposable + { + public ResponseMessage(); + public ResponseMessage(HttpStatusCode statusCode, RequestMessage requestMessage=null, string errorMessage=null); + public virtual Stream Content { get; set; } + public virtual string ContinuationToken { get; } + public virtual CosmosDiagnostics Diagnostics { get; set; } + public virtual string ErrorMessage { get; } + public virtual Headers Headers { get; } + public string IndexMetrics { get; } + public virtual bool IsSuccessStatusCode { get; } + public virtual RequestMessage RequestMessage { get; } + public virtual HttpStatusCode StatusCode { get; } + public void Dispose(); + protected virtual void Dispose(bool disposing); + public virtual ResponseMessage EnsureSuccessStatusCode(); + } + public abstract class Response + { + protected Response(); + public abstract string ActivityId { get; } + public abstract CosmosDiagnostics Diagnostics { get; } + public abstract string ETag { get; } + public abstract Headers Headers { get; } + public abstract double RequestCharge { get; } + public abstract T Resource { get; } + public abstract HttpStatusCode StatusCode { get; } + public static implicit operator T (Response response); + } + public sealed class SpatialPath + { + public SpatialPath(); + public BoundingBoxProperties BoundingBox { get; set; } + public string Path { get; set; } + public Collection SpatialTypes { get; } + } + public enum SpatialType + { + LineString = 1, + MultiPolygon = 3, + Point = 0, + Polygon = 2, + } + public class ThroughputProperties + { + public Nullable AutoscaleMaxThroughput { get; } + public string ETag { get; } + public Nullable LastModified { get; } + public string SelfLink { get; } + public Nullable Throughput { get; } + public static ThroughputProperties CreateAutoscaleThroughput(int autoscaleMaxThroughput); + public static ThroughputProperties CreateManualThroughput(int throughput); + } + public class ThroughputResponse : Response + { + protected ThroughputResponse(); + public override string ActivityId { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public Nullable IsReplacePending { get; } + public Nullable MinThroughput { get; } + public override double RequestCharge { get; } + public override ThroughputProperties Resource { get; } + public override HttpStatusCode StatusCode { get; } + public static implicit operator ThroughputProperties (ThroughputResponse response); + } + public abstract class TransactionalBatch + { + protected TransactionalBatch(); + public abstract TransactionalBatch CreateItemStream(Stream streamPayload, TransactionalBatchItemRequestOptions requestOptions=null); + public abstract TransactionalBatch CreateItem(T item, TransactionalBatchItemRequestOptions requestOptions=null); + public abstract TransactionalBatch DeleteItem(string id, TransactionalBatchItemRequestOptions requestOptions=null); + public abstract Task ExecuteAsync(TransactionalBatchRequestOptions requestOptions, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ExecuteAsync(CancellationToken cancellationToken=default(CancellationToken)); + public abstract TransactionalBatch PatchItem(string id, IReadOnlyList patchOperations, TransactionalBatchPatchItemRequestOptions requestOptions=null); + public abstract TransactionalBatch ReadItem(string id, TransactionalBatchItemRequestOptions requestOptions=null); + public abstract TransactionalBatch ReplaceItemStream(string id, Stream streamPayload, TransactionalBatchItemRequestOptions requestOptions=null); + public abstract TransactionalBatch ReplaceItem(string id, T item, TransactionalBatchItemRequestOptions requestOptions=null); + public abstract TransactionalBatch UpsertItemStream(Stream streamPayload, TransactionalBatchItemRequestOptions requestOptions=null); + public abstract TransactionalBatch UpsertItem(T item, TransactionalBatchItemRequestOptions requestOptions=null); + } + public class TransactionalBatchItemRequestOptions : RequestOptions + { + public TransactionalBatchItemRequestOptions(); + public Nullable EnableContentResponseOnWrite { get; set; } + public Nullable IndexingDirective { get; set; } + } + public class TransactionalBatchOperationResult + { + protected TransactionalBatchOperationResult(); + public virtual string ETag { get; } + public virtual bool IsSuccessStatusCode { get; } + public virtual Stream ResourceStream { get; } + public virtual TimeSpan RetryAfter { get; } + public virtual HttpStatusCode StatusCode { get; } + } + public class TransactionalBatchOperationResult : TransactionalBatchOperationResult + { + protected TransactionalBatchOperationResult(); + public virtual T Resource { get; set; } + } + public class TransactionalBatchPatchItemRequestOptions : TransactionalBatchItemRequestOptions + { + public TransactionalBatchPatchItemRequestOptions(); + public string FilterPredicate { get; set; } + } + public class TransactionalBatchRequestOptions : RequestOptions + { + public TransactionalBatchRequestOptions(); + public Nullable ConsistencyLevel { get; set; } + public string SessionToken { get; set; } + } + public class TransactionalBatchResponse : IDisposable, IEnumerable, IEnumerable, IReadOnlyCollection, IReadOnlyList + { + protected TransactionalBatchResponse(); + public virtual string ActivityId { get; } + public virtual int Count { get; } + public virtual CosmosDiagnostics Diagnostics { get; } + public virtual string ErrorMessage { get; } + public virtual Headers Headers { get; } + public virtual bool IsSuccessStatusCode { get; } + public virtual TransactionalBatchOperationResult this[int index] { get; } + public virtual double RequestCharge { get; } + public virtual Nullable RetryAfter { get; } + public virtual HttpStatusCode StatusCode { get; } + public void Dispose(); + protected virtual void Dispose(bool disposing); + public virtual IEnumerator GetEnumerator(); + public virtual TransactionalBatchOperationResult GetOperationResultAtIndex(int index); + IEnumerator System.Collections.IEnumerable.GetEnumerator(); + } + public class UniqueKey + { + public UniqueKey(); + public Collection Paths { get; } + } + public sealed class UniqueKeyPolicy + { + public UniqueKeyPolicy(); + public Collection UniqueKeys { get; } + } + public abstract class User + { + protected User(); + public abstract string Id { get; } + public abstract Task CreatePermissionAsync(PermissionProperties permissionProperties, Nullable tokenExpiryInSeconds=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task DeleteAsync(RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Permission GetPermission(string id); + public abstract FeedIterator GetPermissionQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetPermissionQueryIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract Task ReadAsync(RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceAsync(UserProperties userProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task UpsertPermissionAsync(PermissionProperties permissionProperties, Nullable tokenExpiryInSeconds=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + } + public class UserProperties + { + protected UserProperties(); + public UserProperties(string id); + public string ETag { get; } + public string Id { get; set; } + public Nullable LastModified { get; } + public string SelfLink { get; } + } + public class UserResponse : Response + { + protected UserResponse(); + public override string ActivityId { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public override double RequestCharge { get; } + public override UserProperties Resource { get; } + public override HttpStatusCode StatusCode { get; } + public virtual User User { get; } + public static implicit operator User (UserResponse response); + } +} +namespace Microsoft.Azure.Cosmos.Fluent +{ + public sealed class ClientEncryptionPolicyDefinition + { + public ContainerBuilder Attach(); + public ClientEncryptionPolicyDefinition WithIncludedPath(ClientEncryptionIncludedPath path); + } + public class CompositeIndexDefinition + { + public T Attach(); + public CompositeIndexDefinition Path(string path); + public CompositeIndexDefinition Path(string path, CompositePathSortOrder sortOrder); + } + public class ConflictResolutionDefinition + { + public ContainerBuilder Attach(); + public ConflictResolutionDefinition WithCustomStoredProcedureResolution(string conflictResolutionProcedure); + public ConflictResolutionDefinition WithLastWriterWinsResolution(string conflictResolutionPath); + } + public class ContainerBuilder : ContainerDefinition + { + protected ContainerBuilder(); + public ContainerBuilder(Database database, string name, string partitionKeyPath); + public new ContainerProperties Build(); + public Task CreateAsync(ThroughputProperties throughputProperties, CancellationToken cancellationToken=default(CancellationToken)); + public Task CreateAsync(Nullable throughput=default(Nullable), CancellationToken cancellationToken=default(CancellationToken)); + public Task CreateIfNotExistsAsync(ThroughputProperties throughputProperties, CancellationToken cancellationToken=default(CancellationToken)); + public Task CreateIfNotExistsAsync(Nullable throughput=default(Nullable), CancellationToken cancellationToken=default(CancellationToken)); + public ClientEncryptionPolicyDefinition WithClientEncryptionPolicy(); + public ClientEncryptionPolicyDefinition WithClientEncryptionPolicy(int policyFormatVersion); + public ConflictResolutionDefinition WithConflictResolution(); + public UniqueKeyDefinition WithUniqueKey(); + } + public abstract class ContainerDefinition where T : ContainerDefinition + { + public ContainerDefinition(); + public ContainerProperties Build(); + public T WithDefaultTimeToLive(int defaultTtlInSeconds); + public T WithDefaultTimeToLive(TimeSpan defaultTtlTimeSpan); + public IndexingPolicyDefinition WithIndexingPolicy(); + public T WithPartitionKeyDefinitionVersion(PartitionKeyDefinitionVersion partitionKeyDefinitionVersion); + public T WithTimeToLivePropertyPath(string propertyPath); + } + public class CosmosClientBuilder + { + public CosmosClientBuilder(string connectionString); + public CosmosClientBuilder(string accountEndpoint, AzureKeyCredential authKeyOrResourceTokenCredential); + public CosmosClientBuilder(string accountEndpoint, TokenCredential tokenCredential); + public CosmosClientBuilder(string accountEndpoint, string authKeyOrResourceToken); + public CosmosClientBuilder AddCustomHandlers(params RequestHandler[] customHandlers); + public CosmosClient Build(); + public Task BuildAndInitializeAsync(IReadOnlyList> containers, CancellationToken cancellationToken=default(CancellationToken)); + public CosmosClientBuilder WithApplicationName(string applicationName); + public CosmosClientBuilder WithApplicationPreferredRegions(IReadOnlyList applicationPreferredRegions); + public CosmosClientBuilder WithApplicationRegion(string applicationRegion); + public CosmosClientBuilder WithBulkExecution(bool enabled); + public CosmosClientBuilder WithConnectionModeDirect(); + public CosmosClientBuilder WithConnectionModeDirect(Nullable idleTcpConnectionTimeout=default(Nullable), Nullable openTcpConnectionTimeout=default(Nullable), Nullable maxRequestsPerTcpConnection=default(Nullable), Nullable maxTcpConnectionsPerEndpoint=default(Nullable), Nullable portReuseMode=default(Nullable), Nullable enableTcpConnectionEndpointRediscovery=default(Nullable)); + public CosmosClientBuilder WithConnectionModeGateway(Nullable maxConnectionLimit=default(Nullable), IWebProxy webProxy=null); + public CosmosClientBuilder WithConsistencyLevel(ConsistencyLevel consistencyLevel); + public CosmosClientBuilder WithContentResponseOnWrite(bool contentResponseOnWrite); + public CosmosClientBuilder WithCustomSerializer(CosmosSerializer cosmosJsonSerializer); + public CosmosClientBuilder WithHttpClientFactory(Func httpClientFactory); + public CosmosClientBuilder WithLimitToEndpoint(bool limitToEndpoint); + public CosmosClientBuilder WithRequestTimeout(TimeSpan requestTimeout); + public CosmosClientBuilder WithSerializerOptions(CosmosSerializationOptions cosmosSerializerOptions); + public CosmosClientBuilder WithThrottlingRetryOptions(TimeSpan maxRetryWaitTimeOnThrottledRequests, int maxRetryAttemptsOnThrottledRequests); + } + public class IndexingPolicyDefinition + { + public IndexingPolicyDefinition(); + public T Attach(); + public IndexingPolicyDefinition WithAutomaticIndexing(bool enabled); + public CompositeIndexDefinition> WithCompositeIndex(); + public PathsDefinition> WithExcludedPaths(); + public PathsDefinition> WithIncludedPaths(); + public IndexingPolicyDefinition WithIndexingMode(IndexingMode indexingMode); + public SpatialIndexDefinition> WithSpatialIndex(); + } + public class PathsDefinition + { + public T Attach(); + public PathsDefinition Path(string path); + } + public class SpatialIndexDefinition + { + public T Attach(); + public SpatialIndexDefinition Path(string path); + public SpatialIndexDefinition Path(string path, params SpatialType[] spatialTypes); + } + public class UniqueKeyDefinition + { + public ContainerBuilder Attach(); + public UniqueKeyDefinition Path(string path); + } +} +namespace Microsoft.Azure.Cosmos.Linq +{ + public static class CosmosLinq + { + public static object InvokeUserDefinedFunction(string udfName, params object[] arguments); + } + public static class CosmosLinqExtensions + { + public static Task> AverageAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> AverageAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> AverageAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> AverageAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> AverageAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> AverageAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> AverageAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> AverageAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> AverageAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> AverageAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> CountAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static bool IsArray(this object obj); + public static bool IsBool(this object obj); + public static bool IsDefined(this object obj); + public static bool IsNull(this object obj); + public static bool IsNumber(this object obj); + public static bool IsObject(this object obj); + public static bool IsPrimitive(this object obj); + public static bool IsString(this object obj); + public static Task> MaxAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> MinAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> SumAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> SumAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> SumAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> SumAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> SumAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> SumAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> SumAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> SumAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> SumAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> SumAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static FeedIterator ToFeedIterator(this IQueryable query); + public static QueryDefinition ToQueryDefinition(this IQueryable query); + public static FeedIterator ToStreamIterator(this IQueryable query); + } +} +namespace Microsoft.Azure.Cosmos.Scripts +{ + public abstract class Scripts + { + protected Scripts(); + public abstract Task CreateStoredProcedureAsync(StoredProcedureProperties storedProcedureProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateTriggerAsync(TriggerProperties triggerProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateUserDefinedFunctionAsync(UserDefinedFunctionProperties userDefinedFunctionProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task DeleteStoredProcedureAsync(string id, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task DeleteTriggerAsync(string id, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task DeleteUserDefinedFunctionAsync(string id, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task> ExecuteStoredProcedureAsync(string storedProcedureId, PartitionKey partitionKey, dynamic parameters, StoredProcedureRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ExecuteStoredProcedureStreamAsync(string storedProcedureId, PartitionKey partitionKey, dynamic parameters, StoredProcedureRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ExecuteStoredProcedureStreamAsync(string storedProcedureId, Stream streamPayload, PartitionKey partitionKey, StoredProcedureRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract FeedIterator GetStoredProcedureQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetStoredProcedureQueryIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetStoredProcedureQueryStreamIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetStoredProcedureQueryStreamIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetTriggerQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetTriggerQueryIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetTriggerQueryStreamIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetTriggerQueryStreamIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetUserDefinedFunctionQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetUserDefinedFunctionQueryIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetUserDefinedFunctionQueryStreamIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetUserDefinedFunctionQueryStreamIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract Task ReadStoredProcedureAsync(string id, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadTriggerAsync(string id, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadUserDefinedFunctionAsync(string id, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceStoredProcedureAsync(StoredProcedureProperties storedProcedureProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceTriggerAsync(TriggerProperties triggerProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceUserDefinedFunctionAsync(UserDefinedFunctionProperties userDefinedFunctionProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + } + public class StoredProcedureExecuteResponse : Response + { + protected StoredProcedureExecuteResponse(); + public override string ActivityId { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public override double RequestCharge { get; } + public override T Resource { get; } + public virtual string ScriptLog { get; } + public virtual string SessionToken { get; } + public override HttpStatusCode StatusCode { get; } + } + public class StoredProcedureProperties + { + public StoredProcedureProperties(); + public StoredProcedureProperties(string id, string body); + public string Body { get; set; } + public string ETag { get; } + public string Id { get; set; } + public Nullable LastModified { get; } + public string SelfLink { get; } + } + public class StoredProcedureRequestOptions : RequestOptions + { + public StoredProcedureRequestOptions(); + public Nullable ConsistencyLevel { get; set; } + public bool EnableScriptLogging { get; set; } + public string SessionToken { get; set; } + } + public class StoredProcedureResponse : Response + { + protected StoredProcedureResponse(); + public override string ActivityId { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public override double RequestCharge { get; } + public override StoredProcedureProperties Resource { get; } + public virtual string SessionToken { get; } + public override HttpStatusCode StatusCode { get; } + public static implicit operator StoredProcedureProperties (StoredProcedureResponse response); + } + public enum TriggerOperation : short + { + All = (short)0, + Create = (short)1, + Delete = (short)3, + Replace = (short)4, + Update = (short)2, + } + public class TriggerProperties + { + public TriggerProperties(); + public string Body { get; set; } + public string ETag { get; } + public string Id { get; set; } + public string SelfLink { get; } + public TriggerOperation TriggerOperation { get; set; } + public TriggerType TriggerType { get; set; } + } + public class TriggerResponse : Response + { + protected TriggerResponse(); + public override string ActivityId { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public override double RequestCharge { get; } + public override TriggerProperties Resource { get; } + public override HttpStatusCode StatusCode { get; } + public static implicit operator TriggerProperties (TriggerResponse response); + } + public enum TriggerType : byte + { + Post = (byte)1, + Pre = (byte)0, + } + public class UserDefinedFunctionProperties + { + public UserDefinedFunctionProperties(); + public string Body { get; set; } + public string ETag { get; } + public string Id { get; set; } + public string SelfLink { get; } + } + public class UserDefinedFunctionResponse : Response + { + protected UserDefinedFunctionResponse(); + public override string ActivityId { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public override double RequestCharge { get; } + public override UserDefinedFunctionProperties Resource { get; } + public override HttpStatusCode StatusCode { get; } + public static implicit operator UserDefinedFunctionProperties (UserDefinedFunctionResponse response); + } +} +namespace Microsoft.Azure.Cosmos.Spatial +{ + public sealed class BoundingBox : IEquatable + { + public BoundingBox(Position min, Position max); + public Position Max { get; } + public Position Min { get; } + public bool Equals(BoundingBox other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public abstract class Crs + { + protected Crs(CrsType type); + public static Crs Default { get; } + public CrsType Type { get; } + public static Crs Unspecified { get; } + public static LinkedCrs Linked(string href); + public static LinkedCrs Linked(string href, string type); + public static NamedCrs Named(string name); + } + public enum CrsType + { + Linked = 1, + Named = 0, + Unspecified = 2, + } + public abstract class Geometry + { + protected Geometry(GeometryType type, GeometryParams geometryParams); + public IDictionary AdditionalProperties { get; } + public BoundingBox BoundingBox { get; } + public Crs Crs { get; } + public GeometryType Type { get; } + public double Distance(Geometry to); + public override bool Equals(object obj); + public override int GetHashCode(); + public bool Intersects(Geometry geometry2); + public bool IsValid(); + public GeometryValidationResult IsValidDetailed(); + public bool Within(Geometry outer); + } + public class GeometryParams + { + public GeometryParams(); + public IDictionary AdditionalProperties { get; set; } + public BoundingBox BoundingBox { get; set; } + public Crs Crs { get; set; } + } + public enum GeometryShape + { + GeometryCollection = 6, + LineString = 2, + MultiLineString = 3, + MultiPoint = 1, + MultiPolygon = 5, + Point = 0, + Polygon = 4, + } + public enum GeometryType + { + GeometryCollection = 6, + LineString = 2, + MultiLineString = 3, + MultiPoint = 1, + MultiPolygon = 5, + Point = 0, + Polygon = 4, + } + public class GeometryValidationResult + { + public GeometryValidationResult(); + public bool IsValid { get; } + public string Reason { get; } + } + public sealed class LinearRing : IEquatable + { + public LinearRing(IList coordinates); + public ReadOnlyCollection Positions { get; } + public bool Equals(LinearRing other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public sealed class LineString : Geometry, IEquatable + { + public LineString(IList coordinates); + public LineString(IList coordinates, GeometryParams geometryParams); + public ReadOnlyCollection Positions { get; } + public bool Equals(LineString other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public sealed class LinkedCrs : Crs, IEquatable + { + public string Href { get; } + public string HrefType { get; } + public bool Equals(LinkedCrs other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public sealed class MultiPolygon : Geometry, IEquatable + { + public MultiPolygon(IList polygons); + public MultiPolygon(IList polygons, GeometryParams geometryParams); + public ReadOnlyCollection Polygons { get; } + public bool Equals(MultiPolygon other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public sealed class NamedCrs : Crs, IEquatable + { + public string Name { get; } + public bool Equals(NamedCrs other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public sealed class Point : Geometry, IEquatable + { + public Point(Position position); + public Point(Position position, GeometryParams geometryParams); + public Point(double longitude, double latitude); + public Position Position { get; } + public bool Equals(Point other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public sealed class Polygon : Geometry, IEquatable + { + public Polygon(IList rings); + public Polygon(IList rings, GeometryParams geometryParams); + public Polygon(IList externalRingPositions); + public ReadOnlyCollection Rings { get; } + public bool Equals(Polygon other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public sealed class PolygonCoordinates : IEquatable + { + public PolygonCoordinates(IList rings); + public ReadOnlyCollection Rings { get; } + public bool Equals(PolygonCoordinates other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public sealed class Position : IEquatable + { + public Position(IList coordinates); + public Position(double longitude, double latitude); + public Position(double longitude, double latitude, Nullable altitude); + public Nullable Altitude { get; } + public ReadOnlyCollection Coordinates { get; } + public double Latitude { get; } + public double Longitude { get; } + public bool Equals(Position other); + public override bool Equals(object obj); + public override int GetHashCode(); + } +} diff --git a/Microsoft.Azure.Cosmos/contracts/API_3.36.0-preview.txt b/Microsoft.Azure.Cosmos/contracts/API_3.36.0-preview.txt new file mode 100644 index 0000000000..e94727e915 --- /dev/null +++ b/Microsoft.Azure.Cosmos/contracts/API_3.36.0-preview.txt @@ -0,0 +1,1610 @@ +namespace Microsoft.Azure.Cosmos +{ + public class AccountConsistency + { + public AccountConsistency(); + public ConsistencyLevel DefaultConsistencyLevel { get; } + public int MaxStalenessIntervalInSeconds { get; } + public int MaxStalenessPrefix { get; } + } + public class AccountProperties + { + public AccountConsistency Consistency { get; } + public string ETag { get; } + public string Id { get; } + public IEnumerable ReadableRegions { get; } + public IEnumerable WritableRegions { get; } + } + public class AccountRegion + { + public AccountRegion(); + public string Endpoint { get; } + public string Name { get; } + } + public sealed class BoundingBoxProperties + { + public BoundingBoxProperties(); + public double Xmax { get; set; } + public double Xmin { get; set; } + public double Ymax { get; set; } + public double Ymin { get; set; } + } + public abstract class ChangeFeedEstimator + { + protected ChangeFeedEstimator(); + public abstract FeedIterator GetCurrentStateIterator(ChangeFeedEstimatorRequestOptions changeFeedEstimatorRequestOptions=null); + } + public sealed class ChangeFeedEstimatorRequestOptions + { + public ChangeFeedEstimatorRequestOptions(); + public Nullable MaxItemCount { get; set; } + } + public class ChangeFeedItemChange + { + public ChangeFeedItemChange(); + public T Current { get; set; } + public ChangeFeedMetadata Metadata { get; set; } + public T Previous { get; set; } + } + public class ChangeFeedMetadata + { + public ChangeFeedMetadata(DateTime conflictResolutionTimestamp, long lsn, ChangeFeedOperationType operationType, long previousLsn); + public DateTime ConflictResolutionTimestamp { get; } + public bool IsTimeToLiveExpired { get; } + public long Lsn { get; } + public ChangeFeedOperationType OperationType { get; } + public long PreviousLsn { get; } + } + public abstract class ChangeFeedMode + { + public static ChangeFeedMode AllVersionsAndDeletes { get; } + public static ChangeFeedMode Incremental { get; } + public static ChangeFeedMode LatestVersion { get; } + } + public enum ChangeFeedOperationType + { + Create = 0, + Delete = 2, + Replace = 1, + } + public sealed class ChangeFeedPolicy + { + public ChangeFeedPolicy(); + public static TimeSpan FullFidelityNoRetention { get; } + public TimeSpan FullFidelityRetention { get; set; } + } + public abstract class ChangeFeedProcessor + { + protected ChangeFeedProcessor(); + public abstract Task StartAsync(); + public abstract Task StopAsync(); + } + public class ChangeFeedProcessorBuilder + { + public ChangeFeedProcessor Build(); + public ChangeFeedProcessorBuilder WithErrorNotification(Container.ChangeFeedMonitorErrorDelegate errorDelegate); + public ChangeFeedProcessorBuilder WithInstanceName(string instanceName); + public ChangeFeedProcessorBuilder WithLeaseAcquireNotification(Container.ChangeFeedMonitorLeaseAcquireDelegate acquireDelegate); + public ChangeFeedProcessorBuilder WithLeaseConfiguration(Nullable acquireInterval=default(Nullable), Nullable expirationInterval=default(Nullable), Nullable renewInterval=default(Nullable)); + public ChangeFeedProcessorBuilder WithLeaseContainer(Container leaseContainer); + public ChangeFeedProcessorBuilder WithLeaseReleaseNotification(Container.ChangeFeedMonitorLeaseReleaseDelegate releaseDelegate); + public ChangeFeedProcessorBuilder WithMaxItems(int maxItemCount); + public ChangeFeedProcessorBuilder WithPollInterval(TimeSpan pollInterval); + public ChangeFeedProcessorBuilder WithStartTime(DateTime startTime); + } + public abstract class ChangeFeedProcessorContext + { + protected ChangeFeedProcessorContext(); + public abstract CosmosDiagnostics Diagnostics { get; } + public abstract Headers Headers { get; } + public abstract string LeaseToken { get; } + } + public sealed class ChangeFeedProcessorState + { + public ChangeFeedProcessorState(string leaseToken, long estimatedLag, string instanceName); + public long EstimatedLag { get; } + public string InstanceName { get; } + public string LeaseToken { get; } + } + public class ChangeFeedProcessorUserException : Exception + { + public ChangeFeedProcessorUserException(Exception originalException, ChangeFeedProcessorContext context); + protected ChangeFeedProcessorUserException(SerializationInfo info, StreamingContext context); + public ChangeFeedProcessorContext ChangeFeedProcessorContext { get; } + public override void GetObjectData(SerializationInfo info, StreamingContext context); + } + public sealed class ChangeFeedRequestOptions : RequestOptions + { + public ChangeFeedRequestOptions(); + public new string IfMatchEtag { get; set; } + public new string IfNoneMatchEtag { get; set; } + public Nullable PageSizeHint { get; set; } + } + public abstract class ChangeFeedStartFrom + { + public static ChangeFeedStartFrom Beginning(); + public static ChangeFeedStartFrom Beginning(FeedRange feedRange); + public static ChangeFeedStartFrom ContinuationToken(string continuationToken); + public static ChangeFeedStartFrom Now(); + public static ChangeFeedStartFrom Now(FeedRange feedRange); + public static ChangeFeedStartFrom Time(DateTime dateTimeUtc); + public static ChangeFeedStartFrom Time(DateTime dateTimeUtc, FeedRange feedRange); + } + public sealed class ClientEncryptionIncludedPath + { + public ClientEncryptionIncludedPath(); + public string ClientEncryptionKeyId { get; set; } + public string EncryptionAlgorithm { get; set; } + public string EncryptionType { get; set; } + public string Path { get; set; } + } + public abstract class ClientEncryptionKey + { + protected ClientEncryptionKey(); + public abstract string Id { get; } + public abstract Task ReadAsync(RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceAsync(ClientEncryptionKeyProperties clientEncryptionKeyProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + } + public class ClientEncryptionKeyProperties : IEquatable + { + protected ClientEncryptionKeyProperties(); + public ClientEncryptionKeyProperties(string id, string encryptionAlgorithm, byte[] wrappedDataEncryptionKey, EncryptionKeyWrapMetadata encryptionKeyWrapMetadata); + public Nullable CreatedTime { get; } + public string EncryptionAlgorithm { get; } + public EncryptionKeyWrapMetadata EncryptionKeyWrapMetadata { get; } + public string ETag { get; } + public string Id { get; } + public Nullable LastModified { get; } + public virtual string SelfLink { get; } + public byte[] WrappedDataEncryptionKey { get; } + public bool Equals(ClientEncryptionKeyProperties other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public class ClientEncryptionKeyResponse : Response + { + protected ClientEncryptionKeyResponse(); + public override string ActivityId { get; } + public virtual ClientEncryptionKey ClientEncryptionKey { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public override double RequestCharge { get; } + public override ClientEncryptionKeyProperties Resource { get; } + public override HttpStatusCode StatusCode { get; } + public static implicit operator ClientEncryptionKey (ClientEncryptionKeyResponse response); + } + public sealed class ClientEncryptionPolicy + { + public ClientEncryptionPolicy(IEnumerable includedPaths); + public ClientEncryptionPolicy(IEnumerable includedPaths, int policyFormatVersion); + public IEnumerable IncludedPaths { get; } + public int PolicyFormatVersion { get; } + } + public sealed class CompositePath + { + public CompositePath(); + public CompositePathSortOrder Order { get; set; } + public string Path { get; set; } + } + public enum CompositePathSortOrder + { + Ascending = 0, + Descending = 1, + } + public sealed class ComputedProperty + { + public ComputedProperty(); + public string Name { get; set; } + public string Query { get; set; } + } + public class ConflictProperties + { + public ConflictProperties(); + public string Id { get; } + public OperationKind OperationKind { get; } + public string SelfLink { get; } + } + public enum ConflictResolutionMode + { + Custom = 1, + LastWriterWins = 0, + } + public class ConflictResolutionPolicy + { + public ConflictResolutionPolicy(); + public ConflictResolutionMode Mode { get; set; } + public string ResolutionPath { get; set; } + public string ResolutionProcedure { get; set; } + } + public abstract class Conflicts + { + protected Conflicts(); + public abstract Task DeleteAsync(ConflictProperties conflict, PartitionKey partitionKey, CancellationToken cancellationToken=default(CancellationToken)); + public abstract FeedIterator GetConflictQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetConflictQueryIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetConflictQueryStreamIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetConflictQueryStreamIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract T ReadConflictContent(ConflictProperties conflict); + public abstract Task> ReadCurrentAsync(ConflictProperties conflict, PartitionKey partitionKey, CancellationToken cancellationToken=default(CancellationToken)); + } + public enum ConnectionMode + { + Direct = 1, + Gateway = 0, + } + public enum ConsistencyLevel + { + BoundedStaleness = 1, + ConsistentPrefix = 4, + Eventual = 3, + Session = 2, + Strong = 0, + } + public abstract class Container + { + protected Container(); + public abstract Conflicts Conflicts { get; } + public abstract Database Database { get; } + public abstract string Id { get; } + public abstract Scripts Scripts { get; } + public abstract Task> CreateItemAsync(T item, Nullable partitionKey=default(Nullable), ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateItemStreamAsync(Stream streamPayload, PartitionKey partitionKey, ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract TransactionalBatch CreateTransactionalBatch(PartitionKey partitionKey); + public abstract Task DeleteAllItemsByPartitionKeyStreamAsync(PartitionKey partitionKey, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task DeleteContainerAsync(ContainerRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task DeleteContainerStreamAsync(ContainerRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task> DeleteItemAsync(string id, PartitionKey partitionKey, ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task DeleteItemStreamAsync(string id, PartitionKey partitionKey, ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract ChangeFeedEstimator GetChangeFeedEstimator(string processorName, Container leaseContainer); + public abstract ChangeFeedProcessorBuilder GetChangeFeedEstimatorBuilder(string processorName, Container.ChangesEstimationHandler estimationDelegate, Nullable estimationPeriod=default(Nullable)); + public abstract FeedIterator GetChangeFeedIterator(ChangeFeedStartFrom changeFeedStartFrom, ChangeFeedMode changeFeedMode, ChangeFeedRequestOptions changeFeedRequestOptions=null); + public abstract ChangeFeedProcessorBuilder GetChangeFeedProcessorBuilder(string processorName, Container.ChangeFeedStreamHandler onChangesDelegate); + public abstract ChangeFeedProcessorBuilder GetChangeFeedProcessorBuilderWithManualCheckpoint(string processorName, Container.ChangeFeedStreamHandlerWithManualCheckpoint onChangesDelegate); + public abstract ChangeFeedProcessorBuilder GetChangeFeedProcessorBuilderWithManualCheckpoint(string processorName, Container.ChangeFeedHandlerWithManualCheckpoint onChangesDelegate); + public abstract ChangeFeedProcessorBuilder GetChangeFeedProcessorBuilder(string processorName, Container.ChangeFeedHandler onChangesDelegate); + public abstract ChangeFeedProcessorBuilder GetChangeFeedProcessorBuilder(string processorName, Container.ChangesHandler onChangesDelegate); + public abstract FeedIterator GetChangeFeedStreamIterator(ChangeFeedStartFrom changeFeedStartFrom, ChangeFeedMode changeFeedMode, ChangeFeedRequestOptions changeFeedRequestOptions=null); + public abstract Task> GetFeedRangesAsync(CancellationToken cancellationToken=default(CancellationToken)); + public abstract IOrderedQueryable GetItemLinqQueryable(bool allowSynchronousQueryExecution=false, string continuationToken=null, QueryRequestOptions requestOptions=null, CosmosLinqSerializerOptions linqSerializerOptions=null); + public abstract FeedIterator GetItemQueryIterator(FeedRange feedRange, QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetItemQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetItemQueryIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetItemQueryStreamIterator(FeedRange feedRange, QueryDefinition queryDefinition, string continuationToken, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetItemQueryStreamIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetItemQueryStreamIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract Task> GetPartitionKeyRangesAsync(FeedRange feedRange, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task> PatchItemAsync(string id, PartitionKey partitionKey, IReadOnlyList patchOperations, PatchItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task PatchItemStreamAsync(string id, PartitionKey partitionKey, IReadOnlyList patchOperations, PatchItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadContainerAsync(ContainerRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadContainerStreamAsync(ContainerRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task> ReadItemAsync(string id, PartitionKey partitionKey, ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadItemStreamAsync(string id, PartitionKey partitionKey, ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task> ReadManyItemsAsync(IReadOnlyList> items, ReadManyRequestOptions readManyRequestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadManyItemsStreamAsync(IReadOnlyList> items, ReadManyRequestOptions readManyRequestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadThroughputAsync(RequestOptions requestOptions, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task> ReadThroughputAsync(CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceContainerAsync(ContainerProperties containerProperties, ContainerRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceContainerStreamAsync(ContainerProperties containerProperties, ContainerRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task> ReplaceItemAsync(T item, string id, Nullable partitionKey=default(Nullable), ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceItemStreamAsync(Stream streamPayload, string id, PartitionKey partitionKey, ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceThroughputAsync(ThroughputProperties throughputProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceThroughputAsync(int throughput, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task> UpsertItemAsync(T item, Nullable partitionKey=default(Nullable), ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task UpsertItemStreamAsync(Stream streamPayload, PartitionKey partitionKey, ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public delegate Task ChangeFeedHandlerWithManualCheckpoint(ChangeFeedProcessorContext context, IReadOnlyCollection changes, Func checkpointAsync, CancellationToken cancellationToken); + public delegate Task ChangeFeedHandler(ChangeFeedProcessorContext context, IReadOnlyCollection changes, CancellationToken cancellationToken); + public delegate Task ChangeFeedMonitorErrorDelegate(string leaseToken, Exception exception); + public delegate Task ChangeFeedMonitorLeaseAcquireDelegate(string leaseToken); + public delegate Task ChangeFeedMonitorLeaseReleaseDelegate(string leaseToken); + public delegate Task ChangeFeedStreamHandler(ChangeFeedProcessorContext context, Stream changes, CancellationToken cancellationToken); + public delegate Task ChangeFeedStreamHandlerWithManualCheckpoint(ChangeFeedProcessorContext context, Stream changes, Func checkpointAsync, CancellationToken cancellationToken); + public delegate Task ChangesEstimationHandler(long estimatedPendingChanges, CancellationToken cancellationToken); + public delegate Task ChangesHandler(IReadOnlyCollection changes, CancellationToken cancellationToken); + } + public class ContainerProperties + { + public ContainerProperties(); + public ContainerProperties(string id, IReadOnlyList partitionKeyPaths); + public ContainerProperties(string id, string partitionKeyPath); + public Nullable AnalyticalStoreTimeToLiveInSeconds { get; set; } + public ChangeFeedPolicy ChangeFeedPolicy { get; set; } + public ClientEncryptionPolicy ClientEncryptionPolicy { get; set; } + public Collection ComputedProperties { get; set; } + public ConflictResolutionPolicy ConflictResolutionPolicy { get; set; } + public Nullable DefaultTimeToLive { get; set; } + public string ETag { get; } + public GeospatialConfig GeospatialConfig { get; set; } + public string Id { get; set; } + public IndexingPolicy IndexingPolicy { get; set; } + public Nullable LastModified { get; } + public Nullable PartitionKeyDefinitionVersion { get; set; } + public string PartitionKeyPath { get; set; } + public IReadOnlyList PartitionKeyPaths { get; set; } + public string SelfLink { get; } + public string TimeToLivePropertyPath { get; set; } + public UniqueKeyPolicy UniqueKeyPolicy { get; set; } + } + public class ContainerRequestOptions : RequestOptions + { + public ContainerRequestOptions(); + public bool PopulateQuotaInfo { get; set; } + } + public class ContainerResponse : Response + { + protected ContainerResponse(); + public override string ActivityId { get; } + public virtual Container Container { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public override double RequestCharge { get; } + public override ContainerProperties Resource { get; } + public override HttpStatusCode StatusCode { get; } + public static implicit operator Container (ContainerResponse response); + } + public class CosmosClient : IDisposable + { + protected CosmosClient(); + public CosmosClient(string accountEndpoint, AzureKeyCredential authKeyOrResourceTokenCredential, CosmosClientOptions clientOptions=null); + public CosmosClient(string accountEndpoint, TokenCredential tokenCredential, CosmosClientOptions clientOptions=null); + public CosmosClient(string connectionString, CosmosClientOptions clientOptions=null); + public CosmosClient(string accountEndpoint, string authKeyOrResourceToken, CosmosClientOptions clientOptions=null); + public virtual CosmosClientOptions ClientOptions { get; } + public virtual Uri Endpoint { get; } + public virtual CosmosResponseFactory ResponseFactory { get; } + public static Task CreateAndInitializeAsync(string accountEndpoint, AzureKeyCredential authKeyOrResourceTokenCredential, IReadOnlyList> containers, CosmosClientOptions cosmosClientOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public static Task CreateAndInitializeAsync(string accountEndpoint, TokenCredential tokenCredential, IReadOnlyList> containers, CosmosClientOptions cosmosClientOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public static Task CreateAndInitializeAsync(string connectionString, IReadOnlyList> containers, CosmosClientOptions cosmosClientOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public static Task CreateAndInitializeAsync(string accountEndpoint, string authKeyOrResourceToken, IReadOnlyList> containers, CosmosClientOptions cosmosClientOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public virtual Task CreateDatabaseAsync(string id, ThroughputProperties throughputProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public virtual Task CreateDatabaseAsync(string id, Nullable throughput=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public virtual Task CreateDatabaseIfNotExistsAsync(string id, ThroughputProperties throughputProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public virtual Task CreateDatabaseIfNotExistsAsync(string id, Nullable throughput=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public virtual Task CreateDatabaseStreamAsync(DatabaseProperties databaseProperties, Nullable throughput=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public void Dispose(); + protected virtual void Dispose(bool disposing); + public virtual Container GetContainer(string databaseId, string containerId); + public virtual Database GetDatabase(string id); + public virtual FeedIterator GetDatabaseQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public virtual FeedIterator GetDatabaseQueryIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public virtual FeedIterator GetDatabaseQueryStreamIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public virtual FeedIterator GetDatabaseQueryStreamIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public virtual Task ReadAccountAsync(); + } + public class CosmosClientOptions + { + public CosmosClientOptions(); + public bool AllowBulkExecution { get; set; } + public string ApplicationName { get; set; } + public IReadOnlyList ApplicationPreferredRegions { get; set; } + public string ApplicationRegion { get; set; } + public ConnectionMode ConnectionMode { get; set; } + public Nullable ConsistencyLevel { get; set; } + public CosmosClientTelemetryOptions CosmosClientTelemetryOptions { get; set; } + public Collection CustomHandlers { get; } + public Nullable EnableContentResponseOnWrite { get; set; } + public bool EnableTcpConnectionEndpointRediscovery { get; set; } + public int GatewayModeMaxConnectionLimit { get; set; } + public Func HttpClientFactory { get; set; } + public Nullable IdleTcpConnectionTimeout { get; set; } + public bool LimitToEndpoint { get; set; } + public Nullable MaxRequestsPerTcpConnection { get; set; } + public Nullable MaxRetryAttemptsOnRateLimitedRequests { get; set; } + public Nullable MaxRetryWaitTimeOnRateLimitedRequests { get; set; } + public Nullable MaxTcpConnectionsPerEndpoint { get; set; } + public Nullable OpenTcpConnectionTimeout { get; set; } + public Nullable PortReuseMode { get; set; } + public TimeSpan RequestTimeout { get; set; } + public CosmosSerializer Serializer { get; set; } + public CosmosSerializationOptions SerializerOptions { get; set; } + public Func ServerCertificateCustomValidationCallback { get; set; } + public Nullable TokenCredentialBackgroundRefreshInterval { get; set; } + public IWebProxy WebProxy { get; set; } + } + public class CosmosClientTelemetryOptions + { + public CosmosClientTelemetryOptions(); + public CosmosThresholdOptions CosmosThresholdOptions { get; set; } + public bool DisableDistributedTracing { get; set; } + public bool DisableSendingMetricsToService { get; set; } + } + public abstract class CosmosDiagnostics + { + protected CosmosDiagnostics(); + public virtual TimeSpan GetClientElapsedTime(); + public abstract IReadOnlyList> GetContactedRegions(); + public virtual int GetFailedRequestCount(); + public virtual ServerSideCumulativeMetrics GetQueryMetrics(); + public virtual Nullable GetStartTimeUtc(); + public abstract override string ToString(); + } + public class CosmosException : Exception + { + public CosmosException(string message, HttpStatusCode statusCode, int subStatusCode, string activityId, double requestCharge); + public virtual string ActivityId { get; } + public virtual CosmosDiagnostics Diagnostics { get; } + public virtual Headers Headers { get; } + public override string Message { get; } + public virtual double RequestCharge { get; } + public virtual string ResponseBody { get; } + public virtual Nullable RetryAfter { get; } + public override string StackTrace { get; } + public virtual HttpStatusCode StatusCode { get; } + public virtual int SubStatusCode { get; } + public override string ToString(); + public virtual bool TryGetHeader(string headerName, out string value); + } + public sealed class CosmosLinqSerializerOptions + { + public CosmosLinqSerializerOptions(); + public CosmosPropertyNamingPolicy PropertyNamingPolicy { get; set; } + } + public class CosmosOperationCanceledException : OperationCanceledException + { + public CosmosOperationCanceledException(OperationCanceledException originalException, CosmosDiagnostics diagnostics); + protected CosmosOperationCanceledException(SerializationInfo info, StreamingContext context); + public override IDictionary Data { get; } + public CosmosDiagnostics Diagnostics { get; } + public override string HelpLink { get; set; } + public override string Message { get; } + public override string Source { get; set; } + public override string StackTrace { get; } + public override Exception GetBaseException(); + public override void GetObjectData(SerializationInfo info, StreamingContext context); + public override string ToString(); + } + public enum CosmosPropertyNamingPolicy + { + CamelCase = 1, + Default = 0, + } + public abstract class CosmosResponseFactory + { + protected CosmosResponseFactory(); + public abstract FeedResponse CreateItemFeedResponse(ResponseMessage responseMessage); + public abstract ItemResponse CreateItemResponse(ResponseMessage responseMessage); + public abstract StoredProcedureExecuteResponse CreateStoredProcedureExecuteResponse(ResponseMessage responseMessage); + } + public sealed class CosmosSerializationOptions + { + public CosmosSerializationOptions(); + public bool IgnoreNullValues { get; set; } + public bool Indented { get; set; } + public CosmosPropertyNamingPolicy PropertyNamingPolicy { get; set; } + } + public abstract class CosmosSerializer + { + protected CosmosSerializer(); + public abstract T FromStream(Stream stream); + public abstract Stream ToStream(T input); + } + public class CosmosThresholdOptions + { + public CosmosThresholdOptions(); + public TimeSpan NonPointOperationLatencyThreshold { get; set; } + public TimeSpan PointOperationLatencyThreshold { get; set; } + } + public abstract class Database + { + protected Database(); + public abstract CosmosClient Client { get; } + public abstract string Id { get; } + public abstract Task CreateClientEncryptionKeyAsync(ClientEncryptionKeyProperties clientEncryptionKeyProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateContainerAsync(ContainerProperties containerProperties, ThroughputProperties throughputProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateContainerAsync(ContainerProperties containerProperties, Nullable throughput=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateContainerAsync(string id, string partitionKeyPath, Nullable throughput=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateContainerIfNotExistsAsync(ContainerProperties containerProperties, ThroughputProperties throughputProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateContainerIfNotExistsAsync(ContainerProperties containerProperties, Nullable throughput=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateContainerIfNotExistsAsync(string id, string partitionKeyPath, Nullable throughput=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateContainerStreamAsync(ContainerProperties containerProperties, ThroughputProperties throughputProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateContainerStreamAsync(ContainerProperties containerProperties, Nullable throughput=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateUserAsync(string id, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract ContainerBuilder DefineContainer(string name, string partitionKeyPath); + public abstract Task DeleteAsync(RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task DeleteStreamAsync(RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract ClientEncryptionKey GetClientEncryptionKey(string id); + public abstract FeedIterator GetClientEncryptionKeyQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract Container GetContainer(string id); + public abstract FeedIterator GetContainerQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetContainerQueryIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetContainerQueryStreamIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetContainerQueryStreamIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract User GetUser(string id); + public abstract FeedIterator GetUserQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetUserQueryIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract Task ReadAsync(RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadStreamAsync(RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadThroughputAsync(RequestOptions requestOptions, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task> ReadThroughputAsync(CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceThroughputAsync(ThroughputProperties throughputProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceThroughputAsync(int throughput, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task UpsertUserAsync(string id, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + } + public class DatabaseProperties + { + public DatabaseProperties(); + public DatabaseProperties(string id); + public string ETag { get; } + public string Id { get; set; } + public Nullable LastModified { get; } + public string SelfLink { get; } + } + public class DatabaseResponse : Response + { + protected DatabaseResponse(); + public override string ActivityId { get; } + public virtual Database Database { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public override double RequestCharge { get; } + public override DatabaseProperties Resource { get; } + public override HttpStatusCode StatusCode { get; } + public static implicit operator Database (DatabaseResponse response); + } + public enum DataType + { + LineString = 3, + MultiPolygon = 5, + Number = 0, + Point = 2, + Polygon = 4, + String = 1, + } + public class DedicatedGatewayRequestOptions + { + public DedicatedGatewayRequestOptions(); + public Nullable BypassIntegratedCache { get; set; } + public Nullable MaxIntegratedCacheStaleness { get; set; } + } + public class EncryptionKeyWrapMetadata : IEquatable + { + public EncryptionKeyWrapMetadata(EncryptionKeyWrapMetadata source); + public EncryptionKeyWrapMetadata(string type, string name, string value, string algorithm); + public string Algorithm { get; } + public string Name { get; } + public string Type { get; } + public string Value { get; } + public bool Equals(EncryptionKeyWrapMetadata other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public sealed class ExcludedPath + { + public ExcludedPath(); + public string Path { get; set; } + } + public abstract class FeedIterator : IDisposable + { + protected FeedIterator(); + public abstract bool HasMoreResults { get; } + public void Dispose(); + protected virtual void Dispose(bool disposing); + public abstract Task ReadNextAsync(CancellationToken cancellationToken=default(CancellationToken)); + } + public abstract class FeedIterator : IDisposable + { + protected FeedIterator(); + public abstract bool HasMoreResults { get; } + public void Dispose(); + protected virtual void Dispose(bool disposing); + public abstract Task> ReadNextAsync(CancellationToken cancellationToken=default(CancellationToken)); + } + public abstract class FeedRange + { + protected FeedRange(); + public static FeedRange FromJsonString(string toStringValue); + public static FeedRange FromPartitionKey(PartitionKey partitionKey); + public abstract string ToJsonString(); + } + public abstract class FeedResponse : IEnumerable, IEnumerable + { + protected FeedResponse(); + public override string ActivityId { get; } + public abstract string ContinuationToken { get; } + public abstract int Count { get; } + public override string ETag { get; } + public abstract string IndexMetrics { get; } + public override double RequestCharge { get; } + public abstract IEnumerator GetEnumerator(); + IEnumerator System.Collections.IEnumerable.GetEnumerator(); + } + public sealed class GeospatialConfig + { + public GeospatialConfig(); + public GeospatialConfig(GeospatialType geospatialType); + public GeospatialType GeospatialType { get; set; } + } + public enum GeospatialType + { + Geography = 0, + Geometry = 1, + } + public class Headers : IEnumerable + { + public Headers(); + public virtual string ActivityId { get; } + public virtual string ContentLength { get; set; } + public virtual string ContentType { get; } + public virtual string ContinuationToken { get; } + public virtual string ETag { get; } + public virtual string this[string headerName] { get; set; } + public virtual string Location { get; } + public virtual double RequestCharge { get; } + public virtual string Session { get; } + public virtual void Add(string headerName, IEnumerable values); + public virtual void Add(string headerName, string value); + public virtual string[] AllKeys(); + public virtual string Get(string headerName); + public virtual IEnumerator GetEnumerator(); + public virtual T GetHeaderValue(string headerName); + public virtual string GetValueOrDefault(string headerName); + public virtual void Remove(string headerName); + public virtual void Set(string headerName, string value); + IEnumerator System.Collections.IEnumerable.GetEnumerator(); + public virtual bool TryGetValue(string headerName, out string value); + } + public sealed class IncludedPath + { + public IncludedPath(); + public string Path { get; set; } + } + public enum IndexingDirective + { + Default = 0, + Exclude = 2, + Include = 1, + } + public enum IndexingMode + { + Consistent = 0, + Lazy = 1, + None = 2, + } + public sealed class IndexingPolicy + { + public IndexingPolicy(); + public bool Automatic { get; set; } + public Collection> CompositeIndexes { get; } + public Collection ExcludedPaths { get; } + public Collection IncludedPaths { get; } + public IndexingMode IndexingMode { get; set; } + public Collection SpatialIndexes { get; } + } + public enum IndexKind + { + Hash = 0, + Range = 1, + Spatial = 2, + } + public class ItemRequestOptions : RequestOptions + { + public ItemRequestOptions(); + public Nullable ConsistencyLevel { get; set; } + public DedicatedGatewayRequestOptions DedicatedGatewayRequestOptions { get; set; } + public Nullable EnableContentResponseOnWrite { get; set; } + public Nullable IndexingDirective { get; set; } + public IEnumerable PostTriggers { get; set; } + public IEnumerable PreTriggers { get; set; } + public string SessionToken { get; set; } + } + public class ItemResponse : Response + { + protected ItemResponse(); + public override string ActivityId { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public override double RequestCharge { get; } + public override T Resource { get; } + public override HttpStatusCode StatusCode { get; } + } + public enum OperationKind + { + Create = 1, + Delete = 3, + Invalid = 0, + Read = 4, + Replace = 2, + } + public struct PartitionKey : IEquatable + { + public static readonly PartitionKey None; + public static readonly PartitionKey Null; + public static readonly string SystemKeyName; + public static readonly string SystemKeyPath; + public PartitionKey(bool partitionKeyValue); + public PartitionKey(double partitionKeyValue); + public PartitionKey(string partitionKeyValue); + public bool Equals(PartitionKey other); + public override bool Equals(object obj); + public override int GetHashCode(); + public static bool operator ==(PartitionKey left, PartitionKey right); + public static bool operator !=(PartitionKey left, PartitionKey right); + public override string ToString(); + } + public sealed class PartitionKeyBuilder + { + public PartitionKeyBuilder(); + public PartitionKeyBuilder Add(bool val); + public PartitionKeyBuilder Add(double val); + public PartitionKeyBuilder Add(string val); + public PartitionKeyBuilder AddNoneType(); + public PartitionKeyBuilder AddNullValue(); + public PartitionKey Build(); + } + public enum PartitionKeyDefinitionVersion + { + V1 = 1, + V2 = 2, + } + public sealed class PatchItemRequestOptions : ItemRequestOptions + { + public PatchItemRequestOptions(); + public string FilterPredicate { get; set; } + } + public abstract class PatchOperation + { + protected PatchOperation(); + public virtual string From { get; set; } + public abstract PatchOperationType OperationType { get; } + public abstract string Path { get; } + public static PatchOperation Add(string path, T value); + public static PatchOperation Increment(string path, double value); + public static PatchOperation Increment(string path, long value); + public static PatchOperation Move(string from, string path); + public static PatchOperation Remove(string path); + public static PatchOperation Replace(string path, T value); + public static PatchOperation Set(string path, T value); + public virtual bool TrySerializeValueParameter(CosmosSerializer cosmosSerializer, out Stream valueParam); + } + public enum PatchOperationType + { + Add = 0, + Increment = 4, + Move = 5, + Remove = 1, + Replace = 2, + Set = 3, + } + public abstract class PatchOperation : PatchOperation + { + protected PatchOperation(); + public abstract T Value { get; } + } + public abstract class Permission + { + protected Permission(); + public abstract string Id { get; } + public abstract Task DeleteAsync(RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadAsync(Nullable tokenExpiryInSeconds=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceAsync(PermissionProperties permissionProperties, Nullable tokenExpiryInSeconds=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + } + public enum PermissionMode : byte + { + All = (byte)2, + Read = (byte)1, + } + public class PermissionProperties + { + public PermissionProperties(string id, PermissionMode permissionMode, Container container, PartitionKey resourcePartitionKey, string itemId); + public PermissionProperties(string id, PermissionMode permissionMode, Container container, Nullable resourcePartitionKey=default(Nullable)); + public string ETag { get; } + public string Id { get; } + public Nullable LastModified { get; } + public PermissionMode PermissionMode { get; } + public Nullable ResourcePartitionKey { get; set; } + public string ResourceUri { get; } + public string SelfLink { get; } + public string Token { get; } + } + public class PermissionResponse : Response + { + protected PermissionResponse(); + public override string ActivityId { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public virtual Permission Permission { get; } + public override double RequestCharge { get; } + public override PermissionProperties Resource { get; } + public override HttpStatusCode StatusCode { get; } + public static implicit operator Permission (PermissionResponse response); + } + public enum PortReuseMode + { + PrivatePortPool = 1, + ReuseUnicastPort = 0, + } + public enum PriorityLevel + { + High = 1, + Low = 2, + } + public class QueryDefinition + { + public QueryDefinition(string query); + public string QueryText { get; } + public IReadOnlyList> GetQueryParameters(); + public QueryDefinition WithParameter(string name, object value); + public QueryDefinition WithParameterStream(string name, Stream valueStream); + } + public class QueryRequestOptions : RequestOptions + { + public QueryRequestOptions(); + public Nullable ConsistencyLevel { get; set; } + public DedicatedGatewayRequestOptions DedicatedGatewayRequestOptions { get; set; } + public Nullable EnableLowPrecisionOrderBy { get; set; } + public bool EnableOptimisticDirectExecution { get; set; } + public Nullable EnableScanInQuery { get; set; } + public Nullable MaxBufferedItemCount { get; set; } + public Nullable MaxConcurrency { get; set; } + public Nullable MaxItemCount { get; set; } + public Nullable PartitionKey { get; set; } + public Nullable PopulateIndexMetrics { get; set; } + public Nullable ResponseContinuationTokenLimitInKb { get; set; } + public string SessionToken { get; set; } + } + public class ReadManyRequestOptions : RequestOptions + { + public ReadManyRequestOptions(); + public Nullable ConsistencyLevel { get; set; } + public string SessionToken { get; set; } + } + public static class Regions + { + public const string AustraliaCentral = "Australia Central"; + public const string AustraliaCentral2 = "Australia Central 2"; + public const string AustraliaEast = "Australia East"; + public const string AustraliaSoutheast = "Australia Southeast"; + public const string BrazilSouth = "Brazil South"; + public const string BrazilSoutheast = "Brazil Southeast"; + public const string CanadaCentral = "Canada Central"; + public const string CanadaEast = "Canada East"; + public const string CentralIndia = "Central India"; + public const string CentralUS = "Central US"; + public const string CentralUSEUAP = "Central US EUAP"; + public const string ChinaEast = "China East"; + public const string ChinaEast2 = "China East 2"; + public const string ChinaEast3 = "China East 3"; + public const string ChinaNorth = "China North"; + public const string ChinaNorth2 = "China North 2"; + public const string ChinaNorth3 = "China North 3"; + public const string EastAsia = "East Asia"; + public const string EastUS = "East US"; + public const string EastUS2 = "East US 2"; + public const string EastUS2EUAP = "East US 2 EUAP"; + public const string EastUSSLV = "East US SLV"; + public const string FranceCentral = "France Central"; + public const string FranceSouth = "France South"; + public const string GermanyCentral = "Germany Central"; + public const string GermanyNorth = "Germany North"; + public const string GermanyNortheast = "Germany Northeast"; + public const string GermanyWestCentral = "Germany West Central"; + public const string IsraelCentral = "Israel Central"; + public const string ItalyNorth = "Italy North"; + public const string JapanEast = "Japan East"; + public const string JapanWest = "Japan West"; + public const string JioIndiaCentral = "Jio India Central"; + public const string JioIndiaWest = "Jio India West"; + public const string KoreaCentral = "Korea Central"; + public const string KoreaSouth = "Korea South"; + public const string MalaysiaSouth = "Malaysia South"; + public const string NorthCentralUS = "North Central US"; + public const string NorthEurope = "North Europe"; + public const string NorwayEast = "Norway East"; + public const string NorwayWest = "Norway West"; + public const string PolandCentral = "Poland Central"; + public const string QatarCentral = "Qatar Central"; + public const string SouthAfricaNorth = "South Africa North"; + public const string SouthAfricaWest = "South Africa West"; + public const string SouthCentralUS = "South Central US"; + public const string SoutheastAsia = "Southeast Asia"; + public const string SouthIndia = "South India"; + public const string SwedenCentral = "Sweden Central"; + public const string SwedenSouth = "Sweden South"; + public const string SwitzerlandNorth = "Switzerland North"; + public const string SwitzerlandWest = "Switzerland West"; + public const string UAECentral = "UAE Central"; + public const string UAENorth = "UAE North"; + public const string UKSouth = "UK South"; + public const string UKWest = "UK West"; + public const string USDoDCentral = "USDoD Central"; + public const string USDoDEast = "USDoD East"; + public const string USGovArizona = "USGov Arizona"; + public const string USGovTexas = "USGov Texas"; + public const string USGovVirginia = "USGov Virginia"; + public const string USNatEast = "USNat East"; + public const string USNatWest = "USNat West"; + public const string USSecEast = "USSec East"; + public const string USSecWest = "USSec West"; + public const string WestCentralUS = "West Central US"; + public const string WestEurope = "West Europe"; + public const string WestIndia = "West India"; + public const string WestUS = "West US"; + public const string WestUS2 = "West US 2"; + public const string WestUS3 = "West US 3"; + } + public abstract class RequestHandler + { + protected RequestHandler(); + public RequestHandler InnerHandler { get; set; } + public virtual Task SendAsync(RequestMessage request, CancellationToken cancellationToken); + } + public class RequestMessage : IDisposable + { + public RequestMessage(); + public RequestMessage(HttpMethod method, Uri requestUri); + public virtual Stream Content { get; set; } + public virtual Headers Headers { get; } + public virtual HttpMethod Method { get; } + public virtual Dictionary Properties { get; } + public virtual Uri RequestUri { get; } + public void Dispose(); + protected virtual void Dispose(bool disposing); + } + public class RequestOptions + { + public RequestOptions(); + public Action AddRequestHeaders { get; set; } + public CosmosThresholdOptions CosmosThresholdOptions { get; set; } + public string IfMatchEtag { get; set; } + public string IfNoneMatchEtag { get; set; } + public Nullable PriorityLevel { get; set; } + public IReadOnlyDictionary Properties { get; set; } + public RequestOptions ShallowCopy(); + } + public class ResponseMessage : IDisposable + { + public ResponseMessage(); + public ResponseMessage(HttpStatusCode statusCode, RequestMessage requestMessage=null, string errorMessage=null); + public virtual Stream Content { get; set; } + public virtual string ContinuationToken { get; } + public virtual CosmosDiagnostics Diagnostics { get; set; } + public virtual string ErrorMessage { get; } + public virtual Headers Headers { get; } + public string IndexMetrics { get; } + public virtual bool IsSuccessStatusCode { get; } + public virtual RequestMessage RequestMessage { get; } + public virtual HttpStatusCode StatusCode { get; } + public void Dispose(); + protected virtual void Dispose(bool disposing); + public virtual ResponseMessage EnsureSuccessStatusCode(); + } + public abstract class Response + { + protected Response(); + public abstract string ActivityId { get; } + public abstract CosmosDiagnostics Diagnostics { get; } + public abstract string ETag { get; } + public abstract Headers Headers { get; } + public abstract double RequestCharge { get; } + public abstract T Resource { get; } + public abstract HttpStatusCode StatusCode { get; } + public static implicit operator T (Response response); + } + public abstract class ServerSideCumulativeMetrics + { + protected ServerSideCumulativeMetrics(); + public abstract ServerSideMetrics CumulativeMetrics { get; } + public abstract IReadOnlyList PartitionedMetrics { get; } + } + public abstract class ServerSideMetrics + { + protected ServerSideMetrics(); + public abstract TimeSpan DocumentLoadTime { get; } + public abstract TimeSpan DocumentWriteTime { get; } + public abstract double IndexHitRatio { get; } + public abstract TimeSpan IndexLookupTime { get; } + public abstract long OutputDocumentCount { get; } + public abstract long OutputDocumentSize { get; } + public abstract TimeSpan QueryPreparationTime { get; } + public abstract long RetrievedDocumentCount { get; } + public abstract long RetrievedDocumentSize { get; } + public abstract TimeSpan RuntimeExecutionTime { get; } + public abstract TimeSpan TotalTime { get; } + public abstract TimeSpan VMExecutionTime { get; } + } + public abstract class ServerSidePartitionedMetrics + { + protected ServerSidePartitionedMetrics(); + public abstract string FeedRange { get; } + public abstract Nullable PartitionKeyRangeId { get; } + public abstract ServerSideMetrics ServerSideMetrics { get; } + } + public sealed class SpatialPath + { + public SpatialPath(); + public BoundingBoxProperties BoundingBox { get; set; } + public string Path { get; set; } + public Collection SpatialTypes { get; } + } + public enum SpatialType + { + LineString = 1, + MultiPolygon = 3, + Point = 0, + Polygon = 2, + } + public class ThroughputProperties + { + public Nullable AutoscaleMaxThroughput { get; } + public string ETag { get; } + public Nullable LastModified { get; } + public string SelfLink { get; } + public Nullable Throughput { get; } + public static ThroughputProperties CreateAutoscaleThroughput(int autoscaleMaxThroughput); + public static ThroughputProperties CreateManualThroughput(int throughput); + } + public class ThroughputResponse : Response + { + protected ThroughputResponse(); + public override string ActivityId { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public Nullable IsReplacePending { get; } + public Nullable MinThroughput { get; } + public override double RequestCharge { get; } + public override ThroughputProperties Resource { get; } + public override HttpStatusCode StatusCode { get; } + public static implicit operator ThroughputProperties (ThroughputResponse response); + } + public abstract class TransactionalBatch + { + protected TransactionalBatch(); + public abstract TransactionalBatch CreateItemStream(Stream streamPayload, TransactionalBatchItemRequestOptions requestOptions=null); + public abstract TransactionalBatch CreateItem(T item, TransactionalBatchItemRequestOptions requestOptions=null); + public abstract TransactionalBatch DeleteItem(string id, TransactionalBatchItemRequestOptions requestOptions=null); + public abstract Task ExecuteAsync(TransactionalBatchRequestOptions requestOptions, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ExecuteAsync(CancellationToken cancellationToken=default(CancellationToken)); + public abstract TransactionalBatch PatchItem(string id, IReadOnlyList patchOperations, TransactionalBatchPatchItemRequestOptions requestOptions=null); + public abstract TransactionalBatch ReadItem(string id, TransactionalBatchItemRequestOptions requestOptions=null); + public abstract TransactionalBatch ReplaceItemStream(string id, Stream streamPayload, TransactionalBatchItemRequestOptions requestOptions=null); + public abstract TransactionalBatch ReplaceItem(string id, T item, TransactionalBatchItemRequestOptions requestOptions=null); + public abstract TransactionalBatch UpsertItemStream(Stream streamPayload, TransactionalBatchItemRequestOptions requestOptions=null); + public abstract TransactionalBatch UpsertItem(T item, TransactionalBatchItemRequestOptions requestOptions=null); + } + public class TransactionalBatchItemRequestOptions : RequestOptions + { + public TransactionalBatchItemRequestOptions(); + public Nullable EnableContentResponseOnWrite { get; set; } + public Nullable IndexingDirective { get; set; } + } + public class TransactionalBatchOperationResult + { + protected TransactionalBatchOperationResult(); + public virtual string ETag { get; } + public virtual bool IsSuccessStatusCode { get; } + public virtual Stream ResourceStream { get; } + public virtual TimeSpan RetryAfter { get; } + public virtual HttpStatusCode StatusCode { get; } + } + public class TransactionalBatchOperationResult : TransactionalBatchOperationResult + { + protected TransactionalBatchOperationResult(); + public virtual T Resource { get; set; } + } + public class TransactionalBatchPatchItemRequestOptions : TransactionalBatchItemRequestOptions + { + public TransactionalBatchPatchItemRequestOptions(); + public string FilterPredicate { get; set; } + } + public class TransactionalBatchRequestOptions : RequestOptions + { + public TransactionalBatchRequestOptions(); + public Nullable ConsistencyLevel { get; set; } + public string SessionToken { get; set; } + } + public class TransactionalBatchResponse : IDisposable, IEnumerable, IEnumerable, IReadOnlyCollection, IReadOnlyList + { + protected TransactionalBatchResponse(); + public virtual string ActivityId { get; } + public virtual int Count { get; } + public virtual CosmosDiagnostics Diagnostics { get; } + public virtual string ErrorMessage { get; } + public virtual Headers Headers { get; } + public virtual bool IsSuccessStatusCode { get; } + public virtual TransactionalBatchOperationResult this[int index] { get; } + public virtual double RequestCharge { get; } + public virtual Nullable RetryAfter { get; } + public virtual HttpStatusCode StatusCode { get; } + public void Dispose(); + protected virtual void Dispose(bool disposing); + public virtual IEnumerator GetEnumerator(); + public virtual TransactionalBatchOperationResult GetOperationResultAtIndex(int index); + IEnumerator System.Collections.IEnumerable.GetEnumerator(); + } + public class UniqueKey + { + public UniqueKey(); + public Collection Paths { get; } + } + public sealed class UniqueKeyPolicy + { + public UniqueKeyPolicy(); + public Collection UniqueKeys { get; } + } + public abstract class User + { + protected User(); + public abstract string Id { get; } + public abstract Task CreatePermissionAsync(PermissionProperties permissionProperties, Nullable tokenExpiryInSeconds=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task DeleteAsync(RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Permission GetPermission(string id); + public abstract FeedIterator GetPermissionQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetPermissionQueryIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract Task ReadAsync(RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceAsync(UserProperties userProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task UpsertPermissionAsync(PermissionProperties permissionProperties, Nullable tokenExpiryInSeconds=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + } + public class UserProperties + { + protected UserProperties(); + public UserProperties(string id); + public string ETag { get; } + public string Id { get; set; } + public Nullable LastModified { get; } + public string SelfLink { get; } + } + public class UserResponse : Response + { + protected UserResponse(); + public override string ActivityId { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public override double RequestCharge { get; } + public override UserProperties Resource { get; } + public override HttpStatusCode StatusCode { get; } + public virtual User User { get; } + public static implicit operator User (UserResponse response); + } +} +namespace Microsoft.Azure.Cosmos.Fluent +{ + public class ChangeFeedPolicyDefinition + { + public ContainerBuilder Attach(); + } + public sealed class ClientEncryptionPolicyDefinition + { + public ContainerBuilder Attach(); + public ClientEncryptionPolicyDefinition WithIncludedPath(ClientEncryptionIncludedPath path); + } + public class CompositeIndexDefinition + { + public T Attach(); + public CompositeIndexDefinition Path(string path); + public CompositeIndexDefinition Path(string path, CompositePathSortOrder sortOrder); + } + public class ComputedPropertiesDefinition + { + public T Attach(); + public ComputedPropertiesDefinition WithComputedProperty(string name, string query); + } + public class ConflictResolutionDefinition + { + public ContainerBuilder Attach(); + public ConflictResolutionDefinition WithCustomStoredProcedureResolution(string conflictResolutionProcedure); + public ConflictResolutionDefinition WithLastWriterWinsResolution(string conflictResolutionPath); + } + public class ContainerBuilder : ContainerDefinition + { + protected ContainerBuilder(); + public ContainerBuilder(Database database, string name, string partitionKeyPath); + public new ContainerProperties Build(); + public Task CreateAsync(ThroughputProperties throughputProperties, CancellationToken cancellationToken=default(CancellationToken)); + public Task CreateAsync(Nullable throughput=default(Nullable), CancellationToken cancellationToken=default(CancellationToken)); + public Task CreateIfNotExistsAsync(ThroughputProperties throughputProperties, CancellationToken cancellationToken=default(CancellationToken)); + public Task CreateIfNotExistsAsync(Nullable throughput=default(Nullable), CancellationToken cancellationToken=default(CancellationToken)); + public ChangeFeedPolicyDefinition WithChangeFeedPolicy(TimeSpan retention); + public ClientEncryptionPolicyDefinition WithClientEncryptionPolicy(); + public ClientEncryptionPolicyDefinition WithClientEncryptionPolicy(int policyFormatVersion); + public ConflictResolutionDefinition WithConflictResolution(); + public UniqueKeyDefinition WithUniqueKey(); + } + public abstract class ContainerDefinition where T : ContainerDefinition + { + public ContainerDefinition(); + public ContainerProperties Build(); + public ComputedPropertiesDefinition WithComputedProperties(); + public T WithDefaultTimeToLive(int defaultTtlInSeconds); + public T WithDefaultTimeToLive(TimeSpan defaultTtlTimeSpan); + public IndexingPolicyDefinition WithIndexingPolicy(); + public T WithPartitionKeyDefinitionVersion(PartitionKeyDefinitionVersion partitionKeyDefinitionVersion); + public T WithTimeToLivePropertyPath(string propertyPath); + } + public class CosmosClientBuilder + { + public CosmosClientBuilder(string connectionString); + public CosmosClientBuilder(string accountEndpoint, AzureKeyCredential authKeyOrResourceTokenCredential); + public CosmosClientBuilder(string accountEndpoint, TokenCredential tokenCredential); + public CosmosClientBuilder(string accountEndpoint, string authKeyOrResourceToken); + public CosmosClientBuilder AddCustomHandlers(params RequestHandler[] customHandlers); + public CosmosClient Build(); + public Task BuildAndInitializeAsync(IReadOnlyList> containers, CancellationToken cancellationToken=default(CancellationToken)); + public CosmosClientBuilder WithApplicationName(string applicationName); + public CosmosClientBuilder WithApplicationPreferredRegions(IReadOnlyList applicationPreferredRegions); + public CosmosClientBuilder WithApplicationRegion(string applicationRegion); + public CosmosClientBuilder WithBulkExecution(bool enabled); + public CosmosClientBuilder WithClientTelemetryOptions(CosmosClientTelemetryOptions options); + public CosmosClientBuilder WithConnectionModeDirect(); + public CosmosClientBuilder WithConnectionModeDirect(Nullable idleTcpConnectionTimeout=default(Nullable), Nullable openTcpConnectionTimeout=default(Nullable), Nullable maxRequestsPerTcpConnection=default(Nullable), Nullable maxTcpConnectionsPerEndpoint=default(Nullable), Nullable portReuseMode=default(Nullable), Nullable enableTcpConnectionEndpointRediscovery=default(Nullable)); + public CosmosClientBuilder WithConnectionModeGateway(Nullable maxConnectionLimit=default(Nullable), IWebProxy webProxy=null); + public CosmosClientBuilder WithConsistencyLevel(ConsistencyLevel consistencyLevel); + public CosmosClientBuilder WithContentResponseOnWrite(bool contentResponseOnWrite); + public CosmosClientBuilder WithCustomSerializer(CosmosSerializer cosmosJsonSerializer); + public CosmosClientBuilder WithHttpClientFactory(Func httpClientFactory); + public CosmosClientBuilder WithLimitToEndpoint(bool limitToEndpoint); + public CosmosClientBuilder WithRequestTimeout(TimeSpan requestTimeout); + public CosmosClientBuilder WithSerializerOptions(CosmosSerializationOptions cosmosSerializerOptions); + public CosmosClientBuilder WithThrottlingRetryOptions(TimeSpan maxRetryWaitTimeOnThrottledRequests, int maxRetryAttemptsOnThrottledRequests); + } + public class IndexingPolicyDefinition + { + public IndexingPolicyDefinition(); + public T Attach(); + public IndexingPolicyDefinition WithAutomaticIndexing(bool enabled); + public CompositeIndexDefinition> WithCompositeIndex(); + public PathsDefinition> WithExcludedPaths(); + public PathsDefinition> WithIncludedPaths(); + public IndexingPolicyDefinition WithIndexingMode(IndexingMode indexingMode); + public SpatialIndexDefinition> WithSpatialIndex(); + } + public class PathsDefinition + { + public T Attach(); + public PathsDefinition Path(string path); + } + public class SpatialIndexDefinition + { + public T Attach(); + public SpatialIndexDefinition Path(string path); + public SpatialIndexDefinition Path(string path, params SpatialType[] spatialTypes); + } + public class UniqueKeyDefinition + { + public ContainerBuilder Attach(); + public UniqueKeyDefinition Path(string path); + } +} +namespace Microsoft.Azure.Cosmos.Linq +{ + public static class CosmosLinq + { + public static object InvokeUserDefinedFunction(string udfName, params object[] arguments); + } + public static class CosmosLinqExtensions + { + public static Task> AverageAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> AverageAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> AverageAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> AverageAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> AverageAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> AverageAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> AverageAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> AverageAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> AverageAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> AverageAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> CountAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static bool IsArray(this object obj); + public static bool IsBool(this object obj); + public static bool IsDefined(this object obj); + public static bool IsNull(this object obj); + public static bool IsNumber(this object obj); + public static bool IsObject(this object obj); + public static bool IsPrimitive(this object obj); + public static bool IsString(this object obj); + public static Task> MaxAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> MinAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static bool RegexMatch(this object obj, string regularExpression); + public static bool RegexMatch(this object obj, string regularExpression, string searchModifier); + public static Task> SumAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> SumAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> SumAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> SumAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> SumAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> SumAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> SumAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> SumAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> SumAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> SumAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static FeedIterator ToFeedIterator(this IQueryable query); + public static QueryDefinition ToQueryDefinition(this IQueryable query); + public static QueryDefinition ToQueryDefinition(this IQueryable query, IDictionary namedParameters); + public static FeedIterator ToStreamIterator(this IQueryable query); + } +} +namespace Microsoft.Azure.Cosmos.Scripts +{ + public abstract class Scripts + { + protected Scripts(); + public abstract Task CreateStoredProcedureAsync(StoredProcedureProperties storedProcedureProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateTriggerAsync(TriggerProperties triggerProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateUserDefinedFunctionAsync(UserDefinedFunctionProperties userDefinedFunctionProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task DeleteStoredProcedureAsync(string id, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task DeleteTriggerAsync(string id, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task DeleteUserDefinedFunctionAsync(string id, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task> ExecuteStoredProcedureAsync(string storedProcedureId, PartitionKey partitionKey, dynamic parameters, StoredProcedureRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ExecuteStoredProcedureStreamAsync(string storedProcedureId, PartitionKey partitionKey, dynamic parameters, StoredProcedureRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ExecuteStoredProcedureStreamAsync(string storedProcedureId, Stream streamPayload, PartitionKey partitionKey, StoredProcedureRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract FeedIterator GetStoredProcedureQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetStoredProcedureQueryIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetStoredProcedureQueryStreamIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetStoredProcedureQueryStreamIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetTriggerQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetTriggerQueryIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetTriggerQueryStreamIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetTriggerQueryStreamIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetUserDefinedFunctionQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetUserDefinedFunctionQueryIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetUserDefinedFunctionQueryStreamIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetUserDefinedFunctionQueryStreamIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract Task ReadStoredProcedureAsync(string id, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadTriggerAsync(string id, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadUserDefinedFunctionAsync(string id, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceStoredProcedureAsync(StoredProcedureProperties storedProcedureProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceTriggerAsync(TriggerProperties triggerProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceUserDefinedFunctionAsync(UserDefinedFunctionProperties userDefinedFunctionProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + } + public class StoredProcedureExecuteResponse : Response + { + protected StoredProcedureExecuteResponse(); + public override string ActivityId { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public override double RequestCharge { get; } + public override T Resource { get; } + public virtual string ScriptLog { get; } + public virtual string SessionToken { get; } + public override HttpStatusCode StatusCode { get; } + } + public class StoredProcedureProperties + { + public StoredProcedureProperties(); + public StoredProcedureProperties(string id, string body); + public string Body { get; set; } + public string ETag { get; } + public string Id { get; set; } + public Nullable LastModified { get; } + public string SelfLink { get; } + } + public class StoredProcedureRequestOptions : RequestOptions + { + public StoredProcedureRequestOptions(); + public Nullable ConsistencyLevel { get; set; } + public bool EnableScriptLogging { get; set; } + public string SessionToken { get; set; } + } + public class StoredProcedureResponse : Response + { + protected StoredProcedureResponse(); + public override string ActivityId { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public override double RequestCharge { get; } + public override StoredProcedureProperties Resource { get; } + public virtual string SessionToken { get; } + public override HttpStatusCode StatusCode { get; } + public static implicit operator StoredProcedureProperties (StoredProcedureResponse response); + } + public enum TriggerOperation : short + { + All = (short)0, + Create = (short)1, + Delete = (short)3, + Replace = (short)4, + Update = (short)2, + Upsert = (short)5, + } + public class TriggerProperties + { + public TriggerProperties(); + public string Body { get; set; } + public string ETag { get; } + public string Id { get; set; } + public string SelfLink { get; } + public TriggerOperation TriggerOperation { get; set; } + public TriggerType TriggerType { get; set; } + } + public class TriggerResponse : Response + { + protected TriggerResponse(); + public override string ActivityId { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public override double RequestCharge { get; } + public override TriggerProperties Resource { get; } + public override HttpStatusCode StatusCode { get; } + public static implicit operator TriggerProperties (TriggerResponse response); + } + public enum TriggerType : byte + { + Post = (byte)1, + Pre = (byte)0, + } + public class UserDefinedFunctionProperties + { + public UserDefinedFunctionProperties(); + public string Body { get; set; } + public string ETag { get; } + public string Id { get; set; } + public string SelfLink { get; } + } + public class UserDefinedFunctionResponse : Response + { + protected UserDefinedFunctionResponse(); + public override string ActivityId { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public override double RequestCharge { get; } + public override UserDefinedFunctionProperties Resource { get; } + public override HttpStatusCode StatusCode { get; } + public static implicit operator UserDefinedFunctionProperties (UserDefinedFunctionResponse response); + } +} +namespace Microsoft.Azure.Cosmos.Spatial +{ + public sealed class BoundingBox : IEquatable + { + public BoundingBox(Position min, Position max); + public Position Max { get; } + public Position Min { get; } + public bool Equals(BoundingBox other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public abstract class Crs + { + protected Crs(CrsType type); + public static Crs Default { get; } + public CrsType Type { get; } + public static Crs Unspecified { get; } + public static LinkedCrs Linked(string href); + public static LinkedCrs Linked(string href, string type); + public static NamedCrs Named(string name); + } + public enum CrsType + { + Linked = 1, + Named = 0, + Unspecified = 2, + } + public abstract class Geometry + { + protected Geometry(GeometryType type, GeometryParams geometryParams); + public IDictionary AdditionalProperties { get; } + public BoundingBox BoundingBox { get; } + public Crs Crs { get; } + public GeometryType Type { get; } + public double Distance(Geometry to); + public override bool Equals(object obj); + public override int GetHashCode(); + public bool Intersects(Geometry geometry2); + public bool IsValid(); + public GeometryValidationResult IsValidDetailed(); + public bool Within(Geometry outer); + } + public class GeometryParams + { + public GeometryParams(); + public IDictionary AdditionalProperties { get; set; } + public BoundingBox BoundingBox { get; set; } + public Crs Crs { get; set; } + } + public enum GeometryShape + { + GeometryCollection = 6, + LineString = 2, + MultiLineString = 3, + MultiPoint = 1, + MultiPolygon = 5, + Point = 0, + Polygon = 4, + } + public enum GeometryType + { + GeometryCollection = 6, + LineString = 2, + MultiLineString = 3, + MultiPoint = 1, + MultiPolygon = 5, + Point = 0, + Polygon = 4, + } + public class GeometryValidationResult + { + public GeometryValidationResult(); + public bool IsValid { get; } + public string Reason { get; } + } + public sealed class LinearRing : IEquatable + { + public LinearRing(IList coordinates); + public ReadOnlyCollection Positions { get; } + public bool Equals(LinearRing other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public sealed class LineString : Geometry, IEquatable + { + public LineString(IList coordinates); + public LineString(IList coordinates, GeometryParams geometryParams); + public ReadOnlyCollection Positions { get; } + public bool Equals(LineString other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public sealed class LinkedCrs : Crs, IEquatable + { + public string Href { get; } + public string HrefType { get; } + public bool Equals(LinkedCrs other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public sealed class MultiPolygon : Geometry, IEquatable + { + public MultiPolygon(IList polygons); + public MultiPolygon(IList polygons, GeometryParams geometryParams); + public ReadOnlyCollection Polygons { get; } + public bool Equals(MultiPolygon other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public sealed class NamedCrs : Crs, IEquatable + { + public string Name { get; } + public bool Equals(NamedCrs other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public sealed class Point : Geometry, IEquatable + { + public Point(Position position); + public Point(Position position, GeometryParams geometryParams); + public Point(double longitude, double latitude); + public Position Position { get; } + public bool Equals(Point other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public sealed class Polygon : Geometry, IEquatable + { + public Polygon(IList rings); + public Polygon(IList rings, GeometryParams geometryParams); + public Polygon(IList externalRingPositions); + public ReadOnlyCollection Rings { get; } + public bool Equals(Polygon other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public sealed class PolygonCoordinates : IEquatable + { + public PolygonCoordinates(IList rings); + public ReadOnlyCollection Rings { get; } + public bool Equals(PolygonCoordinates other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public sealed class Position : IEquatable + { + public Position(IList coordinates); + public Position(double longitude, double latitude); + public Position(double longitude, double latitude, Nullable altitude); + public Nullable Altitude { get; } + public ReadOnlyCollection Coordinates { get; } + public double Latitude { get; } + public double Longitude { get; } + public bool Equals(Position other); + public override bool Equals(object obj); + public override int GetHashCode(); + } +} diff --git a/Microsoft.Azure.Cosmos/contracts/API_3.36.0.txt b/Microsoft.Azure.Cosmos/contracts/API_3.36.0.txt new file mode 100644 index 0000000000..e4f36a2457 --- /dev/null +++ b/Microsoft.Azure.Cosmos/contracts/API_3.36.0.txt @@ -0,0 +1,1551 @@ +namespace Microsoft.Azure.Cosmos +{ + public class AccountConsistency + { + public AccountConsistency(); + public ConsistencyLevel DefaultConsistencyLevel { get; } + public int MaxStalenessIntervalInSeconds { get; } + public int MaxStalenessPrefix { get; } + } + public class AccountProperties + { + public AccountConsistency Consistency { get; } + public string ETag { get; } + public string Id { get; } + public IEnumerable ReadableRegions { get; } + public IEnumerable WritableRegions { get; } + } + public class AccountRegion + { + public AccountRegion(); + public string Endpoint { get; } + public string Name { get; } + } + public sealed class BoundingBoxProperties + { + public BoundingBoxProperties(); + public double Xmax { get; set; } + public double Xmin { get; set; } + public double Ymax { get; set; } + public double Ymin { get; set; } + } + public abstract class ChangeFeedEstimator + { + protected ChangeFeedEstimator(); + public abstract FeedIterator GetCurrentStateIterator(ChangeFeedEstimatorRequestOptions changeFeedEstimatorRequestOptions=null); + } + public sealed class ChangeFeedEstimatorRequestOptions + { + public ChangeFeedEstimatorRequestOptions(); + public Nullable MaxItemCount { get; set; } + } + public abstract class ChangeFeedMode + { + public static ChangeFeedMode Incremental { get; } + public static ChangeFeedMode LatestVersion { get; } + } + public abstract class ChangeFeedProcessor + { + protected ChangeFeedProcessor(); + public abstract Task StartAsync(); + public abstract Task StopAsync(); + } + public class ChangeFeedProcessorBuilder + { + public ChangeFeedProcessor Build(); + public ChangeFeedProcessorBuilder WithErrorNotification(Container.ChangeFeedMonitorErrorDelegate errorDelegate); + public ChangeFeedProcessorBuilder WithInstanceName(string instanceName); + public ChangeFeedProcessorBuilder WithLeaseAcquireNotification(Container.ChangeFeedMonitorLeaseAcquireDelegate acquireDelegate); + public ChangeFeedProcessorBuilder WithLeaseConfiguration(Nullable acquireInterval=default(Nullable), Nullable expirationInterval=default(Nullable), Nullable renewInterval=default(Nullable)); + public ChangeFeedProcessorBuilder WithLeaseContainer(Container leaseContainer); + public ChangeFeedProcessorBuilder WithLeaseReleaseNotification(Container.ChangeFeedMonitorLeaseReleaseDelegate releaseDelegate); + public ChangeFeedProcessorBuilder WithMaxItems(int maxItemCount); + public ChangeFeedProcessorBuilder WithPollInterval(TimeSpan pollInterval); + public ChangeFeedProcessorBuilder WithStartTime(DateTime startTime); + } + public abstract class ChangeFeedProcessorContext + { + protected ChangeFeedProcessorContext(); + public abstract CosmosDiagnostics Diagnostics { get; } + public abstract Headers Headers { get; } + public abstract string LeaseToken { get; } + } + public sealed class ChangeFeedProcessorState + { + public ChangeFeedProcessorState(string leaseToken, long estimatedLag, string instanceName); + public long EstimatedLag { get; } + public string InstanceName { get; } + public string LeaseToken { get; } + } + public class ChangeFeedProcessorUserException : Exception + { + public ChangeFeedProcessorUserException(Exception originalException, ChangeFeedProcessorContext context); + protected ChangeFeedProcessorUserException(SerializationInfo info, StreamingContext context); + public ChangeFeedProcessorContext ChangeFeedProcessorContext { get; } + public override void GetObjectData(SerializationInfo info, StreamingContext context); + } + public sealed class ChangeFeedRequestOptions : RequestOptions + { + public ChangeFeedRequestOptions(); + public new string IfMatchEtag { get; set; } + public new string IfNoneMatchEtag { get; set; } + public Nullable PageSizeHint { get; set; } + } + public abstract class ChangeFeedStartFrom + { + public static ChangeFeedStartFrom Beginning(); + public static ChangeFeedStartFrom Beginning(FeedRange feedRange); + public static ChangeFeedStartFrom ContinuationToken(string continuationToken); + public static ChangeFeedStartFrom Now(); + public static ChangeFeedStartFrom Now(FeedRange feedRange); + public static ChangeFeedStartFrom Time(DateTime dateTimeUtc); + public static ChangeFeedStartFrom Time(DateTime dateTimeUtc, FeedRange feedRange); + } + public sealed class ClientEncryptionIncludedPath + { + public ClientEncryptionIncludedPath(); + public string ClientEncryptionKeyId { get; set; } + public string EncryptionAlgorithm { get; set; } + public string EncryptionType { get; set; } + public string Path { get; set; } + } + public abstract class ClientEncryptionKey + { + protected ClientEncryptionKey(); + public abstract string Id { get; } + public abstract Task ReadAsync(RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceAsync(ClientEncryptionKeyProperties clientEncryptionKeyProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + } + public class ClientEncryptionKeyProperties : IEquatable + { + protected ClientEncryptionKeyProperties(); + public ClientEncryptionKeyProperties(string id, string encryptionAlgorithm, byte[] wrappedDataEncryptionKey, EncryptionKeyWrapMetadata encryptionKeyWrapMetadata); + public Nullable CreatedTime { get; } + public string EncryptionAlgorithm { get; } + public EncryptionKeyWrapMetadata EncryptionKeyWrapMetadata { get; } + public string ETag { get; } + public string Id { get; } + public Nullable LastModified { get; } + public virtual string SelfLink { get; } + public byte[] WrappedDataEncryptionKey { get; } + public bool Equals(ClientEncryptionKeyProperties other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public class ClientEncryptionKeyResponse : Response + { + protected ClientEncryptionKeyResponse(); + public override string ActivityId { get; } + public virtual ClientEncryptionKey ClientEncryptionKey { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public override double RequestCharge { get; } + public override ClientEncryptionKeyProperties Resource { get; } + public override HttpStatusCode StatusCode { get; } + public static implicit operator ClientEncryptionKey (ClientEncryptionKeyResponse response); + } + public sealed class ClientEncryptionPolicy + { + public ClientEncryptionPolicy(IEnumerable includedPaths); + public ClientEncryptionPolicy(IEnumerable includedPaths, int policyFormatVersion); + public IEnumerable IncludedPaths { get; } + public int PolicyFormatVersion { get; } + } + public sealed class CompositePath + { + public CompositePath(); + public CompositePathSortOrder Order { get; set; } + public string Path { get; set; } + } + public enum CompositePathSortOrder + { + Ascending = 0, + Descending = 1, + } + public class ConflictProperties + { + public ConflictProperties(); + public string Id { get; } + public OperationKind OperationKind { get; } + public string SelfLink { get; } + } + public enum ConflictResolutionMode + { + Custom = 1, + LastWriterWins = 0, + } + public class ConflictResolutionPolicy + { + public ConflictResolutionPolicy(); + public ConflictResolutionMode Mode { get; set; } + public string ResolutionPath { get; set; } + public string ResolutionProcedure { get; set; } + } + public abstract class Conflicts + { + protected Conflicts(); + public abstract Task DeleteAsync(ConflictProperties conflict, PartitionKey partitionKey, CancellationToken cancellationToken=default(CancellationToken)); + public abstract FeedIterator GetConflictQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetConflictQueryIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetConflictQueryStreamIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetConflictQueryStreamIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract T ReadConflictContent(ConflictProperties conflict); + public abstract Task> ReadCurrentAsync(ConflictProperties conflict, PartitionKey partitionKey, CancellationToken cancellationToken=default(CancellationToken)); + } + public enum ConnectionMode + { + Direct = 1, + Gateway = 0, + } + public enum ConsistencyLevel + { + BoundedStaleness = 1, + ConsistentPrefix = 4, + Eventual = 3, + Session = 2, + Strong = 0, + } + public abstract class Container + { + protected Container(); + public abstract Conflicts Conflicts { get; } + public abstract Database Database { get; } + public abstract string Id { get; } + public abstract Scripts Scripts { get; } + public abstract Task> CreateItemAsync(T item, Nullable partitionKey=default(Nullable), ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateItemStreamAsync(Stream streamPayload, PartitionKey partitionKey, ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract TransactionalBatch CreateTransactionalBatch(PartitionKey partitionKey); + public abstract Task DeleteContainerAsync(ContainerRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task DeleteContainerStreamAsync(ContainerRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task> DeleteItemAsync(string id, PartitionKey partitionKey, ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task DeleteItemStreamAsync(string id, PartitionKey partitionKey, ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract ChangeFeedEstimator GetChangeFeedEstimator(string processorName, Container leaseContainer); + public abstract ChangeFeedProcessorBuilder GetChangeFeedEstimatorBuilder(string processorName, Container.ChangesEstimationHandler estimationDelegate, Nullable estimationPeriod=default(Nullable)); + public abstract FeedIterator GetChangeFeedIterator(ChangeFeedStartFrom changeFeedStartFrom, ChangeFeedMode changeFeedMode, ChangeFeedRequestOptions changeFeedRequestOptions=null); + public abstract ChangeFeedProcessorBuilder GetChangeFeedProcessorBuilder(string processorName, Container.ChangeFeedStreamHandler onChangesDelegate); + public abstract ChangeFeedProcessorBuilder GetChangeFeedProcessorBuilderWithManualCheckpoint(string processorName, Container.ChangeFeedStreamHandlerWithManualCheckpoint onChangesDelegate); + public abstract ChangeFeedProcessorBuilder GetChangeFeedProcessorBuilderWithManualCheckpoint(string processorName, Container.ChangeFeedHandlerWithManualCheckpoint onChangesDelegate); + public abstract ChangeFeedProcessorBuilder GetChangeFeedProcessorBuilder(string processorName, Container.ChangeFeedHandler onChangesDelegate); + public abstract ChangeFeedProcessorBuilder GetChangeFeedProcessorBuilder(string processorName, Container.ChangesHandler onChangesDelegate); + public abstract FeedIterator GetChangeFeedStreamIterator(ChangeFeedStartFrom changeFeedStartFrom, ChangeFeedMode changeFeedMode, ChangeFeedRequestOptions changeFeedRequestOptions=null); + public abstract Task> GetFeedRangesAsync(CancellationToken cancellationToken=default(CancellationToken)); + public abstract IOrderedQueryable GetItemLinqQueryable(bool allowSynchronousQueryExecution=false, string continuationToken=null, QueryRequestOptions requestOptions=null, CosmosLinqSerializerOptions linqSerializerOptions=null); + public abstract FeedIterator GetItemQueryIterator(FeedRange feedRange, QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetItemQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetItemQueryIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetItemQueryStreamIterator(FeedRange feedRange, QueryDefinition queryDefinition, string continuationToken, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetItemQueryStreamIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetItemQueryStreamIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract Task> PatchItemAsync(string id, PartitionKey partitionKey, IReadOnlyList patchOperations, PatchItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task PatchItemStreamAsync(string id, PartitionKey partitionKey, IReadOnlyList patchOperations, PatchItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadContainerAsync(ContainerRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadContainerStreamAsync(ContainerRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task> ReadItemAsync(string id, PartitionKey partitionKey, ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadItemStreamAsync(string id, PartitionKey partitionKey, ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task> ReadManyItemsAsync(IReadOnlyList> items, ReadManyRequestOptions readManyRequestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadManyItemsStreamAsync(IReadOnlyList> items, ReadManyRequestOptions readManyRequestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadThroughputAsync(RequestOptions requestOptions, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task> ReadThroughputAsync(CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceContainerAsync(ContainerProperties containerProperties, ContainerRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceContainerStreamAsync(ContainerProperties containerProperties, ContainerRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task> ReplaceItemAsync(T item, string id, Nullable partitionKey=default(Nullable), ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceItemStreamAsync(Stream streamPayload, string id, PartitionKey partitionKey, ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceThroughputAsync(ThroughputProperties throughputProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceThroughputAsync(int throughput, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task> UpsertItemAsync(T item, Nullable partitionKey=default(Nullable), ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task UpsertItemStreamAsync(Stream streamPayload, PartitionKey partitionKey, ItemRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public delegate Task ChangeFeedHandlerWithManualCheckpoint(ChangeFeedProcessorContext context, IReadOnlyCollection changes, Func checkpointAsync, CancellationToken cancellationToken); + public delegate Task ChangeFeedHandler(ChangeFeedProcessorContext context, IReadOnlyCollection changes, CancellationToken cancellationToken); + public delegate Task ChangeFeedMonitorErrorDelegate(string leaseToken, Exception exception); + public delegate Task ChangeFeedMonitorLeaseAcquireDelegate(string leaseToken); + public delegate Task ChangeFeedMonitorLeaseReleaseDelegate(string leaseToken); + public delegate Task ChangeFeedStreamHandler(ChangeFeedProcessorContext context, Stream changes, CancellationToken cancellationToken); + public delegate Task ChangeFeedStreamHandlerWithManualCheckpoint(ChangeFeedProcessorContext context, Stream changes, Func checkpointAsync, CancellationToken cancellationToken); + public delegate Task ChangesEstimationHandler(long estimatedPendingChanges, CancellationToken cancellationToken); + public delegate Task ChangesHandler(IReadOnlyCollection changes, CancellationToken cancellationToken); + } + public class ContainerProperties + { + public ContainerProperties(); + public ContainerProperties(string id, IReadOnlyList partitionKeyPaths); + public ContainerProperties(string id, string partitionKeyPath); + public Nullable AnalyticalStoreTimeToLiveInSeconds { get; set; } + public ClientEncryptionPolicy ClientEncryptionPolicy { get; set; } + public ConflictResolutionPolicy ConflictResolutionPolicy { get; set; } + public Nullable DefaultTimeToLive { get; set; } + public string ETag { get; } + public GeospatialConfig GeospatialConfig { get; set; } + public string Id { get; set; } + public IndexingPolicy IndexingPolicy { get; set; } + public Nullable LastModified { get; } + public Nullable PartitionKeyDefinitionVersion { get; set; } + public string PartitionKeyPath { get; set; } + public IReadOnlyList PartitionKeyPaths { get; set; } + public string SelfLink { get; } + public string TimeToLivePropertyPath { get; set; } + public UniqueKeyPolicy UniqueKeyPolicy { get; set; } + } + public class ContainerRequestOptions : RequestOptions + { + public ContainerRequestOptions(); + public bool PopulateQuotaInfo { get; set; } + } + public class ContainerResponse : Response + { + protected ContainerResponse(); + public override string ActivityId { get; } + public virtual Container Container { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public override double RequestCharge { get; } + public override ContainerProperties Resource { get; } + public override HttpStatusCode StatusCode { get; } + public static implicit operator Container (ContainerResponse response); + } + public class CosmosClient : IDisposable + { + protected CosmosClient(); + public CosmosClient(string accountEndpoint, AzureKeyCredential authKeyOrResourceTokenCredential, CosmosClientOptions clientOptions=null); + public CosmosClient(string accountEndpoint, TokenCredential tokenCredential, CosmosClientOptions clientOptions=null); + public CosmosClient(string connectionString, CosmosClientOptions clientOptions=null); + public CosmosClient(string accountEndpoint, string authKeyOrResourceToken, CosmosClientOptions clientOptions=null); + public virtual CosmosClientOptions ClientOptions { get; } + public virtual Uri Endpoint { get; } + public virtual CosmosResponseFactory ResponseFactory { get; } + public static Task CreateAndInitializeAsync(string accountEndpoint, AzureKeyCredential authKeyOrResourceTokenCredential, IReadOnlyList> containers, CosmosClientOptions cosmosClientOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public static Task CreateAndInitializeAsync(string accountEndpoint, TokenCredential tokenCredential, IReadOnlyList> containers, CosmosClientOptions cosmosClientOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public static Task CreateAndInitializeAsync(string connectionString, IReadOnlyList> containers, CosmosClientOptions cosmosClientOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public static Task CreateAndInitializeAsync(string accountEndpoint, string authKeyOrResourceToken, IReadOnlyList> containers, CosmosClientOptions cosmosClientOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public virtual Task CreateDatabaseAsync(string id, ThroughputProperties throughputProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public virtual Task CreateDatabaseAsync(string id, Nullable throughput=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public virtual Task CreateDatabaseIfNotExistsAsync(string id, ThroughputProperties throughputProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public virtual Task CreateDatabaseIfNotExistsAsync(string id, Nullable throughput=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public virtual Task CreateDatabaseStreamAsync(DatabaseProperties databaseProperties, Nullable throughput=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public void Dispose(); + protected virtual void Dispose(bool disposing); + public virtual Container GetContainer(string databaseId, string containerId); + public virtual Database GetDatabase(string id); + public virtual FeedIterator GetDatabaseQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public virtual FeedIterator GetDatabaseQueryIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public virtual FeedIterator GetDatabaseQueryStreamIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public virtual FeedIterator GetDatabaseQueryStreamIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public virtual Task ReadAccountAsync(); + } + public class CosmosClientOptions + { + public CosmosClientOptions(); + public bool AllowBulkExecution { get; set; } + public string ApplicationName { get; set; } + public IReadOnlyList ApplicationPreferredRegions { get; set; } + public string ApplicationRegion { get; set; } + public ConnectionMode ConnectionMode { get; set; } + public Nullable ConsistencyLevel { get; set; } + public CosmosClientTelemetryOptions CosmosClientTelemetryOptions { get; set; } + public Collection CustomHandlers { get; } + public Nullable EnableContentResponseOnWrite { get; set; } + public bool EnableTcpConnectionEndpointRediscovery { get; set; } + public int GatewayModeMaxConnectionLimit { get; set; } + public Func HttpClientFactory { get; set; } + public Nullable IdleTcpConnectionTimeout { get; set; } + public bool LimitToEndpoint { get; set; } + public Nullable MaxRequestsPerTcpConnection { get; set; } + public Nullable MaxRetryAttemptsOnRateLimitedRequests { get; set; } + public Nullable MaxRetryWaitTimeOnRateLimitedRequests { get; set; } + public Nullable MaxTcpConnectionsPerEndpoint { get; set; } + public Nullable OpenTcpConnectionTimeout { get; set; } + public Nullable PortReuseMode { get; set; } + public TimeSpan RequestTimeout { get; set; } + public CosmosSerializer Serializer { get; set; } + public CosmosSerializationOptions SerializerOptions { get; set; } + public Func ServerCertificateCustomValidationCallback { get; set; } + public Nullable TokenCredentialBackgroundRefreshInterval { get; set; } + public IWebProxy WebProxy { get; set; } + } + public class CosmosClientTelemetryOptions + { + public CosmosClientTelemetryOptions(); + public CosmosThresholdOptions CosmosThresholdOptions { get; set; } + public bool DisableDistributedTracing { get; set; } + public bool DisableSendingMetricsToService { get; set; } + } + public abstract class CosmosDiagnostics + { + protected CosmosDiagnostics(); + public virtual TimeSpan GetClientElapsedTime(); + public abstract IReadOnlyList> GetContactedRegions(); + public virtual int GetFailedRequestCount(); + public virtual ServerSideCumulativeMetrics GetQueryMetrics(); + public virtual Nullable GetStartTimeUtc(); + public abstract override string ToString(); + } + public class CosmosException : Exception + { + public CosmosException(string message, HttpStatusCode statusCode, int subStatusCode, string activityId, double requestCharge); + public virtual string ActivityId { get; } + public virtual CosmosDiagnostics Diagnostics { get; } + public virtual Headers Headers { get; } + public override string Message { get; } + public virtual double RequestCharge { get; } + public virtual string ResponseBody { get; } + public virtual Nullable RetryAfter { get; } + public override string StackTrace { get; } + public virtual HttpStatusCode StatusCode { get; } + public virtual int SubStatusCode { get; } + public override string ToString(); + public virtual bool TryGetHeader(string headerName, out string value); + } + public sealed class CosmosLinqSerializerOptions + { + public CosmosLinqSerializerOptions(); + public CosmosPropertyNamingPolicy PropertyNamingPolicy { get; set; } + } + public class CosmosOperationCanceledException : OperationCanceledException + { + public CosmosOperationCanceledException(OperationCanceledException originalException, CosmosDiagnostics diagnostics); + protected CosmosOperationCanceledException(SerializationInfo info, StreamingContext context); + public override IDictionary Data { get; } + public CosmosDiagnostics Diagnostics { get; } + public override string HelpLink { get; set; } + public override string Message { get; } + public override string Source { get; set; } + public override string StackTrace { get; } + public override Exception GetBaseException(); + public override void GetObjectData(SerializationInfo info, StreamingContext context); + public override string ToString(); + } + public enum CosmosPropertyNamingPolicy + { + CamelCase = 1, + Default = 0, + } + public abstract class CosmosResponseFactory + { + protected CosmosResponseFactory(); + public abstract FeedResponse CreateItemFeedResponse(ResponseMessage responseMessage); + public abstract ItemResponse CreateItemResponse(ResponseMessage responseMessage); + public abstract StoredProcedureExecuteResponse CreateStoredProcedureExecuteResponse(ResponseMessage responseMessage); + } + public sealed class CosmosSerializationOptions + { + public CosmosSerializationOptions(); + public bool IgnoreNullValues { get; set; } + public bool Indented { get; set; } + public CosmosPropertyNamingPolicy PropertyNamingPolicy { get; set; } + } + public abstract class CosmosSerializer + { + protected CosmosSerializer(); + public abstract T FromStream(Stream stream); + public abstract Stream ToStream(T input); + } + public class CosmosThresholdOptions + { + public CosmosThresholdOptions(); + public TimeSpan NonPointOperationLatencyThreshold { get; set; } + public TimeSpan PointOperationLatencyThreshold { get; set; } + } + public abstract class Database + { + protected Database(); + public abstract CosmosClient Client { get; } + public abstract string Id { get; } + public abstract Task CreateClientEncryptionKeyAsync(ClientEncryptionKeyProperties clientEncryptionKeyProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateContainerAsync(ContainerProperties containerProperties, ThroughputProperties throughputProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateContainerAsync(ContainerProperties containerProperties, Nullable throughput=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateContainerAsync(string id, string partitionKeyPath, Nullable throughput=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateContainerIfNotExistsAsync(ContainerProperties containerProperties, ThroughputProperties throughputProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateContainerIfNotExistsAsync(ContainerProperties containerProperties, Nullable throughput=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateContainerIfNotExistsAsync(string id, string partitionKeyPath, Nullable throughput=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateContainerStreamAsync(ContainerProperties containerProperties, ThroughputProperties throughputProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateContainerStreamAsync(ContainerProperties containerProperties, Nullable throughput=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateUserAsync(string id, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract ContainerBuilder DefineContainer(string name, string partitionKeyPath); + public abstract Task DeleteAsync(RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task DeleteStreamAsync(RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract ClientEncryptionKey GetClientEncryptionKey(string id); + public abstract FeedIterator GetClientEncryptionKeyQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract Container GetContainer(string id); + public abstract FeedIterator GetContainerQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetContainerQueryIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetContainerQueryStreamIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetContainerQueryStreamIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract User GetUser(string id); + public abstract FeedIterator GetUserQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetUserQueryIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract Task ReadAsync(RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadStreamAsync(RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadThroughputAsync(RequestOptions requestOptions, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task> ReadThroughputAsync(CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceThroughputAsync(ThroughputProperties throughputProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceThroughputAsync(int throughput, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task UpsertUserAsync(string id, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + } + public class DatabaseProperties + { + public DatabaseProperties(); + public DatabaseProperties(string id); + public string ETag { get; } + public string Id { get; set; } + public Nullable LastModified { get; } + public string SelfLink { get; } + } + public class DatabaseResponse : Response + { + protected DatabaseResponse(); + public override string ActivityId { get; } + public virtual Database Database { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public override double RequestCharge { get; } + public override DatabaseProperties Resource { get; } + public override HttpStatusCode StatusCode { get; } + public static implicit operator Database (DatabaseResponse response); + } + public enum DataType + { + LineString = 3, + MultiPolygon = 5, + Number = 0, + Point = 2, + Polygon = 4, + String = 1, + } + public class DedicatedGatewayRequestOptions + { + public DedicatedGatewayRequestOptions(); + public Nullable MaxIntegratedCacheStaleness { get; set; } + } + public class EncryptionKeyWrapMetadata : IEquatable + { + public EncryptionKeyWrapMetadata(EncryptionKeyWrapMetadata source); + public EncryptionKeyWrapMetadata(string type, string name, string value, string algorithm); + public string Algorithm { get; } + public string Name { get; } + public string Type { get; } + public string Value { get; } + public bool Equals(EncryptionKeyWrapMetadata other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public sealed class ExcludedPath + { + public ExcludedPath(); + public string Path { get; set; } + } + public abstract class FeedIterator : IDisposable + { + protected FeedIterator(); + public abstract bool HasMoreResults { get; } + public void Dispose(); + protected virtual void Dispose(bool disposing); + public abstract Task ReadNextAsync(CancellationToken cancellationToken=default(CancellationToken)); + } + public abstract class FeedIterator : IDisposable + { + protected FeedIterator(); + public abstract bool HasMoreResults { get; } + public void Dispose(); + protected virtual void Dispose(bool disposing); + public abstract Task> ReadNextAsync(CancellationToken cancellationToken=default(CancellationToken)); + } + public abstract class FeedRange + { + protected FeedRange(); + public static FeedRange FromJsonString(string toStringValue); + public static FeedRange FromPartitionKey(PartitionKey partitionKey); + public abstract string ToJsonString(); + } + public abstract class FeedResponse : IEnumerable, IEnumerable + { + protected FeedResponse(); + public override string ActivityId { get; } + public abstract string ContinuationToken { get; } + public abstract int Count { get; } + public override string ETag { get; } + public abstract string IndexMetrics { get; } + public override double RequestCharge { get; } + public abstract IEnumerator GetEnumerator(); + IEnumerator System.Collections.IEnumerable.GetEnumerator(); + } + public sealed class GeospatialConfig + { + public GeospatialConfig(); + public GeospatialConfig(GeospatialType geospatialType); + public GeospatialType GeospatialType { get; set; } + } + public enum GeospatialType + { + Geography = 0, + Geometry = 1, + } + public class Headers : IEnumerable + { + public Headers(); + public virtual string ActivityId { get; } + public virtual string ContentLength { get; set; } + public virtual string ContentType { get; } + public virtual string ContinuationToken { get; } + public virtual string ETag { get; } + public virtual string this[string headerName] { get; set; } + public virtual string Location { get; } + public virtual double RequestCharge { get; } + public virtual string Session { get; } + public virtual void Add(string headerName, IEnumerable values); + public virtual void Add(string headerName, string value); + public virtual string[] AllKeys(); + public virtual string Get(string headerName); + public virtual IEnumerator GetEnumerator(); + public virtual T GetHeaderValue(string headerName); + public virtual string GetValueOrDefault(string headerName); + public virtual void Remove(string headerName); + public virtual void Set(string headerName, string value); + IEnumerator System.Collections.IEnumerable.GetEnumerator(); + public virtual bool TryGetValue(string headerName, out string value); + } + public sealed class IncludedPath + { + public IncludedPath(); + public string Path { get; set; } + } + public enum IndexingDirective + { + Default = 0, + Exclude = 2, + Include = 1, + } + public enum IndexingMode + { + Consistent = 0, + Lazy = 1, + None = 2, + } + public sealed class IndexingPolicy + { + public IndexingPolicy(); + public bool Automatic { get; set; } + public Collection> CompositeIndexes { get; } + public Collection ExcludedPaths { get; } + public Collection IncludedPaths { get; } + public IndexingMode IndexingMode { get; set; } + public Collection SpatialIndexes { get; } + } + public enum IndexKind + { + Hash = 0, + Range = 1, + Spatial = 2, + } + public class ItemRequestOptions : RequestOptions + { + public ItemRequestOptions(); + public Nullable ConsistencyLevel { get; set; } + public DedicatedGatewayRequestOptions DedicatedGatewayRequestOptions { get; set; } + public Nullable EnableContentResponseOnWrite { get; set; } + public Nullable IndexingDirective { get; set; } + public IEnumerable PostTriggers { get; set; } + public IEnumerable PreTriggers { get; set; } + public string SessionToken { get; set; } + } + public class ItemResponse : Response + { + protected ItemResponse(); + public override string ActivityId { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public override double RequestCharge { get; } + public override T Resource { get; } + public override HttpStatusCode StatusCode { get; } + } + public enum OperationKind + { + Create = 1, + Delete = 3, + Invalid = 0, + Read = 4, + Replace = 2, + } + public struct PartitionKey : IEquatable + { + public static readonly PartitionKey None; + public static readonly PartitionKey Null; + public static readonly string SystemKeyName; + public static readonly string SystemKeyPath; + public PartitionKey(bool partitionKeyValue); + public PartitionKey(double partitionKeyValue); + public PartitionKey(string partitionKeyValue); + public bool Equals(PartitionKey other); + public override bool Equals(object obj); + public override int GetHashCode(); + public static bool operator ==(PartitionKey left, PartitionKey right); + public static bool operator !=(PartitionKey left, PartitionKey right); + public override string ToString(); + } + public sealed class PartitionKeyBuilder + { + public PartitionKeyBuilder(); + public PartitionKeyBuilder Add(bool val); + public PartitionKeyBuilder Add(double val); + public PartitionKeyBuilder Add(string val); + public PartitionKeyBuilder AddNoneType(); + public PartitionKeyBuilder AddNullValue(); + public PartitionKey Build(); + } + public enum PartitionKeyDefinitionVersion + { + V1 = 1, + V2 = 2, + } + public sealed class PatchItemRequestOptions : ItemRequestOptions + { + public PatchItemRequestOptions(); + public string FilterPredicate { get; set; } + } + public abstract class PatchOperation + { + protected PatchOperation(); + public virtual string From { get; set; } + public abstract PatchOperationType OperationType { get; } + public abstract string Path { get; } + public static PatchOperation Add(string path, T value); + public static PatchOperation Increment(string path, double value); + public static PatchOperation Increment(string path, long value); + public static PatchOperation Move(string from, string path); + public static PatchOperation Remove(string path); + public static PatchOperation Replace(string path, T value); + public static PatchOperation Set(string path, T value); + public virtual bool TrySerializeValueParameter(CosmosSerializer cosmosSerializer, out Stream valueParam); + } + public enum PatchOperationType + { + Add = 0, + Increment = 4, + Move = 5, + Remove = 1, + Replace = 2, + Set = 3, + } + public abstract class PatchOperation : PatchOperation + { + protected PatchOperation(); + public abstract T Value { get; } + } + public abstract class Permission + { + protected Permission(); + public abstract string Id { get; } + public abstract Task DeleteAsync(RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadAsync(Nullable tokenExpiryInSeconds=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceAsync(PermissionProperties permissionProperties, Nullable tokenExpiryInSeconds=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + } + public enum PermissionMode : byte + { + All = (byte)2, + Read = (byte)1, + } + public class PermissionProperties + { + public PermissionProperties(string id, PermissionMode permissionMode, Container container, PartitionKey resourcePartitionKey, string itemId); + public PermissionProperties(string id, PermissionMode permissionMode, Container container, Nullable resourcePartitionKey=default(Nullable)); + public string ETag { get; } + public string Id { get; } + public Nullable LastModified { get; } + public PermissionMode PermissionMode { get; } + public Nullable ResourcePartitionKey { get; set; } + public string ResourceUri { get; } + public string SelfLink { get; } + public string Token { get; } + } + public class PermissionResponse : Response + { + protected PermissionResponse(); + public override string ActivityId { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public virtual Permission Permission { get; } + public override double RequestCharge { get; } + public override PermissionProperties Resource { get; } + public override HttpStatusCode StatusCode { get; } + public static implicit operator Permission (PermissionResponse response); + } + public enum PortReuseMode + { + PrivatePortPool = 1, + ReuseUnicastPort = 0, + } + public class QueryDefinition + { + public QueryDefinition(string query); + public string QueryText { get; } + public IReadOnlyList> GetQueryParameters(); + public QueryDefinition WithParameter(string name, object value); + public QueryDefinition WithParameterStream(string name, Stream valueStream); + } + public class QueryRequestOptions : RequestOptions + { + public QueryRequestOptions(); + public Nullable ConsistencyLevel { get; set; } + public DedicatedGatewayRequestOptions DedicatedGatewayRequestOptions { get; set; } + public Nullable EnableLowPrecisionOrderBy { get; set; } + public Nullable EnableScanInQuery { get; set; } + public Nullable MaxBufferedItemCount { get; set; } + public Nullable MaxConcurrency { get; set; } + public Nullable MaxItemCount { get; set; } + public Nullable PartitionKey { get; set; } + public Nullable PopulateIndexMetrics { get; set; } + public Nullable ResponseContinuationTokenLimitInKb { get; set; } + public string SessionToken { get; set; } + } + public class ReadManyRequestOptions : RequestOptions + { + public ReadManyRequestOptions(); + public Nullable ConsistencyLevel { get; set; } + public string SessionToken { get; set; } + } + public static class Regions + { + public const string AustraliaCentral = "Australia Central"; + public const string AustraliaCentral2 = "Australia Central 2"; + public const string AustraliaEast = "Australia East"; + public const string AustraliaSoutheast = "Australia Southeast"; + public const string BrazilSouth = "Brazil South"; + public const string BrazilSoutheast = "Brazil Southeast"; + public const string CanadaCentral = "Canada Central"; + public const string CanadaEast = "Canada East"; + public const string CentralIndia = "Central India"; + public const string CentralUS = "Central US"; + public const string CentralUSEUAP = "Central US EUAP"; + public const string ChinaEast = "China East"; + public const string ChinaEast2 = "China East 2"; + public const string ChinaEast3 = "China East 3"; + public const string ChinaNorth = "China North"; + public const string ChinaNorth2 = "China North 2"; + public const string ChinaNorth3 = "China North 3"; + public const string EastAsia = "East Asia"; + public const string EastUS = "East US"; + public const string EastUS2 = "East US 2"; + public const string EastUS2EUAP = "East US 2 EUAP"; + public const string EastUSSLV = "East US SLV"; + public const string FranceCentral = "France Central"; + public const string FranceSouth = "France South"; + public const string GermanyCentral = "Germany Central"; + public const string GermanyNorth = "Germany North"; + public const string GermanyNortheast = "Germany Northeast"; + public const string GermanyWestCentral = "Germany West Central"; + public const string IsraelCentral = "Israel Central"; + public const string ItalyNorth = "Italy North"; + public const string JapanEast = "Japan East"; + public const string JapanWest = "Japan West"; + public const string JioIndiaCentral = "Jio India Central"; + public const string JioIndiaWest = "Jio India West"; + public const string KoreaCentral = "Korea Central"; + public const string KoreaSouth = "Korea South"; + public const string MalaysiaSouth = "Malaysia South"; + public const string NorthCentralUS = "North Central US"; + public const string NorthEurope = "North Europe"; + public const string NorwayEast = "Norway East"; + public const string NorwayWest = "Norway West"; + public const string PolandCentral = "Poland Central"; + public const string QatarCentral = "Qatar Central"; + public const string SouthAfricaNorth = "South Africa North"; + public const string SouthAfricaWest = "South Africa West"; + public const string SouthCentralUS = "South Central US"; + public const string SoutheastAsia = "Southeast Asia"; + public const string SouthIndia = "South India"; + public const string SwedenCentral = "Sweden Central"; + public const string SwedenSouth = "Sweden South"; + public const string SwitzerlandNorth = "Switzerland North"; + public const string SwitzerlandWest = "Switzerland West"; + public const string UAECentral = "UAE Central"; + public const string UAENorth = "UAE North"; + public const string UKSouth = "UK South"; + public const string UKWest = "UK West"; + public const string USDoDCentral = "USDoD Central"; + public const string USDoDEast = "USDoD East"; + public const string USGovArizona = "USGov Arizona"; + public const string USGovTexas = "USGov Texas"; + public const string USGovVirginia = "USGov Virginia"; + public const string USNatEast = "USNat East"; + public const string USNatWest = "USNat West"; + public const string USSecEast = "USSec East"; + public const string USSecWest = "USSec West"; + public const string WestCentralUS = "West Central US"; + public const string WestEurope = "West Europe"; + public const string WestIndia = "West India"; + public const string WestUS = "West US"; + public const string WestUS2 = "West US 2"; + public const string WestUS3 = "West US 3"; + } + public abstract class RequestHandler + { + protected RequestHandler(); + public RequestHandler InnerHandler { get; set; } + public virtual Task SendAsync(RequestMessage request, CancellationToken cancellationToken); + } + public class RequestMessage : IDisposable + { + public RequestMessage(); + public RequestMessage(HttpMethod method, Uri requestUri); + public virtual Stream Content { get; set; } + public virtual Headers Headers { get; } + public virtual HttpMethod Method { get; } + public virtual Dictionary Properties { get; } + public virtual Uri RequestUri { get; } + public void Dispose(); + protected virtual void Dispose(bool disposing); + } + public class RequestOptions + { + public RequestOptions(); + public Action AddRequestHeaders { get; set; } + public CosmosThresholdOptions CosmosThresholdOptions { get; set; } + public string IfMatchEtag { get; set; } + public string IfNoneMatchEtag { get; set; } + public IReadOnlyDictionary Properties { get; set; } + public RequestOptions ShallowCopy(); + } + public class ResponseMessage : IDisposable + { + public ResponseMessage(); + public ResponseMessage(HttpStatusCode statusCode, RequestMessage requestMessage=null, string errorMessage=null); + public virtual Stream Content { get; set; } + public virtual string ContinuationToken { get; } + public virtual CosmosDiagnostics Diagnostics { get; set; } + public virtual string ErrorMessage { get; } + public virtual Headers Headers { get; } + public string IndexMetrics { get; } + public virtual bool IsSuccessStatusCode { get; } + public virtual RequestMessage RequestMessage { get; } + public virtual HttpStatusCode StatusCode { get; } + public void Dispose(); + protected virtual void Dispose(bool disposing); + public virtual ResponseMessage EnsureSuccessStatusCode(); + } + public abstract class Response + { + protected Response(); + public abstract string ActivityId { get; } + public abstract CosmosDiagnostics Diagnostics { get; } + public abstract string ETag { get; } + public abstract Headers Headers { get; } + public abstract double RequestCharge { get; } + public abstract T Resource { get; } + public abstract HttpStatusCode StatusCode { get; } + public static implicit operator T (Response response); + } + public abstract class ServerSideCumulativeMetrics + { + protected ServerSideCumulativeMetrics(); + public abstract ServerSideMetrics CumulativeMetrics { get; } + public abstract IReadOnlyList PartitionedMetrics { get; } + } + public abstract class ServerSideMetrics + { + protected ServerSideMetrics(); + public abstract TimeSpan DocumentLoadTime { get; } + public abstract TimeSpan DocumentWriteTime { get; } + public abstract double IndexHitRatio { get; } + public abstract TimeSpan IndexLookupTime { get; } + public abstract long OutputDocumentCount { get; } + public abstract long OutputDocumentSize { get; } + public abstract TimeSpan QueryPreparationTime { get; } + public abstract long RetrievedDocumentCount { get; } + public abstract long RetrievedDocumentSize { get; } + public abstract TimeSpan RuntimeExecutionTime { get; } + public abstract TimeSpan TotalTime { get; } + public abstract TimeSpan VMExecutionTime { get; } + } + public abstract class ServerSidePartitionedMetrics + { + protected ServerSidePartitionedMetrics(); + public abstract string FeedRange { get; } + public abstract Nullable PartitionKeyRangeId { get; } + public abstract ServerSideMetrics ServerSideMetrics { get; } + } + public sealed class SpatialPath + { + public SpatialPath(); + public BoundingBoxProperties BoundingBox { get; set; } + public string Path { get; set; } + public Collection SpatialTypes { get; } + } + public enum SpatialType + { + LineString = 1, + MultiPolygon = 3, + Point = 0, + Polygon = 2, + } + public class ThroughputProperties + { + public Nullable AutoscaleMaxThroughput { get; } + public string ETag { get; } + public Nullable LastModified { get; } + public string SelfLink { get; } + public Nullable Throughput { get; } + public static ThroughputProperties CreateAutoscaleThroughput(int autoscaleMaxThroughput); + public static ThroughputProperties CreateManualThroughput(int throughput); + } + public class ThroughputResponse : Response + { + protected ThroughputResponse(); + public override string ActivityId { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public Nullable IsReplacePending { get; } + public Nullable MinThroughput { get; } + public override double RequestCharge { get; } + public override ThroughputProperties Resource { get; } + public override HttpStatusCode StatusCode { get; } + public static implicit operator ThroughputProperties (ThroughputResponse response); + } + public abstract class TransactionalBatch + { + protected TransactionalBatch(); + public abstract TransactionalBatch CreateItemStream(Stream streamPayload, TransactionalBatchItemRequestOptions requestOptions=null); + public abstract TransactionalBatch CreateItem(T item, TransactionalBatchItemRequestOptions requestOptions=null); + public abstract TransactionalBatch DeleteItem(string id, TransactionalBatchItemRequestOptions requestOptions=null); + public abstract Task ExecuteAsync(TransactionalBatchRequestOptions requestOptions, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ExecuteAsync(CancellationToken cancellationToken=default(CancellationToken)); + public abstract TransactionalBatch PatchItem(string id, IReadOnlyList patchOperations, TransactionalBatchPatchItemRequestOptions requestOptions=null); + public abstract TransactionalBatch ReadItem(string id, TransactionalBatchItemRequestOptions requestOptions=null); + public abstract TransactionalBatch ReplaceItemStream(string id, Stream streamPayload, TransactionalBatchItemRequestOptions requestOptions=null); + public abstract TransactionalBatch ReplaceItem(string id, T item, TransactionalBatchItemRequestOptions requestOptions=null); + public abstract TransactionalBatch UpsertItemStream(Stream streamPayload, TransactionalBatchItemRequestOptions requestOptions=null); + public abstract TransactionalBatch UpsertItem(T item, TransactionalBatchItemRequestOptions requestOptions=null); + } + public class TransactionalBatchItemRequestOptions : RequestOptions + { + public TransactionalBatchItemRequestOptions(); + public Nullable EnableContentResponseOnWrite { get; set; } + public Nullable IndexingDirective { get; set; } + } + public class TransactionalBatchOperationResult + { + protected TransactionalBatchOperationResult(); + public virtual string ETag { get; } + public virtual bool IsSuccessStatusCode { get; } + public virtual Stream ResourceStream { get; } + public virtual TimeSpan RetryAfter { get; } + public virtual HttpStatusCode StatusCode { get; } + } + public class TransactionalBatchOperationResult : TransactionalBatchOperationResult + { + protected TransactionalBatchOperationResult(); + public virtual T Resource { get; set; } + } + public class TransactionalBatchPatchItemRequestOptions : TransactionalBatchItemRequestOptions + { + public TransactionalBatchPatchItemRequestOptions(); + public string FilterPredicate { get; set; } + } + public class TransactionalBatchRequestOptions : RequestOptions + { + public TransactionalBatchRequestOptions(); + public Nullable ConsistencyLevel { get; set; } + public string SessionToken { get; set; } + } + public class TransactionalBatchResponse : IDisposable, IEnumerable, IEnumerable, IReadOnlyCollection, IReadOnlyList + { + protected TransactionalBatchResponse(); + public virtual string ActivityId { get; } + public virtual int Count { get; } + public virtual CosmosDiagnostics Diagnostics { get; } + public virtual string ErrorMessage { get; } + public virtual Headers Headers { get; } + public virtual bool IsSuccessStatusCode { get; } + public virtual TransactionalBatchOperationResult this[int index] { get; } + public virtual double RequestCharge { get; } + public virtual Nullable RetryAfter { get; } + public virtual HttpStatusCode StatusCode { get; } + public void Dispose(); + protected virtual void Dispose(bool disposing); + public virtual IEnumerator GetEnumerator(); + public virtual TransactionalBatchOperationResult GetOperationResultAtIndex(int index); + IEnumerator System.Collections.IEnumerable.GetEnumerator(); + } + public class UniqueKey + { + public UniqueKey(); + public Collection Paths { get; } + } + public sealed class UniqueKeyPolicy + { + public UniqueKeyPolicy(); + public Collection UniqueKeys { get; } + } + public abstract class User + { + protected User(); + public abstract string Id { get; } + public abstract Task CreatePermissionAsync(PermissionProperties permissionProperties, Nullable tokenExpiryInSeconds=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task DeleteAsync(RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Permission GetPermission(string id); + public abstract FeedIterator GetPermissionQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetPermissionQueryIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract Task ReadAsync(RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceAsync(UserProperties userProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task UpsertPermissionAsync(PermissionProperties permissionProperties, Nullable tokenExpiryInSeconds=default(Nullable), RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + } + public class UserProperties + { + protected UserProperties(); + public UserProperties(string id); + public string ETag { get; } + public string Id { get; set; } + public Nullable LastModified { get; } + public string SelfLink { get; } + } + public class UserResponse : Response + { + protected UserResponse(); + public override string ActivityId { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public override double RequestCharge { get; } + public override UserProperties Resource { get; } + public override HttpStatusCode StatusCode { get; } + public virtual User User { get; } + public static implicit operator User (UserResponse response); + } +} +namespace Microsoft.Azure.Cosmos.Fluent +{ + public sealed class ClientEncryptionPolicyDefinition + { + public ContainerBuilder Attach(); + public ClientEncryptionPolicyDefinition WithIncludedPath(ClientEncryptionIncludedPath path); + } + public class CompositeIndexDefinition + { + public T Attach(); + public CompositeIndexDefinition Path(string path); + public CompositeIndexDefinition Path(string path, CompositePathSortOrder sortOrder); + } + public class ConflictResolutionDefinition + { + public ContainerBuilder Attach(); + public ConflictResolutionDefinition WithCustomStoredProcedureResolution(string conflictResolutionProcedure); + public ConflictResolutionDefinition WithLastWriterWinsResolution(string conflictResolutionPath); + } + public class ContainerBuilder : ContainerDefinition + { + protected ContainerBuilder(); + public ContainerBuilder(Database database, string name, string partitionKeyPath); + public new ContainerProperties Build(); + public Task CreateAsync(ThroughputProperties throughputProperties, CancellationToken cancellationToken=default(CancellationToken)); + public Task CreateAsync(Nullable throughput=default(Nullable), CancellationToken cancellationToken=default(CancellationToken)); + public Task CreateIfNotExistsAsync(ThroughputProperties throughputProperties, CancellationToken cancellationToken=default(CancellationToken)); + public Task CreateIfNotExistsAsync(Nullable throughput=default(Nullable), CancellationToken cancellationToken=default(CancellationToken)); + public ClientEncryptionPolicyDefinition WithClientEncryptionPolicy(); + public ClientEncryptionPolicyDefinition WithClientEncryptionPolicy(int policyFormatVersion); + public ConflictResolutionDefinition WithConflictResolution(); + public UniqueKeyDefinition WithUniqueKey(); + } + public abstract class ContainerDefinition where T : ContainerDefinition + { + public ContainerDefinition(); + public ContainerProperties Build(); + public T WithDefaultTimeToLive(int defaultTtlInSeconds); + public T WithDefaultTimeToLive(TimeSpan defaultTtlTimeSpan); + public IndexingPolicyDefinition WithIndexingPolicy(); + public T WithPartitionKeyDefinitionVersion(PartitionKeyDefinitionVersion partitionKeyDefinitionVersion); + public T WithTimeToLivePropertyPath(string propertyPath); + } + public class CosmosClientBuilder + { + public CosmosClientBuilder(string connectionString); + public CosmosClientBuilder(string accountEndpoint, AzureKeyCredential authKeyOrResourceTokenCredential); + public CosmosClientBuilder(string accountEndpoint, TokenCredential tokenCredential); + public CosmosClientBuilder(string accountEndpoint, string authKeyOrResourceToken); + public CosmosClientBuilder AddCustomHandlers(params RequestHandler[] customHandlers); + public CosmosClient Build(); + public Task BuildAndInitializeAsync(IReadOnlyList> containers, CancellationToken cancellationToken=default(CancellationToken)); + public CosmosClientBuilder WithApplicationName(string applicationName); + public CosmosClientBuilder WithApplicationPreferredRegions(IReadOnlyList applicationPreferredRegions); + public CosmosClientBuilder WithApplicationRegion(string applicationRegion); + public CosmosClientBuilder WithBulkExecution(bool enabled); + public CosmosClientBuilder WithClientTelemetryOptions(CosmosClientTelemetryOptions options); + public CosmosClientBuilder WithConnectionModeDirect(); + public CosmosClientBuilder WithConnectionModeDirect(Nullable idleTcpConnectionTimeout=default(Nullable), Nullable openTcpConnectionTimeout=default(Nullable), Nullable maxRequestsPerTcpConnection=default(Nullable), Nullable maxTcpConnectionsPerEndpoint=default(Nullable), Nullable portReuseMode=default(Nullable), Nullable enableTcpConnectionEndpointRediscovery=default(Nullable)); + public CosmosClientBuilder WithConnectionModeGateway(Nullable maxConnectionLimit=default(Nullable), IWebProxy webProxy=null); + public CosmosClientBuilder WithConsistencyLevel(ConsistencyLevel consistencyLevel); + public CosmosClientBuilder WithContentResponseOnWrite(bool contentResponseOnWrite); + public CosmosClientBuilder WithCustomSerializer(CosmosSerializer cosmosJsonSerializer); + public CosmosClientBuilder WithHttpClientFactory(Func httpClientFactory); + public CosmosClientBuilder WithLimitToEndpoint(bool limitToEndpoint); + public CosmosClientBuilder WithRequestTimeout(TimeSpan requestTimeout); + public CosmosClientBuilder WithSerializerOptions(CosmosSerializationOptions cosmosSerializerOptions); + public CosmosClientBuilder WithThrottlingRetryOptions(TimeSpan maxRetryWaitTimeOnThrottledRequests, int maxRetryAttemptsOnThrottledRequests); + } + public class IndexingPolicyDefinition + { + public IndexingPolicyDefinition(); + public T Attach(); + public IndexingPolicyDefinition WithAutomaticIndexing(bool enabled); + public CompositeIndexDefinition> WithCompositeIndex(); + public PathsDefinition> WithExcludedPaths(); + public PathsDefinition> WithIncludedPaths(); + public IndexingPolicyDefinition WithIndexingMode(IndexingMode indexingMode); + public SpatialIndexDefinition> WithSpatialIndex(); + } + public class PathsDefinition + { + public T Attach(); + public PathsDefinition Path(string path); + } + public class SpatialIndexDefinition + { + public T Attach(); + public SpatialIndexDefinition Path(string path); + public SpatialIndexDefinition Path(string path, params SpatialType[] spatialTypes); + } + public class UniqueKeyDefinition + { + public ContainerBuilder Attach(); + public UniqueKeyDefinition Path(string path); + } +} +namespace Microsoft.Azure.Cosmos.Linq +{ + public static class CosmosLinq + { + public static object InvokeUserDefinedFunction(string udfName, params object[] arguments); + } + public static class CosmosLinqExtensions + { + public static Task> AverageAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> AverageAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> AverageAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> AverageAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> AverageAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> AverageAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> AverageAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> AverageAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> AverageAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> AverageAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> CountAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static bool IsArray(this object obj); + public static bool IsBool(this object obj); + public static bool IsDefined(this object obj); + public static bool IsNull(this object obj); + public static bool IsNumber(this object obj); + public static bool IsObject(this object obj); + public static bool IsPrimitive(this object obj); + public static bool IsString(this object obj); + public static Task> MaxAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> MinAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static bool RegexMatch(this object obj, string regularExpression); + public static bool RegexMatch(this object obj, string regularExpression, string searchModifier); + public static Task> SumAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> SumAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> SumAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> SumAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> SumAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> SumAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> SumAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> SumAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task>> SumAsync(this IQueryable> source, CancellationToken cancellationToken=default(CancellationToken)); + public static Task> SumAsync(this IQueryable source, CancellationToken cancellationToken=default(CancellationToken)); + public static FeedIterator ToFeedIterator(this IQueryable query); + public static QueryDefinition ToQueryDefinition(this IQueryable query); + public static FeedIterator ToStreamIterator(this IQueryable query); + } +} +namespace Microsoft.Azure.Cosmos.Scripts +{ + public abstract class Scripts + { + protected Scripts(); + public abstract Task CreateStoredProcedureAsync(StoredProcedureProperties storedProcedureProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateTriggerAsync(TriggerProperties triggerProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task CreateUserDefinedFunctionAsync(UserDefinedFunctionProperties userDefinedFunctionProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task DeleteStoredProcedureAsync(string id, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task DeleteTriggerAsync(string id, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task DeleteUserDefinedFunctionAsync(string id, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task> ExecuteStoredProcedureAsync(string storedProcedureId, PartitionKey partitionKey, dynamic parameters, StoredProcedureRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ExecuteStoredProcedureStreamAsync(string storedProcedureId, PartitionKey partitionKey, dynamic parameters, StoredProcedureRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ExecuteStoredProcedureStreamAsync(string storedProcedureId, Stream streamPayload, PartitionKey partitionKey, StoredProcedureRequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract FeedIterator GetStoredProcedureQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetStoredProcedureQueryIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetStoredProcedureQueryStreamIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetStoredProcedureQueryStreamIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetTriggerQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetTriggerQueryIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetTriggerQueryStreamIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetTriggerQueryStreamIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetUserDefinedFunctionQueryIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetUserDefinedFunctionQueryIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetUserDefinedFunctionQueryStreamIterator(QueryDefinition queryDefinition, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract FeedIterator GetUserDefinedFunctionQueryStreamIterator(string queryText=null, string continuationToken=null, QueryRequestOptions requestOptions=null); + public abstract Task ReadStoredProcedureAsync(string id, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadTriggerAsync(string id, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReadUserDefinedFunctionAsync(string id, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceStoredProcedureAsync(StoredProcedureProperties storedProcedureProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceTriggerAsync(TriggerProperties triggerProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + public abstract Task ReplaceUserDefinedFunctionAsync(UserDefinedFunctionProperties userDefinedFunctionProperties, RequestOptions requestOptions=null, CancellationToken cancellationToken=default(CancellationToken)); + } + public class StoredProcedureExecuteResponse : Response + { + protected StoredProcedureExecuteResponse(); + public override string ActivityId { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public override double RequestCharge { get; } + public override T Resource { get; } + public virtual string ScriptLog { get; } + public virtual string SessionToken { get; } + public override HttpStatusCode StatusCode { get; } + } + public class StoredProcedureProperties + { + public StoredProcedureProperties(); + public StoredProcedureProperties(string id, string body); + public string Body { get; set; } + public string ETag { get; } + public string Id { get; set; } + public Nullable LastModified { get; } + public string SelfLink { get; } + } + public class StoredProcedureRequestOptions : RequestOptions + { + public StoredProcedureRequestOptions(); + public Nullable ConsistencyLevel { get; set; } + public bool EnableScriptLogging { get; set; } + public string SessionToken { get; set; } + } + public class StoredProcedureResponse : Response + { + protected StoredProcedureResponse(); + public override string ActivityId { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public override double RequestCharge { get; } + public override StoredProcedureProperties Resource { get; } + public virtual string SessionToken { get; } + public override HttpStatusCode StatusCode { get; } + public static implicit operator StoredProcedureProperties (StoredProcedureResponse response); + } + public enum TriggerOperation : short + { + All = (short)0, + Create = (short)1, + Delete = (short)3, + Replace = (short)4, + Update = (short)2, + Upsert = (short)5, + } + public class TriggerProperties + { + public TriggerProperties(); + public string Body { get; set; } + public string ETag { get; } + public string Id { get; set; } + public string SelfLink { get; } + public TriggerOperation TriggerOperation { get; set; } + public TriggerType TriggerType { get; set; } + } + public class TriggerResponse : Response + { + protected TriggerResponse(); + public override string ActivityId { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public override double RequestCharge { get; } + public override TriggerProperties Resource { get; } + public override HttpStatusCode StatusCode { get; } + public static implicit operator TriggerProperties (TriggerResponse response); + } + public enum TriggerType : byte + { + Post = (byte)1, + Pre = (byte)0, + } + public class UserDefinedFunctionProperties + { + public UserDefinedFunctionProperties(); + public string Body { get; set; } + public string ETag { get; } + public string Id { get; set; } + public string SelfLink { get; } + } + public class UserDefinedFunctionResponse : Response + { + protected UserDefinedFunctionResponse(); + public override string ActivityId { get; } + public override CosmosDiagnostics Diagnostics { get; } + public override string ETag { get; } + public override Headers Headers { get; } + public override double RequestCharge { get; } + public override UserDefinedFunctionProperties Resource { get; } + public override HttpStatusCode StatusCode { get; } + public static implicit operator UserDefinedFunctionProperties (UserDefinedFunctionResponse response); + } +} +namespace Microsoft.Azure.Cosmos.Spatial +{ + public sealed class BoundingBox : IEquatable + { + public BoundingBox(Position min, Position max); + public Position Max { get; } + public Position Min { get; } + public bool Equals(BoundingBox other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public abstract class Crs + { + protected Crs(CrsType type); + public static Crs Default { get; } + public CrsType Type { get; } + public static Crs Unspecified { get; } + public static LinkedCrs Linked(string href); + public static LinkedCrs Linked(string href, string type); + public static NamedCrs Named(string name); + } + public enum CrsType + { + Linked = 1, + Named = 0, + Unspecified = 2, + } + public abstract class Geometry + { + protected Geometry(GeometryType type, GeometryParams geometryParams); + public IDictionary AdditionalProperties { get; } + public BoundingBox BoundingBox { get; } + public Crs Crs { get; } + public GeometryType Type { get; } + public double Distance(Geometry to); + public override bool Equals(object obj); + public override int GetHashCode(); + public bool Intersects(Geometry geometry2); + public bool IsValid(); + public GeometryValidationResult IsValidDetailed(); + public bool Within(Geometry outer); + } + public class GeometryParams + { + public GeometryParams(); + public IDictionary AdditionalProperties { get; set; } + public BoundingBox BoundingBox { get; set; } + public Crs Crs { get; set; } + } + public enum GeometryShape + { + GeometryCollection = 6, + LineString = 2, + MultiLineString = 3, + MultiPoint = 1, + MultiPolygon = 5, + Point = 0, + Polygon = 4, + } + public enum GeometryType + { + GeometryCollection = 6, + LineString = 2, + MultiLineString = 3, + MultiPoint = 1, + MultiPolygon = 5, + Point = 0, + Polygon = 4, + } + public class GeometryValidationResult + { + public GeometryValidationResult(); + public bool IsValid { get; } + public string Reason { get; } + } + public sealed class LinearRing : IEquatable + { + public LinearRing(IList coordinates); + public ReadOnlyCollection Positions { get; } + public bool Equals(LinearRing other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public sealed class LineString : Geometry, IEquatable + { + public LineString(IList coordinates); + public LineString(IList coordinates, GeometryParams geometryParams); + public ReadOnlyCollection Positions { get; } + public bool Equals(LineString other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public sealed class LinkedCrs : Crs, IEquatable + { + public string Href { get; } + public string HrefType { get; } + public bool Equals(LinkedCrs other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public sealed class MultiPolygon : Geometry, IEquatable + { + public MultiPolygon(IList polygons); + public MultiPolygon(IList polygons, GeometryParams geometryParams); + public ReadOnlyCollection Polygons { get; } + public bool Equals(MultiPolygon other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public sealed class NamedCrs : Crs, IEquatable + { + public string Name { get; } + public bool Equals(NamedCrs other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public sealed class Point : Geometry, IEquatable + { + public Point(Position position); + public Point(Position position, GeometryParams geometryParams); + public Point(double longitude, double latitude); + public Position Position { get; } + public bool Equals(Point other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public sealed class Polygon : Geometry, IEquatable + { + public Polygon(IList rings); + public Polygon(IList rings, GeometryParams geometryParams); + public Polygon(IList externalRingPositions); + public ReadOnlyCollection Rings { get; } + public bool Equals(Polygon other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public sealed class PolygonCoordinates : IEquatable + { + public PolygonCoordinates(IList rings); + public ReadOnlyCollection Rings { get; } + public bool Equals(PolygonCoordinates other); + public override bool Equals(object obj); + public override int GetHashCode(); + } + public sealed class Position : IEquatable + { + public Position(IList coordinates); + public Position(double longitude, double latitude); + public Position(double longitude, double latitude, Nullable altitude); + public Nullable Altitude { get; } + public ReadOnlyCollection Coordinates { get; } + public double Latitude { get; } + public double Longitude { get; } + public bool Equals(Position other); + public override bool Equals(object obj); + public override int GetHashCode(); + } +} diff --git a/Microsoft.Azure.Cosmos/src/ConnectionPolicy.cs b/Microsoft.Azure.Cosmos/src/ConnectionPolicy.cs index 9193abedef..bd1b23b16c 100644 --- a/Microsoft.Azure.Cosmos/src/ConnectionPolicy.cs +++ b/Microsoft.Azure.Cosmos/src/ConnectionPolicy.cs @@ -10,7 +10,6 @@ namespace Microsoft.Azure.Cosmos using System.Net.Http; using System.Net.Security; using System.Security.Cryptography.X509Certificates; - using Microsoft.Azure.Cosmos.Telemetry; using Microsoft.Azure.Documents; using Microsoft.Azure.Documents.Client; @@ -48,8 +47,9 @@ public ConnectionPolicy() this.MaxConnectionLimit = defaultMaxConcurrentConnectionLimit; this.RetryOptions = new RetryOptions(); this.EnableReadRequestsFallback = null; - this.EnableClientTelemetry = ClientTelemetryOptions.IsClientTelemetryEnabled(); this.ServerCertificateCustomValidationCallback = null; + + this.CosmosClientTelemetryOptions = new CosmosClientTelemetryOptions(); } /// @@ -131,7 +131,7 @@ public TimeSpan MediaRequestTimeout /// Default value is /// /// - /// For more information, see Connection policy: Use direct connection mode. + /// For more information, see Connection policy: Use direct connection mode. /// public ConnectionMode ConnectionMode { @@ -160,7 +160,7 @@ public MediaReadMode MediaReadMode /// /// This setting is not used when is set to . /// Gateway mode only supports HTTPS. - /// For more information, see Connection policy: Use the TCP protocol. + /// For more information, see Connection policy: Use the HTTPS protocol. /// public Protocol ConnectionProtocol { @@ -211,12 +211,6 @@ public bool EnableTcpConnectionEndpointRediscovery set; } - internal bool EnableClientTelemetry - { - get; - set; - } - /// /// Gets the default connection policy used to connect to the Azure Cosmos DB service. /// @@ -369,7 +363,7 @@ public int MaxConnectionLimit /// set to 9 and set to 30 seconds. /// /// - /// For more information, see Handle rate limiting/request rate too large. + /// For more information, see Handle rate limiting/request rate too large. /// public RetryOptions RetryOptions { @@ -486,6 +480,15 @@ internal int? MaxTcpPartitionCount set; } + /// + /// Gets or sets Client Telemetry Options like feature flags and corresponding options + /// + internal CosmosClientTelemetryOptions CosmosClientTelemetryOptions + { + get; + set; + } + /// /// GlobalEndpointManager will subscribe to this event if user updates the preferredLocations list in the Azure Cosmos DB service. /// diff --git a/Microsoft.Azure.Cosmos/src/CosmosClient.cs b/Microsoft.Azure.Cosmos/src/CosmosClient.cs index d622e9ddcb..7b143196fe 100644 --- a/Microsoft.Azure.Cosmos/src/CosmosClient.cs +++ b/Microsoft.Azure.Cosmos/src/CosmosClient.cs @@ -28,7 +28,7 @@ namespace Microsoft.Azure.Cosmos /// /// CosmosClient is thread-safe. Its recommended to maintain a single instance of CosmosClient per lifetime /// of the application which enables efficient connection management and performance. Please refer to the - /// performance guide. + /// performance guide. /// /// /// This example create a , , and a . @@ -97,7 +97,7 @@ namespace Microsoft.Azure.Cosmos /// /// /// - /// Performance Tips + /// Performance Tips /// Diagnose and troubleshoot issues /// Global data distribution /// Partitioning and horizontal scaling @@ -160,7 +160,7 @@ protected CosmosClient() /// /// CosmosClient is thread-safe. Its recommended to maintain a single instance of CosmosClient per lifetime /// of the application which enables efficient connection management and performance. Please refer to the - /// performance guide. + /// performance guide. /// /// The connection string to the cosmos account. ex: AccountEndpoint=https://XXXXX.documents.azure.com:443/;AccountKey=SuperSecretKey; /// (Optional) client options @@ -187,7 +187,7 @@ protected CosmosClient() /// /// /// - /// Performance Tips + /// Performance Tips /// Diagnose and troubleshoot issues public CosmosClient( string connectionString, @@ -204,7 +204,7 @@ public CosmosClient( /// /// CosmosClient is thread-safe. Its recommended to maintain a single instance of CosmosClient per lifetime /// of the application which enables efficient connection management and performance. Please refer to the - /// performance guide. + /// performance guide. /// /// The cosmos service endpoint to use /// The cosmos account key or resource token to use to create the client. @@ -232,7 +232,7 @@ public CosmosClient( /// /// /// - /// Performance Tips + /// Performance Tips /// Diagnose and troubleshoot issues public CosmosClient( string accountEndpoint, @@ -250,7 +250,7 @@ public CosmosClient( /// /// CosmosClient is thread-safe. Its recommended to maintain a single instance of CosmosClient per lifetime /// of the application which enables efficient connection management and performance. Please refer to the - /// performance guide. + /// performance guide. /// /// The cosmos service endpoint to use /// AzureKeyCredential with master-key or resource token.. @@ -281,7 +281,7 @@ public CosmosClient( /// /// /// - /// Performance Tips + /// Performance Tips /// Diagnose and troubleshoot issues /// /// AzureKeyCredential enables changing/updating master-key/ResourceToken whle CosmosClient is still in use. @@ -302,7 +302,7 @@ public CosmosClient( /// /// CosmosClient is thread-safe. Its recommended to maintain a single instance of CosmosClient per lifetime /// of the application which enables efficient connection management and performance. Please refer to the - /// performance guide. + /// performance guide. /// /// /// The returned reference doesn't guarantee credentials or connectivity validations because creation doesn't make any network calls. @@ -357,7 +357,7 @@ internal CosmosClient( /// connections before the first call to the service is made. Use this to obtain lower latency while startup of your application. /// CosmosClient is thread-safe. Its recommended to maintain a single instance of CosmosClient per lifetime /// of the application which enables efficient connection management and performance. Please refer to the - /// performance guide. + /// performance guide. /// /// The cosmos service endpoint to use /// The cosmos account key or resource token to use to create the client. @@ -413,7 +413,7 @@ public static async Task CreateAndInitializeAsync(string accountEn /// connections before the first call to the service is made. Use this to obtain lower latency while startup of your application. /// CosmosClient is thread-safe. Its recommended to maintain a single instance of CosmosClient per lifetime /// of the application which enables efficient connection management and performance. Please refer to the - /// performance guide. + /// performance guide. /// /// The cosmos service endpoint to use /// AzureKeyCredential with master-key or resource token. @@ -471,7 +471,7 @@ public static async Task CreateAndInitializeAsync(string accountEn /// connections before the first call to the service is made. Use this to obtain lower latency while startup of your application. /// CosmosClient is thread-safe. Its recommended to maintain a single instance of CosmosClient per lifetime /// of the application which enables efficient connection management and performance. Please refer to the - /// performance guide. + /// performance guide. /// /// The connection string to the cosmos account. ex: AccountEndpoint=https://XXXXX.documents.azure.com:443/;AccountKey=SuperSecretKey; /// Containers to be initialized identified by it's database name and container name. @@ -518,7 +518,7 @@ public static async Task CreateAndInitializeAsync(string connectio /// connections before the first call to the service is made. Use this to obtain lower latency while startup of your application. /// CosmosClient is thread-safe. Its recommended to maintain a single instance of CosmosClient per lifetime /// of the application which enables efficient connection management and performance. Please refer to the - /// performance guide. + /// performance guide. /// /// The cosmos service endpoint to use. /// The token to provide AAD token for authorization. diff --git a/Microsoft.Azure.Cosmos/src/CosmosClientOptions.cs b/Microsoft.Azure.Cosmos/src/CosmosClientOptions.cs index 330738c00b..2f648f5272 100644 --- a/Microsoft.Azure.Cosmos/src/CosmosClientOptions.cs +++ b/Microsoft.Azure.Cosmos/src/CosmosClientOptions.cs @@ -11,7 +11,6 @@ namespace Microsoft.Azure.Cosmos using System.Linq; using System.Net; using System.Net.Http; - using System.Net.Http.Headers; using System.Net.Security; using System.Security.Cryptography.X509Certificates; using Microsoft.Azure.Cosmos.Fluent; @@ -85,6 +84,7 @@ public CosmosClientOptions() this.ConnectionProtocol = CosmosClientOptions.DefaultProtocol; this.ApiType = CosmosClientOptions.DefaultApiType; this.CustomHandlers = new Collection(); + this.CosmosClientTelemetryOptions = new CosmosClientTelemetryOptions(); } /// @@ -250,7 +250,7 @@ public int GatewayModeMaxConnectionLimit /// Default value is /// /// - /// For more information, see Connection policy: Use direct connection mode. + /// For more information, see Connection policy: Use direct connection mode. /// /// /// @@ -614,7 +614,7 @@ public Func HttpClientFactory /// Quorum Read allowed with eventual consistency account or consistent prefix account. /// internal bool EnableUpgradeConsistencyToLocalQuorum { get; set; } = false; - + /// /// Gets or sets the connection protocol when connecting to the Azure Cosmos service. /// @@ -624,7 +624,7 @@ public Func HttpClientFactory /// /// This setting is not used when is set to . /// Gateway mode only supports HTTPS. - /// For more information, see Connection policy: Use the TCP protocol. + /// For more information, see Connection policy: Use the HTTPS protocol. /// internal Protocol ConnectionProtocol { @@ -730,9 +730,9 @@ internal Protocol ConnectionProtocol internal bool? EnableCpuMonitor { get; set; } /// - /// Flag to enable telemetry + /// Gets or sets Client Telemetry Options like feature flags and corresponding options /// - internal bool? EnableClientTelemetry { get; set; } + public CosmosClientTelemetryOptions CosmosClientTelemetryOptions { get; set; } internal void SetSerializerIfNotConfigured(CosmosSerializer serializer) { @@ -771,22 +771,26 @@ internal virtual ConnectionPolicy GetConnectionPolicy(int clientId) EnableTcpConnectionEndpointRediscovery = this.EnableTcpConnectionEndpointRediscovery, EnableAdvancedReplicaSelectionForTcp = this.EnableAdvancedReplicaSelectionForTcp, HttpClientFactory = this.httpClientFactory, - ServerCertificateCustomValidationCallback = this.ServerCertificateCustomValidationCallback + ServerCertificateCustomValidationCallback = this.ServerCertificateCustomValidationCallback, + CosmosClientTelemetryOptions = new CosmosClientTelemetryOptions() }; - if (this.EnableClientTelemetry.HasValue) + if (this.CosmosClientTelemetryOptions != null) { - connectionPolicy.EnableClientTelemetry = this.EnableClientTelemetry.Value; + connectionPolicy.CosmosClientTelemetryOptions = this.CosmosClientTelemetryOptions; } - if (this.ApplicationRegion != null) + RegionNameMapper mapper = new RegionNameMapper(); + if (!string.IsNullOrEmpty(this.ApplicationRegion)) { - connectionPolicy.SetCurrentLocation(this.ApplicationRegion); + connectionPolicy.SetCurrentLocation(mapper.GetCosmosDBRegionName(this.ApplicationRegion)); } if (this.ApplicationPreferredRegions != null) { - connectionPolicy.SetPreferredLocations(this.ApplicationPreferredRegions); + List mappedRegions = this.ApplicationPreferredRegions.Select(s => mapper.GetCosmosDBRegionName(s)).ToList(); + + connectionPolicy.SetPreferredLocations(mappedRegions); } if (this.MaxRetryAttemptsOnRateLimitedRequests != null) @@ -1013,29 +1017,5 @@ public override bool CanConvert(Type objectType) return objectType == typeof(DateTime); } } - - /// - /// Distributed Tracing Options. - /// - /// Applicable only when Operation level distributed tracing is enabled through - internal DistributedTracingOptions DistributedTracingOptions { get; set; } - - /// - /// Gets or sets the flag to generate operation level for methods calls using the Source Name "Azure.Cosmos.Operation". - /// - /// - /// The default value is true (for preview package). - /// - /// This flag is there to disable it from source. Please Refer https://opentelemetry.io/docs/instrumentation/net/exporters/ to know more about open telemetry exporters -#if PREVIEW - public -#else - internal -#endif - bool IsDistributedTracingEnabled { get; set; } -#if PREVIEW - = true; -#endif - } } \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/CosmosClientTelemetryOptions.cs b/Microsoft.Azure.Cosmos/src/CosmosClientTelemetryOptions.cs new file mode 100644 index 0000000000..ec16c0f3b8 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/CosmosClientTelemetryOptions.cs @@ -0,0 +1,38 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos +{ + /// + /// Telemetry Options for Cosmos Client to enable/disable telemetry and distributed tracing along with corresponding threshold values. + /// + public class CosmosClientTelemetryOptions + { + /// + /// Disable sending telemetry to service, is not applicable to this as of now. + /// + /// This option will disable sending telemetry to service.even it is opt-in from portal. + /// true + public bool DisableSendingMetricsToService { get; set; } = true; + + /// + /// This method enable/disable generation of operation level if listener is subscribed to the Source Name "Azure.Cosmos.Operation". + /// + /// false + /// Please Refer https://opentelemetry.io/docs/instrumentation/net/exporters/ to know more about open telemetry exporters + public bool DisableDistributedTracing { get; set; } = +#if PREVIEW + false; +#else + true; +#endif + + /// + /// Threshold values for Distributed Tracing. + /// These values decides whether to generate operation level with request diagnostics or not. + /// + public CosmosThresholdOptions CosmosThresholdOptions { get; set; } = new CosmosThresholdOptions(); + + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/CosmosThresholdOptions.cs b/Microsoft.Azure.Cosmos/src/CosmosThresholdOptions.cs new file mode 100644 index 0000000000..57b7cbf57a --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/CosmosThresholdOptions.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos +{ + using System; + + /// + /// Threshold values for Distributed Tracing + /// + public class CosmosThresholdOptions + { + /// + /// Latency Threshold for non point operations i.e. Query + /// + /// 500 ms + public TimeSpan NonPointOperationLatencyThreshold { get; set; } = TimeSpan.FromSeconds(3); + + /// + /// Latency Threshold for point operations i.e operation other than Query + /// + /// 100 ms + public TimeSpan PointOperationLatencyThreshold { get; set; } = TimeSpan.FromSeconds(1); + } +} diff --git a/Microsoft.Azure.Cosmos/src/Diagnostics/CosmosDiagnostics.cs b/Microsoft.Azure.Cosmos/src/Diagnostics/CosmosDiagnostics.cs index cb3ffe6c04..b88eaa8efe 100644 --- a/Microsoft.Azure.Cosmos/src/Diagnostics/CosmosDiagnostics.cs +++ b/Microsoft.Azure.Cosmos/src/Diagnostics/CosmosDiagnostics.cs @@ -44,9 +44,22 @@ public virtual int GetFailedRequestCount() } /// - /// Gets the string field instance in the Azure CosmosDB database service. + /// This represents the backend query metrics for the request. /// - /// The string field instance in the Azure CosmosDB database service. + /// + /// This is only applicable for query operations. For all other operations this will return null. + /// + /// The accumulated backend metrics for the request. + public virtual ServerSideCumulativeMetrics GetQueryMetrics() + { + // Default implementation avoids breaking change for users upgrading. + throw new NotImplementedException($"{nameof(CosmosDiagnostics)}.{nameof(GetQueryMetrics)}"); + } + + /// + /// Gets the string field instance in the Azure Cosmos DB database service. + /// + /// The string field instance in the Azure Cosmos DB database service. /// /// implements lazy materialization and is only materialized when is called. /// @@ -80,6 +93,9 @@ public virtual int GetFailedRequestCount() /// Gets the list of all regions that were contacted for a request /// /// The list of tuples containing the Region name and the URI + /// + /// The returned list contains unique regions and doesn't guarantee ordering of the regions contacted from the first to the last + /// public abstract IReadOnlyList<(string regionName, Uri uri)> GetContactedRegions(); } } diff --git a/Microsoft.Azure.Cosmos/src/Diagnostics/CosmosTraceDiagnostics.cs b/Microsoft.Azure.Cosmos/src/Diagnostics/CosmosTraceDiagnostics.cs index 07e340f0ac..2d92a2cfb7 100644 --- a/Microsoft.Azure.Cosmos/src/Diagnostics/CosmosTraceDiagnostics.cs +++ b/Microsoft.Azure.Cosmos/src/Diagnostics/CosmosTraceDiagnostics.cs @@ -9,12 +9,15 @@ namespace Microsoft.Azure.Cosmos.Diagnostics using System.Linq; using System.Text; using Microsoft.Azure.Cosmos.Json; + using Microsoft.Azure.Cosmos.Query.Core.Metrics; using Microsoft.Azure.Cosmos.Tracing; using Microsoft.Azure.Cosmos.Tracing.TraceData; using static Microsoft.Azure.Cosmos.Tracing.TraceData.ClientSideRequestStatisticsTraceDatum; internal sealed class CosmosTraceDiagnostics : CosmosDiagnostics { + private readonly Lazy accumulatedMetrics; + public CosmosTraceDiagnostics(ITrace trace) { if (trace == null) @@ -30,6 +33,7 @@ public CosmosTraceDiagnostics(ITrace trace) } this.Value = rootTrace; + this.accumulatedMetrics = new Lazy(() => PopulateServerSideCumulativeMetrics(this.Value)); } public ITrace Value { get; } @@ -49,6 +53,11 @@ public override TimeSpan GetClientElapsedTime() return this.Value?.Summary?.RegionsContacted; } + public override ServerSideCumulativeMetrics GetQueryMetrics() + { + return this.accumulatedMetrics.Value; + } + internal bool IsGoneExceptionHit() { return this.WalkTraceTreeForGoneException(this.Value); @@ -61,9 +70,9 @@ private bool WalkTraceTreeForGoneException(ITrace currentTrace) return false; } - foreach (object datums in currentTrace.Data.Values) + foreach (object datum in currentTrace.Data.Values) { - if (datums is ClientSideRequestStatisticsTraceDatum clientSideRequestStatisticsTraceDatum) + if (datum is ClientSideRequestStatisticsTraceDatum clientSideRequestStatisticsTraceDatum) { foreach (StoreResponseStatistics responseStatistics in clientSideRequestStatisticsTraceDatum.StoreResponseStatisticsList) { @@ -99,6 +108,17 @@ private ReadOnlyMemory WriteTraceToJsonWriter(JsonSerializationFormat json return jsonTextWriter.GetResult(); } + private static ServerSideCumulativeMetrics PopulateServerSideCumulativeMetrics(ITrace trace) + { + ServerSideMetricsInternalAccumulator accumulator = new ServerSideMetricsInternalAccumulator(); + ServerSideMetricsInternalAccumulator.WalkTraceTreeForQueryMetrics(trace, accumulator); + + IReadOnlyList serverSideMetricsList = accumulator.GetPartitionedServerSideMetrics().Select(metrics => new ServerSidePartitionedMetricsInternal(metrics)).ToList(); + + ServerSideCumulativeMetrics accumulatedMetrics = new ServerSideCumulativeMetricsInternal(serverSideMetricsList); + return accumulatedMetrics.PartitionedMetrics.Count != 0 ? accumulatedMetrics : null; + } + public override DateTime? GetStartTimeUtc() { if (this.Value == null || this.Value.StartTime == null) diff --git a/Microsoft.Azure.Cosmos/src/DocumentClient.cs b/Microsoft.Azure.Cosmos/src/DocumentClient.cs index c7aeb07a6f..3c261490a7 100644 --- a/Microsoft.Azure.Cosmos/src/DocumentClient.cs +++ b/Microsoft.Azure.Cosmos/src/DocumentClient.cs @@ -142,7 +142,8 @@ internal partial class DocumentClient : IDisposable, IAuthorizationTokenProvider private Documents.ConsistencyLevel? desiredConsistencyLevel; internal CosmosAccountServiceConfiguration accountServiceConfiguration { get; private set; } - internal ClientTelemetry clientTelemetry { get; set; } + + internal TelemetryToServiceHelper telemetryToServiceHelper { get; set; } private ClientCollectionCache collectionCache; @@ -170,7 +171,7 @@ internal partial class DocumentClient : IDisposable, IAuthorizationTokenProvider internal RemoteCertificateValidationCallback remoteCertificateValidationCallback; //Distributed Tracing Flag - internal bool isDistributedTracingEnabled; + internal CosmosClientTelemetryOptions cosmosClientTelemetryOptions; //SessionContainer. internal ISessionContainer sessionContainer; @@ -431,7 +432,7 @@ internal DocumentClient(Uri serviceEndpoint, /// Flag to allow Quorum Read with Eventual Consistency Account /// /// This delegate responsible for validating the third party certificate. - /// This is distributed tracing flag + /// This is distributed tracing flag /// /// The service endpoint can be obtained from the Azure Management Portal. /// If you are connecting using one of the Master Keys, these can be obtained along with the endpoint from the Azure Management Portal @@ -459,7 +460,7 @@ internal DocumentClient(Uri serviceEndpoint, bool isLocalQuorumConsistency = false, string cosmosClientId = null, RemoteCertificateValidationCallback remoteCertificateValidationCallback = null, - bool isDistributedTracingEnabled = false) + CosmosClientTelemetryOptions cosmosClientTelemetryOptions = null) { if (sendingRequestEventArgs != null) { @@ -493,7 +494,7 @@ internal DocumentClient(Uri serviceEndpoint, storeClientFactory: storeClientFactory, cosmosClientId: cosmosClientId, remoteCertificateValidationCallback: remoteCertificateValidationCallback, - isDistributedTracingEnabled: isDistributedTracingEnabled); + cosmosClientTelemetryOptions: cosmosClientTelemetryOptions); } /// @@ -564,11 +565,11 @@ public DocumentClient(Uri serviceEndpoint, /// /// Internal constructor purely for unit-testing /// - internal DocumentClient(Uri serviceEndpoint, string authKey) + internal DocumentClient(Uri serviceEndpoint, ConnectionPolicy connectionPolicy) { // do nothing this.ServiceEndpoint = serviceEndpoint; - this.ConnectionPolicy = new ConnectionPolicy(); + this.ConnectionPolicy = connectionPolicy ?? new ConnectionPolicy(); } internal virtual async Task GetCollectionCacheAsync(ITrace trace) @@ -660,7 +661,7 @@ private async Task OpenPrivateAsync(CancellationToken cancellationToken) storeModel: this.GatewayStoreModel, tokenProvider: this, retryPolicy: this.retryPolicy, - clientTelemetry: this.clientTelemetry); + telemetryToServiceHelper: this.telemetryToServiceHelper); this.partitionKeyRangeCache = new PartitionKeyRangeCache(this, this.GatewayStoreModel, this.collectionCache); DefaultTrace.TraceWarning("{0} occurred while OpenAsync. Exception Message: {1}", ex.ToString(), ex.Message); @@ -677,7 +678,7 @@ internal virtual void Initialize(Uri serviceEndpoint, TokenCredential tokenCredential = null, string cosmosClientId = null, RemoteCertificateValidationCallback remoteCertificateValidationCallback = null, - bool isDistributedTracingEnabled = false) + CosmosClientTelemetryOptions cosmosClientTelemetryOptions = null) { if (serviceEndpoint == null) { @@ -686,7 +687,7 @@ internal virtual void Initialize(Uri serviceEndpoint, this.clientId = cosmosClientId; this.remoteCertificateValidationCallback = remoteCertificateValidationCallback; - this.isDistributedTracingEnabled = isDistributedTracingEnabled; + this.cosmosClientTelemetryOptions = cosmosClientTelemetryOptions ?? new CosmosClientTelemetryOptions(); this.queryPartitionProvider = new AsyncLazy(async () => { @@ -939,6 +940,15 @@ internal virtual void Initialize(Uri serviceEndpoint, // Loading VM Information (non blocking call and initialization won't fail if this call fails) VmMetadataApiHandler.TryInitialize(this.httpClient); + // Starting ClientTelemetry Job + this.telemetryToServiceHelper = TelemetryToServiceHelper.CreateAndInitializeClientConfigAndTelemetryJob(this.clientId, + this.ConnectionPolicy, + this.cosmosAuthorization, + this.httpClient, + this.ServiceEndpoint, + this.GlobalEndpointManager, + this.cancellationTokenSource); + if (sessionContainer != null) { this.sessionContainer = sessionContainer; @@ -961,12 +971,6 @@ internal virtual void Initialize(Uri serviceEndpoint, // For direct: WFStoreProxy [set in OpenAsync()]. this.eventSource = DocumentClientEventSource.Instance; - // Disable system usage for internal builds. Cosmos DB owns the VMs and already logs - // the system information so no need to track it. -#if !INTERNAL - this.InitializeClientTelemetry(); -#endif - this.initializeTaskFactory = (_) => TaskHelper.InlineIfPossible( () => this.GetInitializationTaskAsync(storeClientFactory: storeClientFactory), new ResourceThrottleRetryPolicy( @@ -1028,7 +1032,7 @@ private async Task GetInitializationTaskAsync(IStoreClientFactory storeCli storeModel: this.GatewayStoreModel, tokenProvider: this, retryPolicy: this.retryPolicy, - clientTelemetry: this.clientTelemetry); + telemetryToServiceHelper: this.telemetryToServiceHelper); this.partitionKeyRangeCache = new PartitionKeyRangeCache(this, this.GatewayStoreModel, this.collectionCache); this.ResetSessionTokenRetryPolicy = new ResetSessionTokenRetryPolicyFactory(this.sessionContainer, this.collectionCache, this.retryPolicy); @@ -1046,36 +1050,6 @@ private async Task GetInitializationTaskAsync(IStoreClientFactory storeCli return true; } - private void InitializeClientTelemetry() - { - if (this.ConnectionPolicy.EnableClientTelemetry) - { - try - { - this.clientTelemetry = ClientTelemetry.CreateAndStartBackgroundTelemetry( - clientId: this.clientId, - httpClient: this.httpClient, - userAgent: this.ConnectionPolicy.UserAgentContainer.BaseUserAgent, - connectionMode: this.ConnectionPolicy.ConnectionMode, - authorizationTokenProvider: this.cosmosAuthorization, - diagnosticsHelper: DiagnosticsHandlerHelper.Instance, - preferredRegions: this.ConnectionPolicy.PreferredLocations, - globalEndpointManager: this.GlobalEndpointManager); - - DefaultTrace.TraceInformation("Client Telemetry Enabled."); - } - catch (Exception ex) - { - DefaultTrace.TraceInformation($"Error While starting Telemetry Job : {ex.Message}. Hence disabling Client Telemetry"); - this.ConnectionPolicy.EnableClientTelemetry = false; - } - } - else - { - DefaultTrace.TraceInformation("Client Telemetry Disabled."); - } - } - private async Task InitializeCachesAsync(string databaseName, DocumentCollection collection, CancellationToken cancellationToken) { if (databaseName == null) @@ -1279,6 +1253,12 @@ public void Dispose() return; } + if (this.telemetryToServiceHelper != null) + { + this.telemetryToServiceHelper.Dispose(); + this.telemetryToServiceHelper = null; + } + if (!this.cancellationTokenSource.IsCancellationRequested) { this.cancellationTokenSource.Cancel(); @@ -1346,11 +1326,6 @@ public void Dispose() this.initTaskCache = null; } - if (this.clientTelemetry != null) - { - this.clientTelemetry.Dispose(); - } - DefaultTrace.TraceInformation("DocumentClient with id {0} disposed.", this.traceId); DefaultTrace.Flush(); @@ -6648,7 +6623,7 @@ private void InitializeDirectConnectivity(IStoreClientFactory storeClientFactory { Documents.Telemetry.DistributedTracingOptions distributedTracingOptions = new () { - IsDistributedTracingEnabled = this.isDistributedTracingEnabled + IsDistributedTracingEnabled = !this.cosmosClientTelemetryOptions.DisableDistributedTracing }; StoreClientFactory newClientFactory = new StoreClientFactory( diff --git a/Microsoft.Azure.Cosmos/src/Fluent/CosmosClientBuilder.cs b/Microsoft.Azure.Cosmos/src/Fluent/CosmosClientBuilder.cs index 8b72bfffa4..59325ecb83 100644 --- a/Microsoft.Azure.Cosmos/src/Fluent/CosmosClientBuilder.cs +++ b/Microsoft.Azure.Cosmos/src/Fluent/CosmosClientBuilder.cs @@ -15,7 +15,6 @@ namespace Microsoft.Azure.Cosmos.Fluent using Microsoft.Azure.Cosmos.Core.Trace; using Microsoft.Azure.Documents; using Microsoft.Azure.Documents.Client; - using Telemetry; /// /// This is a Builder class that creates a cosmos client @@ -349,7 +348,7 @@ public CosmosClientBuilder WithRequestTimeout(TimeSpan requestTimeout) /// Sets the connection mode to Direct. This is used by the client when connecting to the Azure Cosmos DB service. /// /// - /// For more information, see Connection policy: Use direct connection mode. + /// For more information, see Connection policy: Use direct connection mode. /// /// The current . /// @@ -396,7 +395,7 @@ public CosmosClientBuilder WithConnectionModeDirect() /// The default value is false. /// /// - /// For more information, see Connection policy: Use direct connection mode. + /// For more information, see Connection policy: Use direct connection mode. /// /// The current . /// @@ -436,43 +435,13 @@ public CosmosClientBuilder WithConsistencyLevel(Cosmos.ConsistencyLevel consiste } - /// - /// Sets whether Distributed Tracing for "Azure.Cosmos.Operation" source is enabled. - /// - /// Whether is enabled. - /// The current . -#if PREVIEW - public -#else - internal -#endif - CosmosClientBuilder WithDistributedTracing(bool isEnabled = true) - { - this.clientOptions.IsDistributedTracingEnabled = isEnabled; - return this; - } - - /// - /// Enables Distributed Tracing with a Configuration ref. - /// - /// . - /// The current .] - /// Refer https://opentelemetry.io/docs/instrumentation/net/exporters/ to know more about open telemetry exporters - internal CosmosClientBuilder WithDistributedTracingOptions(DistributedTracingOptions options) - { - this.clientOptions.IsDistributedTracingEnabled = true; - this.clientOptions.DistributedTracingOptions = options; - - return this; - } - /// /// Sets the connection mode to Gateway. This is used by the client when connecting to the Azure Cosmos DB service. /// /// The number specifies the number of connections that may be opened simultaneously. Default is 50 connections /// Get or set the proxy information used for web requests. /// - /// For more information, see Connection policy: Use direct connection mode. + /// For more information, see Connection policy: Use direct connection mode. /// /// The current . /// @@ -529,7 +498,7 @@ public CosmosClientBuilder AddCustomHandlers(params RequestHandler[] customHandl /// If the cumulative wait time exceeds the this value, the client will stop retrying and return the error to the application. /// /// - /// For more information, see Handle rate limiting/request rate too large. + /// For more information, see Handle rate limiting/request rate too large. /// /// The current . /// @@ -680,27 +649,6 @@ internal CosmosClientBuilder WithCpuMonitorDisabled() return this; } - /// - /// Disable Telemetry if enabled using environment properties - /// - /// The object - internal CosmosClientBuilder WithTelemetryDisabled() - { - this.clientOptions.EnableClientTelemetry = false; - return this; - } - - /// - /// To enable Telemetry, set COSMOS.CLIENT_TELEMETRY_ENABLED environment property. - /// This function is used by Test only. - /// - /// The object - internal CosmosClientBuilder WithTelemetryEnabled() - { - this.clientOptions.EnableClientTelemetry = true; - return this; - } - /// /// Enabled partition level failover in the SDK /// @@ -732,5 +680,16 @@ internal CosmosClientBuilder WithRetryWithOptions( this.clientOptions.TotalWaitTimeForRetryWithMilliseconds = totalWaitTimeForRetryWithMilliseconds; return this; } + + /// + /// To enable Telemetry features with corresponding options + /// + /// + /// The object + public CosmosClientBuilder WithClientTelemetryOptions(CosmosClientTelemetryOptions options) + { + this.clientOptions.CosmosClientTelemetryOptions = options; + return this; + } } } diff --git a/Microsoft.Azure.Cosmos/src/GlobalSuppressions.cs b/Microsoft.Azure.Cosmos/src/GlobalSuppressions.cs index 71f3a59a50..1328707686 100644 --- a/Microsoft.Azure.Cosmos/src/GlobalSuppressions.cs +++ b/Microsoft.Azure.Cosmos/src/GlobalSuppressions.cs @@ -51,4 +51,820 @@ [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1508:Closing braces should not be preceded by blank line", Justification = "Remove after fixing existing code")] [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1303:Const field names should begin with upper-case letter", Justification = "Remove after fixing existing code")] [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1618:Generic type parameters should be documented", Justification = "Remove after fixing existing code")] -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1005:Single line comments should begin with single space", Justification = "Remove after fixing existing code")] \ No newline at end of file +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1005:Single line comments should begin with single space", Justification = "Remove after fixing existing code")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1200:Using directives should be placed correctly", Justification = "Belongs to Cosmos.Direct Project")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1636:File header copyright text should match", Justification = "Belongs to Cosmos.Direct Project")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1208:System using directives should be placed before other using directives", Justification = "Belongs to Cosmos.Direct Project")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1214:Readonly fields should appear before non-readonly fields", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Azure.Core.ActivityExtensions.ActivityParameter")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1214:Readonly fields should appear before non-readonly fields", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Azure.Core.ActivityExtensions.ActivitySourceType")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1309:Field names should not begin with underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Azure.Core.DiagnosticScope._activityAdapter")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1309:Field names should not begin with underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Azure.Core.DiagnosticScope._suppressNestedClientActivities")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1309:Field names should not begin with underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Azure.Core.DiagnosticScope.ActivityAdapter._activityName")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1309:Field names should not begin with underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Azure.Core.DiagnosticScope.ActivityAdapter._activitySource")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1309:Field names should not begin with underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Azure.Core.DiagnosticScope.ActivityAdapter._currentActivity")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1309:Field names should not begin with underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Azure.Core.DiagnosticScope.ActivityAdapter._diagnosticSource")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1309:Field names should not begin with underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Azure.Core.DiagnosticScope.ActivityAdapter._diagnosticSourceArgs")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1309:Field names should not begin with underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Azure.Core.DiagnosticScope.ActivityAdapter._displayName")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1309:Field names should not begin with underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Azure.Core.DiagnosticScope.ActivityAdapter._kind")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1309:Field names should not begin with underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Azure.Core.DiagnosticScope.ActivityAdapter._links")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1309:Field names should not begin with underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Azure.Core.DiagnosticScope.ActivityAdapter._sampleOutActivity")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1309:Field names should not begin with underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Azure.Core.DiagnosticScope.ActivityAdapter._startTime")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1309:Field names should not begin with underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Azure.Core.DiagnosticScope.ActivityAdapter._tagCollection")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1309:Field names should not begin with underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Azure.Core.DiagnosticScope.ActivityAdapter._traceparent")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1309:Field names should not begin with underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Azure.Core.DiagnosticScope.ActivityAdapter._tracestate")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1309:Field names should not begin with underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Azure.Core.DiagnosticScopeFactory._listeners")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1309:Field names should not begin with underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Azure.Core.DiagnosticScopeFactory._resourceProviderNamespace")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1309:Field names should not begin with underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Azure.Core.DiagnosticScopeFactory._source")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1309:Field names should not begin with underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Azure.Core.DiagnosticScopeFactory._suppressNestedClientActivities")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Azure.Core.DiagnosticScopeFactory.ActivitySources")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1203:Constants should appear before fields", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.ClientSideRequestStatistics.EnableCpuMonitorConfig")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1400:Access modifier should be declared", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Collections.NameValueCollectionWrapper.collection")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Constants.MigratePartitionCallerSource.ACIS_BulkPartitionMigration")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Constants.MigratePartitionCallerSource.ACIS_CrossSubregionAccountMigration")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Constants.MigratePartitionCallerSource.ACIS_MitigateMasterMigrationFailure")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Constants.MigratePartitionCallerSource.ACIS_MitigateServerMigrationFailure")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Constants.MigratePartitionCallerSource.ACIS_PartitionMigration")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Constants.MigratePartitionCallerSource.FederationBuildout_CanaryAccountMigration")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Constants.MigratePartitionCallerSource.PLB_CrossRegion")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Constants.MigratePartitionCallerSource.PLB_localRegion")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Constants.MigratePartitionCallerSource.USER_InPlaceAZMigration")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Constants.MongoServerVersion.Version3_2")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Constants.MongoServerVersion.Version3_6")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Constants.MongoServerVersion.Version4_0")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Constants.MongoServerVersion.Version4_2")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Constants.Offers.OfferType_Invalid")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Constants.Offers.OfferVersion_None")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Constants.Offers.OfferVersion_V1")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Constants.Offers.OfferVersion_V2")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Constants.PartitionedQueryExecutionInfo.Version_1")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Constants.PartitionedQueryExecutionInfo.Version_2")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1203:Constants should appear before fields", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.DocumentServiceRequest.PreferHeadersSeparator")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1025:Code should not contain multiple whitespace in a row", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.GeoLinkTypes.Weak")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1203:Constants should appear before fields", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.GoneAndRetryWithRequestRetryPolicy`1.defaultWaitTimeInMilliSeconds")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1214:Readonly fields should appear before non-readonly fields", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.GoneAndRetryWithRequestRetryPolicy`1.waitTimeInMilliseconds")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1214:Readonly fields should appear before non-readonly fields", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.GoneAndRetryWithRetryPolicy.waitTimeInSeconds")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1214:Readonly fields should appear before non-readonly fields", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.GoneOnlyRequestRetryPolicy`1.retryTimeout")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.HttpConstants.HttpHeaders.A_IM")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.HttpConstants.HttpListenerErrorCodes.ERROR_CONNECTION_ABORT")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.HttpConstants.HttpListenerErrorCodes.ERROR_CONNECTION_INVALID")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.HttpConstants.HttpListenerErrorCodes.ERROR_CONNECTION_RESET")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.HttpConstants.HttpListenerErrorCodes.ERROR_OPERATION_ABORTED")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.HttpConstants.VersionDates.v2014_08_21")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.HttpConstants.VersionDates.v2015_04_08")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.HttpConstants.VersionDates.v2015_06_03")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.HttpConstants.VersionDates.v2015_08_06")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.HttpConstants.VersionDates.v2015_12_16")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.HttpConstants.VersionDates.v2016_05_30")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.HttpConstants.VersionDates.v2016_07_11")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.HttpConstants.VersionDates.v2016_11_14")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.HttpConstants.VersionDates.v2017_01_19")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.HttpConstants.VersionDates.v2017_02_22")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.HttpConstants.VersionDates.v2017_05_03")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.HttpConstants.VersionDates.v2017_11_15")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.HttpConstants.VersionDates.v2018_06_18")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.HttpConstants.VersionDates.v2018_08_31")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.HttpConstants.VersionDates.v2018_09_17")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.HttpConstants.VersionDates.v2018_12_31")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.HttpConstants.VersionDates.v2019_10_14")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.HttpConstants.VersionDates.v2020_07_15")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.HttpConstants.VersionDates.v2020_11_05")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.HttpConstants.Versions.v2014_08_21")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.HttpConstants.Versions.v2015_04_08")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.HttpConstants.Versions.v2015_06_03")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.HttpConstants.Versions.v2015_08_06")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.HttpConstants.Versions.v2015_12_16")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.HttpConstants.Versions.v2016_05_30")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.HttpConstants.Versions.v2016_07_11")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.HttpConstants.Versions.v2016_11_14")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.HttpConstants.Versions.v2017_01_19")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.HttpConstants.Versions.v2017_02_22")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.HttpConstants.Versions.v2017_05_03")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.HttpConstants.Versions.v2017_11_15")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.HttpConstants.Versions.v2018_06_18")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.HttpConstants.Versions.v2018_08_31")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.HttpConstants.Versions.v2018_09_17")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.HttpConstants.Versions.v2018_12_31")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.HttpConstants.Versions.v2019_10_14")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.HttpConstants.Versions.v2020_07_15")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.HttpConstants.Versions.v2020_11_05")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1308:Variable names should not be prefixed", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.HttpUtility.s_entityEndingChars")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1309:Field names should not begin with underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.HttpUtility.UrlDecoder._bufferSize")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1309:Field names should not begin with underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.HttpUtility.UrlDecoder._byteBuffer")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1309:Field names should not begin with underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.HttpUtility.UrlDecoder._charBuffer")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1309:Field names should not begin with underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.HttpUtility.UrlDecoder._encoding")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1309:Field names should not begin with underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.HttpUtility.UrlDecoder._numBytes")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1309:Field names should not begin with underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.HttpUtility.UrlDecoder._numChars")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.Address_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.Attachment_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.Attachments_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.AuthPolicyElement_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.AuthPolicyElements_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.CassandraRoleDefinitionOperationResultSegment_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.CassandraRoleDefinitionOperationResultsSegment_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.CassandraRoleDefinitionResourceSegment_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.CassandraRoleDefinitionResourceType_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.ClientConfig_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.ClientEncryptionKey_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.ClientEncryptionKeys_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.Collection_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.Collections_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.Conflict_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.Conflicts_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.ControllerOperations_BatchGetOutput")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.ControllerOperations_BatchReportCharges")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.CosmosProvider_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.Database_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.DatabaseAccount_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.DatabaseAccountResourceSegment_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.DatabaseAccountType_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.Databases_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.DataExplorer_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.DataExplorerAuthToken_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.DataExplorerAuthToken_WithoutResourceId")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.DataExplorerAuthToken_WithResourceId")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.Document_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.Documents_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.EncryptionScope_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.EncryptionScopes_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.FederationEndpoint_Address_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.FederationEndpoint_Attachment_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.FederationEndpoint_Attachments_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.FederationEndpoint_ClientConfig_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.FederationEndpoint_Collection_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.FederationEndpoint_Collections_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.FederationEndpoint_Database_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.FederationEndpoint_Databases_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.FederationEndpoint_Offer_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.FederationEndpoint_Offers_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.FederationEndpoint_PartitionKeyRanges_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.FederationEndpoint_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.FederationEndpoint_StoredProcedure_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.FederationEndpoint_StoredProcedures_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.File_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.Files_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.InteropUser_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.InteropUsers_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.LocalEmulator_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.LocalEmulatorManagedIdentity_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.Media_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.Medias_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.MongoDbRoleDefinitionOperationResultSegment_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.MongoDbRoleDefinitionOperationResultsSegment_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.MongoDbRoleDefinitionResourceSegment_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.MongoDbRoleDefinitionResourceType_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.MongoDbUserDefinitionOperationResultSegment_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.MongoDbUserDefinitionOperationResultsSegment_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.MongoDbUserDefinitionResourceSegment_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.MongoDbUserDefinitionResourceType_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.Offer_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.Offers_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.Operations_GetAadGroups")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.Operations_GetConfiguration")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.Operations_GetCustomerManagedKeyStatus")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.Operations_GetDatabaseAccountConfigurations")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.Operations_GetFederationConfigurations")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.Operations_GetGraphDatabaseAccountConfiguration")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.Operations_GetStorageAccountKey")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.Operations_GetStorageAccountSas")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.Operations_GetStorageServiceConfigurations")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.Operations_GetUnwrappedDek")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.Operations_MasterInitiatedProgressCoordination")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.Operations_MetadataCheckAccess")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.Operations_ReadReplicaFromMasterPartition")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.Operations_ReadReplicaFromServerPartition")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.Operations_XPDatabaseAccountMetaData")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.ParatitionKeyRangeOperations_Split")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.PartitionedSystemDocument_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.PartitionedSystemDocuments_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.PartitionKeyRange_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.PartitionKeyRangePostSplit_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.PartitionKeyRangePreSplit_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.PartitionKeyRanges_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.Partitions_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.Permission_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.Permissions_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.ProvidersSegment_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.ReplicaOperations_BatchReportThroughputUtilization")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.ReplicaOperations_Crash")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.ReplicaOperations_ForceConfigRefresh")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.ReplicaOperations_Pause")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.ReplicaOperations_Recycle")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.ReplicaOperations_ReportThroughputUtilization")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.ReplicaOperations_Resume")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.ReplicaOperations_Stop")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.ResourceGroupSegment_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.ResourceGroupsSegment_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.RetriableWriteCachedResponse_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.RidRange_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.RoleAssignment_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.RoleAssignments_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.RoleDefinition_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.RoleDefinitions_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.Schema_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.Schemas_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.ServiceReservation_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.Snapshot_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.Snapshots_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.StorageAuthToken_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.StoredProcedure_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.StoredProcedures_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.SubscriptionIdSegment_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.SubscriptionsSegment_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.SystemDocument_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.SystemDocuments_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.Topology_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.Transaction_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.Transactions_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.Trigger_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.Triggers_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.User_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.UserDefinedFunction_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.UserDefinedFunctions_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.UserDefinedType_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.UserDefinedTypes_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.Users_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Paths.XPReplicatorAddress_Root")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1214:Readonly fields should appear before non-readonly fields", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.PerformanceActivity.requestsCounter")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1309:Field names should not begin with underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.PlatformApis._distroInfo")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1309:Field names should not begin with underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.PlatformApis._platform")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1214:Readonly fields should appear before non-readonly fields", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.PooledTimer.tcs")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1214:Readonly fields should appear before non-readonly fields", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.ReferenceCountedDisposable`1._boxedReferenceCount")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1309:Field names should not begin with underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.ReferenceCountedDisposable`1._boxedReferenceCount")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1309:Field names should not begin with underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.ReferenceCountedDisposable`1._instance")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1137:Elements should have the same indentation", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.ReplicatedResourceClient.enableGlobalStrong")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1500:Braces for multi-line statements should not share line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.ReplicatedResourceClient.enableGlobalStrong")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1203:Constants should appear before fields", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.RequestChargeTracker.numberOfDecimalPointToReserveFactor")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1214:Readonly fields should appear before non-readonly fields", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Rntbd.Channel.openingSlim")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1214:Readonly fields should appear before non-readonly fields", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Rntbd.Channel.stateLock")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1214:Readonly fields should appear before non-readonly fields", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Rntbd.ChannelDictionary.chaosInterceptor")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1214:Readonly fields should appear before non-readonly fields", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Rntbd.Connection.idleConnectionTimeout")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1214:Readonly fields should appear before non-readonly fields", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Rntbd.Connection.nameLock")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1214:Readonly fields should appear before non-readonly fields", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Rntbd.Connection.timestampLock")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1214:Readonly fields should appear before non-readonly fields", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Rntbd.CpuMonitor.rwLock")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1214:Readonly fields should appear before non-readonly fields", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Rntbd.Dispatcher.CallInfo.stateLock")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1214:Readonly fields should appear before non-readonly fields", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Rntbd.Dispatcher.callLock")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1214:Readonly fields should appear before non-readonly fields", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Rntbd.Dispatcher.calls")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1214:Readonly fields should appear before non-readonly fields", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Rntbd.Dispatcher.chaosInterceptor")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1214:Readonly fields should appear before non-readonly fields", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Rntbd.Dispatcher.connectionLock")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1400:Access modifier should be declared", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Rntbd.LinuxSystemUtilizationReader.ProcStatFileParser.cpuPrefixFirstLine")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1214:Readonly fields should appear before non-readonly fields", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Rntbd.LoadBalancingPartition.openChannels")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1214:Readonly fields should appear before non-readonly fields", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Rntbd.LoadBalancingPartition.sequenceGenerator")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1214:Readonly fields should appear before non-readonly fields", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Rntbd.TransportClient.DistributedTracingOptions")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.RntbdConstants.Request.a_IM")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1203:Constants should appear before fields", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Routing.PartitionKeyInternal.MaxPartitionKeyBinarySize")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1203:Constants should appear before fields", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.RuntimeConstants.Separators.HeaderEncodingBegin")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1214:Readonly fields should appear before non-readonly fields", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.ServerStoreModel.receivedResponse")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1500:Braces for multi-line statements should not share line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.SharedFiles.Routing.Int128.MaxValue")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1008:Opening parenthesis should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.SharedFiles.Routing.Int128.MaxValue")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1214:Readonly fields should appear before non-readonly fields", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.StoreClientFactory.protocol")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1137:Elements should have the same indentation", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.Telemetry.OpenTelemetryRecorderFactory.LazyScopeFactory")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1203:Constants should appear before fields", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.UserAgentContainer.maxSuffixLength")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1203:Constants should appear before fields", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~F:Microsoft.Azure.Documents.VectorSessionToken.SegmentSeparator")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1137:Elements should have the same indentation", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Azure.Core.ActivityExtensions.CreateActivityLink(System.String,System.String,System.Collections.Generic.ICollection{System.Collections.Generic.KeyValuePair{System.String,System.Object}})~System.Object")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1111:Closing parenthesis should be on line of last parameter", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Azure.Core.ActivityExtensions.CreateActivitySource(System.String)~System.Object")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1128:Put constructor initializers on their own line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Azure.Core.DiagnosticScope.DiagnosticActivity.#ctor(System.String)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1128:Put constructor initializers on their own line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Cosmos.Rntbd.BytesDeserializer.#ctor(System.Byte[],System.Int32)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.AddressInformation.CompareTo(Microsoft.Azure.Documents.AddressInformation)~System.Int32")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1616:Element return value documentation should have text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.AddressSelector.ResolveAllTransportAddressUriAsync(Microsoft.Azure.Documents.DocumentServiceRequest,System.Boolean,System.Boolean)~System.Threading.Tasks.Task{System.ValueTuple{System.Collections.Generic.IReadOnlyList{Microsoft.Azure.Documents.TransportAddressUri},System.Collections.Generic.IReadOnlyList{System.String}}}")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "VSTHRD110:Observe result of async calls", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.AddressSelector.StartBackgroundAddressRefresh(Microsoft.Azure.Documents.DocumentServiceRequest)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Attachment.#ctor")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.BadRequestException.#ctor")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.BadRequestException.#ctor(System.Exception)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.BadRequestException.#ctor(System.String)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.BadRequestException.#ctor(System.String,System.Exception)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.BadRequestException.#ctor(System.String,System.Net.Http.Headers.HttpResponseHeaders,System.Uri)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1108:Block statements should not contain embedded comments", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.BarrierRequestHelper.CreateAsync(Microsoft.Azure.Documents.DocumentServiceRequest,Microsoft.Azure.Documents.IAuthorizationTokenProvider,System.Nullable{System.Int64},System.Nullable{System.Int64})~System.Threading.Tasks.Task{Microsoft.Azure.Documents.DocumentServiceRequest}")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.BarrierRequestHelper.IsCollectionHeadBarrierRequest(Microsoft.Azure.Documents.ResourceType,Microsoft.Azure.Documents.OperationType)~System.Boolean")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Client.DocumentResponse`1.#ctor")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1003:Symbols should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Client.DocumentResponse`1.#ctor(`0)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1024:Colons Should Be Spaced Correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Client.DocumentResponse`1.#ctor(`0)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1003:Symbols should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Client.DocumentResponse`1.#ctor(Microsoft.Azure.Documents.DocumentServiceResponse,Newtonsoft.Json.JsonSerializerSettings)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1024:Colons Should Be Spaced Correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Client.DocumentResponse`1.#ctor(Microsoft.Azure.Documents.DocumentServiceResponse,Newtonsoft.Json.JsonSerializerSettings)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Client.ResourceResponse`1.#ctor")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1003:Symbols should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Client.ResourceResponse`1.#ctor(`0)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1024:Colons Should Be Spaced Correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Client.ResourceResponse`1.#ctor(`0)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1003:Symbols should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Client.ResourceResponse`1.#ctor(Microsoft.Azure.Documents.DocumentServiceResponse,Microsoft.Azure.Documents.ITypeResolver{`0})")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1024:Colons Should Be Spaced Correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Client.ResourceResponse`1.#ctor(Microsoft.Azure.Documents.DocumentServiceResponse,Microsoft.Azure.Documents.ITypeResolver{`0})")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Client.ResourceResponseBase.#ctor")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Client.ResourceResponseBase.GetCurrentQuotaHeader(System.String)~System.Int64")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Client.ResourceResponseBase.GetMaxQuotaHeader(System.String)~System.Int64")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Client.ResourceResponseBase.PopulateQuotaHeader(System.String,System.String)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.ClientEncryptionKey.#ctor")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.ClientSideRequestStatistics.#cctor")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1507:Code should not contain multiple blank lines in a row", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.ClientSideRequestStatistics.#ctor")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.ClientSideRequestStatistics.AppendToBuilder(System.Text.StringBuilder)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.CloneableStream.ConvertToExportableMemoryStream(System.IO.MemoryStream)~System.IO.MemoryStream")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1128:Put constructor initializers on their own line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Collections.DictionaryNameValueCollection.#ctor(Microsoft.Azure.Documents.Collections.INameValueCollection)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1128:Put constructor initializers on their own line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Collections.DictionaryNameValueCollection.#ctor(System.Collections.Specialized.NameValueCollection)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1128:Put constructor initializers on their own line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Collections.DictionaryNameValueCollection.#ctor(System.Int32)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1502:Element should not be on a single line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Collections.DictionaryNameValueCollection.#ctor(System.Int32)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1128:Put constructor initializers on their own line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Collections.DictionaryNameValueCollection.CompositeValue.#ctor(System.String)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1500:Braces for multi-line statements should not share line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Collections.DictionaryNameValueCollection.Set(System.String,System.String)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1606:Element documentation should have summary text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Collections.INameValueCollectionFactory.CreateNewNameValueCollection~Microsoft.Azure.Documents.Collections.INameValueCollection")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1616:Element return value documentation should have text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Collections.INameValueCollectionFactory.CreateNewNameValueCollection~Microsoft.Azure.Documents.Collections.INameValueCollection")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1606:Element documentation should have summary text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Collections.INameValueCollectionFactory.CreateNewNameValueCollection(Microsoft.Azure.Documents.Collections.INameValueCollection)~Microsoft.Azure.Documents.Collections.INameValueCollection")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1616:Element return value documentation should have text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Collections.INameValueCollectionFactory.CreateNewNameValueCollection(Microsoft.Azure.Documents.Collections.INameValueCollection)~Microsoft.Azure.Documents.Collections.INameValueCollection")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1606:Element documentation should have summary text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Collections.INameValueCollectionFactory.CreateNewNameValueCollection(System.Collections.Specialized.NameValueCollection)~Microsoft.Azure.Documents.Collections.INameValueCollection")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1616:Element return value documentation should have text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Collections.INameValueCollectionFactory.CreateNewNameValueCollection(System.Collections.Specialized.NameValueCollection)~Microsoft.Azure.Documents.Collections.INameValueCollection")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1606:Element documentation should have summary text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Collections.INameValueCollectionFactory.CreateNewNameValueCollection(System.Int32)~Microsoft.Azure.Documents.Collections.INameValueCollection")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1616:Element return value documentation should have text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Collections.INameValueCollectionFactory.CreateNewNameValueCollection(System.Int32)~Microsoft.Azure.Documents.Collections.INameValueCollection")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1606:Element documentation should have summary text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Collections.INameValueCollectionFactory.CreateNewNameValueCollection(System.StringComparer)~Microsoft.Azure.Documents.Collections.INameValueCollection")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1616:Element return value documentation should have text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Collections.INameValueCollectionFactory.CreateNewNameValueCollection(System.StringComparer)~Microsoft.Azure.Documents.Collections.INameValueCollection")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1606:Element documentation should have summary text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Collections.NameValueCollectionWrapper.#ctor")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1606:Element documentation should have summary text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Collections.NameValueCollectionWrapper.#ctor(Microsoft.Azure.Documents.Collections.INameValueCollection)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1606:Element documentation should have summary text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Collections.NameValueCollectionWrapper.#ctor(Microsoft.Azure.Documents.Collections.NameValueCollectionWrapper)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1606:Element documentation should have summary text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Collections.NameValueCollectionWrapper.#ctor(System.Collections.Specialized.NameValueCollection)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1606:Element documentation should have summary text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Collections.NameValueCollectionWrapper.#ctor(System.StringComparer)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1606:Element documentation should have summary text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Collections.NameValueCollectionWrapper.Add(System.String,System.String)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1616:Element return value documentation should have text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Collections.NameValueCollectionWrapper.AllKeys~System.String[]")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1606:Element documentation should have summary text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Collections.NameValueCollectionWrapper.AllKeys~System.String[]")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1606:Element documentation should have summary text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Collections.NameValueCollectionWrapper.Clear")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1606:Element documentation should have summary text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Collections.NameValueCollectionWrapper.Clone~Microsoft.Azure.Documents.Collections.INameValueCollection")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1616:Element return value documentation should have text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Collections.NameValueCollectionWrapper.Clone~Microsoft.Azure.Documents.Collections.INameValueCollection")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1616:Element return value documentation should have text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Collections.NameValueCollectionWrapper.Create(System.Collections.Specialized.NameValueCollection)~Microsoft.Azure.Documents.Collections.NameValueCollectionWrapper")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1606:Element documentation should have summary text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Collections.NameValueCollectionWrapper.Create(System.Collections.Specialized.NameValueCollection)~Microsoft.Azure.Documents.Collections.NameValueCollectionWrapper")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1606:Element documentation should have summary text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Collections.NameValueCollectionWrapper.Get(System.String)~System.String")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1616:Element return value documentation should have text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Collections.NameValueCollectionWrapper.Get(System.String)~System.String")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1606:Element documentation should have summary text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Collections.NameValueCollectionWrapper.GetEnumerator~System.Collections.IEnumerator")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1616:Element return value documentation should have text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Collections.NameValueCollectionWrapper.GetEnumerator~System.Collections.IEnumerator")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1616:Element return value documentation should have text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Collections.NameValueCollectionWrapper.GetValues(System.String)~System.String[]")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1606:Element documentation should have summary text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Collections.NameValueCollectionWrapper.GetValues(System.String)~System.String[]")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1606:Element documentation should have summary text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Collections.NameValueCollectionWrapper.Remove(System.String)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1606:Element documentation should have summary text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Collections.NameValueCollectionWrapper.Set(System.String,System.String)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1616:Element return value documentation should have text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Collections.NameValueCollectionWrapper.ToNameValueCollection~System.Collections.Specialized.NameValueCollection")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1606:Element documentation should have summary text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Collections.NameValueCollectionWrapper.ToNameValueCollection~System.Collections.Specialized.NameValueCollection")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1137:Elements should have the same indentation", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Collections.RequestNameValueCollection.ToNameValueCollection~System.Collections.Specialized.NameValueCollection")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Collections.StoreResponseNameValueCollection.ToNameValueCollection~System.Collections.Specialized.NameValueCollection")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1137:Elements should have the same indentation", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Collections.StoreResponseNameValueCollection.ToNameValueCollection~System.Collections.Specialized.NameValueCollection")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1127:Generic type constraints should be on their own line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Conflict.GetResource``1~``0")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1127:Generic type constraints should be on their own line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Conflict.SetResource``1(``0)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.ConflictException.#ctor")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.ConflictException.#ctor(System.Exception)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.ConflictException.#ctor(System.String)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.ConflictException.#ctor(System.String,Microsoft.Azure.Documents.SubStatusCodes)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.ConflictException.#ctor(System.String,System.Exception)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.ConflictException.#ctor(System.String,System.Net.Http.Headers.HttpResponseHeaders,System.Uri)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.ConnectionHealthChecker.IsTransitTimeoutsDetected(System.DateTime,System.DateTime)~System.Boolean")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "VSTHRD110:Observe result of async calls", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.ConnectionStateListener.OnConnectionEvent(Microsoft.Azure.Documents.ConnectionEvent,System.DateTime,Microsoft.Azure.Documents.Rntbd.ServerKey)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.ConsistencyReader.ReadAnyAsync(Microsoft.Azure.Documents.DocumentServiceRequest,Microsoft.Azure.Documents.ReadMode)~System.Threading.Tasks.Task{Microsoft.Azure.Documents.StoreResponse}")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.ConsistencyReader.ReadAsync(Microsoft.Azure.Documents.DocumentServiceRequest,Microsoft.Azure.Documents.TimeoutHelper,System.Boolean,System.Boolean,System.Threading.CancellationToken)~System.Threading.Tasks.Task{Microsoft.Azure.Documents.StoreResponse}")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1024:Colons Should Be Spaced Correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.ConsistencyReader.ReadSessionAsync(Microsoft.Azure.Documents.DocumentServiceRequest,Microsoft.Azure.Documents.ReadMode)~System.Threading.Tasks.Task{Microsoft.Azure.Documents.StoreResponse}")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.CustomTypeExtensions.ByPassQueryParsing~System.Boolean")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1510:Chained statement blocks should not be preceded by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.CustomTypeExtensions.ConfirmOpen(System.Net.Sockets.Socket)~System.Boolean")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Database.#ctor")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Document.#ctor")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Document.FromObject(System.Object,Newtonsoft.Json.JsonSerializerSettings)~Microsoft.Azure.Documents.Document")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Document.GetProperty(System.String,System.Type)~System.Object")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.DocumentCollection.OnSave")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1027:Use tabs correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.DocumentServiceRequest.#ctor(Microsoft.Azure.Documents.OperationType,Microsoft.Azure.Documents.ResourceType,System.String,System.IO.Stream,Microsoft.Azure.Documents.AuthorizationTokenType,Microsoft.Azure.Documents.Collections.INameValueCollection)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1027:Use tabs correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.DocumentServiceRequest.#ctor(Microsoft.Azure.Documents.OperationType,Microsoft.Azure.Documents.ResourceType,System.String,System.IO.Stream,Microsoft.Azure.Documents.AuthorizationTokenType,Microsoft.Azure.Documents.Collections.INameValueCollection,System.Boolean,System.Boolean,System.String,System.String,System.String,System.String,System.String)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1500:Braces for multi-line statements should not share line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.DocumentServiceRequest.Clone~Microsoft.Azure.Documents.DocumentServiceRequest")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1025:Code should not contain multiple whitespace in a row", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.DocumentServiceRequest.Clone~Microsoft.Azure.Documents.DocumentServiceRequest")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1507:Code should not contain multiple blank lines in a row", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.DocumentServiceRequest.Create(Microsoft.Azure.Documents.OperationType,Microsoft.Azure.Documents.Resource,Microsoft.Azure.Documents.ResourceType,Microsoft.Azure.Documents.AuthorizationTokenType,Microsoft.Azure.Documents.Collections.INameValueCollection,System.String,Microsoft.Azure.Documents.SerializationFormattingPolicy)~Microsoft.Azure.Documents.DocumentServiceRequest")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1616:Element return value documentation should have text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.DocumentServiceRequest.IsValidAddress(Microsoft.Azure.Documents.ResourceType)~System.Boolean")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.DocumentServiceRequest.RouteTo(Microsoft.Azure.Documents.PartitionKeyRangeIdentity)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.DocumentServiceRequest.RouteTo(Microsoft.Azure.Documents.ServiceIdentity)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1127:Generic type constraints should be on their own line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.DocumentServiceResponse.GetInternalResource``1(System.Func{``0})~``0")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1108:Block statements should not contain embedded comments", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.DocumentServiceResponse.GetQueryResponse``1(System.Type,System.Boolean,System.Int32@)~System.Collections.Generic.IEnumerable{``0}")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1127:Generic type constraints should be on their own line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.DocumentServiceResponse.GetResource``1(Microsoft.Azure.Documents.ITypeResolver{``0})~``0")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1127:Generic type constraints should be on their own line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.DocumentServiceResponse.GetTypeResolver``1~Microsoft.Azure.Documents.ITypeResolver{``0}")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Error.#ctor")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1616:Element return value documentation should have text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.FaultInjection.IChaosInterceptor.OnRequestCall(Microsoft.Azure.Documents.Rntbd.ChannelCallArguments,Microsoft.Azure.Documents.StoreResponse@)~System.Boolean")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.FeedResource`1.#ctor")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.ForbiddenException.#ctor")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.ForbiddenException.#ctor(System.Exception)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.ForbiddenException.#ctor(System.String)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.ForbiddenException.#ctor(System.String,System.Exception)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.ForbiddenException.#ctor(System.String,System.Net.Http.Headers.HttpResponseHeaders,System.Uri)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1502:Element should not be on a single line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.GoneAndRetryWithRequestRetryPolicy`1.OnBeforeSendRequest(Microsoft.Azure.Documents.DocumentServiceRequest)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.GoneAndRetryWithRequestRetryPolicy`1.TryHandleResponseSynchronously(Microsoft.Azure.Documents.DocumentServiceRequest,`0,System.Exception,Microsoft.Azure.Documents.ShouldRetryResult@)~System.Boolean")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.GoneAndRetryWithRetryPolicy.Microsoft#Azure#Documents#IRetryPolicy#ShouldRetryAsync(System.Exception,System.Threading.CancellationToken)~System.Threading.Tasks.Task{Microsoft.Azure.Documents.ShouldRetryResult{System.Boolean}}")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1507:Code should not contain multiple blank lines in a row", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.GoneAndRetryWithRetryPolicy.Microsoft#Azure#Documents#IRetryPolicy>#ShouldRetryAsync(System.Exception,System.Threading.CancellationToken)~System.Threading.Tasks.Task{Microsoft.Azure.Documents.ShouldRetryResult{System.Tuple{System.Boolean,System.Boolean,System.TimeSpan,System.Int32,System.Int32,System.TimeSpan}}}")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.GoneAndRetryWithRetryPolicy.Microsoft#Azure#Documents#IRetryPolicy>#ShouldRetryAsync(System.Exception,System.Threading.CancellationToken)~System.Threading.Tasks.Task{Microsoft.Azure.Documents.ShouldRetryResult{System.Tuple{System.Boolean,System.Boolean,System.TimeSpan,System.Int32,System.Int32,System.TimeSpan}}}")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.GoneException.#ctor")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1502:Element should not be on a single line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.GoneOnlyRequestRetryPolicy`1.OnBeforeSendRequest(Microsoft.Azure.Documents.DocumentServiceRequest)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1122:Use string.Empty for empty strings", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Helpers.ExtractValuesFromHTTPHeaders(System.Net.Http.Headers.HttpHeaders,System.String[])~System.String[]")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1015:Closing generic brackets should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Helpers.ExtractValuesFromHTTPHeaders(System.Net.Http.Headers.HttpHeaders,System.String[])~System.String[]")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1616:Element return value documentation should have text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Helpers.GetAppSpecificUserAgentSuffix(System.String,System.String)~System.String")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1127:Generic type constraints should be on their own line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Helpers.GetEnvironmentVariable``1(System.String,``0)~``0")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1616:Element return value documentation should have text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Helpers.GetHeaderValueByte(Microsoft.Azure.Documents.Collections.INameValueCollection,System.String,System.Byte)~System.Byte")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "VSTHRD200:Use \"Async\" suffix for async methods", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.HttpTransportClient.CreateErrorResponseFromHttpResponse(System.String,System.String,System.Net.Http.HttpResponseMessage,Microsoft.Azure.Documents.DocumentServiceRequest)~System.Threading.Tasks.Task{Microsoft.Azure.Documents.StoreResponse}")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1137:Elements should have the same indentation", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.HttpTransportClient.CreateErrorResponseFromHttpResponse(System.String,System.String,System.Net.Http.HttpResponseMessage,Microsoft.Azure.Documents.DocumentServiceRequest)~System.Threading.Tasks.Task{Microsoft.Azure.Documents.StoreResponse}")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "VSTHRD200:Use \"Async\" suffix for async methods", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.HttpTransportClient.CreateStoreResponseFromHttpResponse(System.Net.Http.HttpResponseMessage,System.Boolean)~System.Threading.Tasks.Task{Microsoft.Azure.Documents.StoreResponse}")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1137:Elements should have the same indentation", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.HttpTransportClient.ProcessHttpResponse(System.String,System.String,System.Net.Http.HttpResponseMessage,System.Uri,Microsoft.Azure.Documents.DocumentServiceRequest)~System.Threading.Tasks.Task{Microsoft.Azure.Documents.StoreResponse}")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "VSTHRD200:Use \"Async\" suffix for async methods", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.HttpTransportClient.ProcessHttpResponse(System.String,System.String,System.Net.Http.HttpResponseMessage,System.Uri,Microsoft.Azure.Documents.DocumentServiceRequest)~System.Threading.Tasks.Task{Microsoft.Azure.Documents.StoreResponse}")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1507:Code should not contain multiple blank lines in a row", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.HttpUtility.UrlEncode(System.Byte[],System.Int32,System.Int32)~System.String")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.IndexJsonConverter.ReadJson(Newtonsoft.Json.JsonReader,System.Type,System.Object,Newtonsoft.Json.JsonSerializer)~System.Object")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1111:Closing parenthesis should be on line of last parameter", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.IndexJsonConverter.ReadJson(Newtonsoft.Json.JsonReader,System.Type,System.Object,Newtonsoft.Json.JsonSerializer)~System.Object")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.InternalServerErrorException.#ctor")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.InternalServerErrorException.#ctor(Microsoft.Azure.Documents.SubStatusCodes)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.InternalServerErrorException.#ctor(System.Exception)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.InternalServerErrorException.#ctor(System.String,Microsoft.Azure.Documents.SubStatusCodes)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.InternalServerErrorException.#ctor(System.String,System.Exception,System.Uri)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.InternalServerErrorException.#ctor(System.String,System.Net.Http.Headers.HttpResponseHeaders,System.Uri)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.InternalServerErrorException.#ctor(System.String,System.Uri)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.InvalidPartitionException.#ctor")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1616:Element return value documentation should have text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.IRequestRetryPolicy`2.ShouldRetryAsync(`0,`1,System.Exception,System.Threading.CancellationToken)~System.Threading.Tasks.Task{Microsoft.Azure.Documents.ShouldRetryResult}")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1612:Element parameter documentation should match element parameters", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.IRequestRetryPolicy`2.TryHandleResponseSynchronously(`0,`1,System.Exception,Microsoft.Azure.Documents.ShouldRetryResult@)~System.Boolean")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1127:Generic type constraints should be on their own line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.JsonSerializable.GetEnumValue``1(System.String)~System.Nullable{``0}")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1616:Element return value documentation should have text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.JsonSerializable.GetEnumValue``1(System.String)~System.Nullable{``0}")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1622:Generic type parameter documentation should have text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.JsonSerializable.GetEnumValue``1(System.String)~System.Nullable{``0}")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1127:Generic type constraints should be on their own line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.JsonSerializable.GetObject``1(System.String,System.Boolean)~``0")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1127:Generic type constraints should be on their own line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.JsonSerializable.GetObjectCollection``1(System.String,System.Type,System.String,Microsoft.Azure.Documents.ITypeResolver{``0})~System.Collections.ObjectModel.Collection{``0}")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1127:Generic type constraints should be on their own line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.JsonSerializable.GetObjectCollectionWithResolver``1(System.String,Microsoft.Azure.Documents.ITypeResolver{``0})~System.Collections.ObjectModel.Collection{``0}")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.JsonSerializable.GetObjectDictionary``1(System.String,Microsoft.Azure.Documents.ITypeResolver{``0},System.Collections.Generic.IEqualityComparer{System.String})~System.Collections.Generic.Dictionary{System.String,``0}")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1127:Generic type constraints should be on their own line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.JsonSerializable.GetObjectDictionary``1(System.String,Microsoft.Azure.Documents.ITypeResolver{``0},System.Collections.Generic.IEqualityComparer{System.String})~System.Collections.Generic.Dictionary{System.String,``0}")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1127:Generic type constraints should be on their own line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.JsonSerializable.GetObjectDictionaryWithNullableValues``1(System.String)~System.Collections.Generic.Dictionary{System.String,``0}")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1127:Generic type constraints should be on their own line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.JsonSerializable.GetObjectWithResolver``1(System.String,Microsoft.Azure.Documents.ITypeResolver{``0},System.Boolean)~``0")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1127:Generic type constraints should be on their own line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.JsonSerializable.GetTypeResolver``1~Microsoft.Azure.Documents.ITypeResolver{``0}")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1616:Element return value documentation should have text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.JsonSerializable.GetValue``1(System.String)~``0")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1622:Generic type parameter documentation should have text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.JsonSerializable.GetValue``1(System.String)~``0")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1616:Element return value documentation should have text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.JsonSerializable.GetValue``1(System.String,``0)~``0")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1622:Generic type parameter documentation should have text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.JsonSerializable.GetValue``1(System.String,``0)~``0")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1616:Element return value documentation should have text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.JsonSerializable.GetValueByPath``1(System.String[],``0)~``0")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1622:Generic type parameter documentation should have text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.JsonSerializable.GetValueByPath``1(System.String[],``0)~``0")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1507:Code should not contain multiple blank lines in a row", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.JsonSerializable.LoadFrom(Newtonsoft.Json.JsonReader)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1127:Generic type constraints should be on their own line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.JsonSerializable.LoadFrom``1(Newtonsoft.Json.JsonTextReader,Microsoft.Azure.Documents.ITypeResolver{``0},Newtonsoft.Json.JsonSerializerSettings)~``0")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1127:Generic type constraints should be on their own line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.JsonSerializable.LoadFrom``1(System.IO.Stream)~``0")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1127:Generic type constraints should be on their own line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.JsonSerializable.LoadFrom``1(System.IO.Stream,Microsoft.Azure.Documents.ITypeResolver{``0},Newtonsoft.Json.JsonSerializerSettings)~``0")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1127:Generic type constraints should be on their own line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.JsonSerializable.LoadFrom``1(System.String,Microsoft.Azure.Documents.ITypeResolver{``0},Newtonsoft.Json.JsonSerializerSettings)~``0")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1127:Generic type constraints should be on their own line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.JsonSerializable.LoadFromWithResolver``1(Microsoft.Azure.Documents.ITypeResolver{``0},Newtonsoft.Json.JsonSerializerSettings,Newtonsoft.Json.JsonTextReader)~``0")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1127:Generic type constraints should be on their own line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.JsonSerializable.LoadFromWithResolver``1(System.IO.Stream,Microsoft.Azure.Documents.ITypeResolver{``0},Newtonsoft.Json.JsonSerializerSettings)~``0")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1127:Generic type constraints should be on their own line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.JsonSerializable.LoadFromWithResolver``1(System.String,Microsoft.Azure.Documents.ITypeResolver{``0},Newtonsoft.Json.JsonSerializerSettings)~``0")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.JsonSerializable.OnSave")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1127:Generic type constraints should be on their own line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.JsonSerializable.SetObject``1(System.String,``0)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1127:Generic type constraints should be on their own line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.JsonSerializable.SetObjectCollection``1(System.String,System.Collections.ObjectModel.Collection{``0})")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1127:Generic type constraints should be on their own line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.JsonSerializable.SetObjectDictionary``1(System.String,System.Collections.Generic.Dictionary{System.String,``0})")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1127:Generic type constraints should be on their own line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.JsonSerializable.SetObjectDictionaryWithNullableValues``1(System.String,System.Collections.Generic.Dictionary{System.String,``0})")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1616:Element return value documentation should have text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.JsonSerializable.SetValueByPath``1(System.String[],``0)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1617:Void return value should not be documented", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.JsonSerializable.SetValueByPath``1(System.String[],``0)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1622:Generic type parameter documentation should have text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.JsonSerializable.SetValueByPath``1(System.String[],``0)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.KeyWrapMetadata.#ctor")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.LockedException.#ctor")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.LockedException.#ctor(System.Exception)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.LockedException.#ctor(System.String,Microsoft.Azure.Documents.SubStatusCodes)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.LockedException.#ctor(System.String,System.Exception,System.Uri)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.LockedException.#ctor(System.String,System.Net.Http.Headers.HttpResponseHeaders,System.Uri)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.LockedException.#ctor(System.String,System.Uri)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1407:Arithmetic expressions should declare precedence", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.MathUtils.CeilingMultiple(System.Int32,System.Int32)~System.Int32")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.MethodNotAllowedException.#ctor")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.MethodNotAllowedException.#ctor(System.Exception)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1128:Put constructor initializers on their own line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.MethodNotAllowedException.#ctor(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1003:Symbols should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.MethodNotAllowedException.#ctor(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.MethodNotAllowedException.#ctor(System.String)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.MethodNotAllowedException.#ctor(System.String,System.Net.Http.Headers.HttpResponseHeaders,System.Uri)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1616:Element return value documentation should have text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.NetUtil.GetLocalEmulatorIpV4Address~System.String")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1616:Element return value documentation should have text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.NetUtil.GetNonLoopbackIpV4Address~System.String")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.NotFoundException.#ctor")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.NotFoundException.#ctor(System.Exception)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.NotFoundException.#ctor(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.NotFoundException.#ctor(System.String)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.NotFoundException.#ctor(System.String,System.Exception)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.NotFoundException.#ctor(System.String,System.Net.Http.Headers.HttpResponseHeaders,System.Uri)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1128:Put constructor initializers on their own line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.OfferContentV2.#ctor")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.OfferContentV2.#ctor(Microsoft.Azure.Documents.OfferContentV2,System.Int32,System.Nullable{System.Boolean},System.Nullable{System.Double})")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.OfferTypeResolver.Microsoft#Azure#Documents#ITypeResolver#Resolve(Newtonsoft.Json.Linq.JObject)~Microsoft.Azure.Documents.Offer")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1502:Element should not be on a single line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.OpenConnectionPerformanceActivity.#ctor")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.PartitionAddressInformation.#ctor(System.Collections.Generic.IReadOnlyList{Microsoft.Azure.Documents.AddressInformation})")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.PartitionAddressInformation.#ctor(System.Collections.Generic.IReadOnlyList{Microsoft.Azure.Documents.AddressInformation},System.Boolean)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1003:Symbols should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.PartitionAddressInformation.#ctor(System.Collections.Generic.IReadOnlyList{Microsoft.Azure.Documents.AddressInformation},System.Boolean)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1008:Opening parenthesis should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.PartitionKey.#ctor(System.Object[])")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1616:Element return value documentation should have text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.PartitionKeyRangeStatistics.ToString~System.String")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1616:Element return value documentation should have text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.PartitionKeyStatistics.ToString~System.String")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1507:Code should not contain multiple blank lines in a row", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.PathsHelper.GeneratePath(Microsoft.Azure.Documents.ResourceType,System.String,System.Boolean,Microsoft.Azure.Documents.OperationType)~System.String")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.PathsHelper.GeneratePath(Microsoft.Azure.Documents.ResourceType,System.String,System.Boolean,Microsoft.Azure.Documents.OperationType)~System.String")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1025:Code should not contain multiple whitespace in a row", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.PathsHelper.GeneratePathForNamedBasedInternalResources(Microsoft.Azure.Documents.ResourceType,System.String)~System.String")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1520:Use braces consistently", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.PathsHelper.GetParentByIndex(System.String,System.Int32)~System.String")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1520:Use braces consistently", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.PathsHelper.GetResourcePathArray(Microsoft.Azure.Documents.ResourceType)~System.String[]")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.PathsHelper.GetResourcePathArray(Microsoft.Azure.Documents.ResourceType)~System.String[]")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1507:Code should not contain multiple blank lines in a row", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.PathsHelper.ParseCollectionSelfLink(System.String,System.String@,System.String@)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1616:Element return value documentation should have text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.PathsHelper.TryParsePathSegments(System.String,System.Boolean@,System.String@,System.String@,System.Boolean@,System.String)~System.Boolean")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.PathsHelper.TryParsePathSegments(System.String,System.Boolean@,System.String@,System.String@,System.Boolean@,System.String)~System.Boolean")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1616:Element return value documentation should have text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.PathsHelper.TryParsePathSegmentsWithDatabaseAndCollectionAndDocumentNames(System.String,System.Boolean@,System.String@,System.String@,System.Boolean@,System.String@,System.String@,System.String@,System.String,System.Boolean)~System.Boolean")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1616:Element return value documentation should have text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.PathsHelper.TryParsePathSegmentsWithDatabaseAndCollectionAndOperationNames(System.String,System.String@,System.String@,System.Boolean@,System.String@,System.String@,Microsoft.Azure.Documents.ResourceType@,Microsoft.Azure.Documents.OperationType@)~System.Boolean")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1507:Code should not contain multiple blank lines in a row", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.PathsHelper.ValidateResourceId(Microsoft.Azure.Documents.ResourceType,System.String)~System.Boolean")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1111:Closing parenthesis should be on line of last parameter", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.PerformanceActivity.#ctor(System.Diagnostics.PerformanceCounter,System.Diagnostics.PerformanceCounter,System.Diagnostics.PerformanceCounter,System.Diagnostics.PerformanceCounter,System.Diagnostics.PerformanceCounter,System.String)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1025:Code should not contain multiple whitespace in a row", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.PerformanceActivity.ActivityComplete(System.Boolean)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1008:Opening parenthesis should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.PerProtocolPartitionAddressInformation.#ctor(Microsoft.Azure.Documents.Client.Protocol,System.Collections.Generic.IReadOnlyList{Microsoft.Azure.Documents.AddressInformation})")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.PerProtocolPartitionAddressInformation.#ctor(Microsoft.Azure.Documents.Client.Protocol,System.Collections.Generic.IReadOnlyList{Microsoft.Azure.Documents.AddressInformation})")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.PooledTimer.StartTimerAsync~System.Threading.Tasks.Task")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.PreconditionFailedException.#ctor")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.PreconditionFailedException.#ctor(System.Exception)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.PreconditionFailedException.#ctor(System.String,System.Exception)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.PreconditionFailedException.#ctor(System.String,System.Net.Http.Headers.HttpResponseHeaders,System.Uri)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.PreconditionFailedException.#ctor(System.String,System.Nullable{Microsoft.Azure.Documents.SubStatusCodes})")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1502:Element should not be on a single line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.ProcedureRequestPerformanceActivity.#ctor")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1502:Element should not be on a single line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.QueryRequestPerformanceActivity.#ctor")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1003:Symbols should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.QuorumReader.IsQuorumMet(System.Collections.Generic.IList{Microsoft.Azure.Documents.ReferenceCountedDisposable{Microsoft.Azure.Documents.StoreResult}},System.Int32,System.Boolean,System.Boolean,System.Int64@,System.Int64@,Microsoft.Azure.Documents.ReferenceCountedDisposable{Microsoft.Azure.Documents.StoreResult}@)~System.Boolean")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1024:Colons Should Be Spaced Correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.QuorumReader.IsQuorumMet(System.Collections.Generic.IList{Microsoft.Azure.Documents.ReferenceCountedDisposable{Microsoft.Azure.Documents.StoreResult}},System.Int32,System.Boolean,System.Boolean,System.Int64@,System.Int64@,Microsoft.Azure.Documents.ReferenceCountedDisposable{Microsoft.Azure.Documents.StoreResult}@)~System.Boolean")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.QuorumReader.IsQuorumMet(System.Collections.Generic.IList{Microsoft.Azure.Documents.ReferenceCountedDisposable{Microsoft.Azure.Documents.StoreResult}},System.Int32,System.Boolean,System.Boolean,System.Int64@,System.Int64@,Microsoft.Azure.Documents.ReferenceCountedDisposable{Microsoft.Azure.Documents.StoreResult}@)~System.Boolean")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1500:Braces for multi-line statements should not share line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.QuorumReader.ReadBoundedStalenessAsync(Microsoft.Azure.Documents.DocumentServiceRequest,System.Int32)~System.Threading.Tasks.Task{Microsoft.Azure.Documents.StoreResponse}")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1616:Element return value documentation should have text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.QuorumReader.ReadPrimaryAsync(Microsoft.Azure.Documents.DocumentServiceRequest,System.Int32,System.Boolean)~System.Threading.Tasks.Task{Microsoft.Azure.Documents.QuorumReader.ReadPrimaryResult}")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.QuorumReader.ReadQuorumAsync(Microsoft.Azure.Documents.DocumentServiceRequest,System.Int32,System.Boolean,Microsoft.Azure.Documents.ReadMode)~System.Threading.Tasks.Task{Microsoft.Azure.Documents.QuorumReader.ReadQuorumResult}")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1313:Parameter names should begin with lower-case letter", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.QuorumReader.ReadQuorumResult.#ctor(Microsoft.Azure.Documents.RequestChargeTracker,Microsoft.Azure.Documents.QuorumReader.ReadQuorumResultKind,System.Int64,System.Int64,Microsoft.Azure.Documents.ReferenceCountedDisposable{Microsoft.Azure.Documents.StoreResult},Microsoft.Azure.Documents.StoreResult[])")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.QuorumReader.ReadQuorumResult.ToString~System.String")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1500:Braces for multi-line statements should not share line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.QuorumReader.ReadStrongAsync(Microsoft.Azure.Documents.DocumentServiceRequest,System.Int32,Microsoft.Azure.Documents.ReadMode)~System.Threading.Tasks.Task{Microsoft.Azure.Documents.StoreResponse}")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1500:Braces for multi-line statements should not share line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.QuorumReader.WaitForPrimaryLsnAsync(Microsoft.Azure.Documents.DocumentServiceRequest,System.Int64,System.Int32)~System.Threading.Tasks.Task{Microsoft.Azure.Documents.QuorumReader.PrimaryReadOutcome}")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1108:Block statements should not contain embedded comments", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.QuorumReader.WaitForPrimaryLsnAsync(Microsoft.Azure.Documents.DocumentServiceRequest,System.Int64,System.Int32)~System.Threading.Tasks.Task{Microsoft.Azure.Documents.QuorumReader.PrimaryReadOutcome}")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.QuorumReader.WaitForReadBarrierAsync(Microsoft.Azure.Documents.DocumentServiceRequest,System.Boolean,System.Int32,System.Int64,System.Int64,Microsoft.Azure.Documents.ReadMode)~System.Threading.Tasks.Task{System.Boolean}")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1108:Block statements should not contain embedded comments", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.QuorumReader.WaitForReadBarrierAsync(Microsoft.Azure.Documents.DocumentServiceRequest,System.Boolean,System.Int32,System.Int64,System.Int64,Microsoft.Azure.Documents.ReadMode)~System.Threading.Tasks.Task{System.Boolean}")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.RegionProximityUtil.GetLinkTypeThresholdInMs(Microsoft.Azure.Documents.GeoLinkTypes)~System.Int64")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.RegionProximityUtil.GetRegionsForLinkType(Microsoft.Azure.Documents.GeoLinkTypes,System.Collections.Generic.List{System.String})~System.Collections.Generic.List{System.String}")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1500:Braces for multi-line statements should not share line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.ReplicatedResourceClient.InvokeAsync(Microsoft.Azure.Documents.DocumentServiceRequest,System.Threading.CancellationToken)~System.Threading.Tasks.Task{Microsoft.Azure.Documents.StoreResponse}")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1616:Element return value documentation should have text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.RequestChargeTracker.GetAndResetCharge~System.Double")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.RequestEntityTooLargeException.#ctor")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.RequestEntityTooLargeException.#ctor(System.Exception)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.RequestEntityTooLargeException.#ctor(System.String)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.RequestEntityTooLargeException.#ctor(System.String,System.Net.Http.Headers.HttpResponseHeaders,System.Uri)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1502:Element should not be on a single line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.RequestPerformanceActivity.#ctor")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.RequestRateTooLargeException.#ctor")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.RequestRateTooLargeException.#ctor(System.Exception)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.RequestRateTooLargeException.#ctor(System.String)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1502:Element should not be on a single line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.RequestRateTooLargeException.#ctor(System.String,Microsoft.Azure.Documents.SubStatusCodes)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.RequestRateTooLargeException.#ctor(System.String,System.Net.Http.Headers.HttpResponseHeaders,System.Uri)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1111:Closing parenthesis should be on line of last parameter", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.RequestRetryUtility.ProcessRequestAsync``3(System.Func{``0,System.Threading.Tasks.Task{``2}},System.Func{``1},Microsoft.Azure.Documents.IRequestRetryPolicy{``0,``1,``2},System.Func{``0,System.Threading.Tasks.Task{``2}},System.TimeSpan,System.Threading.CancellationToken)~System.Threading.Tasks.Task{``2}")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1111:Closing parenthesis should be on line of last parameter", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.RequestRetryUtility.ProcessRequestAsync``3(System.Func{``0,System.Threading.Tasks.Task{``2}},System.Func{``1},Microsoft.Azure.Documents.IRequestRetryPolicy{``0,``1,``2},System.Threading.CancellationToken)~System.Threading.Tasks.Task{``2}")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.RequestTimeoutException.#ctor")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.RequestTimeoutException.#ctor(System.Exception,System.Uri)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1507:Code should not contain multiple blank lines in a row", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.RequestTimeoutException.#ctor(System.String,System.Exception,System.Net.Http.Headers.HttpResponseHeaders,System.Uri)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.RequestTimeoutException.#ctor(System.String,System.Exception,System.Uri)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.RequestTimeoutException.#ctor(System.String,System.Net.Http.Headers.HttpResponseHeaders,System.Uri)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.RequestTimeoutException.#ctor(System.String,System.Uri)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1502:Element should not be on a single line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.ResolveFabricPerformanceActivity.#ctor")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Resource.#ctor")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.ResourceId.CreateNewCollectionChildResourceId(System.Int32,Microsoft.Azure.Documents.ResourceType,System.String)~System.String")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.ResourceId.NewCollectionChildResourceId(System.String,System.UInt64,Microsoft.Azure.Documents.ResourceType)~Microsoft.Azure.Documents.ResourceId")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1519:Braces should not be omitted from multi-line child statement", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.ResourceId.Parse(System.String)~Microsoft.Azure.Documents.ResourceId")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.ResourceId.TryParse(System.String,Microsoft.Azure.Documents.ResourceId@)~System.Boolean")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1407:Arithmetic expressions should declare precedence", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.ResourceIdBase64Decoder.TryComputeResultLength(System.Char*,System.Int32,System.Int32@)~System.Boolean")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1500:Braces for multi-line statements should not share line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.ResourceIdBase64Decoder.TryDecode(System.String,System.Byte[]@)~System.Boolean")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.RetryWithException.#ctor(System.String)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1003:Symbols should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.Channel.#ctor(System.Guid,System.Uri,Microsoft.Azure.Documents.Rntbd.ChannelProperties,System.Boolean,System.Threading.SemaphoreSlim,Microsoft.Azure.Documents.FaultInjection.IChaosInterceptor,System.Action{System.Guid,System.Uri,Microsoft.Azure.Documents.Rntbd.Channel})")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1003:Symbols should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.Channel.Close")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "VSTHRD110:Observe result of async calls", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.Channel.FinishInitialization(Microsoft.Azure.Documents.Rntbd.Channel.State)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.Channel.OpenChannelAsync(System.Guid)~System.Threading.Tasks.Task")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "VSTHRD002:Avoid problematic synchronous waits", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.Channel.System#IDisposable#Dispose")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1008:Opening parenthesis should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.ChannelCallArguments.#ctor(System.Guid)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1025:Code should not contain multiple whitespace in a row", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.Connection.GetUInt32FromEnvironmentVariableOrDefault(System.String,System.UInt32,System.UInt32,System.UInt32)~System.UInt32")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1507:Code should not contain multiple blank lines in a row", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.Connection.ReadPayloadAsync(System.IO.MemoryStream,System.Int32,System.String,Microsoft.Azure.Documents.Rntbd.ChannelCommonArguments)~System.Threading.Tasks.Task")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "VSTHRD110:Observe result of async calls", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.CpuMonitor.Start")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1501:Statement should not be on a single line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.CpuMonitor.StopCoreAfterReleasingWriteLock(System.Threading.CancellationTokenSource,System.Threading.Tasks.Task)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "VSTHRD002:Avoid problematic synchronous waits", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.CpuMonitor.StopCoreAfterReleasingWriteLock(System.Threading.CancellationTokenSource,System.Threading.Tasks.Task)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "VSTHRD110:Observe result of async calls", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.Dispatcher.CallInfo.RunAsynchronously(System.Action)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "VSTHRD110:Observe result of async calls", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.Dispatcher.CallInfo.RunAsynchronously(System.Func{System.Threading.Tasks.Task})")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1130:Use lambda syntax", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.Dispatcher.CallInfo.SetConnectionBrokenException(System.Exception,System.String)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "VSTHRD200:Use \"Async\" suffix for async methods", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.Dispatcher.CloseConnection~System.Threading.Tasks.Task")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "VSTHRD110:Observe result of async calls", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.Dispatcher.DispatchChannelFailureException(System.Exception)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1003:Symbols should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.Dispatcher.NegotiateRntbdContextAsync(Microsoft.Azure.Documents.Rntbd.ChannelOpenArguments)~System.Threading.Tasks.Task")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1130:Use lambda syntax", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.Dispatcher.OpenAsync(Microsoft.Azure.Documents.Rntbd.ChannelOpenArguments)~System.Threading.Tasks.Task")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1003:Symbols should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.Dispatcher.PrepareCall(Microsoft.Azure.Documents.DocumentServiceRequest,Microsoft.Azure.Documents.TransportAddressUri,Microsoft.Azure.Documents.ResourceOperation,System.Guid,Microsoft.Azure.Documents.TransportRequestStats)~Microsoft.Azure.Documents.Rntbd.Dispatcher.PrepareCallResult")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "VSTHRD110:Observe result of async calls", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.Dispatcher.ScheduleIdleTimer(System.TimeSpan)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "VSTHRD200:Use \"Async\" suffix for async methods", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.Dispatcher.StopIdleTimer~System.Threading.Tasks.Task")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "VSTHRD002:Avoid problematic synchronous waits", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.Dispatcher.WaitTask(System.Threading.Tasks.Task,System.String)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1137:Elements should have the same indentation", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.HeadersTransportSerialization.BuildStoreResponseNameValueCollection(System.Guid,System.String,Microsoft.Azure.Cosmos.Rntbd.BytesDeserializer@)~Microsoft.Azure.Documents.Collections.StoreResponseNameValueCollection")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.HeadersTransportSerialization.BuildStoreResponseNameValueCollection(System.Guid,System.String,Microsoft.Azure.Cosmos.Rntbd.BytesDeserializer@)~Microsoft.Azure.Documents.Collections.StoreResponseNameValueCollection")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.HeadersTransportSerialization.TryParseMandatoryResponseHeaders(Microsoft.Azure.Cosmos.Rntbd.BytesDeserializer@,System.Boolean@,System.UInt32@)~System.Boolean")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1128:Put constructor initializers on their own line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.LinuxSystemUtilizationReader.#ctor")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1024:Colons Should Be Spaced Correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.LinuxSystemUtilizationReader.#ctor")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1616:Element return value documentation should have text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.LinuxSystemUtilizationReader.GetSystemWideMemoryAvailabiltyCore~System.Nullable{System.Int64}")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.LinuxSystemUtilizationReader.GetSystemWideMemoryAvailabiltyCore~System.Nullable{System.Int64}")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1128:Put constructor initializers on their own line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.LinuxSystemUtilizationReader.ProcMemInfoFileParser.#ctor")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.LinuxSystemUtilizationReader.ProcMemInfoFileParser.TryParseMemInfoFile(System.Nullable{System.Int64}@,System.Nullable{System.Int64}@)~System.Boolean")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1128:Put constructor initializers on their own line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.LinuxSystemUtilizationReader.ProcStatFileParser.#ctor")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1616:Element return value documentation should have text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.LinuxSystemUtilizationReader.StringParser.MoveAndExtractNext~System.String")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.LoadBalancingPartition.Dispose")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1003:Symbols should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.LoadBalancingPartition.RequestAsync(Microsoft.Azure.Documents.DocumentServiceRequest,Microsoft.Azure.Documents.TransportAddressUri,Microsoft.Azure.Documents.ResourceOperation,System.Guid,Microsoft.Azure.Documents.TransportRequestStats)~System.Threading.Tasks.Task{Microsoft.Azure.Documents.StoreResponse}")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1137:Elements should have the same indentation", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.LoadBalancingPartition.RequestAsync(Microsoft.Azure.Documents.DocumentServiceRequest,Microsoft.Azure.Documents.TransportAddressUri,Microsoft.Azure.Documents.ResourceOperation,System.Guid,Microsoft.Azure.Documents.TransportRequestStats)~System.Threading.Tasks.Task{Microsoft.Azure.Documents.StoreResponse}")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1008:Opening parenthesis should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.LoadBalancingPartition.RequestAsync(Microsoft.Azure.Documents.DocumentServiceRequest,Microsoft.Azure.Documents.TransportAddressUri,Microsoft.Azure.Documents.ResourceOperation,System.Guid,Microsoft.Azure.Documents.TransportRequestStats)~System.Threading.Tasks.Task{Microsoft.Azure.Documents.StoreResponse}")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1003:Symbols should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.LoadBalancingPartition.SequenceGenerator.Next~System.UInt32")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1008:Opening parenthesis should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.ServerProperties.#ctor(System.String,System.String)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.SystemUsageHistory.#ctor(System.Collections.ObjectModel.ReadOnlyCollection{Microsoft.Azure.Documents.Rntbd.SystemUsageLoad},System.TimeSpan)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1500:Braces for multi-line statements should not share line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.SystemUsageHistory.#ctor(System.Collections.ObjectModel.ReadOnlyCollection{Microsoft.Azure.Documents.Rntbd.SystemUsageLoad},System.TimeSpan)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.SystemUsageHistory.GetCpuHigh~System.Nullable{System.Boolean}")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.SystemUsageLoad.AppendJsonString(System.Text.StringBuilder)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1616:Element return value documentation should have text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.SystemUsageMonitor.GCD(System.Int32,System.Int32)~System.Int32")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.SystemUsageMonitor.RefreshLoopAsync(System.Threading.CancellationToken)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1125:Use shorthand for nullable types", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.SystemUsageMonitor.RefreshLoopAsync(System.Threading.CancellationToken)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "VSTHRD200:Use \"Async\" suffix for async methods", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.SystemUsageMonitor.RefreshLoopAsync(System.Threading.CancellationToken)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1137:Elements should have the same indentation", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.SystemUsageMonitor.RefreshLoopAsync(System.Threading.CancellationToken)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "VSTHRD110:Observe result of async calls", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.SystemUsageMonitor.Start")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1501:Statement should not be on a single line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.SystemUsageMonitor.Stop")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "VSTHRD002:Avoid problematic synchronous waits", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.SystemUsageMonitor.Stop")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.SystemUsageRecorder.Collect(Microsoft.Azure.Documents.Rntbd.SystemUsageLoad)~System.Collections.ObjectModel.ReadOnlyCollection{Microsoft.Azure.Documents.Rntbd.SystemUsageLoad}")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1500:Braces for multi-line statements should not share line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.SystemUtilizationReaderBase.Create~Microsoft.Azure.Documents.Rntbd.SystemUtilizationReaderBase")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.ThreadInformation.Get~Microsoft.Azure.Documents.Rntbd.ThreadInformation")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.ThreadInformation.Get~Microsoft.Azure.Documents.Rntbd.ThreadInformation")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1003:Symbols should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.TransportClient.InvokeStoreAsync(Microsoft.Azure.Documents.TransportAddressUri,Microsoft.Azure.Documents.ResourceOperation,Microsoft.Azure.Documents.DocumentServiceRequest)~System.Threading.Tasks.Task{Microsoft.Azure.Documents.StoreResponse}")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "VSTHRD110:Observe result of async calls", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.TransportClient.RaiseProtocolDowngradeRequest(Microsoft.Azure.Documents.StoreResponse)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1137:Elements should have the same indentation", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.TransportExceptions.GetGoneException(System.Uri,System.Guid,System.Exception,Microsoft.Azure.Documents.TransportRequestStats)~Microsoft.Azure.Documents.GoneException")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1137:Elements should have the same indentation", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.TransportExceptions.GetRequestTimeoutException(System.Uri,System.Guid,System.Exception,Microsoft.Azure.Documents.TransportRequestStats)~Microsoft.Azure.Documents.RequestTimeoutException")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1003:Symbols should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.TransportSerialization.AddAllowScanOnQuery(Microsoft.Azure.Documents.Collections.RequestNameValueCollection,Microsoft.Azure.Documents.RntbdConstants.Request)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1003:Symbols should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.TransportSerialization.AddCanCharge(Microsoft.Azure.Documents.Collections.RequestNameValueCollection,Microsoft.Azure.Documents.RntbdConstants.Request)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1003:Symbols should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.TransportSerialization.AddCanThrottle(Microsoft.Azure.Documents.Collections.RequestNameValueCollection,Microsoft.Azure.Documents.RntbdConstants.Request)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1003:Symbols should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.TransportSerialization.AddConsistencyLevelHeader(Microsoft.Azure.Documents.Collections.RequestNameValueCollection,Microsoft.Azure.Documents.RntbdConstants.Request)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1003:Symbols should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.TransportSerialization.AddDisableRUPerMinuteUsage(Microsoft.Azure.Documents.Collections.RequestNameValueCollection,Microsoft.Azure.Documents.RntbdConstants.Request)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1003:Symbols should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.TransportSerialization.AddEmitVerboseTracesInQuery(Microsoft.Azure.Documents.Collections.RequestNameValueCollection,Microsoft.Azure.Documents.RntbdConstants.Request)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1003:Symbols should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.TransportSerialization.AddEnableLogging(Microsoft.Azure.Documents.Collections.RequestNameValueCollection,Microsoft.Azure.Documents.RntbdConstants.Request)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1003:Symbols should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.TransportSerialization.AddEnableLowPrecisionOrderBy(Microsoft.Azure.Documents.Collections.RequestNameValueCollection,Microsoft.Azure.Documents.RntbdConstants.Request)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1003:Symbols should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.TransportSerialization.AddIndexingDirectiveHeader(Microsoft.Azure.Documents.Collections.RequestNameValueCollection,Microsoft.Azure.Documents.RntbdConstants.Request)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1003:Symbols should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.TransportSerialization.AddIsFanout(Microsoft.Azure.Documents.Collections.RequestNameValueCollection,Microsoft.Azure.Documents.RntbdConstants.Request)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1137:Elements should have the same indentation", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.TransportSerialization.AddMatchHeader(Microsoft.Azure.Documents.Collections.RequestNameValueCollection,Microsoft.Azure.Documents.RntbdConstants.RntbdOperationType,Microsoft.Azure.Documents.RntbdConstants.Request)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1003:Symbols should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.TransportSerialization.AddMigrateCollectionDirectiveHeader(Microsoft.Azure.Documents.Collections.RequestNameValueCollection,Microsoft.Azure.Documents.RntbdConstants.Request)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.TransportSerialization.AddOfferReplaceRURedistribution(Microsoft.Azure.Documents.Collections.RequestNameValueCollection,Microsoft.Azure.Documents.RntbdConstants.Request)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1003:Symbols should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.TransportSerialization.AddPageSize(Microsoft.Azure.Documents.Collections.RequestNameValueCollection,Microsoft.Azure.Documents.RntbdConstants.Request)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1003:Symbols should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.TransportSerialization.AddPopulateCollectionThroughputInfo(Microsoft.Azure.Documents.Collections.RequestNameValueCollection,Microsoft.Azure.Documents.RntbdConstants.Request)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1003:Symbols should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.TransportSerialization.AddPopulatePartitionStatistics(Microsoft.Azure.Documents.Collections.RequestNameValueCollection,Microsoft.Azure.Documents.RntbdConstants.Request)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1003:Symbols should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.TransportSerialization.AddPopulateQueryMetrics(Microsoft.Azure.Documents.Collections.RequestNameValueCollection,Microsoft.Azure.Documents.RntbdConstants.Request)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1003:Symbols should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.TransportSerialization.AddPopulateQuotaInfo(Microsoft.Azure.Documents.Collections.RequestNameValueCollection,Microsoft.Azure.Documents.RntbdConstants.Request)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1003:Symbols should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.TransportSerialization.AddPopulateResourceCount(Microsoft.Azure.Documents.Collections.RequestNameValueCollection,Microsoft.Azure.Documents.RntbdConstants.Request)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1003:Symbols should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.TransportSerialization.AddPreserveFullContent(Microsoft.Azure.Documents.Collections.RequestNameValueCollection,Microsoft.Azure.Documents.RntbdConstants.Request)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1003:Symbols should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.TransportSerialization.AddPriorityLevelHeader(Microsoft.Azure.Documents.DocumentServiceRequest,System.String,System.String,Microsoft.Azure.Documents.Collections.RequestNameValueCollection,Microsoft.Azure.Documents.RntbdConstants.Request)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1003:Symbols should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.TransportSerialization.AddProfileRequest(Microsoft.Azure.Documents.Collections.RequestNameValueCollection,Microsoft.Azure.Documents.RntbdConstants.Request)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1003:Symbols should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.TransportSerialization.AddRemoteStorageType(Microsoft.Azure.Documents.Collections.RequestNameValueCollection,Microsoft.Azure.Documents.RntbdConstants.Request)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1003:Symbols should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.TransportSerialization.AddResponseContinuationTokenLimitInKb(Microsoft.Azure.Documents.Collections.RequestNameValueCollection,Microsoft.Azure.Documents.RntbdConstants.Request)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1003:Symbols should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.TransportSerialization.AddShareThroughput(Microsoft.Azure.Documents.Collections.RequestNameValueCollection,Microsoft.Azure.Documents.RntbdConstants.Request)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.TransportSerialization.AddStartAndEndKeys(Microsoft.Azure.Documents.DocumentServiceRequest,Microsoft.Azure.Documents.Collections.RequestNameValueCollection,Microsoft.Azure.Documents.RntbdConstants.Request)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.TransportSerialization.AddSupportedSerializationFormats(Microsoft.Azure.Documents.Collections.RequestNameValueCollection,Microsoft.Azure.Documents.RntbdConstants.Request)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1003:Symbols should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.TransportSerialization.AddSupportSpatialLegacyCoordinates(Microsoft.Azure.Documents.Collections.RequestNameValueCollection,Microsoft.Azure.Documents.RntbdConstants.Request)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1003:Symbols should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.TransportSerialization.AddUsePolygonsSmallerThanAHemisphere(Microsoft.Azure.Documents.Collections.RequestNameValueCollection,Microsoft.Azure.Documents.RntbdConstants.Request)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.TransportSerialization.BuildContextRequest(System.Guid,Microsoft.Azure.Documents.UserAgentContainer,Microsoft.Azure.Documents.RntbdConstants.CallerId,System.Boolean)~System.Byte[]")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1107:Code should not contain multiple statements on one line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.TransportSerialization.BuildRequestCore(Microsoft.Azure.Documents.DocumentServiceRequest,Microsoft.Azure.Documents.RntbdConstants.Request@,System.String,Microsoft.Azure.Documents.ResourceOperation,System.Guid,Microsoft.Azure.Documents.BufferProvider,System.Int32@,System.Nullable{System.Int32}@)~Microsoft.Azure.Documents.Rntbd.TransportSerialization.SerializedRequest")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.TransportSerialization.BuildRequestForProxy(Microsoft.Azure.Documents.DocumentServiceRequest,Microsoft.Azure.Documents.ResourceOperation,System.Guid,Microsoft.Azure.Documents.BufferProvider,System.Int32@,System.Nullable{System.Int32}@)~Microsoft.Azure.Documents.Rntbd.TransportSerialization.SerializedRequest")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1003:Symbols should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.TransportSerialization.DecodeRntbdHeader(System.Byte[])~Microsoft.Azure.Documents.Rntbd.TransportSerialization.RntbdHeader")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.TransportSerialization.MakeStoreResponse(Microsoft.Azure.Documents.StatusCodes,System.Guid,System.IO.Stream,System.String,Microsoft.Azure.Cosmos.Rntbd.BytesDeserializer@)~Microsoft.Azure.Documents.StoreResponse")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1507:Code should not contain multiple blank lines in a row", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.TransportSerialization.SetBytesValue(Microsoft.Azure.Documents.DocumentServiceRequest,System.String,Microsoft.Azure.Documents.RntbdToken)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1128:Put constructor initializers on their own line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.UnsupportedSystemUtilizationReader.#ctor")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1500:Braces for multi-line statements should not share line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.UserPortPool.MarkUnusable(System.Net.Sockets.AddressFamily,System.UInt16)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1003:Symbols should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.WindowsSystemUtilizationReader.GetSystemWideMemoryAvailabiltyCore~System.Nullable{System.Int64}")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1616:Element return value documentation should have text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.WindowsSystemUtilizationReader.NativeMethods.GetSystemTimes(System.Int64@,System.Int64@,System.Int64@)~System.Boolean")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1612:Element parameter documentation should match element parameters", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.WindowsSystemUtilizationReader.NativeMethods.GlobalMemoryStatusEx(Microsoft.Azure.Documents.Rntbd.WindowsSystemUtilizationReader.NativeMethods.MemoryInfo@)~System.Boolean")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1616:Element return value documentation should have text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Rntbd.WindowsSystemUtilizationReader.NativeMethods.GlobalMemoryStatusEx(Microsoft.Azure.Documents.Rntbd.WindowsSystemUtilizationReader.NativeMethods.MemoryInfo@)~System.Boolean")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.RntbdToken.SerializeToBinaryWriter(Microsoft.Azure.Cosmos.Rntbd.BytesSerializer@,System.Int32@)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.RntbdTokenStream`1.CalculateLength~System.Int32")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.RntbdTokenStream`1.ParseFrom(Microsoft.Azure.Cosmos.Rntbd.BytesDeserializer@)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.RntbdTokenStream`1.SerializeToBinaryWriter(Microsoft.Azure.Cosmos.Rntbd.BytesSerializer@,System.Int32@)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1500:Braces for multi-line statements should not share line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Routing.NumberPartitionKeyComponent.WriteForBinaryEncoding(System.IO.BinaryWriter)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Routing.PartitionIsMigratingException.#ctor")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1507:Code should not contain multiple blank lines in a row", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Routing.PartitionKeyInternal.Clone~System.Object")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Routing.PartitionKeyInternal.GetEPKRangeForPrefixPartitionKey(Microsoft.Azure.Documents.PartitionKeyDefinition)~Microsoft.Azure.Documents.Routing.Range{System.String}")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1407:Arithmetic expressions should declare precedence", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Routing.PartitionKeyInternal.GetMiddleRangeEffectivePartitionKey(System.String,System.String,Microsoft.Azure.Documents.PartitionKeyDefinition)~System.String")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1500:Braces for multi-line statements should not share line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Routing.PartitionKeyInternal.GetMinInclusiveEffectivePartitionKey(System.Int32,System.Int32,Microsoft.Azure.Documents.PartitionKeyDefinition,System.Boolean)~System.String")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1407:Arithmetic expressions should declare precedence", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Routing.PartitionKeyInternal.HexConvert.ToHex(System.Byte[],System.Int32,System.Int32)~System.String")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Routing.PartitionKeyRangeGoneException.#ctor")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Routing.PartitionKeyRangeIsSplittingException.#ctor")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Schema.AsType``1~``0")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Schema.FromObject(System.Object)~Microsoft.Azure.Documents.Schema")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Schema.GetProperty(System.String,System.Type)~System.Object")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Schema.SetProperty(System.String,System.Object)~System.Object")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.ServerStoreModel.Dispose")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.ServerStoreModel.ProcessMessageWithReceivedResponseDelegateAsync(Microsoft.Azure.Documents.DocumentServiceRequest,System.Threading.CancellationToken)~System.Threading.Tasks.Task{Microsoft.Azure.Documents.DocumentServiceResponse}")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "VSTHRD200:Use \"Async\" suffix for async methods", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.SessionTokenMismatchRetryPolicy.ShouldRetryInternalAsync(System.Nullable{System.Net.HttpStatusCode},System.Nullable{Microsoft.Azure.Documents.SubStatusCodes})~Microsoft.Azure.Documents.ShouldRetryResult")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1008:Opening parenthesis should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.SharedFiles.Routing.Int128.op_Division(Microsoft.Azure.Documents.SharedFiles.Routing.Int128,Microsoft.Azure.Documents.SharedFiles.Routing.Int128)~Microsoft.Azure.Documents.SharedFiles.Routing.Int128")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.SnapshotContent.#ctor")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1127:Generic type constraints should be on their own line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.SnapshotContent.GetResourceIfDeserialized``1(System.String)~``0")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1003:Symbols should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.StoreClient.CaptureSessionToken(System.Nullable{System.Net.HttpStatusCode},Microsoft.Azure.Documents.SubStatusCodes,Microsoft.Azure.Documents.DocumentServiceRequest,Microsoft.Azure.Documents.Collections.INameValueCollection)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.StoreClient.ProcessMessageAsync(Microsoft.Azure.Documents.DocumentServiceRequest,System.Threading.CancellationToken,Microsoft.Azure.Documents.IRetryPolicy)~System.Threading.Tasks.Task{Microsoft.Azure.Documents.DocumentServiceResponse}")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1001:Commas should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.StoreClientFactory.#ctor(Microsoft.Azure.Documents.Client.Protocol,System.Int32,System.Int32,Microsoft.Azure.Documents.UserAgentContainer,Microsoft.Azure.Documents.ICommunicationEventSource,System.String,System.Int32,System.Int32,System.Int32,System.Int32,System.Int32,System.Int32,Microsoft.Azure.Documents.PortReuseMode,System.Int32,System.Int32,System.Int32,System.Int32,System.Boolean,Microsoft.Azure.Documents.RetryWithConfiguration,Microsoft.Azure.Documents.RntbdConstants.CallerId,System.Boolean,Microsoft.Azure.Documents.IAddressResolver,System.TimeSpan,System.Boolean,System.Int32,Microsoft.Azure.Documents.MemoryStreamPool,System.Net.Security.RemoteCertificateValidationCallback,System.Func{System.String,System.Threading.Tasks.Task{System.Net.IPAddress}},Microsoft.Azure.Documents.Telemetry.DistributedTracingOptions,Microsoft.Azure.Documents.FaultInjection.IChaosInterceptor)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "VSTHRD200:Use \"Async\" suffix for async methods", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.StoreReader.CompleteActivity(System.Threading.Tasks.Task{Microsoft.Azure.Documents.StoreResponse},Microsoft.Azure.Documents.QueryRequestPerformanceActivity)~System.Threading.Tasks.Task{Microsoft.Azure.Documents.StoreResponse}")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "VSTHRD200:Use \"Async\" suffix for async methods", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.StoreReader.GetResult(Microsoft.Azure.Documents.DocumentServiceRequest,System.Boolean,Microsoft.Azure.Documents.TransportAddressUri,System.Runtime.CompilerServices.StrongBox{System.Nullable{System.DateTime}})~System.Threading.Tasks.Task{Microsoft.Azure.Documents.ReferenceCountedDisposable{Microsoft.Azure.Documents.StoreResult}}")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1500:Braces for multi-line statements should not share line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.StoreReader.ReadMultipleReplicasInternalAsync(Microsoft.Azure.Documents.DocumentServiceRequest,System.Boolean,System.Int32,System.Boolean,System.Boolean,Microsoft.Azure.Documents.ReadMode,System.Boolean,System.Boolean)~System.Threading.Tasks.Task{Microsoft.Azure.Documents.StoreReader.ReadReplicaResult}")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.StoreReader.ReadMultipleReplicasInternalAsync(Microsoft.Azure.Documents.DocumentServiceRequest,System.Boolean,System.Int32,System.Boolean,System.Boolean,Microsoft.Azure.Documents.ReadMode,System.Boolean,System.Boolean)~System.Threading.Tasks.Task{Microsoft.Azure.Documents.StoreReader.ReadReplicaResult}")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.StoreReader.ReadReplicaResult.#ctor(System.Boolean,System.Collections.Generic.IList{Microsoft.Azure.Documents.ReferenceCountedDisposable{Microsoft.Azure.Documents.StoreResult}})")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1003:Symbols should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.StoreResult.#ctor(Microsoft.Azure.Documents.StoreResponse,Microsoft.Azure.Documents.DocumentClientException,System.String,System.Int64,System.Int64,System.Double,System.Int32,System.Int32,System.Boolean,System.Uri,System.Int64,System.Int32,System.Int64,Microsoft.Azure.Documents.ISessionToken,System.Boolean,System.String,System.String,System.String,Microsoft.Azure.Documents.TransportRequestStats,System.Collections.Generic.IEnumerable{System.String})")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1008:Opening parenthesis should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.StoreResult.#ctor(Microsoft.Azure.Documents.StoreResponse,Microsoft.Azure.Documents.DocumentClientException,System.String,System.Int64,System.Int64,System.Double,System.Int32,System.Int32,System.Boolean,System.Uri,System.Int64,System.Int32,System.Int64,Microsoft.Azure.Documents.ISessionToken,System.Boolean,System.String,System.String,System.String,Microsoft.Azure.Documents.TransportRequestStats,System.Collections.Generic.IEnumerable{System.String})")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.StoreResult.AppendToBuilder(System.Text.StringBuilder)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1003:Symbols should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.StoreResult.AppendToBuilder(System.Text.StringBuilder)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.StreamExtension.CopyToAsync(System.IO.Stream,System.IO.Stream,System.Int64)~System.Threading.Tasks.Task")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.Telemetry.OpenTelemetryRecorderFactory.CreateRecorder(Microsoft.Azure.Documents.Telemetry.DistributedTracingOptions,Microsoft.Azure.Documents.DocumentServiceRequest)~Microsoft.Azure.Documents.Telemetry.OpenTelemetryRecorder")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.TimeoutHelper.ThrowTimeoutIfElapsed")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1616:Element return value documentation should have text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.TimerPool.GetPooledTimer(System.Int32)~Microsoft.Azure.Documents.PooledTimer")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1616:Element return value documentation should have text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.TimerPool.GetPooledTimer(System.TimeSpan)~Microsoft.Azure.Documents.PooledTimer")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1612:Element parameter documentation should match element parameters", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.TimerPool.GetPooledTimer(System.TimeSpan)~Microsoft.Azure.Documents.PooledTimer")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.TimerPool.OnTimer(System.Object)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.TimerPool.SubscribeForTimeouts(Microsoft.Azure.Documents.PooledTimer)~System.Int64")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.TransportClient.#ctor")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "VSTHRD200:Use \"Async\" suffix for async methods", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.TransportClient.CompleteUserTransaction(System.Uri,Microsoft.Azure.Documents.DocumentServiceRequest)~System.Threading.Tasks.Task{Microsoft.Azure.Documents.StoreResponse}")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1122:Use string.Empty for empty strings", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.TransportClient.GetErrorResponseAsync(System.Net.Http.HttpResponseMessage)~System.Threading.Tasks.Task{System.String}")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1137:Elements should have the same indentation", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.TransportClient.ThrowServerException(System.String,Microsoft.Azure.Documents.StoreResponse,System.Uri,System.Guid,Microsoft.Azure.Documents.DocumentServiceRequest)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1128:Put constructor initializers on their own line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.TransportException.#ctor(Microsoft.Azure.Documents.TransportErrorCode,System.Exception,System.Guid,System.Uri,System.String,System.Boolean,System.Boolean)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1003:Symbols should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.TransportException.#ctor(Microsoft.Azure.Documents.TransportErrorCode,System.Exception,System.Guid,System.Uri,System.String,System.Boolean,System.Boolean)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.UnauthorizedException.#ctor")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.UnauthorizedException.#ctor(System.Exception)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.UnauthorizedException.#ctor(System.String)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.UnauthorizedException.#ctor(System.String,Microsoft.Azure.Documents.SubStatusCodes)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.UnauthorizedException.#ctor(System.String,System.Exception)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.UnauthorizedException.#ctor(System.String,System.Exception,Microsoft.Azure.Documents.SubStatusCodes)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.UnauthorizedException.#ctor(System.String,System.Net.Http.Headers.HttpResponseHeaders,System.Uri)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1008:Opening parenthesis should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.UnixDateTimeConverter.WriteJson(Newtonsoft.Json.JsonWriter,System.Object,Newtonsoft.Json.JsonSerializer)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1003:Symbols should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.UnixDateTimeConverter.WriteJson(Newtonsoft.Json.JsonWriter,System.Object,Newtonsoft.Json.JsonSerializer)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1502:Element should not be on a single line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.UrlUtility.Element.#ctor")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1312:Variable names should begin with lower-case letter", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.UrlUtility.IsLocalHostUri(System.Uri)~System.Boolean")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1520:Use braces consistently", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.UrlUtility.ParseQuery(System.String)~System.Collections.Specialized.NameValueCollection")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.User.#ctor")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1128:Put constructor initializers on their own line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.UserAgentContainer.#ctor(System.String)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~M:Microsoft.Azure.Documents.VectorSessionToken.TryParseSessionToken(System.String,System.Int64@,System.Int64@,System.Collections.Generic.IReadOnlyDictionary{System.UInt32,System.Int64}@)~System.Boolean")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1633:File should have header", Justification = "Belongs to Cosmos.Direct Project", Scope = "namespace", Target = "~N:Microsoft.Azure.Documents")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1636:File header copyright text should match", Justification = "Belongs to Cosmos.Direct Project", Scope = "namespace", Target = "~N:Microsoft.Azure.Documents")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1518:Use line endings correctly at end of file", Justification = "Belongs to Cosmos.Direct Project", Scope = "namespace", Target = "~N:Microsoft.Azure.Documents")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1208:System using directives should be placed before other using directives", Justification = "Belongs to Cosmos.Direct Project", Scope = "namespace", Target = "~N:Microsoft.Azure.Documents")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1208:System using directives should be placed before other using directives", Justification = "Belongs to Cosmos.Direct Project", Scope = "namespace", Target = "~N:Microsoft.Azure.Documents.FaultInjection")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1210:Using directives should be ordered alphabetically by namespace", Justification = "Belongs to Cosmos.Direct Project", Scope = "namespace", Target = "~N:Microsoft.Azure.Documents.Rntbd")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1208:System using directives should be placed before other using directives", Justification = "Belongs to Cosmos.Direct Project", Scope = "namespace", Target = "~N:Microsoft.Azure.Documents.Rntbd")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1507:Code should not contain multiple blank lines in a row", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~P:Microsoft.Azure.Documents.ClientSideRequestStatistics.RequestLatency")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1606:Element documentation should have summary text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~P:Microsoft.Azure.Documents.Collections.NameValueCollectionWrapper.Item(System.String)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1616:Element return value documentation should have text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~P:Microsoft.Azure.Documents.Collections.NameValueCollectionWrapper.Item(System.String)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1122:Use string.Empty for empty strings", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~P:Microsoft.Azure.Documents.Conflict.OperationKind")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1120:Comments should contain text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~P:Microsoft.Azure.Documents.DocumentClientException.ResponseHeaders")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1120:Comments should contain text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~P:Microsoft.Azure.Documents.DocumentClientException.RetryAfter")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~P:Microsoft.Azure.Documents.DocumentCollection.UniqueIndexNameEncodingMode")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1002:Semicolons should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~P:Microsoft.Azure.Documents.IClientSideRequestStatistics.FailedReplicas")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1002:Semicolons should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~P:Microsoft.Azure.Documents.IClientSideRequestStatistics.RegionsContacted")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1624:Property summary documentation should omit accessor with restricted access", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~P:Microsoft.Azure.Documents.Index.Kind")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1002:Semicolons should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~P:Microsoft.Azure.Documents.IServiceConfigurationReader.ReadPolicy")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1507:Code should not contain multiple blank lines in a row", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~P:Microsoft.Azure.Documents.PartitionKey.InternalKey")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1610:Property documentation should have value text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~P:Microsoft.Azure.Documents.PartitionKeyDefinition.IsSystemKey")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1507:Code should not contain multiple blank lines in a row", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~P:Microsoft.Azure.Documents.PerformanceActivity.OperationName")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1507:Code should not contain multiple blank lines in a row", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~P:Microsoft.Azure.Documents.Resource.Id")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1507:Code should not contain multiple blank lines in a row", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~P:Microsoft.Azure.Documents.ResourceId.ClientEncryptionKeyId")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1507:Code should not contain multiple blank lines in a row", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~P:Microsoft.Azure.Documents.ResourceId.PermissionId")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1507:Code should not contain multiple blank lines in a row", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~P:Microsoft.Azure.Documents.ResourceId.SchemaId")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1507:Code should not contain multiple blank lines in a row", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~P:Microsoft.Azure.Documents.ResourceId.UserDefinedTypeId")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~P:Microsoft.Azure.Documents.ResourceId.Value")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1520:Use braces consistently", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~P:Microsoft.Azure.Documents.ResourceId.Value")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1507:Code should not contain multiple blank lines in a row", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~P:Microsoft.Azure.Documents.Rntbd.Channel.Healthy")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1502:Element should not be on a single line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~P:Microsoft.Azure.Documents.Rntbd.ChannelCallArguments.CommonArguments")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1502:Element should not be on a single line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~P:Microsoft.Azure.Documents.Rntbd.ChannelCallArguments.OperationType")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1502:Element should not be on a single line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~P:Microsoft.Azure.Documents.Rntbd.ChannelCallArguments.RequestHeaders")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1502:Element should not be on a single line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~P:Microsoft.Azure.Documents.Rntbd.ChannelCallArguments.ResolvedCollectionRid")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1502:Element should not be on a single line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~P:Microsoft.Azure.Documents.Rntbd.ChannelCallArguments.ResourceType")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1502:Element should not be on a single line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~P:Microsoft.Azure.Documents.Rntbd.ChannelOpenArguments.CallerId")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1502:Element should not be on a single line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~P:Microsoft.Azure.Documents.Rntbd.ChannelOpenArguments.CommonArguments")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1502:Element should not be on a single line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~P:Microsoft.Azure.Documents.Rntbd.ChannelOpenArguments.OpenTimeline")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1502:Element should not be on a single line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~P:Microsoft.Azure.Documents.Rntbd.ChannelOpenArguments.OpenTimeout")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1502:Element should not be on a single line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~P:Microsoft.Azure.Documents.Rntbd.ChannelOpenArguments.PortPool")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1502:Element should not be on a single line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~P:Microsoft.Azure.Documents.Rntbd.ChannelOpenArguments.PortReuseMode")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1025:Code should not contain multiple whitespace in a row", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~P:Microsoft.Azure.Documents.Rntbd.Connection.ConnectionCorrelationId")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1502:Element should not be on a single line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~P:Microsoft.Azure.Documents.Rntbd.Connection.Disposed")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1502:Element should not be on a single line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~P:Microsoft.Azure.Documents.Rntbd.Connection.NumberOfOpenTcpConnections")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1502:Element should not be on a single line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~P:Microsoft.Azure.Documents.Rntbd.Connection.ServerUri")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1502:Element should not be on a single line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~P:Microsoft.Azure.Documents.Rntbd.CpuLoadHistory.LastTimestamp")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1502:Element should not be on a single line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~P:Microsoft.Azure.Documents.Rntbd.LbChannelState.Channel")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1212:Property accessors should follow order", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~P:Microsoft.Azure.Documents.Rntbd.SystemUsageMonitor.disposed")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1212:Property accessors should follow order", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~P:Microsoft.Azure.Documents.Rntbd.SystemUsageMonitor.periodicTask")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1212:Property accessors should follow order", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~P:Microsoft.Azure.Documents.Rntbd.SystemUsageRecorder.Data")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1504:All accessors should be single-line or multi-line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~P:Microsoft.Azure.Documents.Rntbd.TransportClient.Options.LocalRegionOpenTimeout")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1504:All accessors should be single-line or multi-line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~P:Microsoft.Azure.Documents.Rntbd.TransportClient.Options.OpenTimeout")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1504:All accessors should be single-line or multi-line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~P:Microsoft.Azure.Documents.Rntbd.TransportClient.Options.TimerPoolResolution")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1504:All accessors should be single-line or multi-line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~P:Microsoft.Azure.Documents.Rntbd.TransportClient.Options.UserAgent")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~P:Microsoft.Azure.Documents.SchemaDiscoveryPolicy.SchemaBuilderMode")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1606:Element documentation should have summary text", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~P:Microsoft.Azure.Documents.ShouldRetryResult.ExceptionToThrow")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~P:Microsoft.Azure.Documents.SnapshotContent.GeoLinkIdToPKRangeRid")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1002:Semicolons should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~P:Microsoft.Azure.Documents.StoreResult.BackendRequestDurationInMs")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1506:Element documentation headers should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "member", Target = "~P:Microsoft.Azure.Documents.User.PermissionsLink")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1649:File name should match first type name", Justification = "Belongs to Cosmos.Direct Project", Scope = "type", Target = "~T:AssemblyKeys")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1649:File name should match first type name", Justification = "Belongs to Cosmos.Direct Project", Scope = "type", Target = "~T:Microsoft.Azure.Documents.AuthorizationTokenTypeExtensions")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1127:Generic type constraints should be on their own line", Justification = "Belongs to Cosmos.Direct Project", Scope = "type", Target = "~T:Microsoft.Azure.Documents.Client.IResourceResponse`1")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1127:Generic type constraints should be on their own line", Justification = "Belongs to Cosmos.Direct Project", Scope = "type", Target = "~T:Microsoft.Azure.Documents.Client.ResourceResponse`1")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1024:Colons Should Be Spaced Correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "type", Target = "~T:Microsoft.Azure.Documents.ClientEncryptionKey")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1507:Code should not contain multiple blank lines in a row", Justification = "Belongs to Cosmos.Direct Project", Scope = "type", Target = "~T:Microsoft.Azure.Documents.ClientSideRequestStatistics.AddressResolutionStatistics")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1024:Colons Should Be Spaced Correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "type", Target = "~T:Microsoft.Azure.Documents.Collections.DictionaryNameValueCollection")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1606:Element documentation should have summary text", Justification = "Belongs to Cosmos.Direct Project", Scope = "type", Target = "~T:Microsoft.Azure.Documents.Collections.INameValueCollectionFactory")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1649:File name should match first type name", Justification = "Belongs to Cosmos.Direct Project", Scope = "type", Target = "~T:Microsoft.Azure.Documents.DocumentClientException")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1127:Generic type constraints should be on their own line", Justification = "Belongs to Cosmos.Direct Project", Scope = "type", Target = "~T:Microsoft.Azure.Documents.FeedResource`1")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1127:Generic type constraints should be on their own line", Justification = "Belongs to Cosmos.Direct Project", Scope = "type", Target = "~T:Microsoft.Azure.Documents.GoneAndRetryWithRequestRetryPolicy`1")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1127:Generic type constraints should be on their own line", Justification = "Belongs to Cosmos.Direct Project", Scope = "type", Target = "~T:Microsoft.Azure.Documents.GoneOnlyRequestRetryPolicy`1")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1649:File name should match first type name", Justification = "Belongs to Cosmos.Direct Project", Scope = "type", Target = "~T:Microsoft.Azure.Documents.IndexingDirectiveStrings")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1006:Preprocessor keywords should not be preceded by space", Justification = "Belongs to Cosmos.Direct Project", Scope = "type", Target = "~T:Microsoft.Azure.Documents.IndexingPolicy.CompositePathEqualityComparer")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1649:File name should match first type name", Justification = "Belongs to Cosmos.Direct Project", Scope = "type", Target = "~T:Microsoft.Azure.Documents.IServiceIdentity")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1400:Access modifier should be declared", Justification = "Belongs to Cosmos.Direct Project", Scope = "type", Target = "~T:Microsoft.Azure.Documents.ISessionContainer")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1024:Colons Should Be Spaced Correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "type", Target = "~T:Microsoft.Azure.Documents.IStoreClientFactory")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1127:Generic type constraints should be on their own line", Justification = "Belongs to Cosmos.Direct Project", Scope = "type", Target = "~T:Microsoft.Azure.Documents.ITypeResolver`1")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1302:Interface names should begin with I", Justification = "Belongs to Cosmos.Direct Project", Scope = "type", Target = "~T:Microsoft.Azure.Documents.MemoryStreamPool")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1649:File name should match first type name", Justification = "Belongs to Cosmos.Direct Project", Scope = "type", Target = "~T:Microsoft.Azure.Documents.OperationTypeExtensions")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1507:Code should not contain multiple blank lines in a row", Justification = "Belongs to Cosmos.Direct Project", Scope = "type", Target = "~T:Microsoft.Azure.Documents.Paths")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1313:Parameter names should begin with lower-case letter", Justification = "Belongs to Cosmos.Direct Project", Scope = "type", Target = "~T:Microsoft.Azure.Documents.PerformanceActivity.OperationDurationDelegate")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1649:File name should match first type name", Justification = "Belongs to Cosmos.Direct Project", Scope = "type", Target = "~T:Microsoft.Azure.Documents.ResolveFabricPerformanceActivity")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1025:Code should not contain multiple whitespace in a row", Justification = "Belongs to Cosmos.Direct Project", Scope = "type", Target = "~T:Microsoft.Azure.Documents.ResourceId.RbacResourceType")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1649:File name should match first type name", Justification = "Belongs to Cosmos.Direct Project", Scope = "type", Target = "~T:Microsoft.Azure.Documents.ResourceTypeExtensions")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1137:Elements should have the same indentation", Justification = "Belongs to Cosmos.Direct Project", Scope = "type", Target = "~T:Microsoft.Azure.Documents.Rfc1123DateTimeCache.FormattedTriple")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1400:Access modifier should be declared", Justification = "Belongs to Cosmos.Direct Project", Scope = "type", Target = "~T:Microsoft.Azure.Documents.Rntbd.LbChannelState")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1500:Braces for multi-line statements should not share line", Justification = "Belongs to Cosmos.Direct Project", Scope = "type", Target = "~T:Microsoft.Azure.Documents.Rntbd.UserPortPool.PortState")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "type", Target = "~T:Microsoft.Azure.Documents.Rntbd.WindowsSystemUtilizationReader.NativeMethods")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1120:Comments should contain text", Justification = "Belongs to Cosmos.Direct Project", Scope = "type", Target = "~T:Microsoft.Azure.Documents.RntbdConstants.CallerId")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1649:File name should match first type name", Justification = "Belongs to Cosmos.Direct Project", Scope = "type", Target = "~T:Microsoft.Azure.Documents.RntbdTokenValue")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1649:File name should match first type name", Justification = "Belongs to Cosmos.Direct Project", Scope = "type", Target = "~T:Microsoft.Azure.Documents.Routing.MaxNumber")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1649:File name should match first type name", Justification = "Belongs to Cosmos.Direct Project", Scope = "type", Target = "~T:Microsoft.Azure.Documents.Routing.MaxString")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1649:File name should match first type name", Justification = "Belongs to Cosmos.Direct Project", Scope = "type", Target = "~T:Microsoft.Azure.Documents.Routing.MinNumber")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1649:File name should match first type name", Justification = "Belongs to Cosmos.Direct Project", Scope = "type", Target = "~T:Microsoft.Azure.Documents.Routing.MinString")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1127:Generic type constraints should be on their own line", Justification = "Belongs to Cosmos.Direct Project", Scope = "type", Target = "~T:Microsoft.Azure.Documents.Routing.Range`1")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1003:Symbols should be spaced correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "type", Target = "~T:Microsoft.Azure.Documents.Routing.Range`1")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1024:Colons Should Be Spaced Correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "type", Target = "~T:Microsoft.Azure.Documents.Routing.Range`1")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1024:Colons Should Be Spaced Correctly", Justification = "Belongs to Cosmos.Direct Project", Scope = "type", Target = "~T:Microsoft.Azure.Documents.Routing.UndefinedPartitionKeyComponent")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1507:Code should not contain multiple blank lines in a row", Justification = "Belongs to Cosmos.Direct Project", Scope = "type", Target = "~T:Microsoft.Azure.Documents.RuntimeConstants.Separators")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1106:Code should not contain empty statements", Justification = "Belongs to Cosmos.Direct Project", Scope = "type", Target = "~T:Microsoft.Azure.Documents.ServiceInteropWrapper.PartitionKeyRangesApiOptions")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1507:Code should not contain multiple blank lines in a row", Justification = "Belongs to Cosmos.Direct Project", Scope = "type", Target = "~T:Microsoft.Azure.Documents.SharedFiles.Routing.Int128")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1649:File name should match first type name", Justification = "Belongs to Cosmos.Direct Project", Scope = "type", Target = "~T:Microsoft.Azure.Documents.ShouldRetryResult")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1506:Element documentation headers should not be followed by blank line", Justification = "Belongs to Cosmos.Direct Project", Scope = "type", Target = "~T:Microsoft.Azure.Documents.SnapshotContent")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1649:File name should match first type name", Justification = "Belongs to Cosmos.Direct Project", Scope = "type", Target = "~T:Microsoft.Azure.Documents.StatusCodesExtensions")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1025:Code should not contain multiple whitespace in a row", Justification = "Belongs to Cosmos.Direct Project", Scope = "type", Target = "~T:Microsoft.Azure.Documents.TriggerOperation")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1649:File name should match first type name", Justification = "Belongs to Cosmos.Direct Project", Scope = "type", Target = "~T:Microsoft.Azure.Documents.UrlUtility")] diff --git a/Microsoft.Azure.Cosmos/src/Handler/ClientPipelineBuilder.cs b/Microsoft.Azure.Cosmos/src/Handler/ClientPipelineBuilder.cs index d4c260f904..aa69b770e1 100644 --- a/Microsoft.Azure.Cosmos/src/Handler/ClientPipelineBuilder.cs +++ b/Microsoft.Azure.Cosmos/src/Handler/ClientPipelineBuilder.cs @@ -27,7 +27,7 @@ public ClientPipelineBuilder( CosmosClient client, ConsistencyLevel? requestedClientConsistencyLevel, IReadOnlyCollection customHandlers, - ClientTelemetry telemetry) + TelemetryToServiceHelper telemetryToServiceHelper) { this.client = client ?? throw new ArgumentNullException(nameof(client)); this.requestedClientConsistencyLevel = requestedClientConsistencyLevel; @@ -48,11 +48,8 @@ public ClientPipelineBuilder( #else this.diagnosticsHandler = null; #endif - if (telemetry != null) - { - this.telemetryHandler = new TelemetryHandler(telemetry); - Debug.Assert(this.telemetryHandler.InnerHandler == null, nameof(this.telemetryHandler)); - } + this.telemetryHandler = new TelemetryHandler(telemetryToServiceHelper); + Debug.Assert(this.telemetryHandler.InnerHandler == null, nameof(this.telemetryHandler)); this.UseRetryPolicy(); this.AddCustomHandlers(customHandlers); diff --git a/Microsoft.Azure.Cosmos/src/Handler/DiagnosticsHandler.cs b/Microsoft.Azure.Cosmos/src/Handler/DiagnosticsHandler.cs index f361987f92..de93fca27b 100644 --- a/Microsoft.Azure.Cosmos/src/Handler/DiagnosticsHandler.cs +++ b/Microsoft.Azure.Cosmos/src/Handler/DiagnosticsHandler.cs @@ -4,6 +4,7 @@ namespace Microsoft.Azure.Cosmos.Handlers { + using System; using System.Threading; using System.Threading.Tasks; using Microsoft.Azure.Cosmos.Handler; @@ -25,7 +26,8 @@ public override async Task SendAsync( ResponseMessage responseMessage = await base.SendAsync(request, cancellationToken); // Record the diagnostics on the response to get the CPU of when the request was executing - SystemUsageHistory systemUsageHistory = DiagnosticsHandlerHelper.Instance.GetDiagnosticsSystemHistory(); + SystemUsageHistory systemUsageHistory = DiagnosticsHandlerHelper.GetInstance().GetDiagnosticsSystemHistory(); + if (systemUsageHistory != null) { request.Trace.AddDatum( diff --git a/Microsoft.Azure.Cosmos/src/Handler/DiagnosticsHandlerHelper.cs b/Microsoft.Azure.Cosmos/src/Handler/DiagnosticsHandlerHelper.cs index 1007234125..266524e38b 100644 --- a/Microsoft.Azure.Cosmos/src/Handler/DiagnosticsHandlerHelper.cs +++ b/Microsoft.Azure.Cosmos/src/Handler/DiagnosticsHandlerHelper.cs @@ -6,9 +6,9 @@ namespace Microsoft.Azure.Cosmos.Handler { using System; using System.Collections.Generic; + using System.Threading.Tasks; using Documents.Rntbd; using Microsoft.Azure.Cosmos.Core.Trace; - using Microsoft.Azure.Cosmos.Telemetry; /// /// This is a helper class that creates a single static instance to avoid each @@ -22,34 +22,67 @@ internal class DiagnosticsHandlerHelper private const string Telemetrykey = "telemetry"; public static readonly TimeSpan DiagnosticsRefreshInterval = TimeSpan.FromSeconds(10); - private readonly SystemUsageRecorder diagnosticSystemUsageRecorder = new SystemUsageRecorder( + private static readonly TimeSpan ClientTelemetryRefreshInterval = TimeSpan.FromSeconds(5); + + // Need to reset it in Tests hence kept it non-readonly. + private static SystemUsageRecorder DiagnosticSystemUsageRecorder = new SystemUsageRecorder( identifier: Diagnostickey, historyLength: 6, refreshInterval: DiagnosticsHandlerHelper.DiagnosticsRefreshInterval); - - private static readonly TimeSpan ClientTelemetryRefreshInterval = TimeSpan.FromSeconds(5); - private readonly SystemUsageRecorder telemetrySystemUsageRecorder = new SystemUsageRecorder( - identifier: Telemetrykey, - historyLength: 120, - refreshInterval: DiagnosticsHandlerHelper.ClientTelemetryRefreshInterval); - - private static bool isDiagnosticsMonitoringEnabled = false; - private static bool isTelemetryMonitoringEnabled = false; + private static SystemUsageRecorder TelemetrySystemUsageRecorder = null; /// /// Singleton to make sure only one instance of DiagnosticHandlerHelper is there. /// The system usage collection is disabled for internal builds so it is set to null to avoid /// compute for accidentally creating an instance or trying to use it. /// - public static readonly DiagnosticsHandlerHelper Instance = + private static DiagnosticsHandlerHelper Instance = #if INTERNAL null; #else new DiagnosticsHandlerHelper(); #endif + private static bool isDiagnosticsMonitoringEnabled; + private static bool isTelemetryMonitoringEnabled; + private readonly SystemUsageMonitor systemUsageMonitor = null; + public static DiagnosticsHandlerHelper GetInstance() + { + return DiagnosticsHandlerHelper.Instance; + } + + /// + /// Restart the monitor with client telemetry recorder if telemetry is enabled + /// + /// + public static void Refresh(bool isClientTelemetryEnabled) + { + if (isClientTelemetryEnabled != DiagnosticsHandlerHelper.isTelemetryMonitoringEnabled) + { + DiagnosticsHandlerHelper tempInstance = DiagnosticsHandlerHelper.Instance; + + DiagnosticsHandlerHelper.isTelemetryMonitoringEnabled = isClientTelemetryEnabled; + DiagnosticsHandlerHelper.Instance = new DiagnosticsHandlerHelper(); + + // Stopping the monitor is a blocking call so we do it in a separate thread + _ = Task.Run(() => tempInstance.StopSystemMonitor()); + } + } + + private void StopSystemMonitor() + { + try + { + this.systemUsageMonitor?.Dispose(); + } + catch (ObjectDisposedException ex) + { + DefaultTrace.TraceError("Error while stopping system usage monitor. {0} ", ex); + } + } + /// /// Start System Usage Monitor with Diagnostic and Telemetry Recorder if Telemetry is enabled /// Otherwise Start System Usage Monitor with only Diagnostic Recorder @@ -61,16 +94,24 @@ private DiagnosticsHandlerHelper() // If the CPU monitor fails for some reason don't block the application try { - DiagnosticsHandlerHelper.isTelemetryMonitoringEnabled = ClientTelemetryOptions.IsClientTelemetryEnabled(); - List recorders = new List() { - this.diagnosticSystemUsageRecorder, + DiagnosticsHandlerHelper.DiagnosticSystemUsageRecorder, }; if (DiagnosticsHandlerHelper.isTelemetryMonitoringEnabled) { - recorders.Add(this.telemetrySystemUsageRecorder); + // re-initialize a fresh telemetry recorder when feature is switched on + DiagnosticsHandlerHelper.TelemetrySystemUsageRecorder = new SystemUsageRecorder( + identifier: Telemetrykey, + historyLength: 120, + refreshInterval: DiagnosticsHandlerHelper.ClientTelemetryRefreshInterval); + + recorders.Add(DiagnosticsHandlerHelper.TelemetrySystemUsageRecorder); + } + else + { + DiagnosticsHandlerHelper.TelemetrySystemUsageRecorder = null; } this.systemUsageMonitor = SystemUsageMonitor.CreateAndStart(recorders); @@ -82,7 +123,6 @@ private DiagnosticsHandlerHelper() DefaultTrace.TraceError(ex.Message); DiagnosticsHandlerHelper.isDiagnosticsMonitoringEnabled = false; - DiagnosticsHandlerHelper.isTelemetryMonitoringEnabled = false; } } @@ -99,7 +139,7 @@ public SystemUsageHistory GetDiagnosticsSystemHistory() try { - return this.diagnosticSystemUsageRecorder.Data; + return DiagnosticsHandlerHelper.DiagnosticSystemUsageRecorder.Data; } catch (Exception ex) { @@ -123,7 +163,7 @@ public SystemUsageHistory GetClientTelemetrySystemHistory() try { - return this.telemetrySystemUsageRecorder.Data; + return DiagnosticsHandlerHelper.TelemetrySystemUsageRecorder?.Data; } catch (Exception ex) { diff --git a/Microsoft.Azure.Cosmos/src/Handler/ResponseMessage.cs b/Microsoft.Azure.Cosmos/src/Handler/ResponseMessage.cs index 9694a14713..60ff675172 100644 --- a/Microsoft.Azure.Cosmos/src/Handler/ResponseMessage.cs +++ b/Microsoft.Azure.Cosmos/src/Handler/ResponseMessage.cs @@ -251,21 +251,27 @@ private void CheckDisposed() /// Decode the Index Metrics from the response headers, if exists. /// /// The response headers - /// The encoding of the IndexMetrics response + /// The encoding of the IndexMetrics response /// Lazy implementation of the pretty-printed IndexMetrics - static internal Lazy DecodeIndexMetrics(Headers responseMessageHeaders, bool isBse64Encoded) + static internal Lazy DecodeIndexMetrics(Headers responseMessageHeaders, bool isBase64Encoded) { if (responseMessageHeaders?.IndexUtilizationText != null) { return new Lazy(() => { - IndexUtilizationInfo parsedIndexUtilizationInfo = IndexUtilizationInfo.CreateFromString(responseMessageHeaders.IndexUtilizationText, isBse64Encoded); - - StringBuilder stringBuilder = new StringBuilder(); - IndexMetricWriter indexMetricWriter = new IndexMetricWriter(stringBuilder); - indexMetricWriter.WriteIndexMetrics(parsedIndexUtilizationInfo); + if (isBase64Encoded) + { + IndexUtilizationInfo parsedIndexUtilizationInfo = IndexUtilizationInfo.CreateFromString(responseMessageHeaders.IndexUtilizationText); - return stringBuilder.ToString(); + StringBuilder stringBuilder = new StringBuilder(); + IndexMetricsWriter indexMetricWriter = new IndexMetricsWriter(stringBuilder); + indexMetricWriter.WriteIndexMetrics(parsedIndexUtilizationInfo); + + return stringBuilder.ToString(); + } + + // Return the JSON from the response header + return responseMessageHeaders.IndexUtilizationText; }); } diff --git a/Microsoft.Azure.Cosmos/src/Handler/TelemetryHandler.cs b/Microsoft.Azure.Cosmos/src/Handler/TelemetryHandler.cs index 9d7e504eba..039373718f 100644 --- a/Microsoft.Azure.Cosmos/src/Handler/TelemetryHandler.cs +++ b/Microsoft.Azure.Cosmos/src/Handler/TelemetryHandler.cs @@ -10,14 +10,15 @@ namespace Microsoft.Azure.Cosmos.Handlers using System.Threading.Tasks; using Microsoft.Azure.Cosmos.Core.Trace; using Microsoft.Azure.Cosmos.Telemetry; + using Microsoft.Azure.Cosmos.Telemetry.Collector; internal class TelemetryHandler : RequestHandler { - private readonly ClientTelemetry telemetry; + private readonly TelemetryToServiceHelper telemetryToServiceHelper; - public TelemetryHandler(ClientTelemetry telemetry) + public TelemetryHandler(TelemetryToServiceHelper telemetryToServiceHelper) { - this.telemetry = telemetry ?? throw new ArgumentNullException(nameof(telemetry)); + this.telemetryToServiceHelper = telemetryToServiceHelper ?? throw new ArgumentNullException(nameof(telemetryToServiceHelper)); } public override async Task SendAsync( @@ -29,19 +30,22 @@ public override async Task SendAsync( { try { - this.telemetry - .CollectOperationInfo( - cosmosDiagnostics: response.Diagnostics, - statusCode: response.StatusCode, - responseSizeInBytes: this.GetPayloadSize(response), - containerId: request.ContainerId, - databaseId: request.DatabaseId, - operationType: request.OperationType, - resourceType: request.ResourceType, - consistencyLevel: request.Headers?[Documents.HttpConstants.HttpHeaders.ConsistencyLevel], - requestCharge: response.Headers.RequestCharge, - subStatusCode: response.Headers.SubStatusCode, - trace: response.Trace); + this.telemetryToServiceHelper.GetCollector().CollectOperationAndNetworkInfo( + () => new TelemetryInformation + { + RegionsContactedList = response.Diagnostics.GetContactedRegions(), + RequestLatency = response.Diagnostics.GetClientElapsedTime(), + StatusCode = response.StatusCode, + ResponseSizeInBytes = TelemetryHandler.GetPayloadSize(response), + ContainerId = request.ContainerId, + DatabaseId = request.DatabaseId, + OperationType = request.OperationType, + ResourceType = request.ResourceType, + ConsistencyLevel = request.Headers?[Documents.HttpConstants.HttpHeaders.ConsistencyLevel], + RequestCharge = response.Headers.RequestCharge, + SubStatusCode = response.Headers.SubStatusCode, + Trace = response.Trace + }); } catch (Exception ex) { @@ -63,7 +67,7 @@ private bool IsAllowed(RequestMessage request) /// /// /// Size of Payload - private long GetPayloadSize(ResponseMessage response) + private static long GetPayloadSize(ResponseMessage response) { if (response != null) { diff --git a/Microsoft.Azure.Cosmos/src/Json/JsonBinaryEncoding.FirstValueOffsets.cs b/Microsoft.Azure.Cosmos/src/Json/JsonBinaryEncoding.FirstValueOffsets.cs index 609ede82ef..36070e533c 100644 --- a/Microsoft.Azure.Cosmos/src/Json/JsonBinaryEncoding.FirstValueOffsets.cs +++ b/Microsoft.Azure.Cosmos/src/Json/JsonBinaryEncoding.FirstValueOffsets.cs @@ -21,11 +21,13 @@ private static class FirstValueOffsets 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - // Encoded 1-byte system string (64 values) + // Encoded 1-byte system string (32 values) 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + // Encoded 1-byte user string (32 values) 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, diff --git a/Microsoft.Azure.Cosmos/src/Json/JsonBinaryEncoding.NodeTypes.cs b/Microsoft.Azure.Cosmos/src/Json/JsonBinaryEncoding.NodeTypes.cs index e0aa15c2c5..80885d9296 100644 --- a/Microsoft.Azure.Cosmos/src/Json/JsonBinaryEncoding.NodeTypes.cs +++ b/Microsoft.Azure.Cosmos/src/Json/JsonBinaryEncoding.NodeTypes.cs @@ -36,11 +36,13 @@ public static class NodeTypes Number, Number, Number, Number, Number, Number, Number, Number, Number, Number, Number, Number, Number, Number, Number, Number, - // Encoded 1-byte system string (64 values) + // Encoded 1-byte system string (32 values) String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, + + // Encoded 1-byte user string (32 values) String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, diff --git a/Microsoft.Azure.Cosmos/src/Json/JsonBinaryEncoding.StringLengths.cs b/Microsoft.Azure.Cosmos/src/Json/JsonBinaryEncoding.StringLengths.cs index 09e85f3815..ac68cfe027 100644 --- a/Microsoft.Azure.Cosmos/src/Json/JsonBinaryEncoding.StringLengths.cs +++ b/Microsoft.Azure.Cosmos/src/Json/JsonBinaryEncoding.StringLengths.cs @@ -37,7 +37,7 @@ private static class StringLengths NotStr, NotStr, NotStr, NotStr, NotStr, NotStr, NotStr, NotStr, NotStr, NotStr, NotStr, NotStr, NotStr, NotStr, NotStr, NotStr, - // Encoded 1-byte system string (64 values) + // Encoded 1-byte system string (32 values) SystemStrings.Strings[0].Utf8String.Length, SystemStrings.Strings[1].Utf8String.Length, SystemStrings.Strings[2].Utf8String.Length, SystemStrings.Strings[3].Utf8String.Length, SystemStrings.Strings[4].Utf8String.Length, SystemStrings.Strings[5].Utf8String.Length, @@ -54,22 +54,12 @@ private static class StringLengths SystemStrings.Strings[26].Utf8String.Length, SystemStrings.Strings[27].Utf8String.Length, SystemStrings.Strings[28].Utf8String.Length, SystemStrings.Strings[29].Utf8String.Length, SystemStrings.Strings[30].Utf8String.Length, SystemStrings.Strings[31].Utf8String.Length, - SystemStrings.Strings[32].Utf8String.Length, SystemStrings.Strings[33].Utf8String.Length, - SystemStrings.Strings[34].Utf8String.Length, SystemStrings.Strings[35].Utf8String.Length, - SystemStrings.Strings[36].Utf8String.Length, SystemStrings.Strings[37].Utf8String.Length, - SystemStrings.Strings[38].Utf8String.Length, SystemStrings.Strings[39].Utf8String.Length, - SystemStrings.Strings[40].Utf8String.Length, SystemStrings.Strings[41].Utf8String.Length, - SystemStrings.Strings[42].Utf8String.Length, SystemStrings.Strings[43].Utf8String.Length, - SystemStrings.Strings[44].Utf8String.Length, SystemStrings.Strings[45].Utf8String.Length, - SystemStrings.Strings[46].Utf8String.Length, SystemStrings.Strings[47].Utf8String.Length, - SystemStrings.Strings[48].Utf8String.Length, SystemStrings.Strings[49].Utf8String.Length, - SystemStrings.Strings[50].Utf8String.Length, SystemStrings.Strings[51].Utf8String.Length, - SystemStrings.Strings[52].Utf8String.Length, SystemStrings.Strings[53].Utf8String.Length, - SystemStrings.Strings[54].Utf8String.Length, SystemStrings.Strings[55].Utf8String.Length, - SystemStrings.Strings[56].Utf8String.Length, SystemStrings.Strings[57].Utf8String.Length, - SystemStrings.Strings[58].Utf8String.Length, SystemStrings.Strings[59].Utf8String.Length, - SystemStrings.Strings[60].Utf8String.Length, SystemStrings.Strings[61].Utf8String.Length, - SystemStrings.Strings[62].Utf8String.Length, SystemStrings.Strings[63].Utf8String.Length, + + // Encoded 1-byte user string (32 values) + UsrStr1, UsrStr1, UsrStr1, UsrStr1, UsrStr1, UsrStr1, UsrStr1, UsrStr1, + UsrStr1, UsrStr1, UsrStr1, UsrStr1, UsrStr1, UsrStr1, UsrStr1, UsrStr1, + UsrStr1, UsrStr1, UsrStr1, UsrStr1, UsrStr1, UsrStr1, UsrStr1, UsrStr1, + UsrStr1, UsrStr1, UsrStr1, UsrStr1, UsrStr1, UsrStr1, UsrStr1, UsrStr1, // Encoded 2-byte user string (8 values) UsrStr2, UsrStr2, UsrStr2, UsrStr2, UsrStr2, UsrStr2, UsrStr2, UsrStr2, diff --git a/Microsoft.Azure.Cosmos/src/Json/JsonBinaryEncoding.Strings.cs b/Microsoft.Azure.Cosmos/src/Json/JsonBinaryEncoding.Strings.cs index 5c3bf992a1..d3c866fbf0 100644 --- a/Microsoft.Azure.Cosmos/src/Json/JsonBinaryEncoding.Strings.cs +++ b/Microsoft.Azure.Cosmos/src/Json/JsonBinaryEncoding.Strings.cs @@ -38,11 +38,13 @@ internal static partial class JsonBinaryEncoding false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, - // Encoded 0-byte system string (64 values) + // Encoded 0-byte system string (32 values) true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, + + // Encoded true-byte user string (32 values) true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, @@ -384,14 +386,29 @@ private static bool TryGetUserStringId(ReadOnlySpan stringToken, out int u return false; } - // JsonBinaryEncoding.TypeMarker.IsTwoByteEncodedUserString(typeMarker) must be true - if (stringToken.Length < 2) + if (JsonBinaryEncoding.TypeMarker.IsOneByteEncodedUserString(typeMarker)) { - userStringId = default; - return false; + if (stringToken.Length < 1) + { + userStringId = default; + return false; + } + + userStringId = typeMarker - JsonBinaryEncoding.TypeMarker.UserString1ByteLengthMin; } + else //// JsonBinaryEncoding.TypeMarker.IsTwoByteEncodedUserString(typeMarker) + { + if (stringToken.Length < 2) + { + userStringId = default; + return false; + } - userStringId = stringToken[1] + ((stringToken[0] - JsonBinaryEncoding.TypeMarker.UserString2ByteLengthMin) * 0xFF); + const byte OneByteCount = JsonBinaryEncoding.TypeMarker.UserString1ByteLengthMax - JsonBinaryEncoding.TypeMarker.UserString1ByteLengthMin; + userStringId = OneByteCount + + stringToken[1] + + ((stringToken[0] - JsonBinaryEncoding.TypeMarker.UserString2ByteLengthMin) * 0xFF); + } return true; } diff --git a/Microsoft.Azure.Cosmos/src/Json/JsonBinaryEncoding.SystemStrings.cs b/Microsoft.Azure.Cosmos/src/Json/JsonBinaryEncoding.SystemStrings.cs index 87f2a24062..e9edee7854 100644 --- a/Microsoft.Azure.Cosmos/src/Json/JsonBinaryEncoding.SystemStrings.cs +++ b/Microsoft.Azure.Cosmos/src/Json/JsonBinaryEncoding.SystemStrings.cs @@ -2,7 +2,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // ------------------------------------------------------------ -// This is auto-generated code. Modify: JsonBinaryEncoding.SystemStrings.tt: 86 +// This is auto-generated code. Modify: JsonBinaryEncoding.SystemStrings.tt: 54 namespace Microsoft.Azure.Cosmos.Json { @@ -51,38 +51,6 @@ public static class SystemStrings UtfAllString.Create("Feature"), UtfAllString.Create("FeatureCollection"), UtfAllString.Create("_id"), - UtfAllString.Create("$id"), - UtfAllString.Create("$pk"), - UtfAllString.Create("_isEdge"), - UtfAllString.Create("_partitionKey"), - UtfAllString.Create("_type"), - UtfAllString.Create("_value"), - UtfAllString.Create("data"), - UtfAllString.Create("Data"), - UtfAllString.Create("entity"), - UtfAllString.Create("isDeleted"), - UtfAllString.Create("IsDeleted"), - UtfAllString.Create("key"), - UtfAllString.Create("Key"), - UtfAllString.Create("Location"), - UtfAllString.Create("partition"), - UtfAllString.Create("partition_id"), - UtfAllString.Create("partitionKey"), - UtfAllString.Create("PartitionKey"), - UtfAllString.Create("pk"), - UtfAllString.Create("state"), - UtfAllString.Create("State"), - UtfAllString.Create("status"), - UtfAllString.Create("Status"), - UtfAllString.Create("subscriptionId"), - UtfAllString.Create("SubscriptionId"), - UtfAllString.Create("tenantId"), - UtfAllString.Create("TenantId"), - UtfAllString.Create("timestamp"), - UtfAllString.Create("Timestamp"), - UtfAllString.Create("ttl"), - UtfAllString.Create("userId"), - UtfAllString.Create("UserId"), }.ToImmutableArray(); public static int? GetSystemStringId(Utf8Span buffer) @@ -93,15 +61,11 @@ public static class SystemStrings 3 => GetSystemStringIdLength3(buffer.Span), 4 => GetSystemStringIdLength4(buffer.Span), 5 => GetSystemStringIdLength5(buffer.Span), - 6 => GetSystemStringIdLength6(buffer.Span), 7 => GetSystemStringIdLength7(buffer.Span), 8 => GetSystemStringIdLength8(buffer.Span), - 9 => GetSystemStringIdLength9(buffer.Span), 10 => GetSystemStringIdLength10(buffer.Span), 11 => GetSystemStringIdLength11(buffer.Span), 12 => GetSystemStringIdLength12(buffer.Span), - 13 => GetSystemStringIdLength13(buffer.Span), - 14 => GetSystemStringIdLength14(buffer.Span), 15 => GetSystemStringIdLength15(buffer.Span), 17 => GetSystemStringIdLength17(buffer.Span), 18 => GetSystemStringIdLength18(buffer.Span), @@ -131,11 +95,6 @@ public static class SystemStrings return 12; } - if (buffer.SequenceEqual(Strings[50].Utf8String.Span.Span)) - { - return 50; - } - return null; } private static int? GetSystemStringIdLength3(ReadOnlySpan buffer) @@ -155,31 +114,6 @@ public static class SystemStrings return 31; } - if (buffer.SequenceEqual(Strings[32].Utf8String.Span.Span)) - { - return 32; - } - - if (buffer.SequenceEqual(Strings[33].Utf8String.Span.Span)) - { - return 33; - } - - if (buffer.SequenceEqual(Strings[43].Utf8String.Span.Span)) - { - return 43; - } - - if (buffer.SequenceEqual(Strings[44].Utf8String.Span.Span)) - { - return 44; - } - - if (buffer.SequenceEqual(Strings[61].Utf8String.Span.Span)) - { - return 61; - } - return null; } private static int? GetSystemStringIdLength4(ReadOnlySpan buffer) @@ -214,16 +148,6 @@ public static class SystemStrings return 27; } - if (buffer.SequenceEqual(Strings[38].Utf8String.Span.Span)) - { - return 38; - } - - if (buffer.SequenceEqual(Strings[39].Utf8String.Span.Span)) - { - return 39; - } - return null; } private static int? GetSystemStringIdLength5(ReadOnlySpan buffer) @@ -258,55 +182,6 @@ public static class SystemStrings return 28; } - if (buffer.SequenceEqual(Strings[36].Utf8String.Span.Span)) - { - return 36; - } - - if (buffer.SequenceEqual(Strings[51].Utf8String.Span.Span)) - { - return 51; - } - - if (buffer.SequenceEqual(Strings[52].Utf8String.Span.Span)) - { - return 52; - } - - return null; - } - private static int? GetSystemStringIdLength6(ReadOnlySpan buffer) - { - if (buffer.SequenceEqual(Strings[37].Utf8String.Span.Span)) - { - return 37; - } - - if (buffer.SequenceEqual(Strings[40].Utf8String.Span.Span)) - { - return 40; - } - - if (buffer.SequenceEqual(Strings[53].Utf8String.Span.Span)) - { - return 53; - } - - if (buffer.SequenceEqual(Strings[54].Utf8String.Span.Span)) - { - return 54; - } - - if (buffer.SequenceEqual(Strings[62].Utf8String.Span.Span)) - { - return 62; - } - - if (buffer.SequenceEqual(Strings[63].Utf8String.Span.Span)) - { - return 63; - } - return null; } private static int? GetSystemStringIdLength7(ReadOnlySpan buffer) @@ -321,11 +196,6 @@ public static class SystemStrings return 29; } - if (buffer.SequenceEqual(Strings[34].Utf8String.Span.Span)) - { - return 34; - } - return null; } private static int? GetSystemStringIdLength8(ReadOnlySpan buffer) @@ -335,50 +205,6 @@ public static class SystemStrings return 10; } - if (buffer.SequenceEqual(Strings[45].Utf8String.Span.Span)) - { - return 45; - } - - if (buffer.SequenceEqual(Strings[57].Utf8String.Span.Span)) - { - return 57; - } - - if (buffer.SequenceEqual(Strings[58].Utf8String.Span.Span)) - { - return 58; - } - - return null; - } - private static int? GetSystemStringIdLength9(ReadOnlySpan buffer) - { - if (buffer.SequenceEqual(Strings[41].Utf8String.Span.Span)) - { - return 41; - } - - if (buffer.SequenceEqual(Strings[42].Utf8String.Span.Span)) - { - return 42; - } - - if (buffer.SequenceEqual(Strings[46].Utf8String.Span.Span)) - { - return 46; - } - - if (buffer.SequenceEqual(Strings[59].Utf8String.Span.Span)) - { - return 59; - } - - if (buffer.SequenceEqual(Strings[60].Utf8String.Span.Span)) - { - return 60; - } - return null; } private static int? GetSystemStringIdLength10(ReadOnlySpan buffer) @@ -426,44 +252,6 @@ public static class SystemStrings return 20; } - if (buffer.SequenceEqual(Strings[47].Utf8String.Span.Span)) - { - return 47; - } - - if (buffer.SequenceEqual(Strings[48].Utf8String.Span.Span)) - { - return 48; - } - - if (buffer.SequenceEqual(Strings[49].Utf8String.Span.Span)) - { - return 49; - } - - return null; - } - private static int? GetSystemStringIdLength13(ReadOnlySpan buffer) - { - if (buffer.SequenceEqual(Strings[35].Utf8String.Span.Span)) - { - return 35; - } - - return null; - } - private static int? GetSystemStringIdLength14(ReadOnlySpan buffer) - { - if (buffer.SequenceEqual(Strings[55].Utf8String.Span.Span)) - { - return 55; - } - - if (buffer.SequenceEqual(Strings[56].Utf8String.Span.Span)) - { - return 56; - } - return null; } private static int? GetSystemStringIdLength15(ReadOnlySpan buffer) diff --git a/Microsoft.Azure.Cosmos/src/Json/JsonBinaryEncoding.SystemStrings.tt b/Microsoft.Azure.Cosmos/src/Json/JsonBinaryEncoding.SystemStrings.tt index c369e3e489..fd06958ed0 100644 --- a/Microsoft.Azure.Cosmos/src/Json/JsonBinaryEncoding.SystemStrings.tt +++ b/Microsoft.Azure.Cosmos/src/Json/JsonBinaryEncoding.SystemStrings.tt @@ -43,38 +43,6 @@ string[] systemStrings = new string[] "Feature", "FeatureCollection", "_id", - "$id", - "$pk", - "_isEdge", - "_partitionKey", - "_type", - "_value", - "data", - "Data", - "entity", - "isDeleted", - "IsDeleted", - "key", - "Key", - "Location", - "partition", - "partition_id", - "partitionKey", - "PartitionKey", - "pk", - "state", - "State", - "status", - "Status", - "subscriptionId", - "SubscriptionId", - "tenantId", - "TenantId", - "timestamp", - "Timestamp", - "ttl", - "userId", - "UserId", }; int[] distinctStringLengths = systemStrings.Select(x => x.Length).Distinct().OrderBy(x => x).ToArray(); diff --git a/Microsoft.Azure.Cosmos/src/Json/JsonBinaryEncoding.TypeMarker.cs b/Microsoft.Azure.Cosmos/src/Json/JsonBinaryEncoding.TypeMarker.cs index 5c17074451..8fab1e22fb 100644 --- a/Microsoft.Azure.Cosmos/src/Json/JsonBinaryEncoding.TypeMarker.cs +++ b/Microsoft.Azure.Cosmos/src/Json/JsonBinaryEncoding.TypeMarker.cs @@ -27,7 +27,7 @@ public readonly struct TypeMarker public const byte LiteralIntMax = LiteralIntMin + 32; #endregion - #region [0x20, 0x60): Encoded 1-byte system string (64 values) + #region [0x20, 0x40): Encoded 1-byte system string (32 values) /// /// The first type marker for a system string whose value can be encoded in a 1 byte type marker. /// @@ -36,14 +36,26 @@ public readonly struct TypeMarker /// /// The last type marker for a system string whose value can be encoded in a 1 byte type marker. /// - public const byte SystemString1ByteLengthMax = SystemString1ByteLengthMin + 64; + public const byte SystemString1ByteLengthMax = SystemString1ByteLengthMin + 32; + #endregion + + #region [0x40, 0x60): Encoded 1-byte user string (32 values) + /// + /// The first type marker for a user string whose value can be encoded in a 1 byte type marker. + /// + public const byte UserString1ByteLengthMin = SystemString1ByteLengthMax; + + /// + /// The last type marker for a user string whose value can be encoded in a 1 byte type marker. + /// + public const byte UserString1ByteLengthMax = UserString1ByteLengthMin + 32; #endregion #region [0x60, 0x68): 2-byte user string (8 values) /// /// The first type marker for a system string whose value can be encoded in a 2 byte type marker. /// - public const byte UserString2ByteLengthMin = SystemString1ByteLengthMax; + public const byte UserString2ByteLengthMin = UserString1ByteLengthMax; /// /// The last type marker for a system string whose value can be encoded in a 2 byte type marker. @@ -455,6 +467,17 @@ public static bool IsSystemString(byte typeMarker) return InRange(typeMarker, SystemString1ByteLengthMin, SystemString1ByteLengthMax); } + /// + /// Gets whether a typeMarker is for a one byte encoded user string. + /// + /// The input type marker. + /// Whether the typeMarker is for a one byte encoded user string. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsOneByteEncodedUserString(byte typeMarker) + { + return InRange(typeMarker, UserString1ByteLengthMin, UserString1ByteLengthMax); + } + /// /// Gets whether a typeMarker is for a two byte encoded user string. /// @@ -474,7 +497,7 @@ public static bool IsTwoByteEncodedUserString(byte typeMarker) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsUserString(byte typeMarker) { - return IsTwoByteEncodedUserString(typeMarker); + return IsOneByteEncodedUserString(typeMarker) || IsTwoByteEncodedUserString(typeMarker); } /// @@ -485,7 +508,7 @@ public static bool IsUserString(byte typeMarker) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsOneByteEncodedString(byte typeMarker) { - return InRange(typeMarker, SystemString1ByteLengthMin, SystemString1ByteLengthMax); + return InRange(typeMarker, SystemString1ByteLengthMin, UserString1ByteLengthMax); } /// diff --git a/Microsoft.Azure.Cosmos/src/Json/JsonBinaryEncoding.ValueLengths.cs b/Microsoft.Azure.Cosmos/src/Json/JsonBinaryEncoding.ValueLengths.cs index c8b8daac7d..29427c9dbd 100644 --- a/Microsoft.Azure.Cosmos/src/Json/JsonBinaryEncoding.ValueLengths.cs +++ b/Microsoft.Azure.Cosmos/src/Json/JsonBinaryEncoding.ValueLengths.cs @@ -43,11 +43,13 @@ private static class ValueLengths 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - // Encoded 1-byte system string (64 values) + // Encoded 1-byte system string (32 values) 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + // Encoded 1-byte user string (32 values) 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, diff --git a/Microsoft.Azure.Cosmos/src/Json/JsonReader.JsonBinaryReader.cs b/Microsoft.Azure.Cosmos/src/Json/JsonReader.JsonBinaryReader.cs index 1c64b1999a..02b11a9cc1 100644 --- a/Microsoft.Azure.Cosmos/src/Json/JsonReader.JsonBinaryReader.cs +++ b/Microsoft.Azure.Cosmos/src/Json/JsonReader.JsonBinaryReader.cs @@ -26,11 +26,13 @@ abstract partial class JsonReader : IJsonReader JsonTokenType.Number, JsonTokenType.Number, JsonTokenType.Number, JsonTokenType.Number, JsonTokenType.Number, JsonTokenType.Number, JsonTokenType.Number, JsonTokenType.Number, JsonTokenType.Number, JsonTokenType.Number, JsonTokenType.Number, JsonTokenType.Number, JsonTokenType.Number, JsonTokenType.Number, JsonTokenType.Number, JsonTokenType.Number, - // Encoded 1-byte system string (64 values) + // Encoded 1-byte system string (32 values) JsonTokenType.String, JsonTokenType.String, JsonTokenType.String, JsonTokenType.String, JsonTokenType.String, JsonTokenType.String, JsonTokenType.String, JsonTokenType.String, JsonTokenType.String, JsonTokenType.String, JsonTokenType.String, JsonTokenType.String, JsonTokenType.String, JsonTokenType.String, JsonTokenType.String, JsonTokenType.String, JsonTokenType.String, JsonTokenType.String, JsonTokenType.String, JsonTokenType.String, JsonTokenType.String, JsonTokenType.String, JsonTokenType.String, JsonTokenType.String, JsonTokenType.String, JsonTokenType.String, JsonTokenType.String, JsonTokenType.String, JsonTokenType.String, JsonTokenType.String, JsonTokenType.String, JsonTokenType.String, + + // Encoded 1-byte user string (32 values) JsonTokenType.String, JsonTokenType.String, JsonTokenType.String, JsonTokenType.String, JsonTokenType.String, JsonTokenType.String, JsonTokenType.String, JsonTokenType.String, JsonTokenType.String, JsonTokenType.String, JsonTokenType.String, JsonTokenType.String, JsonTokenType.String, JsonTokenType.String, JsonTokenType.String, JsonTokenType.String, JsonTokenType.String, JsonTokenType.String, JsonTokenType.String, JsonTokenType.String, JsonTokenType.String, JsonTokenType.String, JsonTokenType.String, JsonTokenType.String, diff --git a/Microsoft.Azure.Cosmos/src/Json/JsonWriter.JsonBinaryWriter.cs b/Microsoft.Azure.Cosmos/src/Json/JsonWriter.JsonBinaryWriter.cs index 0df6582cf6..6b20d99f59 100644 --- a/Microsoft.Azure.Cosmos/src/Json/JsonWriter.JsonBinaryWriter.cs +++ b/Microsoft.Azure.Cosmos/src/Json/JsonWriter.JsonBinaryWriter.cs @@ -81,16 +81,18 @@ private enum RawValueType : byte RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, - // Encoded 1-byte system string (64 values) - RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, - RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, - RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, - RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, + // Encoded 1-byte system string (32 values) RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, RawValueType.Token, + // Encoded 1-byte user string (32 values) + RawValueType.StrUsr, RawValueType.StrUsr, RawValueType.StrUsr, RawValueType.StrUsr, RawValueType.StrUsr, RawValueType.StrUsr, RawValueType.StrUsr, RawValueType.StrUsr, + RawValueType.StrUsr, RawValueType.StrUsr, RawValueType.StrUsr, RawValueType.StrUsr, RawValueType.StrUsr, RawValueType.StrUsr, RawValueType.StrUsr, RawValueType.StrUsr, + RawValueType.StrUsr, RawValueType.StrUsr, RawValueType.StrUsr, RawValueType.StrUsr, RawValueType.StrUsr, RawValueType.StrUsr, RawValueType.StrUsr, RawValueType.StrUsr, + RawValueType.StrUsr, RawValueType.StrUsr, RawValueType.StrUsr, RawValueType.StrUsr, RawValueType.StrUsr, RawValueType.StrUsr, RawValueType.StrUsr, RawValueType.StrUsr, + // Encoded 2-byte user string (8 values) RawValueType.StrUsr, RawValueType.StrUsr, RawValueType.StrUsr, RawValueType.StrUsr, RawValueType.StrUsr, RawValueType.StrUsr, RawValueType.StrUsr, RawValueType.StrUsr, diff --git a/Microsoft.Azure.Cosmos/src/Linq/BuiltinFunctions/BuiltinFunctionVisitor.cs b/Microsoft.Azure.Cosmos/src/Linq/BuiltinFunctions/BuiltinFunctionVisitor.cs index e3814ba1fd..d7e79b5c50 100644 --- a/Microsoft.Azure.Cosmos/src/Linq/BuiltinFunctions/BuiltinFunctionVisitor.cs +++ b/Microsoft.Azure.Cosmos/src/Linq/BuiltinFunctions/BuiltinFunctionVisitor.cs @@ -5,6 +5,7 @@ namespace Microsoft.Azure.Cosmos.Linq { using System; + using System.Collections.Generic; using System.Globalization; using System.Linq.Expressions; using Microsoft.Azure.Cosmos; @@ -49,6 +50,12 @@ public static SqlScalarExpression VisitBuiltinFunctionCall(MethodCallExpression if (methodCallExpression.Method.DeclaringType.GeUnderlyingSystemType() == typeof(CosmosLinqExtensions)) { + // CosmosLinq Extensions are either RegexMatch or Type check functions (IsString, IsBool, etc.) + if (methodCallExpression.Method.Name == nameof(CosmosLinqExtensions.RegexMatch)) + { + return StringBuiltinFunctions.Visit(methodCallExpression, context); + } + return TypeCheckFunctions.Visit(methodCallExpression, context); } } diff --git a/Microsoft.Azure.Cosmos/src/Linq/BuiltinFunctions/StringBuiltinFunctions.cs b/Microsoft.Azure.Cosmos/src/Linq/BuiltinFunctions/StringBuiltinFunctions.cs index b04bd58c3c..7d833a03bd 100644 --- a/Microsoft.Azure.Cosmos/src/Linq/BuiltinFunctions/StringBuiltinFunctions.cs +++ b/Microsoft.Azure.Cosmos/src/Linq/BuiltinFunctions/StringBuiltinFunctions.cs @@ -327,6 +327,43 @@ protected override SqlScalarExpression VisitExplicit(MethodCallExpression method } } + private class RegexMatchVisitor : SqlBuiltinFunctionVisitor + { + public RegexMatchVisitor() + : base(SqlFunctionCallScalarExpression.Names.RegexMatch, + isStatic: true, + new List() + { + new Type[]{ typeof(object), typeof(string)}, // search string, regex pattern + new Type[]{ typeof(object), typeof(string), typeof(string)} // search string, regex pattern, search modifier + }) + { + } + + protected override SqlScalarExpression VisitImplicit(MethodCallExpression methodCallExpression, TranslationContext context) + { + int argumentCount = methodCallExpression.Arguments.Count; + if (argumentCount == 0 || argumentCount > 3 || (methodCallExpression.Arguments[1].NodeType != ExpressionType.Constant)) + { + return null; + } + + List arguments = new List + { + // Argument 0 and the Method object is the same, since Regex is an extension method + ExpressionToSql.VisitNonSubqueryScalarExpression(methodCallExpression.Arguments[0], context), + ExpressionToSql.VisitNonSubqueryScalarExpression(methodCallExpression.Arguments[1], context) + }; + + if (argumentCount > 2 && (methodCallExpression.Arguments[2].NodeType == ExpressionType.Constant)) + { + arguments.Add(ExpressionToSql.VisitNonSubqueryScalarExpression(methodCallExpression.Arguments[2], context)); + } + + return SqlFunctionCallScalarExpression.CreateBuiltin(SqlFunctionCallScalarExpression.Names.RegexMatch, arguments.ToArray()); + } + } + private class StringVisitToString : SqlBuiltinFunctionVisitor { public StringVisitToString() @@ -432,6 +469,10 @@ static StringBuiltinFunctions() "TrimStart", new StringVisitTrimStart() }, + { + nameof(CosmosLinqExtensions.RegexMatch), + new RegexMatchVisitor() + }, { "Replace", new SqlBuiltinFunctionVisitor(SqlFunctionCallScalarExpression.Names.Replace, diff --git a/Microsoft.Azure.Cosmos/src/Linq/CosmosLinqExtensions.cs b/Microsoft.Azure.Cosmos/src/Linq/CosmosLinqExtensions.cs index 6663f52673..619c1c1ecf 100644 --- a/Microsoft.Azure.Cosmos/src/Linq/CosmosLinqExtensions.cs +++ b/Microsoft.Azure.Cosmos/src/Linq/CosmosLinqExtensions.cs @@ -10,6 +10,7 @@ namespace Microsoft.Azure.Cosmos.Linq using System.Linq; using System.Linq.Expressions; using System.Reflection; + using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; using Microsoft.Azure.Cosmos.Diagnostics; @@ -175,6 +176,49 @@ public static bool IsString(this object obj) throw new NotImplementedException(ClientResources.TypeCheckExtensionFunctionsNotImplemented); } + /// + /// Returns a Boolean value indicating if the specified expression matches the supplied regex pattern. + /// For more information, see https://learn.microsoft.com/en-us/azure/cosmos-db/nosql/query/regexmatch. + /// This method is to be used in LINQ expressions only and will be evaluated on server. + /// There's no implementation provided in the client library. + /// + /// + /// A string expression with a regular expression defined to use when searching. + /// Returns true if the string matches the regex expressions; otherwise, false. + /// + /// + /// document.Name.RegexMatch()); + /// ]]> + /// + /// + public static bool RegexMatch(this object obj, string regularExpression) + { + throw new NotImplementedException(ClientResources.TypeCheckExtensionFunctionsNotImplemented); + } + + /// + /// Returns a Boolean value indicating if the specified expression matches the supplied regex pattern. + /// For more information, see https://learn.microsoft.com/en-us/azure/cosmos-db/nosql/query/regexmatch. + /// This method is to be used in LINQ expressions only and will be evaluated on server. + /// There's no implementation provided in the client library. + /// + /// + /// A string expression with a regular expression defined to use when searching. + /// An optional string expression with the selected modifiers to use with the regular expression. + /// Returns true if the string matches the regex expressions; otherwise, false. + /// + /// + /// document.Name.RegexMatch(, )); + /// ]]> + /// + /// + public static bool RegexMatch(this object obj, string regularExpression, string searchModifier) + { + throw new NotImplementedException(ClientResources.TypeCheckExtensionFunctionsNotImplemented); + } + /// /// This method generate query definition from LINQ query. /// diff --git a/Microsoft.Azure.Cosmos/src/Linq/ExpressionToSQL.cs b/Microsoft.Azure.Cosmos/src/Linq/ExpressionToSQL.cs index beeff94dc3..c64922186f 100644 --- a/Microsoft.Azure.Cosmos/src/Linq/ExpressionToSQL.cs +++ b/Microsoft.Azure.Cosmos/src/Linq/ExpressionToSQL.cs @@ -15,12 +15,10 @@ namespace Microsoft.Azure.Cosmos.Linq using System.Reflection; using Microsoft.Azure.Cosmos.CosmosElements; using Microsoft.Azure.Cosmos.CosmosElements.Numbers; - using Microsoft.Azure.Cosmos.Serializer; using Microsoft.Azure.Cosmos.Spatial; using Microsoft.Azure.Cosmos.SqlObjects; using Microsoft.Azure.Documents; using Newtonsoft.Json; - using Newtonsoft.Json.Linq; using static Microsoft.Azure.Cosmos.Linq.FromParameterBindings; // ReSharper disable UnusedParameter.Local @@ -77,10 +75,9 @@ public static class LinqMethods public const string Where = "Where"; } - private static string SqlRoot = "root"; - private static string DefaultParameterName = "v"; - private static bool usePropertyRef = false; - private static SqlIdentifier RootIdentifier = SqlIdentifier.Create(SqlRoot); + private static readonly string SqlRoot = "root"; + private static readonly string DefaultParameterName = "v"; + private static readonly bool usePropertyRef = false; /// /// Toplevel entry point. @@ -455,12 +452,12 @@ private static SqlScalarExpression VisitBinary(BinaryExpression inputExpression, { if (TryMatchStringCompareTo(methodCallExpression, constantExpression, inputExpression.NodeType)) { - return ExpressionToSql.VisitStringCompareTo(methodCallExpression, constantExpression, inputExpression.NodeType, reverseNodeType, context); + return ExpressionToSql.VisitStringCompareTo(methodCallExpression, inputExpression.NodeType, reverseNodeType, context); } if (TryMatchStringCompare(methodCallExpression, constantExpression, inputExpression.NodeType)) { - return ExpressionToSql.VisitStringCompare(methodCallExpression, constantExpression, inputExpression.NodeType, reverseNodeType, context); + return ExpressionToSql.VisitStringCompare(methodCallExpression, inputExpression.NodeType, reverseNodeType, context); } } @@ -613,7 +610,6 @@ private static bool TryMatchStringCompareTo(MethodCallExpression left, ConstantE private static SqlScalarExpression VisitStringCompareTo( MethodCallExpression left, - ConstantExpression right, ExpressionType compareOperator, bool reverseNodeType, TranslationContext context) @@ -690,7 +686,6 @@ private static bool TryMatchStringCompare(MethodCallExpression left, ConstantExp private static SqlScalarExpression VisitStringCompare( MethodCallExpression left, - ConstantExpression right, ExpressionType compareOperator, bool reverseNodeType, TranslationContext context) diff --git a/Microsoft.Azure.Cosmos/src/Microsoft.Azure.Cosmos.csproj b/Microsoft.Azure.Cosmos/src/Microsoft.Azure.Cosmos.csproj index bd125c58ba..5a16c54a99 100644 --- a/Microsoft.Azure.Cosmos/src/Microsoft.Azure.Cosmos.csproj +++ b/Microsoft.Azure.Cosmos/src/Microsoft.Azure.Cosmos.csproj @@ -17,6 +17,7 @@ $(ClientVersion) Microsoft netstandard2.0 + true true Microsoft.Azure.Cosmos.Client Microsoft Azure Cosmos DB Client library @@ -42,6 +43,7 @@ true $(LangVersion) LICENSE + CS1572; CS1573; CS1574; CS1580 @@ -96,40 +98,31 @@ True SystemStrings.tt - - True - True - RMResources.resx - ResXFileCodeGenerator ClientResources.Designer.cs - - ResXFileCodeGenerator - RMResources.Designer.cs - Microsoft.Azure.Documents - - - - + + + + + + - - @@ -154,28 +147,31 @@ - - - TextTemplatingFileGenerator - CosmosNumberCodeGenerator.cs - - - TextTemplatingFileGenerator - JsonBinaryEncoding.SystemStrings.cs - - - - - true - true - ..\..\35MSSharedLib1024.snk - - - - TRACE;NETSTANDARD20;DOCDBCLIENT;COSMOSCLIENT;CODE_ANALYSIS;NETSTANDARD2_0 - $(DefineConstants);SignAssembly - $(DefineConstants);DelaySignKeys - $(DefineConstants);DOCDBCLIENT;COSMOSCLIENT;NETSTANDARD20 - - - \ No newline at end of file + + + TextTemplatingFileGenerator + CosmosNumberCodeGenerator.cs + + + TextTemplatingFileGenerator + JsonBinaryEncoding.SystemStrings.cs + + + + + + + + + true + true + ..\..\35MSSharedLib1024.snk + + + + $(DefineConstants);SignAssembly + $(DefineConstants);DelaySignKeys + $(DefineConstants);DOCDBCLIENT;COSMOSCLIENT;NETSTANDARD20 + + + diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/ClientDistributionPlanDeserializer.cs b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/ClientDistributionPlanDeserializer.cs new file mode 100644 index 0000000000..df19b88b3d --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/ClientDistributionPlanDeserializer.cs @@ -0,0 +1,561 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.ClientDistributionPlan +{ + using System; + using System.Collections.Generic; + using System.Reflection; + using Cql; + using Microsoft.Azure.Cosmos.CosmosElements; + + internal static class ClientDistributionPlanDeserializer + { + private static class Constants + { + public const string Arguments = "Arguments"; + public const string ArrayKind = "ArrayKind"; + public const string Aggregate = "Aggregate"; + public const string Aggregates = "Aggregates"; + public const string Builtin = "Builtin"; + public const string Cql = "Cql"; + public const string ConditionExpression = "ConditionExpression"; + public const string ClientDistributionPlan = "clientDistributionPlan"; + public const string DeclaredVariable = "DeclaredVariable"; + public const string DeclaredVariableExpression = "DeclaredVariableExpression"; + public const string Distinct = "Distinct"; + public const string EnumerationKind = "EnumerationKind"; + public const string Expression = "Expression"; + public const string FunctionKind = "FunctionKind"; + public const string GroupBy = "GroupBy"; + public const string Identifier = "Identifier"; + public const string Index = "Index"; + public const string Input = "Input"; + public const string Items = "Items"; + public const string KeyCount = "KeyCount"; + public const string Kind = "Kind"; + public const string LeftExpression = "LeftExpression"; + public const string Literal = "Literal"; + public const string MaxDepth = "MaxDepth"; + public const string Name = "Name"; + public const string ObjectKind = "ObjectKind"; + public const string OperatorKind = "OperatorKind"; + public const string Options = "Options"; + public const string OrderBy = "OrderBy"; + public const string Pattern = "Pattern"; + public const string Properties = "Properties"; + public const string PropertyName = "PropertyName"; + public const string RightExpression = "RightExpression"; + public const string ScalarAsEnumerable = "ScalarAsEnumerable"; + public const string Select = "Select"; + public const string SelectorExpression = "SelectorExpression"; + public const string SelectMany = "SelectMany"; + public const string SingletonKind = "SingletonKind"; + public const string SkipValue = "SkipValue"; + public const string SortOrder = "SortOrder"; + public const string SourceExpression = "SourceExpression"; + public const string Take = "Take"; + public const string TakeValue = "TakeValue"; + public const string Tuple = "Tuple"; + public const string Type = "Type"; + public const string UniqueId = "UniqueId"; + public const string Value = "Value"; + public const string Variable = "Variable"; + public const string Where = "Where"; + } + + public static ClientDistributionPlan DeserializeClientDistributionPlan(string jsonString) + { + CosmosObject cosmosObject = CosmosObject.Parse(jsonString); + CosmosObject clientDistributionPlanElement = GetValue(cosmosObject, Constants.ClientDistributionPlan); + CosmosObject cqlElement = GetValue(clientDistributionPlanElement, Constants.Cql); + CqlEnumerableExpression expression = DeserializeCqlEnumerableExpression(cqlElement); + + return new ClientDistributionPlan(expression); + } + + #region Enumerable Expressions + + private static CqlEnumerableExpression DeserializeCqlEnumerableExpression(CosmosObject cosmosObject) + { + CosmosString kindProperty = GetValue(cosmosObject, Constants.Kind); + switch (kindProperty.Value) + { + case Constants.Aggregate: + return DeserializeAggregateEnumerableExpression(cosmosObject); + case Constants.Distinct: + return DeserializeDistinctEnumerableExpression(cosmosObject); + case Constants.GroupBy: + return DeserializeGroupByEnumerableExpression(cosmosObject); + case Constants.Input: + return DeserializeInputEnumerableExpression(cosmosObject); + case Constants.OrderBy: + return DeserializeOrderByEnumerableExpression(cosmosObject); + case Constants.ScalarAsEnumerable: + return DeserializeScalarAsEnumerableExpression(cosmosObject); + case Constants.Select: + return DeserializeSelectEnumerableExpression(cosmosObject); + case Constants.SelectMany: + return DeserializeSelectManyEnumerableExpression(cosmosObject); + case Constants.Take: + return DeserializeTakeEnumerableExpression(cosmosObject); + case Constants.Where: + return DeserializeWhereEnumerableExpression(cosmosObject); + default: + throw new NotSupportedException($"Invalid CqlExpression kind: {kindProperty.Value}"); + } + } + + private static CqlAggregateEnumerableExpression DeserializeAggregateEnumerableExpression(CosmosObject cosmosObject) + { + CqlEnumerableExpression sourceExpression = DeserializeCqlEnumerableExpression(GetValue(cosmosObject, Constants.SourceExpression)); + CqlAggregate aggregate = DeserializeAggregate(GetValue(cosmosObject, Constants.Aggregate)); + return new CqlAggregateEnumerableExpression(sourceExpression, aggregate); + } + + private static CqlDistinctEnumerableExpression DeserializeDistinctEnumerableExpression(CosmosObject cosmosObject) + { + CqlEnumerableExpression sourceExpression = DeserializeCqlEnumerableExpression(GetValue(cosmosObject, Constants.SourceExpression)); + CqlVariable declaredVariable = DeserializeCqlVariable(GetValue(cosmosObject, Constants.DeclaredVariable)); + IReadOnlyList expressions = DeserializeScalarExpressionArray(GetValue(cosmosObject, Constants.Expression)); + return new CqlDistinctEnumerableExpression(sourceExpression, declaredVariable, expressions); + } + + private static CqlGroupByEnumerableExpression DeserializeGroupByEnumerableExpression(CosmosObject cosmosObject) + { + CqlEnumerableExpression sourceExpression = DeserializeCqlEnumerableExpression(GetValue(cosmosObject, Constants.SourceExpression)); + long keyCount = Number64.ToLong(GetValue(cosmosObject, Constants.KeyCount).Value); + IReadOnlyList aggregates = DeserializeAggregateArray(GetValue(cosmosObject, Constants.Aggregates)); + return new CqlGroupByEnumerableExpression(sourceExpression, Convert.ToUInt64(keyCount), aggregates); + } + + private static CqlInputEnumerableExpression DeserializeInputEnumerableExpression(CosmosObject cosmosObject) + { + return new CqlInputEnumerableExpression(GetValue(cosmosObject, Constants.Name).Value); + } + + private static CqlOrderByEnumerableExpression DeserializeOrderByEnumerableExpression(CosmosObject cosmosObject) + { + CqlEnumerableExpression sourceExpression = DeserializeCqlEnumerableExpression(GetValue(cosmosObject, Constants.SourceExpression)); + CqlVariable declaredVariable = DeserializeCqlVariable(GetValue(cosmosObject, Constants.DeclaredVariable)); + IReadOnlyList orderByItems = DeserializeOrderByItemArray(GetValue(cosmosObject, Constants.Items)); + return new CqlOrderByEnumerableExpression(sourceExpression, declaredVariable, orderByItems); + } + + private static CqlScalarAsEnumerableExpression DeserializeScalarAsEnumerableExpression(CosmosObject cosmosObject) + { + CqlScalarExpression expression = DeserializeScalarExpression(GetValue(cosmosObject, Constants.Expression)); + CqlEnumerationKind enumerationKind = GetEnumValue(GetValue(cosmosObject, Constants.EnumerationKind).Value); + return new CqlScalarAsEnumerableExpression(expression, enumerationKind); + } + + private static CqlSelectEnumerableExpression DeserializeSelectEnumerableExpression(CosmosObject cosmosObject) + { + CqlEnumerableExpression sourceExpression = DeserializeCqlEnumerableExpression(GetValue(cosmosObject, Constants.SourceExpression)); + CqlVariable declaredVariable = DeserializeCqlVariable(GetValue(cosmosObject, Constants.DeclaredVariable)); + CqlScalarExpression expression = DeserializeScalarExpression(GetValue(cosmosObject, Constants.Expression)); + return new CqlSelectEnumerableExpression(sourceExpression, declaredVariable, expression); + } + + private static CqlSelectManyEnumerableExpression DeserializeSelectManyEnumerableExpression(CosmosObject cosmosObject) + { + CqlEnumerableExpression sourceExpression = DeserializeCqlEnumerableExpression(GetValue(cosmosObject, Constants.SourceExpression)); + CqlVariable declaredVariable = DeserializeCqlVariable(GetValue(cosmosObject, Constants.DeclaredVariable)); + CqlEnumerableExpression selectorExpression = DeserializeCqlEnumerableExpression(GetValue(cosmosObject, Constants.SelectorExpression)); + return new CqlSelectManyEnumerableExpression(sourceExpression, declaredVariable, selectorExpression); + } + + private static CqlTakeEnumerableExpression DeserializeTakeEnumerableExpression(CosmosObject cosmosObject) + { + CqlEnumerableExpression sourceExpression = DeserializeCqlEnumerableExpression(GetValue(cosmosObject, Constants.SourceExpression)); + long skipValue = Number64.ToLong(GetValue(cosmosObject, Constants.SkipValue).Value); + long takeExpression = Number64.ToLong(GetValue(cosmosObject, Constants.TakeValue).Value); + return new CqlTakeEnumerableExpression(sourceExpression, Convert.ToUInt64(skipValue), Convert.ToUInt64(takeExpression)); + } + + private static CqlWhereEnumerableExpression DeserializeWhereEnumerableExpression(CosmosObject cosmosObject) + { + CqlEnumerableExpression sourceExpression = DeserializeCqlEnumerableExpression(GetValue(cosmosObject, Constants.SourceExpression)); + CqlVariable declaredVariable = DeserializeCqlVariable(GetValue(cosmosObject, Constants.DeclaredVariable)); + CqlScalarExpression expression = DeserializeScalarExpression(GetValue(cosmosObject, Constants.Expression)); + return new CqlWhereEnumerableExpression(sourceExpression, declaredVariable, expression); + } + + #endregion + + #region Scalar Expressions + + private static CqlScalarExpression DeserializeScalarExpression(CosmosObject cosmosObject) + { + CqlScalarExpressionKind scalarExpressionKind = GetEnumValue(GetValue(cosmosObject, Constants.Kind).Value); + switch (scalarExpressionKind) + { + case CqlScalarExpressionKind.ArrayCreate: + return DeserializeArrayCreateScalarExpression(cosmosObject); + case CqlScalarExpressionKind.ArrayIndexer: + return DeserializeArrayIndexerScalarExpression(cosmosObject); + case CqlScalarExpressionKind.BinaryOperator: + return DeserializeBinaryOperatorScalarExpression(cosmosObject); + case CqlScalarExpressionKind.IsOperator: + return DeserializeIsOperatorScalarExpression(cosmosObject); + case CqlScalarExpressionKind.Let: + return DeserializeLetScalarExpression(cosmosObject); + case CqlScalarExpressionKind.Literal: + return DeserializeLiteralScalarExpression(cosmosObject); + case CqlScalarExpressionKind.Mux: + return DeserializeMuxScalarExpression(cosmosObject); + case CqlScalarExpressionKind.ObjectCreate: + return DeserializeObjectCreateScalarExpression(cosmosObject); + case CqlScalarExpressionKind.PropertyRef: + return DeserializePropertyRefScalarExpression(cosmosObject); + case CqlScalarExpressionKind.SystemFunctionCall: + return DeserializeSystemFunctionCallScalarExpression(cosmosObject); + case CqlScalarExpressionKind.TupleCreate: + return DeserializeTupleCreateScalarExpression(cosmosObject); + case CqlScalarExpressionKind.TupleItemRef: + return DeserializeTupleItemRefScalarExpression(cosmosObject); + case CqlScalarExpressionKind.UnaryOperator: + return DeserializeUnaryScalarExpression(cosmosObject); + case CqlScalarExpressionKind.UserDefinedFunctionCall: + return DeserializeUserDefinedFunctionCallScalarExpression(cosmosObject); + case CqlScalarExpressionKind.VariableRef: + return DeserializeVariableRefScalarExpression(cosmosObject); + default: + throw new NotSupportedException($"Invalid CqlExpression kind: {scalarExpressionKind}"); + } + } + + private static CqlArrayCreateScalarExpression DeserializeArrayCreateScalarExpression(CosmosObject cosmosObject) + { + IReadOnlyList items = DeserializeScalarExpressionArray(GetValue(cosmosObject, Constants.Items)); + return new CqlArrayCreateScalarExpression(items); + } + + private static CqlArrayIndexerScalarExpression DeserializeArrayIndexerScalarExpression(CosmosObject cosmosObject) + { + CqlScalarExpression expression = DeserializeScalarExpression(GetValue(cosmosObject, Constants.Expression)); + long index = Number64.ToLong(GetValue(cosmosObject, Constants.Index).Value); + return new CqlArrayIndexerScalarExpression(expression, Convert.ToUInt64(index)); + } + + private static CqlBinaryScalarExpression DeserializeBinaryOperatorScalarExpression(CosmosObject cosmosObject) + { + CqlBinaryScalarOperatorKind operatorKind = GetEnumValue(GetValue(cosmosObject, Constants.OperatorKind).Value); + CqlScalarExpression leftExpression = DeserializeScalarExpression(GetValue(cosmosObject, Constants.LeftExpression)); + CqlScalarExpression rightExpression = DeserializeScalarExpression(GetValue(cosmosObject, Constants.RightExpression)); + return new CqlBinaryScalarExpression(operatorKind, leftExpression, rightExpression); + } + + private static CqlIsOperatorScalarExpression DeserializeIsOperatorScalarExpression(CosmosObject cosmosObject) + { + CqlIsOperatorKind operatorKind = GetEnumValue(GetValue(cosmosObject, Constants.OperatorKind).Value); + CqlScalarExpression expression = DeserializeScalarExpression(GetValue(cosmosObject, Constants.Expression)); + return new CqlIsOperatorScalarExpression(operatorKind, expression); + } + + private static CqlLetScalarExpression DeserializeLetScalarExpression(CosmosObject cosmosObject) + { + CqlVariable declaredVariable = DeserializeCqlVariable(GetValue(cosmosObject, Constants.DeclaredVariable)); + CqlScalarExpression declaredVariableExpression = DeserializeScalarExpression(GetValue(cosmosObject, Constants.DeclaredVariableExpression)); + CqlScalarExpression expression = DeserializeScalarExpression(GetValue(cosmosObject, Constants.Expression)); + return new CqlLetScalarExpression(declaredVariable, declaredVariableExpression, expression); + } + + private static CqlLiteralScalarExpression DeserializeLiteralScalarExpression(CosmosObject cosmosObject) + { + CosmosObject literalObject = GetValue(cosmosObject, Constants.Literal); + return new CqlLiteralScalarExpression(DeserializeLiteral(literalObject)); + } + + private static CqlMuxScalarExpression DeserializeMuxScalarExpression(CosmosObject cosmosObject) + { + CqlScalarExpression conditionExpression = DeserializeScalarExpression(GetValue(cosmosObject, Constants.ConditionExpression)); + CqlScalarExpression leftExpression = DeserializeScalarExpression(GetValue(cosmosObject, Constants.LeftExpression)); + CqlScalarExpression rightExpression = DeserializeScalarExpression(GetValue(cosmosObject, Constants.RightExpression)); + return new CqlMuxScalarExpression(conditionExpression, leftExpression, rightExpression); + } + + private static CqlObjectCreateScalarExpression DeserializeObjectCreateScalarExpression(CosmosObject cosmosObject) + { + IReadOnlyList properties = DeserializeObjectProperties(GetValue(cosmosObject, Constants.Properties)); + return new CqlObjectCreateScalarExpression(properties); + } + + private static CqlPropertyRefScalarExpression DeserializePropertyRefScalarExpression(CosmosObject cosmosObject) + { + CqlScalarExpression expression = DeserializeScalarExpression(GetValue(cosmosObject, Constants.Expression)); + string propertyName = GetValue(cosmosObject, Constants.PropertyName).Value; + return new CqlPropertyRefScalarExpression(expression, propertyName); + } + + private static CqlSystemFunctionCallScalarExpression DeserializeSystemFunctionCallScalarExpression(CosmosObject cosmosObject) + { + CqlBuiltinScalarFunctionKind functionKind = GetEnumValue(GetValue(cosmosObject, Constants.FunctionKind).Value); + IReadOnlyList arguments = DeserializeScalarExpressionArray(GetValue(cosmosObject, Constants.Arguments)); + return new CqlSystemFunctionCallScalarExpression(functionKind, arguments); + } + + private static CqlTupleCreateScalarExpression DeserializeTupleCreateScalarExpression(CosmosObject cosmosObject) + { + IReadOnlyList items = DeserializeScalarExpressionArray(GetValue(cosmosObject, Constants.Items)); + return new CqlTupleCreateScalarExpression(items); + } + + private static CqlTupleItemRefScalarExpression DeserializeTupleItemRefScalarExpression(CosmosObject cosmosObject) + { + CqlScalarExpression expression = DeserializeScalarExpression(GetValue(cosmosObject, Constants.Expression)); + long index = Number64.ToLong(GetValue(cosmosObject, Constants.Index).Value); + return new CqlTupleItemRefScalarExpression(expression, Convert.ToUInt64(index)); + } + + private static CqlUnaryScalarExpression DeserializeUnaryScalarExpression(CosmosObject cosmosObject) + { + CqlUnaryScalarOperatorKind operatorKind = GetEnumValue(GetValue(cosmosObject, Constants.OperatorKind).Value); + CqlScalarExpression scalarExpression = DeserializeScalarExpression(GetValue(cosmosObject, Constants.Expression)); + return new CqlUnaryScalarExpression(operatorKind, scalarExpression); + } + + private static CqlUserDefinedFunctionCallScalarExpression DeserializeUserDefinedFunctionCallScalarExpression(CosmosObject cosmosObject) + { + string identifierString = GetValue(cosmosObject, Constants.Identifier).Value; + CqlFunctionIdentifier functionIdentifier = new CqlFunctionIdentifier(identifierString); + IReadOnlyList arguments = DeserializeScalarExpressionArray(GetValue(cosmosObject, Constants.Arguments)); + bool builtin = GetValue(cosmosObject, Constants.Builtin).Value; + return new CqlUserDefinedFunctionCallScalarExpression(functionIdentifier, arguments, builtin); + } + + private static CqlVariableRefScalarExpression DeserializeVariableRefScalarExpression(CosmosObject cosmosObject) + { + CqlVariable variable = DeserializeCqlVariable(GetValue(cosmosObject, Constants.Variable)); + return new CqlVariableRefScalarExpression(variable); + } + + #endregion + + #region Aggregate + + private static IReadOnlyList DeserializeAggregateArray(CosmosArray cosmosArray) + { + List aggregates = new List(cosmosArray.Count); + foreach (CosmosElement aggregateElement in cosmosArray) + { + CosmosObject aggregateObject = CastToCosmosObject(aggregateElement); + aggregates.Add(DeserializeAggregate(aggregateObject)); + } + + return aggregates; + } + + private static CqlAggregate DeserializeAggregate(CosmosObject cosmosObject) + { + CqlAggregateKind aggregateKind = GetEnumValue(GetValue(cosmosObject, Constants.Kind).Value); + switch (aggregateKind) + { + case CqlAggregateKind.Builtin: + return DeserializeBuiltInAggregateExpression(cosmosObject); + case CqlAggregateKind.Tuple: + return DeserializeTupleAggregateExpression(cosmosObject); + default: + throw new NotSupportedException($"Invalid CqlExpression kind: {aggregateKind}"); + } + } + + private static CqlBuiltinAggregate DeserializeBuiltInAggregateExpression(CosmosObject cosmosObject) + { + CqlAggregateOperatorKind aggregateOperatorKind = GetEnumValue(GetValue(cosmosObject, Constants.OperatorKind).Value); + return new CqlBuiltinAggregate(aggregateOperatorKind); + } + + private static CqlTupleAggregate DeserializeTupleAggregateExpression(CosmosObject cosmosObject) + { + CosmosArray tupleArray = GetValue(cosmosObject, Constants.Items); + List aggregates = new List(tupleArray.Count); + + foreach (CosmosElement tupleElement in tupleArray) + { + CosmosObject tupleObject = CastToCosmosObject(tupleElement); + CqlAggregate aggregate = DeserializeAggregate(tupleObject); + aggregates.Add(aggregate); + } + + return new CqlTupleAggregate(aggregates); + } + + #endregion + + #region Literal + + private static CqlLiteral DeserializeLiteral(CosmosObject cosmosObject) + { + CqlLiteralKind literalKind = GetEnumValue(GetValue(cosmosObject, Constants.Kind).Value); + switch (literalKind) + { + case CqlLiteralKind.Array: + return new CqlArrayLiteral(DeserializeLiteralArray(GetValue(cosmosObject, Constants.Items))); + case CqlLiteralKind.Boolean: + return new CqlBooleanLiteral(GetValue(cosmosObject, Constants.Value).Value); + case CqlLiteralKind.Null: + return CqlNullLiteral.Singleton; + case CqlLiteralKind.Number: + return new CqlNumberLiteral(GetValue(cosmosObject, Constants.Value).Value); + case CqlLiteralKind.Object: + return new CqlObjectLiteral(DeserializeObjectLiteralArray(GetValue(cosmosObject, Constants.Properties))); + case CqlLiteralKind.String: + return new CqlStringLiteral(GetValue(cosmosObject, Constants.Value).Value); + case CqlLiteralKind.Undefined: + return CqlUndefinedLiteral.Singleton; + default: + throw new NotSupportedException($"Invalid CqlExpression kind: {literalKind}"); + } + } + + private static IReadOnlyList DeserializeLiteralArray(CosmosArray cosmosArray) + { + List literals = new List(cosmosArray.Count); + foreach (CosmosElement literalElement in cosmosArray) + { + CosmosObject literalObject = CastToCosmosObject(literalElement); + literals.Add(DeserializeLiteral(literalObject)); + } + + return literals; + } + + private static IReadOnlyList DeserializeObjectLiteralArray(CosmosArray cosmosArray) + { + List objectLiterals = new List(cosmosArray.Count); + foreach (CosmosElement objectLiteralElement in cosmosArray) + { + CosmosObject propertyObject = CastToCosmosObject(objectLiteralElement); + string name = GetValue(propertyObject, Constants.Name).Value; + CqlLiteral literal = DeserializeLiteral(propertyObject); + CqlObjectLiteralProperty objectLiteralProperty = new CqlObjectLiteralProperty(name, literal); + objectLiterals.Add(objectLiteralProperty); + } + + return objectLiterals; + } + + #endregion + + #region Helper Functions + + private static CqlVariable DeserializeCqlVariable(CosmosObject cosmosObject) + { + string name = GetValue(cosmosObject, Constants.Name).Value; + long uniqueId = Number64.ToLong(GetValue(cosmosObject, Constants.UniqueId).Value); + + return new CqlVariable(name, uniqueId); + } + + private static IReadOnlyList DeserializeObjectProperties(CosmosArray cosmosArray) + { + List properties = new List(cosmosArray.Count); + foreach (CosmosElement propertyElement in cosmosArray) + { + CosmosObject propertyObject = CastToCosmosObject(propertyElement); + string objectPropertyName = GetValue(propertyObject, Constants.Name).Value; + CqlScalarExpression expression = DeserializeScalarExpression(GetValue(propertyObject, Constants.Expression)); + properties.Add(new CqlObjectProperty(objectPropertyName, expression)); + } + + return properties; + } + + private static IReadOnlyList DeserializeScalarExpressionArray(CosmosArray cosmosArray) + { + List expressions = new List(cosmosArray.Count); + foreach (CosmosElement itemElement in cosmosArray) + { + CosmosObject itemObject = CastToCosmosObject(itemElement); + CqlScalarExpression expression = DeserializeScalarExpression(itemObject); + expressions.Add(expression); + } + + return expressions; + } + + private static IReadOnlyList DeserializeOrderByItemArray(CosmosArray cosmosArray) + { + List expressions = new List(cosmosArray.Count); + foreach (CosmosElement itemElement in cosmosArray) + { + CosmosObject itemObject = CastToCosmosObject(itemElement); + CqlSortOrder sortOrder = GetEnumValue(GetValue(itemObject, Constants.SortOrder).Value); + CqlScalarExpression scalarExpression = DeserializeScalarExpression(itemObject); + expressions.Add(new CqlOrderByItem(scalarExpression, sortOrder)); + } + + return expressions; + } + + private static T GetValue(CosmosObject cosmosObject, string propertyName) + where T : CosmosElement + { + bool found = TryGetValue(cosmosObject, propertyName, out T value); + + if (!found) + { + throw new InvalidOperationException($"{GetExceptionMessage()} The required property {propertyName} was not found in {cosmosObject}"); + } + + return value; + } + + private static bool TryGetValue(CosmosObject cosmosObject, string propertyName, out T result) + where T : CosmosElement + { + bool found = cosmosObject.TryGetValue(propertyName, out CosmosElement value); + + if (found && value != null) + { + result = value as T; + if (result == null) + { + throw new InvalidOperationException($"{GetExceptionMessage()} Type mismatch for property {propertyName}. Expected {typeof(T)}, Actual {value?.GetType()}"); + } + + return found; + } + + result = default(T); + return found; + } + + private static TEnum GetEnumValue(string propertyName) + where TEnum : struct + { + bool success = Enum.TryParse(propertyName, ignoreCase: true, out TEnum result); + if (!success) + { + throw new InvalidOperationException($"{GetExceptionMessage()} The string representation of {propertyName} enumerated constant was not able to be converted to an equivalent enumerated object"); + } + + return result; + } + + private static string GetExceptionMessage() + { + Version sdkVersion = Assembly.GetAssembly(typeof(CosmosClient)).GetName().Version; + string clientSDKVersion = $"{sdkVersion.Major}.{sdkVersion.Minor}.{sdkVersion.Build}"; + + return $"Exception occurred while deserializing query plan. Version : '{clientSDKVersion}', Exception/Reason : "; + } + + private static CosmosObject CastToCosmosObject(CosmosElement cosmosElement) + { + CosmosObject propertyObject = cosmosElement as CosmosObject; + if (propertyObject != null) + { + return propertyObject; + } + else + { + throw new InvalidOperationException("Unable to cast CosmosElement to CosmosObject."); + } + } + + #endregion + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/ClientDistributionPlan.cs b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/ClientDistributionPlan.cs new file mode 100644 index 0000000000..51da84c03e --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/ClientDistributionPlan.cs @@ -0,0 +1,18 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.ClientDistributionPlan.Cql +{ + using System; + + internal class ClientDistributionPlan + { + public ClientDistributionPlan(CqlEnumerableExpression cql) + { + this.Cql = cql ?? throw new ArgumentNullException(nameof(cql)); + } + + public CqlEnumerableExpression Cql { get; } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlAggregate.cs b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlAggregate.cs new file mode 100644 index 0000000000..3df9af326f --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlAggregate.cs @@ -0,0 +1,16 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.ClientDistributionPlan.Cql +{ + internal abstract class CqlAggregate + { + protected CqlAggregate(CqlAggregateKind kind) + { + this.Kind = kind; + } + + public CqlAggregateKind Kind { get; } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlAggregateEnumerableExpression.cs b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlAggregateEnumerableExpression.cs new file mode 100644 index 0000000000..eb4a09a966 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlAggregateEnumerableExpression.cs @@ -0,0 +1,22 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.ClientDistributionPlan.Cql +{ + using System; + + internal class CqlAggregateEnumerableExpression : CqlEnumerableExpression + { + public CqlAggregateEnumerableExpression(CqlEnumerableExpression sourceExpression, CqlAggregate aggregate) + : base(CqlEnumerableExpressionKind.Aggregate) + { + this.SourceExpression = sourceExpression ?? throw new ArgumentNullException(nameof(sourceExpression)); + this.Aggregate = aggregate ?? throw new ArgumentNullException(nameof(aggregate)); + } + + public CqlEnumerableExpression SourceExpression { get; } + + public CqlAggregate Aggregate { get; } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlAggregateKind.cs b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlAggregateKind.cs new file mode 100644 index 0000000000..c25ae41bb8 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlAggregateKind.cs @@ -0,0 +1,12 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.ClientDistributionPlan.Cql +{ + internal enum CqlAggregateKind + { + Builtin, + Tuple, + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlAggregateOperatorKind.cs b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlAggregateOperatorKind.cs new file mode 100644 index 0000000000..57c1955b74 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlAggregateOperatorKind.cs @@ -0,0 +1,19 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.ClientDistributionPlan.Cql +{ + internal enum CqlAggregateOperatorKind + { + All, + Any, + Array, + Count, + First, + Last, + Max, + Min, + Sum, + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlArrayCreateScalarExpression.cs b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlArrayCreateScalarExpression.cs new file mode 100644 index 0000000000..84b829179c --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlArrayCreateScalarExpression.cs @@ -0,0 +1,25 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.ClientDistributionPlan.Cql +{ + using System; + using System.Collections.Generic; + + internal class CqlArrayCreateScalarExpression : CqlScalarExpression + { + private const string Array = "Array"; + + public CqlArrayCreateScalarExpression(IReadOnlyList items) + : base(CqlScalarExpressionKind.ArrayCreate) + { + this.ArrayKind = Array; + this.Items = items ?? throw new ArgumentNullException(nameof(items)); + } + + public string ArrayKind { get; } + + public IReadOnlyList Items { get; } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlArrayIndexerScalarExpression.cs b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlArrayIndexerScalarExpression.cs new file mode 100644 index 0000000000..65d280a02e --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlArrayIndexerScalarExpression.cs @@ -0,0 +1,22 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.ClientDistributionPlan.Cql +{ + using System; + + internal class CqlArrayIndexerScalarExpression : CqlScalarExpression + { + public CqlArrayIndexerScalarExpression(CqlScalarExpression expression, ulong index) + : base(CqlScalarExpressionKind.ArrayIndexer) + { + this.Expression = expression ?? throw new ArgumentNullException(nameof(expression)); + this.Index = index; + } + + public CqlScalarExpression Expression { get; } + + public ulong Index { get; } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlArrayLiteral.cs b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlArrayLiteral.cs new file mode 100644 index 0000000000..a50036123d --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlArrayLiteral.cs @@ -0,0 +1,20 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.ClientDistributionPlan.Cql +{ + using System; + using System.Collections.Generic; + + internal class CqlArrayLiteral : CqlLiteral + { + public CqlArrayLiteral(IReadOnlyList items) + : base(CqlLiteralKind.Array) + { + this.Items = items ?? throw new ArgumentNullException(nameof(items)); + } + + public IReadOnlyList Items { get; } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlBinaryScalarExpression.cs b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlBinaryScalarExpression.cs new file mode 100644 index 0000000000..9f3a382fd0 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlBinaryScalarExpression.cs @@ -0,0 +1,25 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.ClientDistributionPlan.Cql +{ + using System; + + internal class CqlBinaryScalarExpression : CqlScalarExpression + { + public CqlBinaryScalarExpression(CqlBinaryScalarOperatorKind operatorKind, CqlScalarExpression leftExpression, CqlScalarExpression rightExpression) + : base(CqlScalarExpressionKind.BinaryOperator) + { + this.OperatorKind = operatorKind; + this.LeftExpression = leftExpression ?? throw new ArgumentNullException(nameof(leftExpression)); + this.RightExpression = rightExpression ?? throw new ArgumentNullException(nameof(rightExpression)); + } + + public CqlBinaryScalarOperatorKind OperatorKind { get; } + + public CqlScalarExpression LeftExpression { get; } + + public CqlScalarExpression RightExpression { get; } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlBinaryScalarOperatorKind.cs b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlBinaryScalarOperatorKind.cs new file mode 100644 index 0000000000..c41a740994 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlBinaryScalarOperatorKind.cs @@ -0,0 +1,29 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.ClientDistributionPlan.Cql +{ + internal enum CqlBinaryScalarOperatorKind + { + Add, + And, + BitwiseAnd, + BitwiseOr, + BitwiseXor, + Divide, + Equal, + GreaterThan, + GreaterThanOrEqual, + LeftShift, + LessThan, + LessThanOrEqual, + Modulo, + Multiply, + NotEqual, + Or, + RightShift, + Subtract, + ZeroFillRightShift + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlBooleanLiteral.cs b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlBooleanLiteral.cs new file mode 100644 index 0000000000..06f06b4e64 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlBooleanLiteral.cs @@ -0,0 +1,17 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.ClientDistributionPlan.Cql +{ + internal class CqlBooleanLiteral : CqlLiteral + { + public CqlBooleanLiteral(bool value) + : base(CqlLiteralKind.Boolean) + { + this.Value = value; + } + + public bool Value { get; } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlBuiltinAggregate.cs b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlBuiltinAggregate.cs new file mode 100644 index 0000000000..8dcebf5bb8 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlBuiltinAggregate.cs @@ -0,0 +1,17 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.ClientDistributionPlan.Cql +{ + internal class CqlBuiltinAggregate : CqlAggregate + { + public CqlBuiltinAggregate(CqlAggregateOperatorKind operatorKind) + : base(CqlAggregateKind.Builtin) + { + this.OperatorKind = operatorKind; + } + + public CqlAggregateOperatorKind OperatorKind { get; } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlBuiltinScalarFunctionKind.cs b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlBuiltinScalarFunctionKind.cs new file mode 100644 index 0000000000..ae59e55cf1 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlBuiltinScalarFunctionKind.cs @@ -0,0 +1,126 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.ClientDistributionPlan.Cql +{ + internal enum CqlBuiltinScalarFunctionKind + { + Abs, + Acos, + All, + Any, + Array, + Array_Concat, + Array_Contains, + Array_Length, + Array_Slice, + Asin, + Atan, + Atn2, + Avg, + Ceiling, + Choose, + Concat, + Contains, + Cos, + Cot, + Count, + DateTimeAdd, + DateTimeBin, + DateTimeDiff, + DateTimeFromParts, + DateTimePart, + DateTimeToTicks, + DateTimeToTimestamp, + Degrees, + DocumentId, + EndsWith, + Exp, + First, + Floor, + GetCurrentDateTime, + GetCurrentDateTimeStatic, + GetCurrentTicks, + GetCurrentTicksStatic, + GetCurrentTimestamp, + GetCurrentTimestampStatic, + Iif, + Index_Of, + IntAdd, + IntBitAnd, + IntBitLeftShift, + IntBitNot, + IntBitOr, + IntBitRightShift, + IntBitXor, + IntDiv, + IntMod, + IntMul, + IntSub, + Is_Array, + Is_Bool, + Is_DateTime, + Is_Defined, + Is_Finite_Number, + Is_Integer, + Is_Null, + Is_Number, + Is_Object, + Is_Primitive, + Is_String, + Last, + LastIndexOf, + Left, + Length, + Like, + Log, + Log10, + Lower, + Ltrim, + Max, + Min, + NumberBin, + ObjectToArray, + Pi, + Power, + Radians, + Rand, + RegexMatch, + Replace, + Replicate, + Reverse, + Right, + Round, + Rtrim, + SetDifference, + SetIntersect, + SetUnion, + Sign, + Sin, + Sqrt, + Square, + ST_Area, + ST_Distance, + ST_Intersects, + ST_IsValid, + ST_IsValidDetailed, + ST_Within, + StartsWith, + StringEquals, + StringToArray, + StringToBoolean, + StringToNull, + StringToNumber, + StringToObject, + Substring, + Sum, + Tan, + TicksToDateTime, + TimestampToDateTime, + ToString, + Trim, + Trunc, + Upper + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlDistinctEnumerableExpression.cs b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlDistinctEnumerableExpression.cs new file mode 100644 index 0000000000..8fa7515235 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlDistinctEnumerableExpression.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.ClientDistributionPlan.Cql +{ + using System; + using System.Collections.Generic; + + internal class CqlDistinctEnumerableExpression : CqlEnumerableExpression + { + public CqlDistinctEnumerableExpression(CqlEnumerableExpression sourceExpression, CqlVariable declaredVariable, IReadOnlyList expression) + : base(CqlEnumerableExpressionKind.Distinct) + { + this.SourceExpression = sourceExpression ?? throw new ArgumentNullException(nameof(sourceExpression)); + this.DeclaredVariable = declaredVariable ?? throw new ArgumentNullException(nameof(declaredVariable)); + this.Expression = expression ?? throw new ArgumentNullException(nameof(expression)); + } + + public CqlEnumerableExpression SourceExpression { get; } + + public CqlVariable DeclaredVariable { get; } + + public IReadOnlyList Expression { get; } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlEnumerableExpression.cs b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlEnumerableExpression.cs new file mode 100644 index 0000000000..7b30bdc629 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlEnumerableExpression.cs @@ -0,0 +1,16 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.ClientDistributionPlan.Cql +{ + internal abstract class CqlEnumerableExpression + { + protected CqlEnumerableExpression(CqlEnumerableExpressionKind kind) + { + this.Kind = kind; + } + + public CqlEnumerableExpressionKind Kind { get; } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlEnumerableExpressionKind.cs b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlEnumerableExpressionKind.cs new file mode 100644 index 0000000000..11b135895d --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlEnumerableExpressionKind.cs @@ -0,0 +1,20 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.ClientDistributionPlan.Cql +{ + internal enum CqlEnumerableExpressionKind + { + Aggregate, + Distinct, + GroupBy, + Input, + OrderBy, + ScalarAsEnumerable, + Select, + SelectMany, + Take, + Where, + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlEnumerationKind.cs b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlEnumerationKind.cs new file mode 100644 index 0000000000..60d96d2703 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlEnumerationKind.cs @@ -0,0 +1,14 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.ClientDistributionPlan.Cql +{ + internal enum CqlEnumerationKind + { + ArrayItems, + PropertyValues, + Children, + Descendants, + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlFunctionIdentifier.cs b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlFunctionIdentifier.cs new file mode 100644 index 0000000000..16a717bdfe --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlFunctionIdentifier.cs @@ -0,0 +1,18 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.ClientDistributionPlan.Cql +{ + using System; + + internal class CqlFunctionIdentifier + { + public CqlFunctionIdentifier(string name) + { + this.Name = name ?? throw new ArgumentNullException(nameof(name)); + } + + public string Name { get; } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlGroupByEnumerableExpression.cs b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlGroupByEnumerableExpression.cs new file mode 100644 index 0000000000..b3efe8cb5d --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlGroupByEnumerableExpression.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.ClientDistributionPlan.Cql +{ + using System; + using System.Collections.Generic; + + internal class CqlGroupByEnumerableExpression : CqlEnumerableExpression + { + public CqlGroupByEnumerableExpression(CqlEnumerableExpression sourceExpression, ulong keyCount, IReadOnlyList aggregates) + : base(CqlEnumerableExpressionKind.GroupBy) + { + this.SourceExpression = sourceExpression ?? throw new ArgumentNullException(nameof(sourceExpression)); + this.KeyCount = keyCount; + this.Aggregates = aggregates ?? throw new ArgumentNullException(nameof(aggregates)); + } + + public CqlEnumerableExpression SourceExpression { get; } + + public ulong KeyCount { get; } + + public IReadOnlyList Aggregates { get; } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlInputEnumerableExpression.cs b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlInputEnumerableExpression.cs new file mode 100644 index 0000000000..a9a1ba8d6f --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlInputEnumerableExpression.cs @@ -0,0 +1,19 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.ClientDistributionPlan.Cql +{ + using System; + + internal class CqlInputEnumerableExpression : CqlEnumerableExpression + { + public CqlInputEnumerableExpression(string name) + : base(CqlEnumerableExpressionKind.Input) + { + this.Name = name ?? throw new ArgumentNullException(nameof(name)); + } + + public string Name { get; } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlIsOperatorKind.cs b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlIsOperatorKind.cs new file mode 100644 index 0000000000..84a8e17601 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlIsOperatorKind.cs @@ -0,0 +1,11 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.ClientDistributionPlan.Cql +{ + internal enum CqlIsOperatorKind + { + Defined, + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlIsOperatorScalarExpression.cs b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlIsOperatorScalarExpression.cs new file mode 100644 index 0000000000..c1aa03907d --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlIsOperatorScalarExpression.cs @@ -0,0 +1,23 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.ClientDistributionPlan.Cql +{ + using System; + using System.Collections.Generic; + + internal class CqlIsOperatorScalarExpression : CqlScalarExpression + { + public CqlIsOperatorScalarExpression(CqlIsOperatorKind operatorKind, CqlScalarExpression expression) + : base(CqlScalarExpressionKind.IsOperator) + { + this.OperatorKind = operatorKind; + this.Expression = expression ?? throw new ArgumentNullException(nameof(expression)); + } + + public CqlIsOperatorKind OperatorKind { get; } + + public CqlScalarExpression Expression { get; } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlLetScalarExpression.cs b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlLetScalarExpression.cs new file mode 100644 index 0000000000..329e2f36cd --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlLetScalarExpression.cs @@ -0,0 +1,25 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.ClientDistributionPlan.Cql +{ + using System; + + internal class CqlLetScalarExpression : CqlScalarExpression + { + public CqlLetScalarExpression(CqlVariable declaredVariable, CqlScalarExpression declaredVariableExpression, CqlScalarExpression expression) + : base(CqlScalarExpressionKind.Let) + { + this.DeclaredVariable = declaredVariable ?? throw new ArgumentNullException(nameof(declaredVariable)); + this.DeclaredVariableExpression = declaredVariableExpression ?? throw new ArgumentNullException(nameof(declaredVariableExpression)); + this.Expression = expression ?? throw new ArgumentNullException(nameof(expression)); + } + + public CqlVariable DeclaredVariable { get; } + + public CqlScalarExpression DeclaredVariableExpression { get; } + + public CqlScalarExpression Expression { get; } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlLiteral.cs b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlLiteral.cs new file mode 100644 index 0000000000..d5b17b06ac --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlLiteral.cs @@ -0,0 +1,16 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.ClientDistributionPlan.Cql +{ + internal abstract class CqlLiteral + { + protected CqlLiteral(CqlLiteralKind kind) + { + this.Kind = kind; + } + + public CqlLiteralKind Kind { get; } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlLiteralKind.cs b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlLiteralKind.cs new file mode 100644 index 0000000000..e03b18a28a --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlLiteralKind.cs @@ -0,0 +1,17 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.ClientDistributionPlan.Cql +{ + internal enum CqlLiteralKind + { + Undefined, + Array, + Boolean, + Null, + Number, + Object, + String, + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlLiteralScalarExpression.cs b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlLiteralScalarExpression.cs new file mode 100644 index 0000000000..ebc82d9048 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlLiteralScalarExpression.cs @@ -0,0 +1,19 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.ClientDistributionPlan.Cql +{ + using System; + + internal class CqlLiteralScalarExpression : CqlScalarExpression + { + public CqlLiteralScalarExpression(CqlLiteral literal) + : base(CqlScalarExpressionKind.Literal) + { + this.Literal = literal ?? throw new ArgumentNullException(nameof(literal)); + } + + public CqlLiteral Literal { get; } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlMuxScalarExpression.cs b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlMuxScalarExpression.cs new file mode 100644 index 0000000000..0ebb3cab53 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlMuxScalarExpression.cs @@ -0,0 +1,25 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.ClientDistributionPlan.Cql +{ + using System; + + internal class CqlMuxScalarExpression : CqlScalarExpression + { + public CqlMuxScalarExpression(CqlScalarExpression conditionExpression, CqlScalarExpression leftExpression, CqlScalarExpression rightExpression) + : base(CqlScalarExpressionKind.Mux) + { + this.ConditionExpression = conditionExpression ?? throw new ArgumentNullException(nameof(conditionExpression)); + this.LeftExpression = leftExpression ?? throw new ArgumentNullException(nameof(leftExpression)); + this.RightExpression = rightExpression ?? throw new ArgumentNullException(nameof(rightExpression)); + } + + public CqlScalarExpression ConditionExpression { get; } + + public CqlScalarExpression LeftExpression { get; } + + public CqlScalarExpression RightExpression { get; } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlNullLiteral.cs b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlNullLiteral.cs new file mode 100644 index 0000000000..53696840b1 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlNullLiteral.cs @@ -0,0 +1,16 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.ClientDistributionPlan.Cql +{ + internal class CqlNullLiteral : CqlLiteral + { + public static readonly CqlNullLiteral Singleton = new CqlNullLiteral(); + + private CqlNullLiteral() + : base(CqlLiteralKind.Null) + { + } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlNumberLiteral.cs b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlNumberLiteral.cs new file mode 100644 index 0000000000..28769462d7 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlNumberLiteral.cs @@ -0,0 +1,19 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.ClientDistributionPlan.Cql +{ + using System.Collections.Generic; + + internal class CqlNumberLiteral : CqlLiteral + { + public CqlNumberLiteral(Number64 value) + : base(CqlLiteralKind.Number) + { + this.Value = value; + } + + public Number64 Value { get; } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlObjectCreateScalarExpression.cs b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlObjectCreateScalarExpression.cs new file mode 100644 index 0000000000..1bcd44e106 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlObjectCreateScalarExpression.cs @@ -0,0 +1,25 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.ClientDistributionPlan.Cql +{ + using System; + using System.Collections.Generic; + + internal class CqlObjectCreateScalarExpression : CqlScalarExpression + { + private const string Object = "Object"; + + public CqlObjectCreateScalarExpression(IReadOnlyList properties) + : base(CqlScalarExpressionKind.ObjectCreate) + { + this.Properties = properties ?? throw new ArgumentNullException(nameof(properties)); + this.ObjectKind = Object; + } + + public IReadOnlyList Properties { get; } + + public string ObjectKind { get; } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlObjectLiteral.cs b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlObjectLiteral.cs new file mode 100644 index 0000000000..e5ba8ff343 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlObjectLiteral.cs @@ -0,0 +1,20 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.ClientDistributionPlan.Cql +{ + using System; + using System.Collections.Generic; + + internal class CqlObjectLiteral : CqlLiteral + { + public CqlObjectLiteral(IReadOnlyList properties) + : base(CqlLiteralKind.Object) + { + this.Properties = properties ?? throw new ArgumentNullException(nameof(properties)); + } + + public IReadOnlyList Properties { get; } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlObjectLiteralProperty.cs b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlObjectLiteralProperty.cs new file mode 100644 index 0000000000..4a063d4449 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlObjectLiteralProperty.cs @@ -0,0 +1,21 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.ClientDistributionPlan.Cql +{ + using System; + + internal class CqlObjectLiteralProperty + { + public CqlObjectLiteralProperty(string name, CqlLiteral literal) + { + this.Name = name ?? throw new ArgumentNullException(nameof(name)); + this.Literal = literal ?? throw new ArgumentNullException(nameof(literal)); + } + + public string Name { get; } + + public CqlLiteral Literal { get; } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlObjectProperty.cs b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlObjectProperty.cs new file mode 100644 index 0000000000..7b97de1620 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlObjectProperty.cs @@ -0,0 +1,21 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.ClientDistributionPlan.Cql +{ + using System; + + internal class CqlObjectProperty + { + public CqlObjectProperty(string name, CqlScalarExpression expression) + { + this.Name = name ?? throw new ArgumentNullException(nameof(name)); + this.Expression = expression ?? throw new ArgumentNullException(nameof(expression)); + } + + public string Name { get; } + + public CqlScalarExpression Expression { get; } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlOrderByEnumerableExpression.cs b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlOrderByEnumerableExpression.cs new file mode 100644 index 0000000000..b4b9603841 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlOrderByEnumerableExpression.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.ClientDistributionPlan.Cql +{ + using System; + using System.Collections.Generic; + + internal class CqlOrderByEnumerableExpression : CqlEnumerableExpression + { + public CqlOrderByEnumerableExpression(CqlEnumerableExpression sourceExpression, CqlVariable declaredVariable, IReadOnlyList items) + : base(CqlEnumerableExpressionKind.OrderBy) + { + this.SourceExpression = sourceExpression ?? throw new ArgumentNullException(nameof(sourceExpression)); + this.DeclaredVariable = declaredVariable ?? throw new ArgumentNullException(nameof(declaredVariable)); + this.Items = items ?? throw new ArgumentNullException(nameof(items)); + } + + public CqlEnumerableExpression SourceExpression { get; } + + public CqlVariable DeclaredVariable { get; } + + public IReadOnlyList Items { get; } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlOrderByItem.cs b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlOrderByItem.cs new file mode 100644 index 0000000000..8fb4a73810 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlOrderByItem.cs @@ -0,0 +1,21 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.ClientDistributionPlan.Cql +{ + using System; + + internal class CqlOrderByItem + { + public CqlOrderByItem(CqlScalarExpression expression, CqlSortOrder sortOrder) + { + this.Expression = expression ?? throw new ArgumentNullException(nameof(expression)); + this.SortOrder = sortOrder; + } + + public CqlScalarExpression Expression { get; } + + public CqlSortOrder SortOrder { get; } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlPropertyRefScalarExpression.cs b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlPropertyRefScalarExpression.cs new file mode 100644 index 0000000000..e93a31fe3e --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlPropertyRefScalarExpression.cs @@ -0,0 +1,23 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.ClientDistributionPlan.Cql +{ + using System; + using System.Collections.Generic; + + internal class CqlPropertyRefScalarExpression : CqlScalarExpression + { + public CqlPropertyRefScalarExpression(CqlScalarExpression expression, string propertyName) + : base(CqlScalarExpressionKind.PropertyRef) + { + this.Expression = expression ?? throw new ArgumentNullException(nameof(expression)); + this.PropertyName = propertyName ?? throw new ArgumentNullException(nameof(propertyName)); + } + + public CqlScalarExpression Expression { get; } + + public string PropertyName { get; } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlScalarAsEnumerableExpression.cs b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlScalarAsEnumerableExpression.cs new file mode 100644 index 0000000000..0d69d8b424 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlScalarAsEnumerableExpression.cs @@ -0,0 +1,22 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.ClientDistributionPlan.Cql +{ + using System; + + internal class CqlScalarAsEnumerableExpression : CqlEnumerableExpression + { + public CqlScalarAsEnumerableExpression(CqlScalarExpression expression, CqlEnumerationKind enumerationKind) + : base(CqlEnumerableExpressionKind.ScalarAsEnumerable) + { + this.Expression = expression ?? throw new ArgumentNullException(nameof(expression)); + this.EnumerationKind = enumerationKind; + } + + public CqlScalarExpression Expression { get; } + + public CqlEnumerationKind EnumerationKind { get; } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlScalarExpression.cs b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlScalarExpression.cs new file mode 100644 index 0000000000..659bdc5f58 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlScalarExpression.cs @@ -0,0 +1,16 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.ClientDistributionPlan.Cql +{ + internal abstract class CqlScalarExpression + { + protected CqlScalarExpression(CqlScalarExpressionKind kind) + { + this.Kind = kind; + } + + public CqlScalarExpressionKind Kind { get; } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlScalarExpressionKind.cs b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlScalarExpressionKind.cs new file mode 100644 index 0000000000..fede841576 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlScalarExpressionKind.cs @@ -0,0 +1,25 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.ClientDistributionPlan.Cql +{ + internal enum CqlScalarExpressionKind + { + ArrayCreate, + ArrayIndexer, + BinaryOperator, + IsOperator, + Let, + Literal, + Mux, + ObjectCreate, + PropertyRef, + SystemFunctionCall, + TupleCreate, + TupleItemRef, + UnaryOperator, + UserDefinedFunctionCall, + VariableRef, + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlSelectEnumerableExpression.cs b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlSelectEnumerableExpression.cs new file mode 100644 index 0000000000..0d052e980b --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlSelectEnumerableExpression.cs @@ -0,0 +1,25 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.ClientDistributionPlan.Cql +{ + using System; + + internal class CqlSelectEnumerableExpression : CqlEnumerableExpression + { + public CqlSelectEnumerableExpression(CqlEnumerableExpression sourceExpression, CqlVariable declaredVariable, CqlScalarExpression expression) + : base(CqlEnumerableExpressionKind.Select) + { + this.SourceExpression = sourceExpression ?? throw new ArgumentNullException(nameof(sourceExpression)); + this.DeclaredVariable = declaredVariable ?? throw new ArgumentNullException(nameof(declaredVariable)); + this.Expression = expression ?? throw new ArgumentNullException(nameof(expression)); + } + + public CqlEnumerableExpression SourceExpression { get; } + + public CqlVariable DeclaredVariable { get; } + + public CqlScalarExpression Expression { get; } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlSelectManyEnumerableExpression.cs b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlSelectManyEnumerableExpression.cs new file mode 100644 index 0000000000..e34d4ba874 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlSelectManyEnumerableExpression.cs @@ -0,0 +1,25 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.ClientDistributionPlan.Cql +{ + using System; + + internal class CqlSelectManyEnumerableExpression : CqlEnumerableExpression + { + public CqlSelectManyEnumerableExpression(CqlEnumerableExpression sourceExpression, CqlVariable declaredVariable, CqlEnumerableExpression selectorExpression) + : base(CqlEnumerableExpressionKind.SelectMany) + { + this.SourceExpression = sourceExpression ?? throw new ArgumentNullException(nameof(sourceExpression)); + this.DeclaredVariable = declaredVariable ?? throw new ArgumentNullException(nameof(declaredVariable)); + this.SelectorExpression = selectorExpression ?? throw new ArgumentNullException(nameof(selectorExpression)); + } + + public CqlEnumerableExpression SourceExpression { get; } + + public CqlVariable DeclaredVariable { get; } + + public CqlEnumerableExpression SelectorExpression { get; } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlSortOrder.cs b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlSortOrder.cs new file mode 100644 index 0000000000..efd5aaeb42 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlSortOrder.cs @@ -0,0 +1,12 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.ClientDistributionPlan.Cql +{ + internal enum CqlSortOrder + { + Ascending, + Descending + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlStringLiteral.cs b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlStringLiteral.cs new file mode 100644 index 0000000000..a20947b0dd --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlStringLiteral.cs @@ -0,0 +1,19 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.ClientDistributionPlan.Cql +{ + using System; + + internal class CqlStringLiteral : CqlLiteral + { + public CqlStringLiteral(string value) + : base(CqlLiteralKind.String) + { + this.Value = value ?? throw new ArgumentNullException(nameof(value)); + } + + public string Value { get; } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlSystemFunctionCallScalarExpression.cs b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlSystemFunctionCallScalarExpression.cs new file mode 100644 index 0000000000..d42ee09f15 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlSystemFunctionCallScalarExpression.cs @@ -0,0 +1,23 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.ClientDistributionPlan.Cql +{ + using System; + using System.Collections.Generic; + + internal class CqlSystemFunctionCallScalarExpression : CqlScalarExpression + { + public CqlSystemFunctionCallScalarExpression(CqlBuiltinScalarFunctionKind functionKind, IReadOnlyList arguments) + : base(CqlScalarExpressionKind.SystemFunctionCall) + { + this.FunctionKind = functionKind; + this.Arguments = arguments ?? throw new ArgumentNullException(nameof(arguments)); + } + + public CqlBuiltinScalarFunctionKind FunctionKind { get; } + + public IReadOnlyList Arguments { get; } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlTakeEnumerableExpression.cs b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlTakeEnumerableExpression.cs new file mode 100644 index 0000000000..0391db64fd --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlTakeEnumerableExpression.cs @@ -0,0 +1,25 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.ClientDistributionPlan.Cql +{ + using System; + + internal class CqlTakeEnumerableExpression : CqlEnumerableExpression + { + public CqlTakeEnumerableExpression(CqlEnumerableExpression sourceExpression, ulong skipValue, ulong takeValue) + : base(CqlEnumerableExpressionKind.Take) + { + this.SourceExpression = sourceExpression ?? throw new ArgumentNullException(nameof(sourceExpression)); + this.SkipValue = skipValue; + this.TakeValue = takeValue; + } + + public CqlEnumerableExpression SourceExpression { get; } + + public ulong SkipValue { get; } + + public ulong TakeValue { get; } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlTupleAggregate.cs b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlTupleAggregate.cs new file mode 100644 index 0000000000..6f553c1ec8 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlTupleAggregate.cs @@ -0,0 +1,20 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.ClientDistributionPlan.Cql +{ + using System; + using System.Collections.Generic; + + internal class CqlTupleAggregate : CqlAggregate + { + public CqlTupleAggregate(IReadOnlyList items) + : base(CqlAggregateKind.Tuple) + { + this.Items = items ?? throw new ArgumentNullException(nameof(items)); + } + + public IReadOnlyList Items { get; } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlTupleCreateScalarExpression.cs b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlTupleCreateScalarExpression.cs new file mode 100644 index 0000000000..0c30e79d33 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlTupleCreateScalarExpression.cs @@ -0,0 +1,20 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.ClientDistributionPlan.Cql +{ + using System; + using System.Collections.Generic; + + internal class CqlTupleCreateScalarExpression : CqlScalarExpression + { + public CqlTupleCreateScalarExpression(IReadOnlyList items) + : base(CqlScalarExpressionKind.TupleCreate) + { + this.Items = items ?? throw new ArgumentNullException(nameof(items)); + } + + public IReadOnlyList Items { get; } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlTupleItemRefScalarExpression.cs b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlTupleItemRefScalarExpression.cs new file mode 100644 index 0000000000..bc011cecf7 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlTupleItemRefScalarExpression.cs @@ -0,0 +1,22 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.ClientDistributionPlan.Cql +{ + using System; + + internal class CqlTupleItemRefScalarExpression : CqlScalarExpression + { + public CqlTupleItemRefScalarExpression(CqlScalarExpression expression, ulong index) + : base(CqlScalarExpressionKind.TupleItemRef) + { + this.Expression = expression ?? throw new ArgumentNullException(nameof(expression)); + this.Index = index; + } + + public CqlScalarExpression Expression { get; } + + public ulong Index { get; } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlUnaryScalarExpression.cs b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlUnaryScalarExpression.cs new file mode 100644 index 0000000000..8131ea618d --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlUnaryScalarExpression.cs @@ -0,0 +1,22 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.ClientDistributionPlan.Cql +{ + using System; + + internal class CqlUnaryScalarExpression : CqlScalarExpression + { + public CqlUnaryScalarExpression(CqlUnaryScalarOperatorKind operatorKind, CqlScalarExpression expression) + : base(CqlScalarExpressionKind.UnaryOperator) + { + this.OperatorKind = operatorKind; + this.Expression = expression ?? throw new ArgumentNullException(nameof(expression)); + } + + public CqlUnaryScalarOperatorKind OperatorKind { get; } + + public CqlScalarExpression Expression { get; } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlUnaryScalarOperatorKind.cs b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlUnaryScalarOperatorKind.cs new file mode 100644 index 0000000000..30c0cedc54 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlUnaryScalarOperatorKind.cs @@ -0,0 +1,14 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.ClientDistributionPlan.Cql +{ + internal enum CqlUnaryScalarOperatorKind + { + BitwiseNot, + Minus, + Not, + Plus + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlUndefinedLiteral.cs b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlUndefinedLiteral.cs new file mode 100644 index 0000000000..ecc8d556b2 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlUndefinedLiteral.cs @@ -0,0 +1,16 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.ClientDistributionPlan.Cql +{ + internal class CqlUndefinedLiteral : CqlLiteral + { + public static readonly CqlUndefinedLiteral Singleton = new CqlUndefinedLiteral(); + + private CqlUndefinedLiteral() + : base(CqlLiteralKind.Undefined) + { + } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlUserDefinedFunctionCallScalarExpression.cs b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlUserDefinedFunctionCallScalarExpression.cs new file mode 100644 index 0000000000..fda301a6a1 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlUserDefinedFunctionCallScalarExpression.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.ClientDistributionPlan.Cql +{ + using System; + using System.Collections.Generic; + + internal class CqlUserDefinedFunctionCallScalarExpression : CqlScalarExpression + { + public CqlUserDefinedFunctionCallScalarExpression(CqlFunctionIdentifier identifier, IReadOnlyList arguments, bool builtin) + : base(CqlScalarExpressionKind.UserDefinedFunctionCall) + { + this.Identifier = identifier ?? throw new ArgumentNullException(nameof(identifier)); + this.Arguments = arguments ?? throw new ArgumentNullException(nameof(arguments)); + this.Builtin = builtin; + } + + public CqlFunctionIdentifier Identifier { get; } + + public IReadOnlyList Arguments { get; } + + public bool Builtin { get; } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlVariable.cs b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlVariable.cs new file mode 100644 index 0000000000..73cbac8324 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlVariable.cs @@ -0,0 +1,21 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.ClientDistributionPlan.Cql +{ + using System; + + internal class CqlVariable + { + public CqlVariable(string name, long uniqueId) + { + this.Name = name ?? throw new ArgumentNullException(nameof(name)); + this.UniqueId = uniqueId; + } + + public string Name { get; } + + public long UniqueId { get; } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlVariableRefScalarExpression.cs b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlVariableRefScalarExpression.cs new file mode 100644 index 0000000000..a909fb39a1 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlVariableRefScalarExpression.cs @@ -0,0 +1,19 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.ClientDistributionPlan.Cql +{ + using System; + + internal class CqlVariableRefScalarExpression : CqlScalarExpression + { + public CqlVariableRefScalarExpression(CqlVariable variable) + : base(CqlScalarExpressionKind.VariableRef) + { + this.Variable = variable ?? throw new ArgumentNullException(nameof(variable)); + } + + public CqlVariable Variable { get; } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlWhereEnumerableExpression.cs b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlWhereEnumerableExpression.cs new file mode 100644 index 0000000000..3f6db64aa2 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/ClientDistributionPlan/Cql/CqlWhereEnumerableExpression.cs @@ -0,0 +1,25 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.ClientDistributionPlan.Cql +{ + using System; + + internal class CqlWhereEnumerableExpression : CqlEnumerableExpression + { + public CqlWhereEnumerableExpression(CqlEnumerableExpression sourceExpression, CqlVariable declaredVariable, CqlScalarExpression expression) + : base(CqlEnumerableExpressionKind.Where) + { + this.SourceExpression = sourceExpression ?? throw new ArgumentNullException(nameof(sourceExpression)); + this.DeclaredVariable = declaredVariable ?? throw new ArgumentNullException(nameof(declaredVariable)); + this.Expression = expression ?? throw new ArgumentNullException(nameof(expression)); + } + + public CqlEnumerableExpression SourceExpression { get; } + + public CqlVariable DeclaredVariable { get; } + + public CqlScalarExpression Expression { get; } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/BackendMetrics.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/BackendMetrics.cs deleted file mode 100644 index e958aee949..0000000000 --- a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/BackendMetrics.cs +++ /dev/null @@ -1,237 +0,0 @@ -//------------------------------------------------------------ -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------ - -namespace Microsoft.Azure.Cosmos.Query.Core.Metrics -{ - using System; - using System.Collections.Generic; - - /// - /// Metrics received for queries from the backend. - /// -#if INTERNAL -#pragma warning disable SA1600 -#pragma warning disable CS1591 - public -#else - internal -#endif - sealed class BackendMetrics - { - /// - /// QueryMetrics that with all members having default (but not null) members. - /// - public static readonly BackendMetrics Empty = new BackendMetrics( - retrievedDocumentCount: default, - retrievedDocumentSize: default, - outputDocumentCount: default, - outputDocumentSize: default, - indexHitRatio: default, - totalQueryExecutionTime: default, - queryPreparationTimes: QueryPreparationTimes.Zero, - indexLookupTime: default, - documentLoadTime: default, - vmExecutionTime: default, - runtimeExecutionTimes: RuntimeExecutionTimes.Empty, - documentWriteTime: default); - - public BackendMetrics( - long retrievedDocumentCount, - long retrievedDocumentSize, - long outputDocumentCount, - long outputDocumentSize, - double indexHitRatio, - TimeSpan totalQueryExecutionTime, - QueryPreparationTimes queryPreparationTimes, - TimeSpan indexLookupTime, - TimeSpan documentLoadTime, - TimeSpan vmExecutionTime, - RuntimeExecutionTimes runtimeExecutionTimes, - TimeSpan documentWriteTime) - { - this.RetrievedDocumentCount = retrievedDocumentCount; - this.RetrievedDocumentSize = retrievedDocumentSize; - this.OutputDocumentCount = outputDocumentCount; - this.OutputDocumentSize = outputDocumentSize; - this.IndexHitRatio = indexHitRatio; - this.TotalTime = totalQueryExecutionTime; - this.QueryPreparationTimes = queryPreparationTimes ?? throw new ArgumentNullException($"{nameof(queryPreparationTimes)} can not be null."); - this.IndexLookupTime = indexLookupTime; - this.DocumentLoadTime = documentLoadTime; - this.VMExecutionTime = vmExecutionTime; - this.RuntimeExecutionTimes = runtimeExecutionTimes ?? throw new ArgumentNullException($"{nameof(runtimeExecutionTimes)} can not be null."); - this.DocumentWriteTime = documentWriteTime; - } - - /// - /// Gets the total query time in the Azure Cosmos database service. - /// - public TimeSpan TotalTime { get; } - - /// - /// Gets the number of documents retrieved during query in the Azure Cosmos database service. - /// - public long RetrievedDocumentCount { get; } - - /// - /// Gets the size of documents retrieved in bytes during query in the Azure Cosmos DB service. - /// - public long RetrievedDocumentSize { get; } - - /// - /// Gets the number of documents returned by query in the Azure Cosmos DB service. - /// - public long OutputDocumentCount { get; } - - /// - /// Gets the size of documents outputted in bytes during query in the Azure Cosmos database service. - /// - public long OutputDocumentSize { get; } - - /// - /// Gets the query QueryPreparationTimes in the Azure Cosmos database service. - /// - public QueryPreparationTimes QueryPreparationTimes { get; } - - /// - /// Gets the query index lookup time in the Azure Cosmos database service. - /// - public TimeSpan IndexLookupTime { get; } - - /// - /// Gets the document loading time during query in the Azure Cosmos database service. - /// - public TimeSpan DocumentLoadTime { get; } - - /// - /// Gets the query runtime execution times during query in the Azure Cosmos database service. - /// - public RuntimeExecutionTimes RuntimeExecutionTimes { get; } - - /// - /// Gets the output writing/serializing time during query in the Azure Cosmos database service. - /// - public TimeSpan DocumentWriteTime { get; } - - /// - /// Gets the index hit ratio by query in the Azure Cosmos database service. - /// - public double IndexHitRatio { get; } - - /// - /// Gets the VMExecution Time. - /// - public TimeSpan VMExecutionTime { get; } - - public override string ToString() - { - return $"totalExecutionTimeInMs={this.TotalTime.TotalMilliseconds};queryCompileTimeInMs={this.QueryPreparationTimes.QueryCompilationTime.TotalMilliseconds};queryLogicalPlanBuildTimeInMs={this.QueryPreparationTimes.LogicalPlanBuildTime.TotalMilliseconds};queryPhysicalPlanBuildTimeInMs={this.QueryPreparationTimes.PhysicalPlanBuildTime.TotalMilliseconds};queryOptimizationTimeInMs={this.QueryPreparationTimes.QueryOptimizationTime.TotalMilliseconds};indexLookupTimeInMs={this.IndexLookupTime.TotalMilliseconds};documentLoadTimeInMs={this.DocumentLoadTime.TotalMilliseconds};systemFunctionExecuteTimeInMs={this.RuntimeExecutionTimes.SystemFunctionExecutionTime.TotalMilliseconds};userFunctionExecuteTimeInMs={this.RuntimeExecutionTimes.UserDefinedFunctionExecutionTime.TotalMilliseconds};retrievedDocumentCount={this.RetrievedDocumentCount};retrievedDocumentSize={this.RetrievedDocumentSize};outputDocumentCount={this.OutputDocumentCount};outputDocumentSize={this.OutputDocumentSize};writeOutputTimeInMs={this.DocumentWriteTime.TotalMilliseconds};indexUtilizationRatio={this.IndexHitRatio}"; - } - - public static BackendMetrics CreateFromIEnumerable(IEnumerable backendMetricsEnumerable) - { - BackendMetrics.Accumulator accumulator = default; - foreach (BackendMetrics backendMetrics in backendMetricsEnumerable) - { - accumulator = accumulator.Accumulate(backendMetrics); - } - - return BackendMetrics.Accumulator.ToBackendMetrics(accumulator); - } - - public static bool TryParseFromDelimitedString(string delimitedString, out BackendMetrics backendMetrics) - { - return BackendMetricsParser.TryParse(delimitedString, out backendMetrics); - } - - public static BackendMetrics ParseFromDelimitedString(string delimitedString) - { - if (!BackendMetricsParser.TryParse(delimitedString, out BackendMetrics backendMetrics)) - { - throw new FormatException(); - } - - return backendMetrics; - } - - public ref struct Accumulator - { - public Accumulator( - TimeSpan totalTime, - long retrievedDocumentCount, - long retrievedDocumentSize, - long outputDocumentCount, - long outputDocumentSize, - double indexHitRatio, - QueryPreparationTimes.Accumulator queryPreparationTimesAccumulator, - TimeSpan indexLookupTime, - TimeSpan documentLoadTime, - RuntimeExecutionTimes.Accumulator runtimeExecutionTimesAccumulator, - TimeSpan documentWriteTime, - TimeSpan vmExecutionTime) - { - this.TotalTime = totalTime; - this.RetrievedDocumentCount = retrievedDocumentCount; - this.RetrievedDocumentSize = retrievedDocumentSize; - this.OutputDocumentCount = outputDocumentCount; - this.OutputDocumentSize = outputDocumentSize; - this.IndexHitRatio = indexHitRatio; - this.QueryPreparationTimesAccumulator = queryPreparationTimesAccumulator; - this.IndexLookupTime = indexLookupTime; - this.DocumentLoadTime = documentLoadTime; - this.RuntimeExecutionTimesAccumulator = runtimeExecutionTimesAccumulator; - this.DocumentWriteTime = documentWriteTime; - this.VMExecutionTime = vmExecutionTime; - } - - public TimeSpan TotalTime { get; } - public long RetrievedDocumentCount { get; } - public long RetrievedDocumentSize { get; } - public long OutputDocumentCount { get; } - public long OutputDocumentSize { get; } - public double IndexHitRatio { get; } - public QueryPreparationTimes.Accumulator QueryPreparationTimesAccumulator { get; } - public TimeSpan IndexLookupTime { get; } - public TimeSpan DocumentLoadTime { get; } - public RuntimeExecutionTimes.Accumulator RuntimeExecutionTimesAccumulator { get; } - public TimeSpan DocumentWriteTime { get; } - public TimeSpan VMExecutionTime { get; } - - public Accumulator Accumulate(BackendMetrics backendMetrics) - { - return new Accumulator( - totalTime: this.TotalTime + backendMetrics.TotalTime, - retrievedDocumentCount: this.RetrievedDocumentCount + backendMetrics.RetrievedDocumentCount, - retrievedDocumentSize: this.RetrievedDocumentSize + backendMetrics.RetrievedDocumentSize, - outputDocumentCount: this.OutputDocumentCount + backendMetrics.OutputDocumentCount, - outputDocumentSize: this.OutputDocumentSize + backendMetrics.OutputDocumentSize, - indexHitRatio: ((this.OutputDocumentCount * this.IndexHitRatio) + (backendMetrics.OutputDocumentCount * backendMetrics.IndexHitRatio)) / (this.RetrievedDocumentCount + backendMetrics.RetrievedDocumentCount), - queryPreparationTimesAccumulator: this.QueryPreparationTimesAccumulator.Accumulate(backendMetrics.QueryPreparationTimes), - indexLookupTime: this.IndexLookupTime + backendMetrics.IndexLookupTime, - documentLoadTime: this.DocumentLoadTime + backendMetrics.DocumentLoadTime, - runtimeExecutionTimesAccumulator: this.RuntimeExecutionTimesAccumulator.Accumulate(backendMetrics.RuntimeExecutionTimes), - documentWriteTime: this.DocumentWriteTime + backendMetrics.DocumentWriteTime, - vmExecutionTime: this.VMExecutionTime + backendMetrics.VMExecutionTime); - - } - - public static BackendMetrics ToBackendMetrics(BackendMetrics.Accumulator accumulator) - { - return new BackendMetrics( - retrievedDocumentCount: accumulator.RetrievedDocumentCount, - retrievedDocumentSize: accumulator.RetrievedDocumentSize, - outputDocumentCount: accumulator.OutputDocumentCount, - outputDocumentSize: accumulator.OutputDocumentSize, - indexHitRatio: accumulator.IndexHitRatio, - totalQueryExecutionTime: accumulator.TotalTime, - queryPreparationTimes: QueryPreparationTimes.Accumulator.ToQueryPreparationTimes(accumulator.QueryPreparationTimesAccumulator), - indexLookupTime: accumulator.IndexLookupTime, - documentLoadTime: accumulator.DocumentLoadTime, - vmExecutionTime: accumulator.VMExecutionTime, - runtimeExecutionTimes: RuntimeExecutionTimes.Accumulator.ToRuntimeExecutionTimes(accumulator.RuntimeExecutionTimesAccumulator), - documentWriteTime: accumulator.DocumentWriteTime); - } - } - } -} diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ClientSideMetrics.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ClientSideMetrics.cs index e69f4c5808..ff68271a69 100644 --- a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ClientSideMetrics.cs +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ClientSideMetrics.cs @@ -5,7 +5,6 @@ namespace Microsoft.Azure.Cosmos.Query.Core.Metrics { using System; using System.Collections.Generic; - using System.Linq; /// /// Stores client side QueryMetrics. @@ -54,42 +53,5 @@ public ClientSideMetrics( /// Gets the Fetch Execution Ranges for this continuation of the query. /// public IEnumerable FetchExecutionRanges { get; } - - public ref struct Accumulator - { - public Accumulator(long retries, double requestCharge, IEnumerable fetchExecutionRanges) - { - this.Retries = retries; - this.RequestCharge = requestCharge; - this.FetchExecutionRanges = fetchExecutionRanges; - } - - public long Retries { get; } - - public double RequestCharge { get; } - - public IEnumerable FetchExecutionRanges { get; } - - public Accumulator Accumulate(ClientSideMetrics clientSideMetrics) - { - if (clientSideMetrics == null) - { - throw new ArgumentNullException(nameof(clientSideMetrics)); - } - - return new Accumulator( - retries: this.Retries + clientSideMetrics.Retries, - requestCharge: this.RequestCharge + clientSideMetrics.RequestCharge, - fetchExecutionRanges: (this.FetchExecutionRanges ?? Enumerable.Empty()).Concat(clientSideMetrics.FetchExecutionRanges)); - } - - public static ClientSideMetrics ToClientSideMetrics(Accumulator accumulator) - { - return new ClientSideMetrics( - retries: accumulator.Retries, - requestCharge: accumulator.RequestCharge, - fetchExecutionRanges: accumulator.FetchExecutionRanges); - } - } } } diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ClientSideMetricsAccumulator.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ClientSideMetricsAccumulator.cs new file mode 100644 index 0000000000..57816580b6 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ClientSideMetricsAccumulator.cs @@ -0,0 +1,47 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ +namespace Microsoft.Azure.Cosmos.Query.Core.Metrics +{ + using System; + using System.Collections.Generic; + + internal sealed class ClientSideMetricsAccumulator + { + private readonly List clientSideMetricsList; + + public ClientSideMetricsAccumulator() + { + this.clientSideMetricsList = new List(); + } + + public void Accumulate(ClientSideMetrics clientSideMetrics) + { + if (clientSideMetrics == null) + { + throw new ArgumentNullException(nameof(clientSideMetrics)); + } + + this.clientSideMetricsList.Add(clientSideMetrics); + } + + public ClientSideMetrics GetClientSideMetrics() + { + long retries = 0; + double requestCharge = 0; + List fetchExecutionRanges = new List(); + + foreach (ClientSideMetrics clientSideMetrics in this.clientSideMetricsList) + { + retries += clientSideMetrics.Retries; + requestCharge += clientSideMetrics.RequestCharge; + fetchExecutionRanges.AddRange(clientSideMetrics.FetchExecutionRanges); + } + + return new ClientSideMetrics( + retries: retries, + requestCharge: requestCharge, + fetchExecutionRanges: fetchExecutionRanges); + } + } +} diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/CompositeIndexIndexMetrics.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/CompositeIndexIndexMetrics.cs new file mode 100644 index 0000000000..5ee147dc87 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/CompositeIndexIndexMetrics.cs @@ -0,0 +1,48 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ +namespace Microsoft.Azure.Cosmos.Query.Core.Metrics +{ + using System; + using System.Collections.Generic; + using Newtonsoft.Json; + + /// + /// Query index utilization data for composite indexes (sub-structure of the Index Metrics class) in the Azure Cosmos database service. + /// + #if INTERNAL +#pragma warning disable SA1600 +#pragma warning disable CS1591 + public +#else + internal +#endif + sealed class CompositeIndexIndexMetrics + { + /// + /// Initialized a new instance of an Index Metrics' Composite Index class. + /// + /// The string list representation of the composite index. + /// The index impact score. + [JsonConstructor] + private CompositeIndexIndexMetrics( + IReadOnlyList indexDocumentExpressions, + string indexImpactScore) + { + this.IndexSpecs = indexDocumentExpressions; + this.IndexImpactScore = indexImpactScore; + } + + /// + /// String list representation of index paths of a composite index. + /// + [JsonProperty(PropertyName = "IndexSpecs")] + public IReadOnlyList IndexSpecs { get; } + + /// + /// The index impact score of the composite index. + /// + [JsonProperty(PropertyName = "IndexImpactScore")] + public string IndexImpactScore { get; } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/IndexMetricsInfo.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/IndexMetricsInfo.cs new file mode 100644 index 0000000000..4156e520a7 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/IndexMetricsInfo.cs @@ -0,0 +1,83 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ +namespace Microsoft.Azure.Cosmos.Query.Core.Metrics +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using Microsoft.Azure.Cosmos.Core; + using Microsoft.Azure.Cosmos.Core.Utf8; + using Newtonsoft.Json; + + /// + /// Query index utilization data for composite indexes (sub-structure of the Index Metrics class) in the Azure Cosmos database service. + /// +#if INTERNAL +#pragma warning disable SA1600 +#pragma warning disable CS1591 + public +#else + internal +#endif + sealed class IndexMetricsInfo + { + /// + /// Initializes a new instance of the Index Metrics class. + /// + /// The utilized indexes + /// The potential indexes + [JsonConstructor] + public IndexMetricsInfo( + IndexMetricsInfoEntity utilizedEntity, + IndexMetricsInfoEntity potentialEntity) + { + this.UtilizedEntity = utilizedEntity; + this.PotentialEntity = potentialEntity; + } + + [JsonProperty("Utilized")] + public IndexMetricsInfoEntity UtilizedEntity { get; } + + [JsonProperty("Potential")] + public IndexMetricsInfoEntity PotentialEntity { get; } + + /// + /// Creates a new IndexMetricsInfo from the backend delimited string. + /// + /// The backend delimited string to deserialize from. + /// The parsed index utilization info + /// A new IndexMetricsInfo from the backend delimited string. + public static bool TryCreateFromString(string delimitedString, out IndexMetricsInfo result) + { + if (delimitedString == null) + { + result = null; + return false; + } + + try + { + // Decode and deserialize the response string + string decodedString = System.Web.HttpUtility.UrlDecode(delimitedString, Encoding.UTF8); + + result = JsonConvert.DeserializeObject(decodedString, new JsonSerializerSettings() + { + // Allowing null values to be resilient to Json structure change + MissingMemberHandling = MissingMemberHandling.Ignore, + NullValueHandling = NullValueHandling.Ignore, + // Ignore parsing error encountered in deserialization + Error = (sender, parsingErrorEvent) => parsingErrorEvent.ErrorContext.Handled = true + }) ?? null; + + return true; + } + catch (JsonException) + { + result = null; + return false; + } + } + } +} diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/IndexMetricsInfoEntity.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/IndexMetricsInfoEntity.cs new file mode 100644 index 0000000000..69a0f3270a --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/IndexMetricsInfoEntity.cs @@ -0,0 +1,43 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ +namespace Microsoft.Azure.Cosmos.Query.Core.Metrics +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using Microsoft.Azure.Cosmos.Core; + using Microsoft.Azure.Cosmos.Core.Utf8; + using Newtonsoft.Json; + + /// + /// Query index utilization metrics in the Azure Cosmos database service. + /// +#if INTERNAL +#pragma warning disable SA1600 +#pragma warning disable CS1591 + public +#else + internal +#endif + sealed class IndexMetricsInfoEntity + { + /// + /// Initializes a new instance of the Index Utilization class. This is the legacy class of IndexMetricsInfoEntity. + /// + /// The utilized single indexes list + /// The potential single indexes list + [JsonConstructor] + public IndexMetricsInfoEntity( + IReadOnlyList singleIndexes, + IReadOnlyList compositeIndexes) + { + this.SingleIndexes = (singleIndexes ?? Enumerable.Empty()).Where(item => item != null).ToList(); + this.CompositeIndexes = (compositeIndexes ?? Enumerable.Empty()).Where(item => item != null).ToList(); + } + + public IReadOnlyList SingleIndexes { get; } + public IReadOnlyList CompositeIndexes { get; } + } +} diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/IndexMetricWriter.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/IndexMetricsWriter.cs similarity index 65% rename from Microsoft.Azure.Cosmos/src/Query/Core/Metrics/IndexMetricWriter.cs rename to Microsoft.Azure.Cosmos/src/Query/Core/Metrics/IndexMetricsWriter.cs index 7deb1f767b..138275fda9 100644 --- a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/IndexMetricWriter.cs +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/IndexMetricsWriter.cs @@ -9,7 +9,7 @@ namespace Microsoft.Azure.Cosmos.Query.Core.Metrics using System.Text; /// - /// Base class for visiting and serializing a . + /// Base class for visiting and serializing a . /// #if INTERNAL #pragma warning disable SA1600 @@ -18,7 +18,7 @@ namespace Microsoft.Azure.Cosmos.Query.Core.Metrics #else internal #endif - class IndexMetricWriter + class IndexMetricsWriter { private const string IndexUtilizationInfo = "Index Utilization Information"; private const string UtilizedSingleIndexes = "Utilized Single Indexes"; @@ -32,7 +32,7 @@ class IndexMetricWriter private readonly StringBuilder stringBuilder; - public IndexMetricWriter(StringBuilder stringBuilder) + public IndexMetricsWriter(StringBuilder stringBuilder) { this.stringBuilder = stringBuilder ?? throw new ArgumentNullException($"{nameof(stringBuilder)} must not be null."); } @@ -50,37 +50,37 @@ public void WriteIndexMetrics(IndexUtilizationInfo indexUtilizationInfo) #region IndexUtilizationInfo protected void WriteBeforeIndexUtilizationInfo() { - IndexMetricWriter.AppendNewlineToStringBuilder(this.stringBuilder); - IndexMetricWriter.AppendHeaderToStringBuilder( + IndexMetricsWriter.AppendNewlineToStringBuilder(this.stringBuilder); + IndexMetricsWriter.AppendHeaderToStringBuilder( this.stringBuilder, - IndexMetricWriter.IndexUtilizationInfo, + IndexMetricsWriter.IndexUtilizationInfo, indentLevel: 0); } protected void WriteIndexUtilizationInfo(IndexUtilizationInfo indexUtilizationInfo) { - IndexMetricWriter.AppendHeaderToStringBuilder(this.stringBuilder, IndexMetricWriter.UtilizedSingleIndexes, indentLevel: 1); + IndexMetricsWriter.AppendHeaderToStringBuilder(this.stringBuilder, IndexMetricsWriter.UtilizedSingleIndexes, indentLevel: 1); foreach (SingleIndexUtilizationEntity indexUtilizationEntity in indexUtilizationInfo.UtilizedSingleIndexes) { WriteSingleIndexUtilizationEntity(indexUtilizationEntity); } - IndexMetricWriter.AppendHeaderToStringBuilder(this.stringBuilder, IndexMetricWriter.PotentialSingleIndexes, indentLevel: 1); + IndexMetricsWriter.AppendHeaderToStringBuilder(this.stringBuilder, IndexMetricsWriter.PotentialSingleIndexes, indentLevel: 1); foreach (SingleIndexUtilizationEntity indexUtilizationEntity in indexUtilizationInfo.PotentialSingleIndexes) { WriteSingleIndexUtilizationEntity(indexUtilizationEntity); } - IndexMetricWriter.AppendHeaderToStringBuilder(this.stringBuilder, IndexMetricWriter.UtilizedCompositeIndexes, indentLevel: 1); + IndexMetricsWriter.AppendHeaderToStringBuilder(this.stringBuilder, IndexMetricsWriter.UtilizedCompositeIndexes, indentLevel: 1); foreach (CompositeIndexUtilizationEntity indexUtilizationEntity in indexUtilizationInfo.UtilizedCompositeIndexes) { WriteCompositeIndexUtilizationEntity(indexUtilizationEntity); } - IndexMetricWriter.AppendHeaderToStringBuilder(this.stringBuilder, IndexMetricWriter.PotentialCompositeIndexes, indentLevel: 1); + IndexMetricsWriter.AppendHeaderToStringBuilder(this.stringBuilder, IndexMetricsWriter.PotentialCompositeIndexes, indentLevel: 1); foreach (CompositeIndexUtilizationEntity indexUtilizationEntity in indexUtilizationInfo.PotentialCompositeIndexes) { @@ -89,16 +89,16 @@ protected void WriteIndexUtilizationInfo(IndexUtilizationInfo indexUtilizationIn void WriteSingleIndexUtilizationEntity(SingleIndexUtilizationEntity indexUtilizationEntity) { - IndexMetricWriter.AppendHeaderToStringBuilder(this.stringBuilder, $"{IndexMetricWriter.IndexExpression}: {indexUtilizationEntity.IndexDocumentExpression}", indentLevel: 2); - IndexMetricWriter.AppendHeaderToStringBuilder(this.stringBuilder, $"{IndexMetricWriter.IndexImpactScore}: {indexUtilizationEntity.IndexImpactScore}", indentLevel: 2); - IndexMetricWriter.AppendHeaderToStringBuilder(this.stringBuilder, IndexMetricWriter.IndexUtilizationSeparator, indentLevel: 2); + IndexMetricsWriter.AppendHeaderToStringBuilder(this.stringBuilder, $"{IndexMetricsWriter.IndexExpression}: {indexUtilizationEntity.IndexDocumentExpression}", indentLevel: 2); + IndexMetricsWriter.AppendHeaderToStringBuilder(this.stringBuilder, $"{IndexMetricsWriter.IndexImpactScore}: {indexUtilizationEntity.IndexImpactScore}", indentLevel: 2); + IndexMetricsWriter.AppendHeaderToStringBuilder(this.stringBuilder, IndexMetricsWriter.IndexUtilizationSeparator, indentLevel: 2); } void WriteCompositeIndexUtilizationEntity(CompositeIndexUtilizationEntity indexUtilizationEntity) { - IndexMetricWriter.AppendHeaderToStringBuilder(this.stringBuilder, $"{IndexMetricWriter.IndexExpression}: {String.Join(", ", indexUtilizationEntity.IndexDocumentExpressions)}", indentLevel: 2); - IndexMetricWriter.AppendHeaderToStringBuilder(this.stringBuilder, $"{IndexMetricWriter.IndexImpactScore}: {indexUtilizationEntity.IndexImpactScore}", indentLevel: 2); - IndexMetricWriter.AppendHeaderToStringBuilder(this.stringBuilder, IndexMetricWriter.IndexUtilizationSeparator, indentLevel: 2); + IndexMetricsWriter.AppendHeaderToStringBuilder(this.stringBuilder, $"{IndexMetricsWriter.IndexExpression}: {String.Join(", ", indexUtilizationEntity.IndexDocumentExpressions)}", indentLevel: 2); + IndexMetricsWriter.AppendHeaderToStringBuilder(this.stringBuilder, $"{IndexMetricsWriter.IndexImpactScore}: {indexUtilizationEntity.IndexImpactScore}", indentLevel: 2); + IndexMetricsWriter.AppendHeaderToStringBuilder(this.stringBuilder, IndexMetricsWriter.IndexUtilizationSeparator, indentLevel: 2); } } @@ -123,7 +123,7 @@ private static void AppendHeaderToStringBuilder(StringBuilder stringBuilder, str private static void AppendNewlineToStringBuilder(StringBuilder stringBuilder) { - IndexMetricWriter.AppendHeaderToStringBuilder( + IndexMetricsWriter.AppendHeaderToStringBuilder( stringBuilder, string.Empty, indentLevel: 0); diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/IndexUtilizationInfo.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/IndexUtilizationInfo.cs index 2dba73132e..a9ef4569b5 100644 --- a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/IndexUtilizationInfo.cs +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/IndexUtilizationInfo.cs @@ -8,6 +8,7 @@ namespace Microsoft.Azure.Cosmos.Query.Core.Metrics using System.Linq; using System.Text; using Microsoft.Azure.Cosmos.Core; + using Microsoft.Azure.Cosmos.Core.Utf8; using Newtonsoft.Json; /// @@ -29,7 +30,7 @@ sealed class IndexUtilizationInfo potentialCompositeIndexes: new List()); /// - /// Initializes a new instance of the Index Utilization class. + /// Initializes a new instance of the Index Utilization class. This is the legacy class of IndexMetricsInfo. /// /// The utilized single indexes list /// The potential single indexes list @@ -60,23 +61,6 @@ public IndexUtilizationInfo( /// The parsed index utilization info /// A new IndexUtilizationInfo from the backend delimited string. internal static bool TryCreateFromDelimitedBase64String(string delimitedString, out IndexUtilizationInfo result) - { - if (delimitedString == null) - { - result = IndexUtilizationInfo.Empty; - return true; - } - - return TryCreateFromDelimitedString(System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(delimitedString)), out result); - } - - /// - /// Creates a new IndexUtilizationInfo from the backend delimited string. - /// - /// The backend delimited string to deserialize from. - /// The parsed index utilization info - /// A new IndexUtilizationInfo from the backend delimited string. - internal static bool TryCreateFromDelimitedString(string delimitedString, out IndexUtilizationInfo result) { if (delimitedString == null) { @@ -84,9 +68,15 @@ internal static bool TryCreateFromDelimitedString(string delimitedString, out In return true; } + // Even though this parsing is resilient, older version of the SDK doesn't have such lenient parsing. + // As such, it is right not not possible to remove some of the field in the IndexUtilizationInfo class. + // However, in newer version of the SDKs, the code base is going to start returning IndexMetricsInfo, + // so this class exists solely for legacy support. try { - result = JsonConvert.DeserializeObject(delimitedString, new JsonSerializerSettings() + string decodedString = System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(delimitedString)); + + result = JsonConvert.DeserializeObject(decodedString, new JsonSerializerSettings() { // Allowing null values to be resilient to Json structure change MissingMemberHandling = MissingMemberHandling.Ignore, @@ -108,60 +98,12 @@ internal static bool TryCreateFromDelimitedString(string delimitedString, out In /// Materialize the Index Utilization String into Concrete objects. /// /// The index utilization response string as sent by the back end. - /// The encoding of the string. /// Cpncrete Index utilization object. - public static IndexUtilizationInfo CreateFromString(string delimitedString, bool isBse64Encoded) + public static IndexUtilizationInfo CreateFromString(string delimitedString) { - IndexUtilizationInfo indexUtilizationInfo; - - if (isBse64Encoded) - { - TryCreateFromDelimitedBase64String(delimitedString, out indexUtilizationInfo); - } - else - { - TryCreateFromDelimitedString(delimitedString, out indexUtilizationInfo); - } + TryCreateFromDelimitedBase64String(delimitedString, out IndexUtilizationInfo indexUtilizationInfo); return indexUtilizationInfo; } - - public ref struct Accumulator - { - public Accumulator( - IEnumerable utilizedSingleIndexes, - IEnumerable potentialSingleIndexes, - IEnumerable utilizedCompositeIndexes, - IEnumerable potentialCompositeIndexes) - { - this.UtilizedSingleIndexes = utilizedSingleIndexes; - this.PotentialSingleIndexes = potentialSingleIndexes; - this.UtilizedCompositeIndexes = utilizedCompositeIndexes; - this.PotentialCompositeIndexes = potentialCompositeIndexes; - } - - public IEnumerable UtilizedSingleIndexes { get; } - public IEnumerable PotentialSingleIndexes { get; } - public IEnumerable UtilizedCompositeIndexes { get; } - public IEnumerable PotentialCompositeIndexes { get; } - - public Accumulator Accumulate(IndexUtilizationInfo indexUtilizationInfo) - { - return new Accumulator( - utilizedSingleIndexes: (this.UtilizedSingleIndexes ?? Enumerable.Empty()).Concat(indexUtilizationInfo.UtilizedSingleIndexes), - potentialSingleIndexes: (this.PotentialSingleIndexes ?? Enumerable.Empty()).Concat(indexUtilizationInfo.PotentialSingleIndexes), - utilizedCompositeIndexes: (this.UtilizedCompositeIndexes ?? Enumerable.Empty()).Concat(indexUtilizationInfo.UtilizedCompositeIndexes), - potentialCompositeIndexes: (this.PotentialCompositeIndexes ?? Enumerable.Empty()).Concat(indexUtilizationInfo.PotentialCompositeIndexes)); - } - - public static IndexUtilizationInfo ToIndexUtilizationInfo(Accumulator accumulator) - { - return new IndexUtilizationInfo( - utilizedSingleIndexes: accumulator.UtilizedSingleIndexes.ToList(), - potentialSingleIndexes: accumulator.PotentialSingleIndexes.ToList(), - utilizedCompositeIndexes: accumulator.UtilizedCompositeIndexes.ToList(), - potentialCompositeIndexes: accumulator.PotentialCompositeIndexes.ToList()); - } - } } } diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/IndexUtilizationInfoAccumulator.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/IndexUtilizationInfoAccumulator.cs new file mode 100644 index 0000000000..978abba77a --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/IndexUtilizationInfoAccumulator.cs @@ -0,0 +1,51 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.Metrics +{ + using System; + using System.Collections.Generic; + + internal sealed class IndexUtilizationInfoAccumulator + { + private readonly List indexUtilizationInfoList; + + public IndexUtilizationInfoAccumulator() + { + this.indexUtilizationInfoList = new List(); + } + + public void Accumulate(IndexUtilizationInfo indexUtilizationInfo) + { + if (indexUtilizationInfo == null) + { + throw new ArgumentNullException(nameof(indexUtilizationInfo)); + } + + this.indexUtilizationInfoList.Add(indexUtilizationInfo); + } + + public IndexUtilizationInfo GetIndexUtilizationInfo() + { + List utilizedSingleIndexes = new List(); + List potentialSingleIndexes = new List(); + List utilizedCompositeIndexes = new List(); + List potentialCompositeIndexes = new List(); + + foreach (IndexUtilizationInfo indexUtilizationInfo in this.indexUtilizationInfoList) + { + utilizedSingleIndexes.AddRange(indexUtilizationInfo.UtilizedSingleIndexes); + potentialSingleIndexes.AddRange(indexUtilizationInfo.PotentialSingleIndexes); + utilizedCompositeIndexes.AddRange(indexUtilizationInfo.UtilizedCompositeIndexes); + potentialCompositeIndexes.AddRange(indexUtilizationInfo.PotentialCompositeIndexes); + } + + return new IndexUtilizationInfo( + utilizedSingleIndexes: utilizedSingleIndexes, + potentialSingleIndexes: potentialSingleIndexes, + utilizedCompositeIndexes: utilizedCompositeIndexes, + potentialCompositeIndexes: potentialCompositeIndexes); + } + } +} diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/QueryMetrics.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/QueryMetrics.cs index 5a7e9377ed..ed3993d47e 100644 --- a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/QueryMetrics.cs +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/QueryMetrics.cs @@ -29,11 +29,11 @@ sealed class QueryMetrics clientSideMetrics: ClientSideMetrics.Empty); public QueryMetrics( - BackendMetrics backendMetrics, - IndexUtilizationInfo indexUtilizationInfo, - ClientSideMetrics clientSideMetrics) + ServerSideMetricsInternal serverSideMetrics, + IndexUtilizationInfo indexUtilizationInfo, + ClientSideMetrics clientSideMetrics) { - this.BackendMetrics = backendMetrics ?? throw new ArgumentNullException(nameof(backendMetrics)); + this.ServerSideMetrics = serverSideMetrics ?? throw new ArgumentNullException(nameof(serverSideMetrics)); this.IndexUtilizationInfo = indexUtilizationInfo ?? throw new ArgumentNullException(nameof(indexUtilizationInfo)); this.ClientSideMetrics = clientSideMetrics ?? throw new ArgumentNullException(nameof(clientSideMetrics)); } @@ -43,13 +43,13 @@ public QueryMetrics( IndexUtilizationInfo indexUtilizationInfo, ClientSideMetrics clientSideMetrics) : this(!String.IsNullOrWhiteSpace(deliminatedString) && - BackendMetricsParser.TryParse(deliminatedString, out BackendMetrics backendMetrics) - ? backendMetrics - : BackendMetrics.Empty, indexUtilizationInfo, clientSideMetrics) + ServerSideMetricsParser.TryParse(deliminatedString, out ServerSideMetricsInternal serverSideMetrics) + ? serverSideMetrics + : ServerSideMetricsInternal.Empty, indexUtilizationInfo, clientSideMetrics) { } - public BackendMetrics BackendMetrics { get; } + public ServerSideMetricsInternal ServerSideMetrics { get; } public IndexUtilizationInfo IndexUtilizationInfo { get; } @@ -63,11 +63,11 @@ public QueryMetrics( /// A new instance that is the sum of two instances public static QueryMetrics operator +(QueryMetrics queryMetrics1, QueryMetrics queryMetrics2) { - QueryMetrics.Accumulator queryMetricsAccumulator = new QueryMetrics.Accumulator(); - queryMetricsAccumulator = queryMetricsAccumulator.Accumulate(queryMetrics1); - queryMetricsAccumulator = queryMetricsAccumulator.Accumulate(queryMetrics2); + QueryMetricsAccumulator queryMetricsAccumulator = new QueryMetricsAccumulator(); + queryMetricsAccumulator.Accumulate(queryMetrics1); + queryMetricsAccumulator.Accumulate(queryMetrics2); - return QueryMetrics.Accumulator.ToQueryMetrics(queryMetricsAccumulator); + return queryMetricsAccumulator.GetQueryMetrics(); } /// @@ -94,53 +94,13 @@ public static QueryMetrics CreateFromIEnumerable(IEnumerable query throw new ArgumentNullException(nameof(queryMetricsList)); } - QueryMetrics.Accumulator queryMetricsAccumulator = new QueryMetrics.Accumulator(); + QueryMetricsAccumulator queryMetricsAccumulator = new QueryMetricsAccumulator(); foreach (QueryMetrics queryMetrics in queryMetricsList) { - queryMetricsAccumulator = queryMetricsAccumulator.Accumulate(queryMetrics); + queryMetricsAccumulator.Accumulate(queryMetrics); } - return QueryMetrics.Accumulator.ToQueryMetrics(queryMetricsAccumulator); - } - - public ref struct Accumulator - { - public Accumulator( - BackendMetrics.Accumulator backendMetricsAccumulator, - IndexUtilizationInfo.Accumulator indexUtilizationInfoAccumulator, - ClientSideMetrics.Accumulator clientSideMetricsAccumulator) - { - this.BackendMetricsAccumulator = backendMetricsAccumulator; - this.IndexUtilizationInfoAccumulator = indexUtilizationInfoAccumulator; - this.ClientSideMetricsAccumulator = clientSideMetricsAccumulator; - } - - public BackendMetrics.Accumulator BackendMetricsAccumulator { get; } - - public IndexUtilizationInfo.Accumulator IndexUtilizationInfoAccumulator { get; } - - public ClientSideMetrics.Accumulator ClientSideMetricsAccumulator { get; } - - public Accumulator Accumulate(QueryMetrics queryMetrics) - { - if (queryMetrics == null) - { - throw new ArgumentNullException(nameof(queryMetrics)); - } - - return new Accumulator( - backendMetricsAccumulator: this.BackendMetricsAccumulator.Accumulate(queryMetrics.BackendMetrics), - indexUtilizationInfoAccumulator: this.IndexUtilizationInfoAccumulator.Accumulate(queryMetrics.IndexUtilizationInfo), - clientSideMetricsAccumulator: this.ClientSideMetricsAccumulator.Accumulate(queryMetrics.ClientSideMetrics)); - } - - public static QueryMetrics ToQueryMetrics(Accumulator accumulator) - { - return new QueryMetrics( - BackendMetrics.Accumulator.ToBackendMetrics(accumulator.BackendMetricsAccumulator), - IndexUtilizationInfo.Accumulator.ToIndexUtilizationInfo(accumulator.IndexUtilizationInfoAccumulator), - ClientSideMetrics.Accumulator.ToClientSideMetrics(accumulator.ClientSideMetricsAccumulator)); - } + return queryMetricsAccumulator.GetQueryMetrics(); } } } \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/QueryMetricsAccumulator.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/QueryMetricsAccumulator.cs new file mode 100644 index 0000000000..b6b817e95d --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/QueryMetricsAccumulator.cs @@ -0,0 +1,48 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.Metrics +{ + using System; + using System.Collections.Generic; + + internal sealed class QueryMetricsAccumulator + { + private readonly List queryMetricsList; + + public QueryMetricsAccumulator() + { + this.queryMetricsList = new List(); + } + + public void Accumulate(QueryMetrics queryMetrics) + { + if (queryMetrics == null) + { + throw new ArgumentNullException(nameof(queryMetrics)); + } + + this.queryMetricsList.Add(queryMetrics); + } + + public QueryMetrics GetQueryMetrics() + { + ServerSideMetricsInternalAccumulator serverSideMetricsAccumulator = new ServerSideMetricsInternalAccumulator(); + IndexUtilizationInfoAccumulator indexUtilizationInfoAccumulator = new IndexUtilizationInfoAccumulator(); + ClientSideMetricsAccumulator clientSideMetricsAccumulator = new ClientSideMetricsAccumulator(); + + foreach (QueryMetrics queryMetrics in this.queryMetricsList) + { + serverSideMetricsAccumulator.Accumulate(queryMetrics.ServerSideMetrics); + indexUtilizationInfoAccumulator.Accumulate(queryMetrics.IndexUtilizationInfo); + clientSideMetricsAccumulator.Accumulate(queryMetrics.ClientSideMetrics); + } + + return new QueryMetrics( + serverSideMetricsAccumulator.GetServerSideMetrics(), + indexUtilizationInfoAccumulator.GetIndexUtilizationInfo(), + clientSideMetricsAccumulator.GetClientSideMetrics()); + } + } +} diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/QueryMetricsTextWriter.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/QueryMetricsTextWriter.cs index bd634815e9..1802e60e28 100644 --- a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/QueryMetricsTextWriter.cs +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/QueryMetricsTextWriter.cs @@ -215,7 +215,7 @@ protected override void WriteTotalQueryExecutionTime(TimeSpan totalQueryExecutio indentLevel: 0); } - protected override void WriteQueryPreparationTime(QueryPreparationTimes queryPreparationTimes) + protected override void WriteQueryPreparationTime(QueryPreparationTimesInternal queryPreparationTimes) { QueryMetricsTextWriter.AppendTimeSpanToStringBuilder( this.stringBuilder, @@ -250,7 +250,7 @@ protected override void WriteVMExecutionTime(TimeSpan vmExecutionTime) // Do Nothing } - protected override void WriteRuntimeExecutionTime(RuntimeExecutionTimes runtimeExecutionTimes) + protected override void WriteRuntimeExecutionTime(RuntimeExecutionTimesInternal runtimeExecutionTimes) { QueryMetricsTextWriter.AppendTimeSpanToStringBuilder( this.stringBuilder, diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/QueryMetricsWriter.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/QueryMetricsWriter.cs index 2fbb455152..f0d6f7b0fa 100644 --- a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/QueryMetricsWriter.cs +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/QueryMetricsWriter.cs @@ -23,25 +23,25 @@ public void WriteQueryMetrics(QueryMetrics queryMetrics) this.WriteBeforeQueryMetrics(); // Top Level Properties - this.WriteRetrievedDocumentCount(queryMetrics.BackendMetrics.RetrievedDocumentCount); - this.WriteRetrievedDocumentSize(queryMetrics.BackendMetrics.RetrievedDocumentSize); - this.WriteOutputDocumentCount(queryMetrics.BackendMetrics.OutputDocumentCount); - this.WriteOutputDocumentSize(queryMetrics.BackendMetrics.OutputDocumentSize); - this.WriteIndexHitRatio(queryMetrics.BackendMetrics.IndexHitRatio); + this.WriteRetrievedDocumentCount(queryMetrics.ServerSideMetrics.RetrievedDocumentCount); + this.WriteRetrievedDocumentSize(queryMetrics.ServerSideMetrics.RetrievedDocumentSize); + this.WriteOutputDocumentCount(queryMetrics.ServerSideMetrics.OutputDocumentCount); + this.WriteOutputDocumentSize(queryMetrics.ServerSideMetrics.OutputDocumentSize); + this.WriteIndexHitRatio(queryMetrics.ServerSideMetrics.IndexHitRatio); - this.WriteTotalQueryExecutionTime(queryMetrics.BackendMetrics.TotalTime); + this.WriteTotalQueryExecutionTime(queryMetrics.ServerSideMetrics.TotalTime); // QueryPreparationTimes - this.WriteQueryPreparationTime(queryMetrics.BackendMetrics.QueryPreparationTimes); + this.WriteQueryPreparationTime(queryMetrics.ServerSideMetrics.QueryPreparationTimes); - this.WriteIndexLookupTime(queryMetrics.BackendMetrics.IndexLookupTime); - this.WriteDocumentLoadTime(queryMetrics.BackendMetrics.DocumentLoadTime); - this.WriteVMExecutionTime(queryMetrics.BackendMetrics.VMExecutionTime); + this.WriteIndexLookupTime(queryMetrics.ServerSideMetrics.IndexLookupTime); + this.WriteDocumentLoadTime(queryMetrics.ServerSideMetrics.DocumentLoadTime); + this.WriteVMExecutionTime(queryMetrics.ServerSideMetrics.VMExecutionTime); // RuntimesExecutionTimes - this.WriteRuntimeExecutionTime(queryMetrics.BackendMetrics.RuntimeExecutionTimes); + this.WriteRuntimeExecutionTime(queryMetrics.ServerSideMetrics.RuntimeExecutionTimes); - this.WriteDocumentWriteTime(queryMetrics.BackendMetrics.DocumentWriteTime); + this.WriteDocumentWriteTime(queryMetrics.ServerSideMetrics.DocumentWriteTime); #if false // ClientSideMetrics this.WriteClientSideMetrics(queryMetrics.ClientSideMetrics); @@ -70,7 +70,7 @@ public void WriteQueryMetrics(QueryMetrics queryMetrics) protected abstract void WriteTotalQueryExecutionTime(TimeSpan totalQueryExecutionTime); - protected abstract void WriteQueryPreparationTime(QueryPreparationTimes queryPreparationTimes); + protected abstract void WriteQueryPreparationTime(QueryPreparationTimesInternal queryPreparationTimes); protected abstract void WriteIndexLookupTime(TimeSpan indexLookupTime); @@ -78,7 +78,7 @@ public void WriteQueryMetrics(QueryMetrics queryMetrics) protected abstract void WriteVMExecutionTime(TimeSpan vMExecutionTime); - protected abstract void WriteRuntimeExecutionTime(RuntimeExecutionTimes runtimeExecutionTimes); + protected abstract void WriteRuntimeExecutionTime(RuntimeExecutionTimesInternal runtimeExecutionTimes); protected abstract void WriteDocumentWriteTime(TimeSpan documentWriteTime); diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/QueryPreparationTimes.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/QueryPreparationTimes.cs deleted file mode 100644 index 4b2d3b1b20..0000000000 --- a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/QueryPreparationTimes.cs +++ /dev/null @@ -1,104 +0,0 @@ -//------------------------------------------------------------ -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------ -namespace Microsoft.Azure.Cosmos.Query.Core.Metrics -{ - using System; - - /// - /// Query preparation metrics in the Azure DocumentDB database service. - /// -#if INTERNAL -#pragma warning disable SA1600 -#pragma warning disable CS1591 - public -#else - internal -#endif - sealed class QueryPreparationTimes - { - public static readonly QueryPreparationTimes Zero = new QueryPreparationTimes( - queryCompilationTime: default, - logicalPlanBuildTime: default, - physicalPlanBuildTime: default, - queryOptimizationTime: default); - - /// - /// Initializes a new instance of the QueryPreparationTimes class. - /// - /// Query compile and optimization time - /// Query logical plan build time - /// Query physical plan build time - /// Query optimization time - public QueryPreparationTimes( - TimeSpan queryCompilationTime, - TimeSpan logicalPlanBuildTime, - TimeSpan physicalPlanBuildTime, - TimeSpan queryOptimizationTime) - { - this.QueryCompilationTime = queryCompilationTime; - this.LogicalPlanBuildTime = logicalPlanBuildTime; - this.PhysicalPlanBuildTime = physicalPlanBuildTime; - this.QueryOptimizationTime = queryOptimizationTime; - } - - /// - /// Gets the query compile time in the Azure DocumentDB database service. - /// - public TimeSpan QueryCompilationTime { get; } - - /// - /// Gets the query logical plan build time in the Azure DocumentDB database service. - /// - public TimeSpan LogicalPlanBuildTime { get; } - - /// - /// Gets the query physical plan build time in the Azure DocumentDB database service. - /// - public TimeSpan PhysicalPlanBuildTime { get; } - - /// - /// Gets the query optimization time in the Azure DocumentDB database service. - /// - public TimeSpan QueryOptimizationTime { get; } - - public ref struct Accumulator - { - public Accumulator(TimeSpan queryCompliationTime, TimeSpan logicalPlanBuildTime, TimeSpan physicalPlanBuildTime, TimeSpan queryOptimizationTime) - { - this.QueryCompilationTime = queryCompliationTime; - this.LogicalPlanBuildTime = logicalPlanBuildTime; - this.PhysicalPlanBuildTime = physicalPlanBuildTime; - this.QueryOptimizationTime = queryOptimizationTime; - } - - public TimeSpan QueryCompilationTime { get; } - public TimeSpan LogicalPlanBuildTime { get; } - public TimeSpan PhysicalPlanBuildTime { get; } - public TimeSpan QueryOptimizationTime { get; } - - public Accumulator Accumulate(QueryPreparationTimes queryPreparationTimes) - { - if (queryPreparationTimes == null) - { - throw new ArgumentNullException(nameof(queryPreparationTimes)); - } - - return new Accumulator( - queryCompliationTime: this.QueryCompilationTime + queryPreparationTimes.QueryCompilationTime, - logicalPlanBuildTime: this.LogicalPlanBuildTime + queryPreparationTimes.LogicalPlanBuildTime, - physicalPlanBuildTime: this.PhysicalPlanBuildTime + queryPreparationTimes.PhysicalPlanBuildTime, - queryOptimizationTime: this.QueryOptimizationTime + queryPreparationTimes.QueryOptimizationTime); - } - - public static QueryPreparationTimes ToQueryPreparationTimes(QueryPreparationTimes.Accumulator accumulator) - { - return new QueryPreparationTimes( - queryCompilationTime: accumulator.QueryCompilationTime, - logicalPlanBuildTime: accumulator.LogicalPlanBuildTime, - physicalPlanBuildTime: accumulator.PhysicalPlanBuildTime, - queryOptimizationTime: accumulator.QueryOptimizationTime); - } - } - } -} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/QueryPreparationTimesAccumulator.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/QueryPreparationTimesAccumulator.cs new file mode 100644 index 0000000000..6b79e8c1f8 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/QueryPreparationTimesAccumulator.cs @@ -0,0 +1,51 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.Metrics +{ + using System; + using System.Collections.Generic; + + internal sealed class QueryPreparationTimesAccumulator + { + private readonly List queryPreparationTimesList; + + public QueryPreparationTimesAccumulator() + { + this.queryPreparationTimesList = new List(); + } + + public void Accumulate(QueryPreparationTimesInternal queryPreparationTimes) + { + if (queryPreparationTimes == null) + { + throw new ArgumentNullException(nameof(queryPreparationTimes)); + } + + this.queryPreparationTimesList.Add(queryPreparationTimes); + } + + public QueryPreparationTimesInternal GetQueryPreparationTimes() + { + TimeSpan queryCompilationTime = TimeSpan.Zero; + TimeSpan logicalPlanBuildTime = TimeSpan.Zero; + TimeSpan physicalPlanBuildTime = TimeSpan.Zero; + TimeSpan queryOptimizationTime = TimeSpan.Zero; + + foreach (QueryPreparationTimesInternal queryPreparationTimes in this.queryPreparationTimesList) + { + queryCompilationTime += queryPreparationTimes.QueryCompilationTime; + logicalPlanBuildTime += queryPreparationTimes.LogicalPlanBuildTime; + physicalPlanBuildTime += queryPreparationTimes.PhysicalPlanBuildTime; + queryOptimizationTime += queryPreparationTimes.QueryOptimizationTime; + } + + return new QueryPreparationTimesInternal( + queryCompilationTime: queryCompilationTime, + logicalPlanBuildTime: logicalPlanBuildTime, + physicalPlanBuildTime: physicalPlanBuildTime, + queryOptimizationTime: queryOptimizationTime); + } + } +} diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/QueryPreparationTimesInternal.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/QueryPreparationTimesInternal.cs new file mode 100644 index 0000000000..4e8ee38276 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/QueryPreparationTimesInternal.cs @@ -0,0 +1,65 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ +namespace Microsoft.Azure.Cosmos.Query.Core.Metrics +{ + using System; + + /// + /// Query preparation metrics in the Azure DocumentDB database service. + /// +#if INTERNAL +#pragma warning disable SA1600 +#pragma warning disable CS1591 + public +#else + internal +#endif + sealed class QueryPreparationTimesInternal + { + public static readonly QueryPreparationTimesInternal Zero = new QueryPreparationTimesInternal( + queryCompilationTime: TimeSpan.Zero, + logicalPlanBuildTime: TimeSpan.Zero, + physicalPlanBuildTime: TimeSpan.Zero, + queryOptimizationTime: TimeSpan.Zero); + + /// + /// Initializes a new instance of the QueryPreparationTimes class. + /// + /// Query compile and optimization time + /// Query logical plan build time + /// Query physical plan build time + /// Query optimization time + public QueryPreparationTimesInternal( + TimeSpan queryCompilationTime, + TimeSpan logicalPlanBuildTime, + TimeSpan physicalPlanBuildTime, + TimeSpan queryOptimizationTime) + { + this.QueryCompilationTime = queryCompilationTime; + this.LogicalPlanBuildTime = logicalPlanBuildTime; + this.PhysicalPlanBuildTime = physicalPlanBuildTime; + this.QueryOptimizationTime = queryOptimizationTime; + } + + /// + /// Gets the query compile time in the Azure DocumentDB database service. + /// + public TimeSpan QueryCompilationTime { get; } + + /// + /// Gets the query logical plan build time in the Azure DocumentDB database service. + /// + public TimeSpan LogicalPlanBuildTime { get; } + + /// + /// Gets the query physical plan build time in the Azure DocumentDB database service. + /// + public TimeSpan PhysicalPlanBuildTime { get; } + + /// + /// Gets the query optimization time in the Azure DocumentDB database service. + /// + public TimeSpan QueryOptimizationTime { get; } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/RuntimeExecutionTimes.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/RuntimeExecutionTimes.cs deleted file mode 100644 index 0fd8dc22f0..0000000000 --- a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/RuntimeExecutionTimes.cs +++ /dev/null @@ -1,91 +0,0 @@ -//------------------------------------------------------------ -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------ -namespace Microsoft.Azure.Cosmos.Query.Core.Metrics -{ - using System; - - /// - /// Query runtime execution times in the Azure Cosmos DB service. - /// -#if INTERNAL -#pragma warning disable SA1600 -#pragma warning disable CS1591 - public -#else - internal -#endif - sealed class RuntimeExecutionTimes - { - public static readonly RuntimeExecutionTimes Empty = new RuntimeExecutionTimes( - queryEngineExecutionTime: default, - systemFunctionExecutionTime: default, - userDefinedFunctionExecutionTime: default); - - /// - /// Initializes a new instance of the RuntimeExecutionTimes class. - /// - /// Query end - to - end execution time - /// Total time spent executing system functions - /// Total time spent executing user - defined functions - public RuntimeExecutionTimes( - TimeSpan queryEngineExecutionTime, - TimeSpan systemFunctionExecutionTime, - TimeSpan userDefinedFunctionExecutionTime) - { - this.QueryEngineExecutionTime = queryEngineExecutionTime; - this.SystemFunctionExecutionTime = systemFunctionExecutionTime; - this.UserDefinedFunctionExecutionTime = userDefinedFunctionExecutionTime; - } - - /// - /// Gets the total query runtime execution time in the Azure Cosmos DB service. - /// - public TimeSpan QueryEngineExecutionTime { get; } - - /// - /// Gets the query system function execution time in the Azure Cosmos DB service. - /// - public TimeSpan SystemFunctionExecutionTime { get; } - - /// - /// Gets the query user defined function execution time in the Azure Cosmos DB service. - /// - public TimeSpan UserDefinedFunctionExecutionTime { get; } - - public ref struct Accumulator - { - public Accumulator(TimeSpan queryEngineExecutionTime, TimeSpan systemFunctionExecutionTime, TimeSpan userDefinedFunctionExecutionTimes) - { - this.QueryEngineExecutionTime = queryEngineExecutionTime; - this.SystemFunctionExecutionTime = systemFunctionExecutionTime; - this.UserDefinedFunctionExecutionTime = userDefinedFunctionExecutionTimes; - } - - public TimeSpan QueryEngineExecutionTime { get; set; } - public TimeSpan SystemFunctionExecutionTime { get; set; } - public TimeSpan UserDefinedFunctionExecutionTime { get; set; } - - public Accumulator Accumulate(RuntimeExecutionTimes runtimeExecutionTimes) - { - if (runtimeExecutionTimes == null) - { - throw new ArgumentNullException(nameof(runtimeExecutionTimes)); - } - - return new Accumulator( - queryEngineExecutionTime: this.QueryEngineExecutionTime + runtimeExecutionTimes.QueryEngineExecutionTime, - systemFunctionExecutionTime: this.SystemFunctionExecutionTime + runtimeExecutionTimes.SystemFunctionExecutionTime, - userDefinedFunctionExecutionTimes: this.UserDefinedFunctionExecutionTime + runtimeExecutionTimes.UserDefinedFunctionExecutionTime); - } - - public static RuntimeExecutionTimes ToRuntimeExecutionTimes(Accumulator accumulator) - { - return new RuntimeExecutionTimes( - queryEngineExecutionTime: accumulator.QueryEngineExecutionTime, - systemFunctionExecutionTime: accumulator.SystemFunctionExecutionTime, - userDefinedFunctionExecutionTime: accumulator.UserDefinedFunctionExecutionTime); - } - } - } -} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/RuntimeExecutionTimesAccumulator.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/RuntimeExecutionTimesAccumulator.cs new file mode 100644 index 0000000000..60f5e37573 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/RuntimeExecutionTimesAccumulator.cs @@ -0,0 +1,48 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.Metrics +{ + using System; + using System.Collections.Generic; + + internal sealed class RuntimeExecutionTimesAccumulator + { + private readonly List runtimeExecutionTimesList; + + public RuntimeExecutionTimesAccumulator() + { + this.runtimeExecutionTimesList = new List(); + } + + public void Accumulate(RuntimeExecutionTimesInternal runtimeExecutionTimes) + { + if (runtimeExecutionTimes == null) + { + throw new ArgumentNullException(nameof(runtimeExecutionTimes)); + } + + this.runtimeExecutionTimesList.Add(runtimeExecutionTimes); + } + + public RuntimeExecutionTimesInternal GetRuntimeExecutionTimes() + { + TimeSpan queryEngineExecutionTime = TimeSpan.Zero; + TimeSpan systemFunctionExecutionTime = TimeSpan.Zero; + TimeSpan userDefinedFunctionExecutionTime = TimeSpan.Zero; + + foreach (RuntimeExecutionTimesInternal runtimeExecutionTimes in this.runtimeExecutionTimesList) + { + queryEngineExecutionTime += runtimeExecutionTimes.QueryEngineExecutionTime; + systemFunctionExecutionTime += runtimeExecutionTimes.SystemFunctionExecutionTime; + userDefinedFunctionExecutionTime += runtimeExecutionTimes.UserDefinedFunctionExecutionTime; + } + + return new RuntimeExecutionTimesInternal( + queryEngineExecutionTime: queryEngineExecutionTime, + systemFunctionExecutionTime: systemFunctionExecutionTime, + userDefinedFunctionExecutionTime: userDefinedFunctionExecutionTime); + } + } +} diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/RuntimeExecutionTimesInternal.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/RuntimeExecutionTimesInternal.cs new file mode 100644 index 0000000000..bbd97ca45d --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/RuntimeExecutionTimesInternal.cs @@ -0,0 +1,56 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ +namespace Microsoft.Azure.Cosmos.Query.Core.Metrics +{ + using System; + + /// + /// Query runtime execution times in the Azure Cosmos DB service. + /// +#if INTERNAL +#pragma warning disable SA1600 +#pragma warning disable CS1591 + public +#else + internal +#endif + sealed class RuntimeExecutionTimesInternal + { + public static readonly RuntimeExecutionTimesInternal Empty = new RuntimeExecutionTimesInternal( + queryEngineExecutionTime: TimeSpan.Zero, + systemFunctionExecutionTime: TimeSpan.Zero, + userDefinedFunctionExecutionTime: TimeSpan.Zero); + + /// + /// Initializes a new instance of the RuntimeExecutionTimes class. + /// + /// Query end - to - end execution time + /// Total time spent executing system functions + /// Total time spent executing user - defined functions + public RuntimeExecutionTimesInternal( + TimeSpan queryEngineExecutionTime, + TimeSpan systemFunctionExecutionTime, + TimeSpan userDefinedFunctionExecutionTime) + { + this.QueryEngineExecutionTime = queryEngineExecutionTime; + this.SystemFunctionExecutionTime = systemFunctionExecutionTime; + this.UserDefinedFunctionExecutionTime = userDefinedFunctionExecutionTime; + } + + /// + /// Gets the total query runtime execution time in the Azure Cosmos DB service. + /// + public TimeSpan QueryEngineExecutionTime { get; } + + /// + /// Gets the query system function execution time in the Azure Cosmos DB service. + /// + public TimeSpan SystemFunctionExecutionTime { get; } + + /// + /// Gets the query user defined function execution time in the Azure Cosmos DB service. + /// + public TimeSpan UserDefinedFunctionExecutionTime { get; } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideCumulativeMetrics.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideCumulativeMetrics.cs new file mode 100644 index 0000000000..3e7364f957 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideCumulativeMetrics.cs @@ -0,0 +1,23 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ +namespace Microsoft.Azure.Cosmos +{ + using System.Collections.Generic; + + /// + /// Metrics received for queries from the backend. + /// + public abstract class ServerSideCumulativeMetrics + { + /// + /// Gets the ServerSideMetrics accumulated for a single round trip. + /// + public abstract ServerSideMetrics CumulativeMetrics { get; } + + /// + /// Gets the list of ServerSideMetrics, one for for each partition. + /// + public abstract IReadOnlyList PartitionedMetrics { get; } + } +} diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideCumulativeMetricsInternal.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideCumulativeMetricsInternal.cs new file mode 100644 index 0000000000..5405482bb5 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideCumulativeMetricsInternal.cs @@ -0,0 +1,29 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ +namespace Microsoft.Azure.Cosmos +{ + using System.Collections.Generic; + using System.Linq; + using Microsoft.Azure.Cosmos.Query.Core.Metrics; + + /// + /// Internal implementation of metrics received for queries from the backend. + /// + internal class ServerSideCumulativeMetricsInternal : ServerSideCumulativeMetrics + { + /// + /// Initializes a new instance of the class. + /// + /// + internal ServerSideCumulativeMetricsInternal(IEnumerable serverSideMetricsList) + { + this.PartitionedMetrics = serverSideMetricsList.ToList(); + this.CumulativeMetrics = ServerSideMetricsInternal.Create(serverSideMetricsList.Select(partitionedMetrics => partitionedMetrics.ServerSideMetricsInternal)); + } + + public override ServerSideMetrics CumulativeMetrics { get; } + + public override IReadOnlyList PartitionedMetrics { get; } + } +} diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideMetrics.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideMetrics.cs new file mode 100644 index 0000000000..ff215a582e --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideMetrics.cs @@ -0,0 +1,74 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos +{ + using System; + + /// + /// Metrics received for queries from the backend. + /// + public abstract class ServerSideMetrics + { + /// + /// Gets the total query time in the Azure Cosmos database service. + /// + public abstract TimeSpan TotalTime { get; } + + /// + /// Gets the number of documents retrieved during query in the Azure Cosmos database service. + /// + public abstract long RetrievedDocumentCount { get; } + + /// + /// Gets the size of documents retrieved in bytes during query in the Azure Cosmos DB service. + /// + public abstract long RetrievedDocumentSize { get; } + + /// + /// Gets the number of documents returned by query in the Azure Cosmos DB service. + /// + public abstract long OutputDocumentCount { get; } + + /// + /// Gets the size of documents outputted in bytes during query in the Azure Cosmos database service. + /// + public abstract long OutputDocumentSize { get; } + + /// + /// Gets the query preparation time in the Azure Cosmos database service. + /// + public abstract TimeSpan QueryPreparationTime { get; } + + /// + /// Gets the query index lookup time in the Azure Cosmos database service. + /// + public abstract TimeSpan IndexLookupTime { get; } + + /// + /// Gets the document loading time during query in the Azure Cosmos database service. + /// + public abstract TimeSpan DocumentLoadTime { get; } + + /// + /// Gets the query runtime execution time during query in the Azure Cosmos database service. + /// + public abstract TimeSpan RuntimeExecutionTime { get; } + + /// + /// Gets the output writing/serializing time during query in the Azure Cosmos database service. + /// + public abstract TimeSpan DocumentWriteTime { get; } + + /// + /// Gets the index hit ratio by query in the Azure Cosmos database service. Value is within the range [0,1]. + /// + public abstract double IndexHitRatio { get; } + + /// + /// Gets the VMExecution Time. + /// + public abstract TimeSpan VMExecutionTime { get; } + } +} diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideMetricsInternal.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideMetricsInternal.cs new file mode 100644 index 0000000000..6e80de06a5 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideMetricsInternal.cs @@ -0,0 +1,153 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.Metrics +{ + using System; + using System.Collections.Generic; + + /// + /// internal implementation of metrics received for queries from the backend. + /// +#if INTERNAL +#pragma warning disable SA1600 +#pragma warning disable CS1591 + public +#else + internal +#endif + sealed class ServerSideMetricsInternal : ServerSideMetrics + { + /// + /// QueryMetrics with all members having default (but not null) members. + /// + public static readonly ServerSideMetricsInternal Empty = new ServerSideMetricsInternal( + retrievedDocumentCount: 0, + retrievedDocumentSize: 0, + outputDocumentCount: 0, + outputDocumentSize: 0, + indexHitRatio: 0, + totalQueryExecutionTime: TimeSpan.Zero, + queryPreparationTimes: QueryPreparationTimesInternal.Zero, + indexLookupTime: TimeSpan.Zero, + documentLoadTime: TimeSpan.Zero, + vmExecutionTime: TimeSpan.Zero, + runtimeExecutionTimes: RuntimeExecutionTimesInternal.Empty, + documentWriteTime: TimeSpan.Zero); + + /// + /// Initializes a new instance of the class. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public ServerSideMetricsInternal( + long retrievedDocumentCount, + long retrievedDocumentSize, + long outputDocumentCount, + long outputDocumentSize, + double indexHitRatio, + TimeSpan totalQueryExecutionTime, + QueryPreparationTimesInternal queryPreparationTimes, + TimeSpan indexLookupTime, + TimeSpan documentLoadTime, + TimeSpan vmExecutionTime, + RuntimeExecutionTimesInternal runtimeExecutionTimes, + TimeSpan documentWriteTime, + string feedRange = null, + int? partitionKeyRangeId = null) + { + this.RetrievedDocumentCount = retrievedDocumentCount; + this.RetrievedDocumentSize = retrievedDocumentSize; + this.OutputDocumentCount = outputDocumentCount; + this.OutputDocumentSize = outputDocumentSize; + this.IndexHitRatio = indexHitRatio; + this.TotalTime = totalQueryExecutionTime; + this.QueryPreparationTimes = queryPreparationTimes ?? throw new ArgumentNullException($"{nameof(queryPreparationTimes)} can not be null."); + this.IndexLookupTime = indexLookupTime; + this.DocumentLoadTime = documentLoadTime; + this.VMExecutionTime = vmExecutionTime; + this.RuntimeExecutionTimes = runtimeExecutionTimes ?? throw new ArgumentNullException($"{nameof(runtimeExecutionTimes)} can not be null."); + this.DocumentWriteTime = documentWriteTime; + this.FeedRange = feedRange; + this.PartitionKeyRangeId = partitionKeyRangeId; + } + + public override TimeSpan TotalTime { get; } + + public override long RetrievedDocumentCount { get; } + + public override long RetrievedDocumentSize { get; } + + public override long OutputDocumentCount { get; } + + public override long OutputDocumentSize { get; } + + public QueryPreparationTimesInternal QueryPreparationTimes { get; } + + public override TimeSpan QueryPreparationTime => + this.QueryPreparationTimes.LogicalPlanBuildTime + + this.QueryPreparationTimes.PhysicalPlanBuildTime + + this.QueryPreparationTimes.QueryCompilationTime + + this.QueryPreparationTimes.QueryOptimizationTime; + + public override TimeSpan IndexLookupTime { get; } + + public override TimeSpan DocumentLoadTime { get; } + + public RuntimeExecutionTimesInternal RuntimeExecutionTimes { get; } + + public override TimeSpan RuntimeExecutionTime => + this.RuntimeExecutionTimes.QueryEngineExecutionTime + + this.RuntimeExecutionTimes.SystemFunctionExecutionTime + + this.RuntimeExecutionTimes.UserDefinedFunctionExecutionTime; + + public override TimeSpan DocumentWriteTime { get; } + + public override double IndexHitRatio { get; } + + public override TimeSpan VMExecutionTime { get; } + + public string FeedRange { get; set; } + + public int? PartitionKeyRangeId { get; set; } + + public static ServerSideMetricsInternal Create(IEnumerable serverSideMetricsEnumerable) + { + ServerSideMetricsInternalAccumulator accumulator = new ServerSideMetricsInternalAccumulator(); + foreach (ServerSideMetricsInternal serverSideMetrics in serverSideMetricsEnumerable) + { + accumulator.Accumulate(serverSideMetrics); + } + + return accumulator.GetServerSideMetrics(); + } + + public static bool TryParseFromDelimitedString(string delimitedString, out ServerSideMetricsInternal serverSideMetrics) + { + return ServerSideMetricsParser.TryParse(delimitedString, out serverSideMetrics); + } + + public static ServerSideMetricsInternal ParseFromDelimitedString(string delimitedString) + { + if (!ServerSideMetricsParser.TryParse(delimitedString, out ServerSideMetricsInternal serverSideMetrics)) + { + throw new FormatException(); + } + + return serverSideMetrics; + } + } +} diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideMetricsInternalAccumulator.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideMetricsInternalAccumulator.cs new file mode 100644 index 0000000000..64be05e6b8 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideMetricsInternalAccumulator.cs @@ -0,0 +1,146 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core.Metrics +{ + using System; + using System.Collections.Generic; + using Microsoft.Azure.Cosmos.Tracing; + using Microsoft.Azure.Cosmos.Tracing.TraceData; + + internal sealed class ServerSideMetricsInternalAccumulator + { + private readonly List serverSideMetricsList; + + public ServerSideMetricsInternalAccumulator() + { + this.serverSideMetricsList = new List(); + } + + public void Accumulate(ServerSideMetricsInternal serverSideMetrics) + { + if (serverSideMetrics == null) + { + throw new ArgumentNullException(nameof(serverSideMetrics)); + } + + this.serverSideMetricsList.Add(serverSideMetrics); + } + + public ServerSideMetricsInternal GetServerSideMetrics() + { + TimeSpan totalTime = TimeSpan.Zero; + long retrievedDocumentCount = 0; + long retrievedDocumentSize = 0; + long outputDocumentCount = 0; + long outputDocumentSize = 0; + double indexHitRatio = 0; + QueryPreparationTimesAccumulator queryPreparationTimesAccumulator = new QueryPreparationTimesAccumulator(); + TimeSpan indexLookupTime = TimeSpan.Zero; + TimeSpan documentLoadTime = TimeSpan.Zero; + RuntimeExecutionTimesAccumulator runtimeExecutionTimesAccumulator = new RuntimeExecutionTimesAccumulator(); + TimeSpan documentWriteTime = TimeSpan.Zero; + TimeSpan vMExecutionTime = TimeSpan.Zero; + + foreach (ServerSideMetricsInternal serverSideMetrics in this.serverSideMetricsList) + { + indexHitRatio = (retrievedDocumentCount + serverSideMetrics.RetrievedDocumentCount) != 0 ? + ((retrievedDocumentCount * indexHitRatio) + (serverSideMetrics.RetrievedDocumentCount * serverSideMetrics.IndexHitRatio)) / (retrievedDocumentCount + serverSideMetrics.RetrievedDocumentCount) : + 0; + totalTime += serverSideMetrics.TotalTime; + retrievedDocumentCount += serverSideMetrics.RetrievedDocumentCount; + retrievedDocumentSize += serverSideMetrics.RetrievedDocumentSize; + outputDocumentCount += serverSideMetrics.OutputDocumentCount; + outputDocumentSize += serverSideMetrics.OutputDocumentSize; + queryPreparationTimesAccumulator.Accumulate(serverSideMetrics.QueryPreparationTimes); + indexLookupTime += serverSideMetrics.IndexLookupTime; + documentLoadTime += serverSideMetrics.DocumentLoadTime; + runtimeExecutionTimesAccumulator.Accumulate(serverSideMetrics.RuntimeExecutionTimes); + documentWriteTime += serverSideMetrics.DocumentWriteTime; + vMExecutionTime += serverSideMetrics.VMExecutionTime; + } + + return new ServerSideMetricsInternal( + retrievedDocumentCount: retrievedDocumentCount, + retrievedDocumentSize: retrievedDocumentSize, + outputDocumentCount: outputDocumentCount, + outputDocumentSize: outputDocumentSize, + indexHitRatio: indexHitRatio, + totalQueryExecutionTime: totalTime, + queryPreparationTimes: queryPreparationTimesAccumulator.GetQueryPreparationTimes(), + indexLookupTime: indexLookupTime, + documentLoadTime: documentLoadTime, + vmExecutionTime: vMExecutionTime, + runtimeExecutionTimes: runtimeExecutionTimesAccumulator.GetRuntimeExecutionTimes(), + documentWriteTime: documentWriteTime); + } + + public List GetPartitionedServerSideMetrics() + { + return this.serverSideMetricsList; + } + + public static void WalkTraceTreeForQueryMetrics(ITrace currentTrace, ServerSideMetricsInternalAccumulator accumulator) + { + if (currentTrace == null) + { + return; + } + + foreach (object datum in currentTrace.Data.Values) + { + if (datum is QueryMetricsTraceDatum queryMetricsTraceDatum) + { + queryMetricsTraceDatum.QueryMetrics.ServerSideMetrics.FeedRange = currentTrace.Name; + queryMetricsTraceDatum.QueryMetrics.ServerSideMetrics.PartitionKeyRangeId = WalkTraceTreeForPartitionKeyRangeId(currentTrace); + accumulator.Accumulate(queryMetricsTraceDatum.QueryMetrics.ServerSideMetrics); + return; + } + } + + foreach (ITrace childTrace in currentTrace.Children) + { + WalkTraceTreeForQueryMetrics(childTrace, accumulator); + } + + return; + } + + private static int? WalkTraceTreeForPartitionKeyRangeId(ITrace currentTrace) + { + if (currentTrace == null) + { + return null; + } + + foreach (Object datum in currentTrace.Data.Values) + { + if (datum is ClientSideRequestStatisticsTraceDatum clientSideRequestStatisticsTraceDatum) + { + if (clientSideRequestStatisticsTraceDatum.StoreResponseStatisticsList.Count > 0) + { + return int.TryParse(clientSideRequestStatisticsTraceDatum.StoreResponseStatisticsList[0].StoreResult.PartitionKeyRangeId, out int pKRangeId) + ? pKRangeId + : null; + } + else + { + return null; + } + } + } + + foreach (ITrace childTrace in currentTrace.Children) + { + int? partitionKeyRangeId = WalkTraceTreeForPartitionKeyRangeId(childTrace); + if (partitionKeyRangeId != null) + { + return partitionKeyRangeId; + } + } + + return null; + } + } +} diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/BackendMetricsParser.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideMetricsParser.cs similarity index 53% rename from Microsoft.Azure.Cosmos/src/Query/Core/Metrics/BackendMetricsParser.cs rename to Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideMetricsParser.cs index ecd5becdd4..eeba3c6c85 100644 --- a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/BackendMetricsParser.cs +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideMetricsParser.cs @@ -8,7 +8,7 @@ namespace Microsoft.Azure.Cosmos.Query.Core.Metrics using System.Text; /// - /// Parser for . + /// Parser for . /// #if INTERNAL #pragma warning disable SA1600 @@ -17,9 +17,9 @@ namespace Microsoft.Azure.Cosmos.Query.Core.Metrics #else internal #endif - static class BackendMetricsParser + static class ServerSideMetricsParser { - public static unsafe bool TryParse(string deliminatedString, out BackendMetrics backendMetrics) + public static unsafe bool TryParse(string deliminatedString, out ServerSideMetricsInternal serverSideMetrics) { if (deliminatedString == null) { @@ -30,7 +30,7 @@ public static unsafe bool TryParse(string deliminatedString, out BackendMetrics { // Stack allocating a zero length buffer returns a null pointer // so we special case the zero length string. - backendMetrics = BackendMetrics.Empty; + serverSideMetrics = ServerSideMetricsInternal.Empty; return true; } @@ -72,7 +72,7 @@ public static unsafe bool TryParse(string deliminatedString, out BackendMetrics while (!corpus.IsEmpty) { - (BackendMetricsTokenizer.TokenType? tokenType, ReadOnlyMemory buffer) = BackendMetricsTokenizer.Read(corpus); + (ServerSideMetricsTokenizer.TokenType? tokenType, ReadOnlyMemory buffer) = ServerSideMetricsTokenizer.Read(corpus); int bytesConsumed; if (!tokenType.HasValue) @@ -95,162 +95,162 @@ public static unsafe bool TryParse(string deliminatedString, out BackendMetrics { switch (tokenType.Value) { - case BackendMetricsTokenizer.TokenType.DocumentLoadTimeInMs: - corpus = corpus.Slice(BackendMetricsTokenizer.TokenBuffers.DocumentLoadTimeInMs.Length); - if (!BackendMetricsParser.TryParseTimeSpanField(corpus, out documentLoadTime, out bytesConsumed)) + case ServerSideMetricsTokenizer.TokenType.DocumentLoadTimeInMs: + corpus = corpus.Slice(ServerSideMetricsTokenizer.TokenBuffers.DocumentLoadTimeInMs.Length); + if (!ServerSideMetricsParser.TryParseTimeSpanField(corpus, out documentLoadTime, out bytesConsumed)) { - backendMetrics = default; + serverSideMetrics = default; return false; } break; - case BackendMetricsTokenizer.TokenType.WriteOutputTimeInMs: - corpus = corpus.Slice(BackendMetricsTokenizer.TokenBuffers.WriteOutputTimeInMs.Length); - if (!BackendMetricsParser.TryParseTimeSpanField(corpus, out documentWriteTime, out bytesConsumed)) + case ServerSideMetricsTokenizer.TokenType.WriteOutputTimeInMs: + corpus = corpus.Slice(ServerSideMetricsTokenizer.TokenBuffers.WriteOutputTimeInMs.Length); + if (!ServerSideMetricsParser.TryParseTimeSpanField(corpus, out documentWriteTime, out bytesConsumed)) { - backendMetrics = default; + serverSideMetrics = default; return false; } break; - case BackendMetricsTokenizer.TokenType.IndexLookupTimeInMs: - corpus = corpus.Slice(BackendMetricsTokenizer.TokenBuffers.IndexLookupTimeInMs.Length); - if (!BackendMetricsParser.TryParseTimeSpanField(corpus, out indexLookupTime, out bytesConsumed)) + case ServerSideMetricsTokenizer.TokenType.IndexLookupTimeInMs: + corpus = corpus.Slice(ServerSideMetricsTokenizer.TokenBuffers.IndexLookupTimeInMs.Length); + if (!ServerSideMetricsParser.TryParseTimeSpanField(corpus, out indexLookupTime, out bytesConsumed)) { - backendMetrics = default; + serverSideMetrics = default; return false; } break; - case BackendMetricsTokenizer.TokenType.IndexUtilizationRatio: - corpus = corpus.Slice(BackendMetricsTokenizer.TokenBuffers.IndexUtilizationRatio.Length); - if (!BackendMetricsParser.TryParseDoubleField(corpus, out indexHitRatio, out bytesConsumed)) + case ServerSideMetricsTokenizer.TokenType.IndexUtilizationRatio: + corpus = corpus.Slice(ServerSideMetricsTokenizer.TokenBuffers.IndexUtilizationRatio.Length); + if (!ServerSideMetricsParser.TryParseDoubleField(corpus, out indexHitRatio, out bytesConsumed)) { - backendMetrics = default; + serverSideMetrics = default; return false; } break; - case BackendMetricsTokenizer.TokenType.QueryLogicalPlanBuildTimeInMs: - corpus = corpus.Slice(BackendMetricsTokenizer.TokenBuffers.QueryLogicalPlanBuildTimeInMs.Length); - if (!BackendMetricsParser.TryParseTimeSpanField(corpus, out logicalPlanBuildTime, out bytesConsumed)) + case ServerSideMetricsTokenizer.TokenType.QueryLogicalPlanBuildTimeInMs: + corpus = corpus.Slice(ServerSideMetricsTokenizer.TokenBuffers.QueryLogicalPlanBuildTimeInMs.Length); + if (!ServerSideMetricsParser.TryParseTimeSpanField(corpus, out logicalPlanBuildTime, out bytesConsumed)) { - backendMetrics = default; + serverSideMetrics = default; return false; } break; - case BackendMetricsTokenizer.TokenType.OutputDocumentCount: - corpus = corpus.Slice(BackendMetricsTokenizer.TokenBuffers.OutputDocumentCount.Length); - if (!BackendMetricsParser.TryParseLongField(corpus, out outputDocumentCount, out bytesConsumed)) + case ServerSideMetricsTokenizer.TokenType.OutputDocumentCount: + corpus = corpus.Slice(ServerSideMetricsTokenizer.TokenBuffers.OutputDocumentCount.Length); + if (!ServerSideMetricsParser.TryParseLongField(corpus, out outputDocumentCount, out bytesConsumed)) { - backendMetrics = default; + serverSideMetrics = default; return false; } break; - case BackendMetricsTokenizer.TokenType.OutputDocumentSize: - corpus = corpus.Slice(BackendMetricsTokenizer.TokenBuffers.OutputDocumentSize.Length); - if (!BackendMetricsParser.TryParseLongField(corpus, out outputDocumentSize, out bytesConsumed)) + case ServerSideMetricsTokenizer.TokenType.OutputDocumentSize: + corpus = corpus.Slice(ServerSideMetricsTokenizer.TokenBuffers.OutputDocumentSize.Length); + if (!ServerSideMetricsParser.TryParseLongField(corpus, out outputDocumentSize, out bytesConsumed)) { - backendMetrics = default; + serverSideMetrics = default; return false; } break; - case BackendMetricsTokenizer.TokenType.QueryPhysicalPlanBuildTimeInMs: - corpus = corpus.Slice(BackendMetricsTokenizer.TokenBuffers.QueryPhysicalPlanBuildTimeInMs.Length); - if (!BackendMetricsParser.TryParseTimeSpanField(corpus, out physicalPlanBuildTime, out bytesConsumed)) + case ServerSideMetricsTokenizer.TokenType.QueryPhysicalPlanBuildTimeInMs: + corpus = corpus.Slice(ServerSideMetricsTokenizer.TokenBuffers.QueryPhysicalPlanBuildTimeInMs.Length); + if (!ServerSideMetricsParser.TryParseTimeSpanField(corpus, out physicalPlanBuildTime, out bytesConsumed)) { - backendMetrics = default; + serverSideMetrics = default; return false; } break; - case BackendMetricsTokenizer.TokenType.QueryCompileTimeInMs: - corpus = corpus.Slice(BackendMetricsTokenizer.TokenBuffers.QueryCompileTimeInMs.Length); - if (!BackendMetricsParser.TryParseTimeSpanField(corpus, out queryCompilationTime, out bytesConsumed)) + case ServerSideMetricsTokenizer.TokenType.QueryCompileTimeInMs: + corpus = corpus.Slice(ServerSideMetricsTokenizer.TokenBuffers.QueryCompileTimeInMs.Length); + if (!ServerSideMetricsParser.TryParseTimeSpanField(corpus, out queryCompilationTime, out bytesConsumed)) { - backendMetrics = default; + serverSideMetrics = default; return false; } break; - case BackendMetricsTokenizer.TokenType.QueryOptimizationTimeInMs: - corpus = corpus.Slice(BackendMetricsTokenizer.TokenBuffers.QueryOptimizationTimeInMs.Length); - if (!BackendMetricsParser.TryParseTimeSpanField(corpus, out queryOptimizationTime, out bytesConsumed)) + case ServerSideMetricsTokenizer.TokenType.QueryOptimizationTimeInMs: + corpus = corpus.Slice(ServerSideMetricsTokenizer.TokenBuffers.QueryOptimizationTimeInMs.Length); + if (!ServerSideMetricsParser.TryParseTimeSpanField(corpus, out queryOptimizationTime, out bytesConsumed)) { - backendMetrics = default; + serverSideMetrics = default; return false; } break; - case BackendMetricsTokenizer.TokenType.RetrievedDocumentCount: - corpus = corpus.Slice(BackendMetricsTokenizer.TokenBuffers.RetrievedDocumentCount.Length); - if (!BackendMetricsParser.TryParseLongField(corpus, out retrievedDocumentCount, out bytesConsumed)) + case ServerSideMetricsTokenizer.TokenType.RetrievedDocumentCount: + corpus = corpus.Slice(ServerSideMetricsTokenizer.TokenBuffers.RetrievedDocumentCount.Length); + if (!ServerSideMetricsParser.TryParseLongField(corpus, out retrievedDocumentCount, out bytesConsumed)) { - backendMetrics = default; + serverSideMetrics = default; return false; } break; - case BackendMetricsTokenizer.TokenType.RetrievedDocumentSize: - corpus = corpus.Slice(BackendMetricsTokenizer.TokenBuffers.RetrievedDocumentSize.Length); - if (!BackendMetricsParser.TryParseLongField(corpus, out retrievedDocumentSize, out bytesConsumed)) + case ServerSideMetricsTokenizer.TokenType.RetrievedDocumentSize: + corpus = corpus.Slice(ServerSideMetricsTokenizer.TokenBuffers.RetrievedDocumentSize.Length); + if (!ServerSideMetricsParser.TryParseLongField(corpus, out retrievedDocumentSize, out bytesConsumed)) { - backendMetrics = default; + serverSideMetrics = default; return false; } break; - case BackendMetricsTokenizer.TokenType.SystemFunctionExecuteTimeInMs: - corpus = corpus.Slice(BackendMetricsTokenizer.TokenBuffers.SystemFunctionExecuteTimeInMs.Length); - if (!BackendMetricsParser.TryParseTimeSpanField(corpus, out systemFunctionExecutionTime, out bytesConsumed)) + case ServerSideMetricsTokenizer.TokenType.SystemFunctionExecuteTimeInMs: + corpus = corpus.Slice(ServerSideMetricsTokenizer.TokenBuffers.SystemFunctionExecuteTimeInMs.Length); + if (!ServerSideMetricsParser.TryParseTimeSpanField(corpus, out systemFunctionExecutionTime, out bytesConsumed)) { - backendMetrics = default; + serverSideMetrics = default; return false; } break; - case BackendMetricsTokenizer.TokenType.TotalExecutionTimeInMs: - corpus = corpus.Slice(BackendMetricsTokenizer.TokenBuffers.TotalExecutionTimeInMs.Length); - if (!BackendMetricsParser.TryParseTimeSpanField(corpus, out totalQueryExecutionTime, out bytesConsumed)) + case ServerSideMetricsTokenizer.TokenType.TotalExecutionTimeInMs: + corpus = corpus.Slice(ServerSideMetricsTokenizer.TokenBuffers.TotalExecutionTimeInMs.Length); + if (!ServerSideMetricsParser.TryParseTimeSpanField(corpus, out totalQueryExecutionTime, out bytesConsumed)) { - backendMetrics = default; + serverSideMetrics = default; return false; } break; - case BackendMetricsTokenizer.TokenType.UserFunctionExecuteTimeInMs: - corpus = corpus.Slice(BackendMetricsTokenizer.TokenBuffers.UserFunctionExecuteTimeInMs.Length); - if (!BackendMetricsParser.TryParseTimeSpanField(corpus, out userDefinedFunctionExecutionTime, out bytesConsumed)) + case ServerSideMetricsTokenizer.TokenType.UserFunctionExecuteTimeInMs: + corpus = corpus.Slice(ServerSideMetricsTokenizer.TokenBuffers.UserFunctionExecuteTimeInMs.Length); + if (!ServerSideMetricsParser.TryParseTimeSpanField(corpus, out userDefinedFunctionExecutionTime, out bytesConsumed)) { - backendMetrics = default; + serverSideMetrics = default; return false; } break; - case BackendMetricsTokenizer.TokenType.VMExecutionTimeInMs: - corpus = corpus.Slice(BackendMetricsTokenizer.TokenBuffers.VMExecutionTimeInMs.Length); - if (!BackendMetricsParser.TryParseTimeSpanField(corpus, out vmExecutionTime, out bytesConsumed)) + case ServerSideMetricsTokenizer.TokenType.VMExecutionTimeInMs: + corpus = corpus.Slice(ServerSideMetricsTokenizer.TokenBuffers.VMExecutionTimeInMs.Length); + if (!ServerSideMetricsParser.TryParseTimeSpanField(corpus, out vmExecutionTime, out bytesConsumed)) { - backendMetrics = default; + serverSideMetrics = default; return false; } break; default: - backendMetrics = default; + serverSideMetrics = default; return false; } } corpus = corpus.Slice(bytesConsumed); if (!corpus.IsEmpty) { - (BackendMetricsTokenizer.TokenType? semicolonToken, ReadOnlyMemory semicolonBuffer) = BackendMetricsTokenizer.Read(corpus); - if (!semicolonToken.HasValue || (semicolonToken != BackendMetricsTokenizer.TokenType.SemiColonDelimiter)) + (ServerSideMetricsTokenizer.TokenType? semicolonToken, ReadOnlyMemory semicolonBuffer) = ServerSideMetricsTokenizer.Read(corpus); + if (!semicolonToken.HasValue || (semicolonToken != ServerSideMetricsTokenizer.TokenType.SemiColonDelimiter)) { - backendMetrics = default; + serverSideMetrics = default; return false; } @@ -258,14 +258,14 @@ public static unsafe bool TryParse(string deliminatedString, out BackendMetrics } } - backendMetrics = new BackendMetrics( + serverSideMetrics = new ServerSideMetricsInternal( retrievedDocumentCount: retrievedDocumentCount, retrievedDocumentSize: retrievedDocumentSize, outputDocumentCount: outputDocumentCount, outputDocumentSize: outputDocumentSize, indexHitRatio: indexHitRatio, totalQueryExecutionTime: totalQueryExecutionTime, - queryPreparationTimes: new QueryPreparationTimes( + queryPreparationTimes: new QueryPreparationTimesInternal( queryCompilationTime: queryCompilationTime, logicalPlanBuildTime: logicalPlanBuildTime, physicalPlanBuildTime: physicalPlanBuildTime, @@ -273,7 +273,7 @@ public static unsafe bool TryParse(string deliminatedString, out BackendMetrics indexLookupTime: indexLookupTime, documentLoadTime: documentLoadTime, vmExecutionTime: vmExecutionTime, - runtimeExecutionTimes: new RuntimeExecutionTimes( + runtimeExecutionTimes: new RuntimeExecutionTimesInternal( queryEngineExecutionTime: vmExecutionTime - indexLookupTime - documentLoadTime - documentWriteTime, systemFunctionExecutionTime: systemFunctionExecutionTime, userDefinedFunctionExecutionTime: userDefinedFunctionExecutionTime), @@ -283,8 +283,8 @@ public static unsafe bool TryParse(string deliminatedString, out BackendMetrics private static bool TryParseTimeSpanField(ReadOnlySpan corpus, out TimeSpan timeSpan, out int bytesConsumed) { - (BackendMetricsTokenizer.TokenType? tokenType, ReadOnlyMemory buffer) = BackendMetricsTokenizer.Read(corpus); - if (!tokenType.HasValue || (tokenType.Value != BackendMetricsTokenizer.TokenType.EqualsDelimiter)) + (ServerSideMetricsTokenizer.TokenType? tokenType, ReadOnlyMemory buffer) = ServerSideMetricsTokenizer.Read(corpus); + if (!tokenType.HasValue || (tokenType.Value != ServerSideMetricsTokenizer.TokenType.EqualsDelimiter)) { timeSpan = default; bytesConsumed = default; @@ -306,8 +306,8 @@ private static bool TryParseTimeSpanField(ReadOnlySpan corpus, out TimeSpa private static bool TryParseLongField(ReadOnlySpan corpus, out long value, out int bytesConsumed) { - (BackendMetricsTokenizer.TokenType? tokenType, ReadOnlyMemory buffer) = BackendMetricsTokenizer.Read(corpus); - if (!tokenType.HasValue || (tokenType.Value != BackendMetricsTokenizer.TokenType.EqualsDelimiter)) + (ServerSideMetricsTokenizer.TokenType? tokenType, ReadOnlyMemory buffer) = ServerSideMetricsTokenizer.Read(corpus); + if (!tokenType.HasValue || (tokenType.Value != ServerSideMetricsTokenizer.TokenType.EqualsDelimiter)) { value = default; bytesConsumed = default; @@ -327,8 +327,8 @@ private static bool TryParseLongField(ReadOnlySpan corpus, out long value, private static bool TryParseDoubleField(ReadOnlySpan corpus, out double value, out int bytesConsumed) { - (BackendMetricsTokenizer.TokenType? tokenType, ReadOnlyMemory buffer) = BackendMetricsTokenizer.Read(corpus); - if (!tokenType.HasValue || (tokenType.Value != BackendMetricsTokenizer.TokenType.EqualsDelimiter)) + (ServerSideMetricsTokenizer.TokenType? tokenType, ReadOnlyMemory buffer) = ServerSideMetricsTokenizer.Read(corpus); + if (!tokenType.HasValue || (tokenType.Value != ServerSideMetricsTokenizer.TokenType.EqualsDelimiter)) { value = default; bytesConsumed = default; diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/BackendMetricsTokenizer.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideMetricsTokenizer.cs similarity index 98% rename from Microsoft.Azure.Cosmos/src/Query/Core/Metrics/BackendMetricsTokenizer.cs rename to Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideMetricsTokenizer.cs index f17e6afbf4..431f3add64 100644 --- a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/BackendMetricsTokenizer.cs +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideMetricsTokenizer.cs @@ -8,7 +8,7 @@ namespace Microsoft.Azure.Cosmos.Query.Core.Metrics using System.Text; /// - /// Tokenizer for + /// Tokenizer for /// #if INTERNAL #pragma warning disable SA1600 @@ -18,7 +18,7 @@ namespace Microsoft.Azure.Cosmos.Query.Core.Metrics #else internal #endif - static class BackendMetricsTokenizer + static class ServerSideMetricsTokenizer { public enum TokenType { diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideMetricsUtils.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideMetricsUtils.cs new file mode 100644 index 0000000000..a439bdfd57 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideMetricsUtils.cs @@ -0,0 +1,13 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ +namespace Microsoft.Azure.Cosmos.Query.Core.Metrics +{ + internal static class ServerSideMetricsUtils + { + public static string FormatTrace(this ServerSideMetricsInternal serverSideMetrics) + { + return $"totalExecutionTimeInMs={serverSideMetrics.TotalTime.TotalMilliseconds};queryCompileTimeInMs={serverSideMetrics.QueryPreparationTimes.QueryCompilationTime.TotalMilliseconds};queryLogicalPlanBuildTimeInMs={serverSideMetrics.QueryPreparationTimes.LogicalPlanBuildTime.TotalMilliseconds};queryPhysicalPlanBuildTimeInMs={serverSideMetrics.QueryPreparationTimes.PhysicalPlanBuildTime.TotalMilliseconds};queryOptimizationTimeInMs={serverSideMetrics.QueryPreparationTimes.QueryOptimizationTime.TotalMilliseconds};indexLookupTimeInMs={serverSideMetrics.IndexLookupTime.TotalMilliseconds};documentLoadTimeInMs={serverSideMetrics.DocumentLoadTime.TotalMilliseconds};systemFunctionExecuteTimeInMs={serverSideMetrics.RuntimeExecutionTimes.SystemFunctionExecutionTime.TotalMilliseconds};userFunctionExecuteTimeInMs={serverSideMetrics.RuntimeExecutionTimes.UserDefinedFunctionExecutionTime.TotalMilliseconds};retrievedDocumentCount={serverSideMetrics.RetrievedDocumentCount};retrievedDocumentSize={serverSideMetrics.RetrievedDocumentSize};outputDocumentCount={serverSideMetrics.OutputDocumentCount};outputDocumentSize={serverSideMetrics.OutputDocumentSize};writeOutputTimeInMs={serverSideMetrics.DocumentWriteTime.TotalMilliseconds};indexUtilizationRatio={serverSideMetrics.IndexHitRatio}"; + } + } +} diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSidePartitionedMetrics.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSidePartitionedMetrics.cs new file mode 100644 index 0000000000..be5a624a42 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSidePartitionedMetrics.cs @@ -0,0 +1,30 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos +{ + /// + /// Represents server side metrics specific for a single partition. + /// + public abstract class ServerSidePartitionedMetrics + { + /// + /// Gets the backend metrics for the request. + /// + public abstract ServerSideMetrics ServerSideMetrics { get; } + + /// + /// Gets the FeedRange for the partition. + /// + public abstract string FeedRange { get; } + + /// + /// Gets the partition key range id for the partition. + /// + /// + /// Only has a value in direct mode. When using gateway mode, this is null. + /// + public abstract int? PartitionKeyRangeId { get; } + } +} diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSidePartitionedMetricsInternal.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSidePartitionedMetricsInternal.cs new file mode 100644 index 0000000000..9ed30963a6 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSidePartitionedMetricsInternal.cs @@ -0,0 +1,40 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos +{ + using Microsoft.Azure.Cosmos.Query.Core.Metrics; + + /// + /// The internal implementation for server side metrics specific for a single partition. + /// + internal class ServerSidePartitionedMetricsInternal : ServerSidePartitionedMetrics + { + internal ServerSidePartitionedMetricsInternal(ServerSideMetricsInternal serverSideMetricsInternal) + : this(serverSideMetricsInternal, serverSideMetricsInternal.FeedRange, serverSideMetricsInternal.PartitionKeyRangeId) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// + /// + /// + internal ServerSidePartitionedMetricsInternal(ServerSideMetricsInternal serverSideMetricsInternal, string feedRange, int? partitionKeyRangeId) + { + this.ServerSideMetricsInternal = serverSideMetricsInternal; + this.FeedRange = feedRange; + this.PartitionKeyRangeId = partitionKeyRangeId; + } + + public ServerSideMetricsInternal ServerSideMetricsInternal { get; } + + public override ServerSideMetrics ServerSideMetrics => this.ServerSideMetricsInternal; + + public override string FeedRange { get; } + + public override int? PartitionKeyRangeId { get; } + } +} diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/SingleIndexIndexMetrics.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/SingleIndexIndexMetrics.cs new file mode 100644 index 0000000000..2c8826c3ea --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/SingleIndexIndexMetrics.cs @@ -0,0 +1,47 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ +namespace Microsoft.Azure.Cosmos.Query.Core.Metrics +{ + using System; + using Newtonsoft.Json; + + /// + /// Query index utilization data for single indexes (sub-structure of the Index Metrics class) in the Azure Cosmos database service. + /// + #if INTERNAL +#pragma warning disable SA1600 +#pragma warning disable CS1591 + public +#else + internal +#endif + sealed class SingleIndexIndexMetrics + { + /// + /// Initialized a new instance of an Index Metrics' Single Index class. + /// + /// The string representation of the single index. + /// The index impact score. + [JsonConstructor] + public SingleIndexIndexMetrics( + string indexDocumentExpression, + string indexImpactScore) + { + this.IndexDocumentExpression = indexDocumentExpression; + this.IndexImpactScore = indexImpactScore; + } + + /// + /// String representation of index paths of a composite index. + /// + [JsonProperty(PropertyName = "IndexSpec")] + public string IndexDocumentExpression { get; } + + /// + /// The index impact score of the single index. + /// + [JsonProperty(PropertyName = "IndexImpactScore")] + public string IndexImpactScore { get; } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Parser/CstToAstVisitor.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Parser/CstToAstVisitor.cs index 7ca3a60a71..fd92b233a8 100644 --- a/Microsoft.Azure.Cosmos/src/Query/Core/Parser/CstToAstVisitor.cs +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Parser/CstToAstVisitor.cs @@ -9,6 +9,7 @@ namespace Microsoft.Azure.Cosmos.Query.Core.Parser using System.Collections.Immutable; using System.Diagnostics.Contracts; using System.Globalization; + using System.Text; using Antlr4.Runtime.Misc; using Antlr4.Runtime.Tree; using Microsoft.Azure.Cosmos.SqlObjects; @@ -950,8 +951,45 @@ public UnknownSqlObjectException(SqlObject sqlObject, Exception innerException = private static string GetStringValueFromNode(IParseTree parseTree) { string text = parseTree.GetText(); - string textWithoutQuotes = text.Substring(1, text.Length - 2).Replace("\\\"", "\""); - return textWithoutQuotes; + + // 1. Remove leading and trailing (single or double) quotes. + // 2. Unescape following characters: + // \" => " + // \\ => \ + // \/ => / + // Based on the documentation, we should also escape single quote \'. + // https://learn.microsoft.com/en-us/azure/cosmos-db/nosql/query/constants#remarks + // However that's failing in the parser (before reaching this point) and will be fixed separately (after checking server's behavior). + StringBuilder stringBuilder = new StringBuilder(text.Length); + for (int index = 1; index < text.Length - 1; index++) + { + switch (text[index]) + { + case '\\': + if ((index + 1) < (text.Length - 1)) + { + switch (text[index + 1]) + { + case '"': + case '\\': + case '/': + stringBuilder.Append(text[index + 1]); + index++; + break; + default: + stringBuilder.Append(text[index]); + break; + } + } + break; + + default: + stringBuilder.Append(text[index]); + break; + } + } + + return stringBuilder.ToString(); } private static Number64 GetNumber64ValueFromNode(IParseTree parseTree) diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/CosmosQueryExecutionContextFactory.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/CosmosQueryExecutionContextFactory.cs index 47aa1c4490..adb19c303f 100644 --- a/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/CosmosQueryExecutionContextFactory.cs +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/CosmosQueryExecutionContextFactory.cs @@ -7,6 +7,7 @@ namespace Microsoft.Azure.Cosmos.Query.Core.ExecutionContext using System.Collections.Generic; using System.Diagnostics; using System.Linq; + using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using Microsoft.Azure.Cosmos; @@ -27,14 +28,17 @@ namespace Microsoft.Azure.Cosmos.Query.Core.ExecutionContext using Microsoft.Azure.Cosmos.SqlObjects; using Microsoft.Azure.Cosmos.SqlObjects.Visitors; using Microsoft.Azure.Cosmos.Tracing; + using Microsoft.Azure.Documents.Routing; internal static class CosmosQueryExecutionContextFactory { private const string InternalPartitionKeyDefinitionProperty = "x-ms-query-partitionkey-definition"; + private const string QueryInspectionPattern = @"\s+(GROUP\s+BY\s+|COUNT\s*\(|MIN\s*\(|MAX\s*\(|AVG\s*\(|SUM\s*\(|DISTINCT\s+)"; private const string OptimisticDirectExecution = "OptimisticDirectExecution"; private const string Passthrough = "Passthrough"; private const string Specialized = "Specialized"; private const int PageSizeFactorForTop = 5; + private static readonly Regex QueryInspectionRegex = new Regex(QueryInspectionPattern, RegexOptions.IgnoreCase | RegexOptions.Compiled); public static IQueryPipelineStage Create( DocumentContainer documentContainer, @@ -145,14 +149,14 @@ private static async Task> TryCreateCoreContextAsy if (targetRange != null) { - return await TryCreateExecutionContextAsync( + return await TryCreateSinglePartitionExecutionContextAsync( documentContainer, partitionedQueryExecutionInfo: null, cosmosQueryContext, containerQueryProperties, inputParameters, targetRange, - trace, + createQueryPipelineTrace, cancellationToken); } @@ -211,10 +215,10 @@ private static async Task> TryCreateCoreContextAsy // Only thing that matters is that we target the correct range. Documents.PartitionKeyDefinition partitionKeyDefinition = GetPartitionKeyDefinition(inputParameters, containerQueryProperties); - List targetRanges = await cosmosQueryContext.QueryClient.GetTargetPartitionKeyRangesByEpkStringAsync( + List targetRanges = await cosmosQueryContext.QueryClient.GetTargetPartitionKeyRangesAsync( cosmosQueryContext.ResourceLink, containerQueryProperties.ResourceId, - containerQueryProperties.EffectivePartitionKeyString, + containerQueryProperties.EffectiveRangesForPartitionKey, forceRefresh: false, createQueryPipelineTrace); @@ -295,7 +299,7 @@ private static async Task> TryCreateFromPartitione if (targetRange != null) { - tryCreatePipelineStage = await TryCreateExecutionContextAsync( + tryCreatePipelineStage = await TryCreateSinglePartitionExecutionContextAsync( documentContainer, partitionedQueryExecutionInfo, cosmosQueryContext, @@ -326,7 +330,7 @@ private static async Task> TryCreateFromPartitione return tryCreatePipelineStage; } - private static async Task> TryCreateExecutionContextAsync( + private static async Task> TryCreateSinglePartitionExecutionContextAsync( DocumentContainer documentContainer, PartitionedQueryExecutionInfo partitionedQueryExecutionInfo, CosmosQueryContext cosmosQueryContext, @@ -336,6 +340,17 @@ private static async Task> TryCreateExecutionConte ITrace trace, CancellationToken cancellationToken) { + // Retrieve the query plan in a subset of cases to ensure the query is valid before creating the Ode pipeline + if (partitionedQueryExecutionInfo == null && QueryInspectionRegex.IsMatch(inputParameters.SqlQuerySpec.QueryText)) + { + partitionedQueryExecutionInfo = await GetPartitionedQueryExecutionInfoAsync( + cosmosQueryContext, + inputParameters, + containerQueryProperties, + trace, + cancellationToken); + } + // Test code added to confirm the correct pipeline is being utilized SetTestInjectionPipelineType(inputParameters, OptimisticDirectExecution); @@ -635,67 +650,54 @@ private static async Task GetPartitionedQueryExec ITrace trace) { List targetRanges; - if (containerQueryProperties.EffectivePartitionKeyString != null) + if (containerQueryProperties.EffectiveRangesForPartitionKey != null) { - targetRanges = await queryClient.GetTargetPartitionKeyRangesByEpkStringAsync( + targetRanges = await queryClient.GetTargetPartitionKeyRangesAsync( resourceLink, containerQueryProperties.ResourceId, - containerQueryProperties.EffectivePartitionKeyString, + containerQueryProperties.EffectiveRangesForPartitionKey, forceRefresh: false, trace); } else if (TryGetEpkProperty(properties, out string effectivePartitionKeyString)) { - targetRanges = await queryClient.GetTargetPartitionKeyRangesByEpkStringAsync( + //Note that here we have no way to consume the EPK string as there is no way to convert + //the string to the partition key type to evaulate the number of components which needs to be done for the + //multihahs methods/classes. This is particually important for queries with prefix partition key. + //the EPK sting header is only for internal use but this needs to be fixed in the future. + List> effectiveRanges = new List> + { Range.GetPointRange(effectivePartitionKeyString) }; + + targetRanges = await queryClient.GetTargetPartitionKeyRangesAsync( resourceLink, containerQueryProperties.ResourceId, - effectivePartitionKeyString, + effectiveRanges, forceRefresh: false, trace); } else if (feedRangeInternal != null) { targetRanges = await queryClient.GetTargetPartitionKeyRangeByFeedRangeAsync( - resourceLink, - containerQueryProperties.ResourceId, - containerQueryProperties.PartitionKeyDefinition, - feedRangeInternal, - forceRefresh: false, - trace); + resourceLink, + containerQueryProperties.ResourceId, + containerQueryProperties.PartitionKeyDefinition, + feedRangeInternal, + forceRefresh: false, + trace); } else { - targetRanges = await queryClient.GetTargetPartitionKeyRangesAsync( - resourceLink, - containerQueryProperties.ResourceId, - partitionedQueryExecutionInfo.QueryRanges, - forceRefresh: false, - trace); + targetRanges = await queryClient.GetTargetPartitionKeyRangesAsync( + resourceLink, + containerQueryProperties.ResourceId, + partitionedQueryExecutionInfo.QueryRanges, + forceRefresh: false, + trace); } return targetRanges; } - private static void SetTestInjectionPipelineType(InputParameters inputParameters, string pipelineType) - { - TestInjections.ResponseStats responseStats = inputParameters?.TestInjections?.Stats; - if (responseStats != null) - { - if (pipelineType == OptimisticDirectExecution) - { - responseStats.PipelineType = TestInjections.PipelineType.OptimisticDirectExecution; - } - else if (pipelineType == Specialized) - { - responseStats.PipelineType = TestInjections.PipelineType.Specialized; - } - else - { - responseStats.PipelineType = TestInjections.PipelineType.Passthrough; - } - } - } - private static bool TryGetEpkProperty( IReadOnlyDictionary properties, out string effectivePartitionKeyString) @@ -718,6 +720,26 @@ private static bool TryGetEpkProperty( return false; } + private static void SetTestInjectionPipelineType(InputParameters inputParameters, string pipelineType) + { + TestInjections.ResponseStats responseStats = inputParameters?.TestInjections?.Stats; + if (responseStats != null) + { + if (pipelineType == OptimisticDirectExecution) + { + responseStats.PipelineType = TestInjections.PipelineType.OptimisticDirectExecution; + } + else if (pipelineType == Specialized) + { + responseStats.PipelineType = TestInjections.PipelineType.Specialized; + } + else + { + responseStats.PipelineType = TestInjections.PipelineType.Passthrough; + } + } + } + private static Documents.PartitionKeyDefinition GetPartitionKeyDefinition(InputParameters inputParameters, ContainerQueryProperties containerQueryProperties) { //todo:elasticcollections this may rely on information from collection cache which is outdated @@ -752,7 +774,17 @@ private static Documents.PartitionKeyDefinition GetPartitionKeyDefinition(InputP ContainerQueryProperties containerQueryProperties, ITrace trace) { - if (!inputParameters.EnableOptimisticDirectExecution) return null; + if (!inputParameters.EnableOptimisticDirectExecution) + { + if (inputParameters.InitialUserContinuationToken != null + && OptimisticDirectExecutionContinuationToken.IsOptimisticDirectExecutionContinuationToken(inputParameters.InitialUserContinuationToken)) + { + throw new MalformedContinuationTokenException($"The continuation token supplied requires the Optimistic Direct Execution flag to be enabled in QueryRequestOptions for the query execution to resume. " + + $"{inputParameters.InitialUserContinuationToken}"); + } + + return null; + } Debug.Assert(containerQueryProperties.ResourceId != null, "CosmosQueryExecutionContextFactory Assert!", "Container ResourceId cannot be null!"); @@ -771,14 +803,13 @@ private static Documents.PartitionKeyDefinition GetPartitionKeyDefinition(InputP else { Documents.PartitionKeyDefinition partitionKeyDefinition = GetPartitionKeyDefinition(inputParameters, containerQueryProperties); - if (inputParameters.PartitionKey != null) + if (inputParameters.PartitionKey.HasValue) { Debug.Assert(partitionKeyDefinition != null, "CosmosQueryExecutionContextFactory Assert!", "PartitionKeyDefinition cannot be null if partitionKey is defined"); - - targetRanges = await cosmosQueryContext.QueryClient.GetTargetPartitionKeyRangesByEpkStringAsync( + targetRanges = await cosmosQueryContext.QueryClient.GetTargetPartitionKeyRangesAsync( cosmosQueryContext.ResourceLink, containerQueryProperties.ResourceId, - containerQueryProperties.EffectivePartitionKeyString, + containerQueryProperties.EffectiveRangesForPartitionKey, forceRefresh: false, trace); } diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/OptimisticDirectExecution/OptimisticDirectExecutionContinuationToken.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/OptimisticDirectExecution/OptimisticDirectExecutionContinuationToken.cs index 59f87295f3..76b2531f01 100644 --- a/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/OptimisticDirectExecution/OptimisticDirectExecutionContinuationToken.cs +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/OptimisticDirectExecution/OptimisticDirectExecutionContinuationToken.cs @@ -4,9 +4,7 @@ namespace Microsoft.Azure.Cosmos.Query.Core.Pipeline.OptimisticDirectExecutionQuery { - using System; using System.Collections.Generic; - using Microsoft.Azure.Cosmos.ChangeFeed; using Microsoft.Azure.Cosmos.CosmosElements; using Microsoft.Azure.Cosmos.Query.Core.Exceptions; using Microsoft.Azure.Cosmos.Query.Core.Monads; @@ -30,6 +28,12 @@ public OptimisticDirectExecutionContinuationToken(ParallelContinuationToken toke public Range Range => this.Token.Range; + public static bool IsOptimisticDirectExecutionContinuationToken(CosmosElement continuationToken) + { + CosmosObject cosmosObjectContinuationToken = continuationToken as CosmosObject; + return !(cosmosObjectContinuationToken == null || !cosmosObjectContinuationToken.ContainsKey(OptimisticDirectExecutionToken)); + } + public static CosmosElement ToCosmosElement(OptimisticDirectExecutionContinuationToken continuationToken) { CosmosElement inner = ParallelContinuationToken.ToCosmosElement(continuationToken.Token); @@ -42,14 +46,14 @@ public static CosmosElement ToCosmosElement(OptimisticDirectExecutionContinuatio public static TryCatch TryCreateFromCosmosElement(CosmosElement cosmosElement) { - CosmosObject cosmosObjectContinuationToken = cosmosElement as CosmosObject; - if (cosmosObjectContinuationToken == null || !cosmosObjectContinuationToken.ContainsKey(OptimisticDirectExecutionToken)) + if (!IsOptimisticDirectExecutionContinuationToken(cosmosElement)) { return TryCatch.FromException( - new MalformedContinuationTokenException( - message: $"Malformed Continuation Token: Expected OptimisticDirectExecutionToken\r\n")); + new MalformedContinuationTokenException( + message: $"Malformed Continuation Token: Expected OptimisticDirectExecutionToken\r\n")); } + CosmosObject cosmosObjectContinuationToken = (CosmosObject)cosmosElement; TryCatch inner = ParallelContinuationToken.TryCreateFromCosmosElement(cosmosObjectContinuationToken[OptimisticDirectExecutionToken]); return inner.Succeeded ? diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/QueryClient/ContainerQueryProperties.cs b/Microsoft.Azure.Cosmos/src/Query/Core/QueryClient/ContainerQueryProperties.cs index 0baaceb9c6..279b7585b9 100644 --- a/Microsoft.Azure.Cosmos/src/Query/Core/QueryClient/ContainerQueryProperties.cs +++ b/Microsoft.Azure.Cosmos/src/Query/Core/QueryClient/ContainerQueryProperties.cs @@ -4,24 +4,29 @@ namespace Microsoft.Azure.Cosmos.Query.Core.QueryClient { + using System.Collections.Generic; using Microsoft.Azure.Documents; + using Microsoft.Azure.Documents.Routing; internal readonly struct ContainerQueryProperties { public ContainerQueryProperties( string resourceId, - string effectivePartitionKeyString, + IReadOnlyList> effectivePartitionKeyRanges, PartitionKeyDefinition partitionKeyDefinition, Cosmos.GeospatialType geospatialType) { this.ResourceId = resourceId; - this.EffectivePartitionKeyString = effectivePartitionKeyString; + this.EffectiveRangesForPartitionKey = effectivePartitionKeyRanges; this.PartitionKeyDefinition = partitionKeyDefinition; this.GeospatialType = geospatialType; } public string ResourceId { get; } - public string EffectivePartitionKeyString { get; } + + //A PartitionKey has one range when it is a full PartitionKey value. + //It can span many it is a prefix PartitionKey for a sub-partitioned container. + public IReadOnlyList> EffectiveRangesForPartitionKey { get; } public PartitionKeyDefinition PartitionKeyDefinition { get; } public Cosmos.GeospatialType GeospatialType { get; } } diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/QueryClient/CosmosQueryClient.cs b/Microsoft.Azure.Cosmos/src/Query/Core/QueryClient/CosmosQueryClient.cs index 3fa4cb90e7..d9dc0ac976 100644 --- a/Microsoft.Azure.Cosmos/src/Query/Core/QueryClient/CosmosQueryClient.cs +++ b/Microsoft.Azure.Cosmos/src/Query/Core/QueryClient/CosmosQueryClient.cs @@ -76,13 +76,6 @@ public abstract Task ExecuteQueryPlanRequestAsync public abstract void ClearSessionTokenCache(string collectionFullName); - public abstract Task> GetTargetPartitionKeyRangesByEpkStringAsync( - string resourceLink, - string collectionResourceId, - string effectivePartitionKeyString, - bool forceRefresh, - ITrace trace); - public abstract Task> GetTargetPartitionKeyRangeByFeedRangeAsync( string resourceLink, string collectionResourceId, @@ -94,7 +87,7 @@ public abstract Task ExecuteQueryPlanRequestAsync public abstract Task> GetTargetPartitionKeyRangesAsync( string resourceLink, string collectionResourceId, - List> providedRanges, + IReadOnlyList> providedRanges, bool forceRefresh, ITrace trace); diff --git a/Microsoft.Azure.Cosmos/src/Query/v2Query/DefaultDocumentQueryExecutionContext.cs b/Microsoft.Azure.Cosmos/src/Query/v2Query/DefaultDocumentQueryExecutionContext.cs index b53c3c5c71..9895bd5f5a 100644 --- a/Microsoft.Azure.Cosmos/src/Query/v2Query/DefaultDocumentQueryExecutionContext.cs +++ b/Microsoft.Azure.Cosmos/src/Query/v2Query/DefaultDocumentQueryExecutionContext.cs @@ -108,7 +108,7 @@ protected override async Task> ExecuteIntern partitionIdentifier, new QueryMetrics( response.ResponseHeaders[HttpConstants.HttpHeaders.QueryMetrics], - IndexUtilizationInfo.CreateFromString(response.ResponseHeaders[HttpConstants.HttpHeaders.IndexUtilization], true), + IndexUtilizationInfo.CreateFromString(response.ResponseHeaders[HttpConstants.HttpHeaders.IndexUtilization]), new ClientSideMetrics( this.retries, response.RequestCharge, diff --git a/Microsoft.Azure.Cosmos/src/Query/v3Query/CosmosQueryClientCore.cs b/Microsoft.Azure.Cosmos/src/Query/v3Query/CosmosQueryClientCore.cs index cce1a5268a..a392632649 100644 --- a/Microsoft.Azure.Cosmos/src/Query/v3Query/CosmosQueryClientCore.cs +++ b/Microsoft.Azure.Cosmos/src/Query/v3Query/CosmosQueryClientCore.cs @@ -63,17 +63,26 @@ public override async Task GetCachedContainerQueryProp trace, cancellationToken); - string effectivePartitionKeyString = null; + List> effectivePartitionKeyRange = null; if (partitionKey != null) { // Dis-ambiguate the NonePK if used PartitionKeyInternal partitionKeyInternal = partitionKey.Value.IsNone ? containerProperties.GetNoneValue() : partitionKey.Value.InternalKey; - effectivePartitionKeyString = partitionKeyInternal.GetEffectivePartitionKeyString(containerProperties.PartitionKey); + effectivePartitionKeyRange = new List> + { + PartitionKeyInternal.GetEffectivePartitionKeyRange( + containerProperties.PartitionKey, + new Range( + min: partitionKeyInternal, + max: partitionKeyInternal, + isMinInclusive: true, + isMaxInclusive: true)) + }; } return new ContainerQueryProperties( containerProperties.ResourceId, - effectivePartitionKeyString, + effectivePartitionKeyRange, containerProperties.PartitionKey, containerProperties.GeospatialConfig.GeospatialType); } @@ -200,24 +209,6 @@ public override async Task ExecuteQueryPlanReques return partitionedQueryExecutionInfo; } - public override Task> GetTargetPartitionKeyRangesByEpkStringAsync( - string resourceLink, - string collectionResourceId, - string effectivePartitionKeyString, - bool forceRefresh, - ITrace trace) - { - return this.GetTargetPartitionKeyRangesAsync( - resourceLink, - collectionResourceId, - new List> - { - Range.GetPointRange(effectivePartitionKeyString) - }, - forceRefresh, - trace); - } - public override async Task> GetTargetPartitionKeyRangeByFeedRangeAsync( string resourceLink, string collectionResourceId, @@ -243,7 +234,7 @@ public override async Task> GetTargetPartitionKeyRangeBy public override async Task> GetTargetPartitionKeyRangesAsync( string resourceLink, string collectionResourceId, - List> providedRanges, + IReadOnlyList> providedRanges, bool forceRefresh, ITrace trace) { diff --git a/Microsoft.Azure.Cosmos/src/Query/v3Query/QueryResponse.cs b/Microsoft.Azure.Cosmos/src/Query/v3Query/QueryResponse.cs index 6c7777ebff..47c9136a8f 100644 --- a/Microsoft.Azure.Cosmos/src/Query/v3Query/QueryResponse.cs +++ b/Microsoft.Azure.Cosmos/src/Query/v3Query/QueryResponse.cs @@ -12,6 +12,7 @@ namespace Microsoft.Azure.Cosmos using Microsoft.Azure.Cosmos.Query.Core.Metrics; using Microsoft.Azure.Cosmos.Serializer; using Microsoft.Azure.Cosmos.Tracing; + using Microsoft.Azure.Documents; /// /// Represents the template class used by feed methods (enumeration operations) for the Azure Cosmos DB service. @@ -183,7 +184,13 @@ private QueryResponse( cosmosArray: cosmosElements, serializerCore: serializerCore); - this.IndexUtilizationText = ResponseMessage.DecodeIndexMetrics(responseMessageHeaders, true); + // Chose how to decode depending on which PopulateIndexMetrics request header was sent + // If none was sent, we currently default to V1 + // TODO: Switch the flag to false once V2 is deployed + this.IndexUtilizationText = ResponseMessage.DecodeIndexMetrics( + responseMessageHeaders, + isBase64Encoded: true); + this.RequestMessage = requestMessage; } diff --git a/Microsoft.Azure.Cosmos/src/RMResources.Designer.cs b/Microsoft.Azure.Cosmos/src/RMResources.Designer.cs index 294ed6c3ad..18f3aa1cdb 100644 --- a/Microsoft.Azure.Cosmos/src/RMResources.Designer.cs +++ b/Microsoft.Azure.Cosmos/src/RMResources.Designer.cs @@ -4269,9 +4269,12 @@ internal static string FreeTierNotSupportedForInternalSubscription } } - /// Looks up a localized string similar to Could not resolve DataTransfer state store account for region [{0}].. + +#pragma warning disable CS1570 // XML comment has badly formed XML +/// Looks up a localized string similar to Could not resolve DataTransfer state store account for region [{0}].. /// internal static string DataTransferStateStoreNotResolved +#pragma warning restore CS1570 // XML comment has badly formed XML { get { diff --git a/Microsoft.Azure.Cosmos/src/RegionNameMapper.cs b/Microsoft.Azure.Cosmos/src/RegionNameMapper.cs new file mode 100644 index 0000000000..dbcf0d7c08 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/RegionNameMapper.cs @@ -0,0 +1,53 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos +{ + using System; + using System.Collections.Generic; + using System.Reflection; + + /// + /// Maps a normalized region name to the format that CosmosDB is expecting (for e.g. from 'westus2' to 'West US 2') + /// + internal sealed class RegionNameMapper + { + private readonly Dictionary normalizedToCosmosDBRegionNameMapping; + + public RegionNameMapper() + { + FieldInfo[] fields = typeof(Regions).GetFields(BindingFlags.Public | BindingFlags.Static); + + this.normalizedToCosmosDBRegionNameMapping = new Dictionary(StringComparer.OrdinalIgnoreCase); + + foreach (FieldInfo field in fields) + { + this.normalizedToCosmosDBRegionNameMapping[field.Name] = field.GetValue(null).ToString(); + } + } + + /// + /// Given a normalized region name, this function retrieves the region name in the format that CosmosDB expects. + /// If the region is not known, the same value as input is returned. + /// + /// An Azure region name in a normalized format. The input is not case sensitive. + /// A string that contains the region name in the format that CosmosDB expects. + public string GetCosmosDBRegionName(string normalizedRegionName) + { + if (string.IsNullOrEmpty(normalizedRegionName)) + { + return string.Empty; + } + + normalizedRegionName = normalizedRegionName.Replace(" ", string.Empty); + if (this.normalizedToCosmosDBRegionNameMapping.TryGetValue(normalizedRegionName, + out string cosmosDBRegionName)) + { + return cosmosDBRegionName; + } + + return normalizedRegionName; + } + } +} diff --git a/Microsoft.Azure.Cosmos/src/RequestOptions/QueryRequestOptions.cs b/Microsoft.Azure.Cosmos/src/RequestOptions/QueryRequestOptions.cs index f723107ede..2b4aba5ac0 100644 --- a/Microsoft.Azure.Cosmos/src/RequestOptions/QueryRequestOptions.cs +++ b/Microsoft.Azure.Cosmos/src/RequestOptions/QueryRequestOptions.cs @@ -269,6 +269,7 @@ internal override void PopulateRequestOptions(RequestMessage request) if (this.PopulateIndexMetrics.HasValue) { + // TODO: Switch to V2 request.Headers.CosmosMessageHeaders.Add(HttpConstants.HttpHeaders.PopulateIndexMetrics, this.PopulateIndexMetrics.ToString()); } diff --git a/Microsoft.Azure.Cosmos/src/RequestOptions/RequestOptions.cs b/Microsoft.Azure.Cosmos/src/RequestOptions/RequestOptions.cs index dc02f9a248..e8d4c602ff 100644 --- a/Microsoft.Azure.Cosmos/src/RequestOptions/RequestOptions.cs +++ b/Microsoft.Azure.Cosmos/src/RequestOptions/RequestOptions.cs @@ -64,9 +64,10 @@ public class RequestOptions PriorityLevel? PriorityLevel { get; set; } /// - /// Set Request Level Distributed Tracing Options. + /// Threshold values for Distributed Tracing. + /// These values decides whether to generate operation level with request diagnostics or not. /// - internal DistributedTracingOptions DistributedTracingOptions { get; set; } + public CosmosThresholdOptions CosmosThresholdOptions { get; set; } /// /// Gets or sets the boolean to use effective partition key routing in the cosmos db request. diff --git a/Microsoft.Azure.Cosmos/src/Resource/ClientContextCore.cs b/Microsoft.Azure.Cosmos/src/Resource/ClientContextCore.cs index 42e128ac2e..5d5b66ee71 100644 --- a/Microsoft.Azure.Cosmos/src/Resource/ClientContextCore.cs +++ b/Microsoft.Azure.Cosmos/src/Resource/ClientContextCore.cs @@ -13,8 +13,6 @@ namespace Microsoft.Azure.Cosmos using System.Text; using System.Threading; using System.Threading.Tasks; - using Microsoft.Azure.Cosmos.Core.Trace; - using Microsoft.Azure.Cosmos.Handler; using Microsoft.Azure.Cosmos.Handlers; using Microsoft.Azure.Cosmos.Resource.CosmosExceptions; using Microsoft.Azure.Cosmos.Routing; @@ -84,7 +82,7 @@ internal static CosmosClientContext Create( sessionContainer: clientOptions.SessionContainer, cosmosClientId: cosmosClient.Id, remoteCertificateValidationCallback: ClientContextCore.SslCustomValidationCallBack(clientOptions.ServerCertificateCustomValidationCallback), - isDistributedTracingEnabled: clientOptions.IsDistributedTracingEnabled); + cosmosClientTelemetryOptions: clientOptions.CosmosClientTelemetryOptions); return ClientContextCore.Create( cosmosClient, @@ -122,7 +120,7 @@ internal static CosmosClientContext Create( cosmosClient, clientOptions.ConsistencyLevel, clientOptions.CustomHandlers, - telemetry: documentClient.clientTelemetry); + telemetryToServiceHelper: documentClient.telemetryToServiceHelper); requestInvokerHandler = clientPipelineBuilder.Build(); } diff --git a/Microsoft.Azure.Cosmos/src/Resource/Container/ContainerCore.Items.cs b/Microsoft.Azure.Cosmos/src/Resource/Container/ContainerCore.Items.cs index a694b78019..fd9ad03b53 100644 --- a/Microsoft.Azure.Cosmos/src/Resource/Container/ContainerCore.Items.cs +++ b/Microsoft.Azure.Cosmos/src/Resource/Container/ContainerCore.Items.cs @@ -16,8 +16,6 @@ namespace Microsoft.Azure.Cosmos using Microsoft.Azure.Cosmos.ChangeFeed; using Microsoft.Azure.Cosmos.ChangeFeed.FeedProcessing; using Microsoft.Azure.Cosmos.ChangeFeed.Pagination; - using Microsoft.Azure.Cosmos.ChangeFeed.Utils; - using Microsoft.Azure.Cosmos.Common; using Microsoft.Azure.Cosmos.CosmosElements; using Microsoft.Azure.Cosmos.Json; using Microsoft.Azure.Cosmos.Linq; @@ -29,11 +27,8 @@ namespace Microsoft.Azure.Cosmos using Microsoft.Azure.Cosmos.Query.Core.QueryPlan; using Microsoft.Azure.Cosmos.ReadFeed; using Microsoft.Azure.Cosmos.ReadFeed.Pagination; - using Microsoft.Azure.Cosmos.Routing; - using Microsoft.Azure.Cosmos.Serializer; using Microsoft.Azure.Cosmos.Tracing; using Microsoft.Azure.Documents; - using Microsoft.Azure.Documents.Routing; /// /// Used to perform operations on items. There are two different types of operations. diff --git a/Microsoft.Azure.Cosmos/src/Resource/CosmosExceptions/CosmosExceptionFactory.cs b/Microsoft.Azure.Cosmos/src/Resource/CosmosExceptions/CosmosExceptionFactory.cs index 0648aecbc3..741f8906fa 100644 --- a/Microsoft.Azure.Cosmos/src/Resource/CosmosExceptions/CosmosExceptionFactory.cs +++ b/Microsoft.Azure.Cosmos/src/Resource/CosmosExceptions/CosmosExceptionFactory.cs @@ -159,6 +159,7 @@ internal static (Error, string) GetErrorFromStream( using (StreamReader streamReader = new StreamReader(content)) { string errorContent = streamReader.ReadToEnd(); + try { JObject errorObj = JObject.Parse(errorContent); @@ -179,7 +180,7 @@ internal static (Error, string) GetErrorFromStream( return (error, message.ToString()); } } - catch (Newtonsoft.Json.JsonReaderException) + catch (Exception exception) when (CosmosExceptionFactory.ExceptionsToIgnore(exception)) { } @@ -193,6 +194,12 @@ internal static (Error, string) GetErrorFromStream( } } + private static bool ExceptionsToIgnore(Exception exception) + { + return exception is Newtonsoft.Json.JsonReaderException || + exception is Newtonsoft.Json.JsonSerializationException; + } + internal static CosmosException CreateRequestTimeoutException( string message, Headers headers, diff --git a/Microsoft.Azure.Cosmos/src/Resource/Settings/AccountClientConfiguration.cs b/Microsoft.Azure.Cosmos/src/Resource/Settings/AccountClientConfiguration.cs new file mode 100644 index 0000000000..fd7d125dac --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Resource/Settings/AccountClientConfiguration.cs @@ -0,0 +1,29 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos +{ + using System.Collections.Generic; + using Microsoft.Azure.Documents; + using Newtonsoft.Json; + using Newtonsoft.Json.Linq; + + internal class AccountClientConfiguration + { + [JsonProperty(PropertyName = Constants.Properties.ClientTelemetryConfiguration)] + public ClientTelemetryConfiguration ClientTelemetryConfiguration { get; set; } + + /// + /// This contains additional values for scenarios where the SDK is not aware of new fields. + /// This ensures that if resource is read and updated none of the fields will be lost in the process. + /// + [JsonExtensionData] + internal IDictionary AdditionalProperties { get; private set; } + + internal bool IsClientTelemetryEnabled() + { + return this.ClientTelemetryConfiguration.IsEnabled && this.ClientTelemetryConfiguration.Endpoint != null; + } + } +} diff --git a/Microsoft.Azure.Cosmos/src/Resource/Settings/ClientTelemetryConfiguration.cs b/Microsoft.Azure.Cosmos/src/Resource/Settings/ClientTelemetryConfiguration.cs new file mode 100644 index 0000000000..3229b69fa2 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Resource/Settings/ClientTelemetryConfiguration.cs @@ -0,0 +1,27 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos +{ + using System.Collections.Generic; + using Microsoft.Azure.Documents; + using Newtonsoft.Json; + using Newtonsoft.Json.Linq; + + internal class ClientTelemetryConfiguration + { + [JsonProperty(PropertyName = Constants.Properties.ClientTelemetryEnabled)] + public bool IsEnabled { get; set; } + + [JsonProperty(PropertyName = Constants.Properties.ClientTelemetryEndpoint)] + public string Endpoint { get; set; } + + /// + /// This contains additional values for scenarios where the SDK is not aware of new fields. + /// This ensures that if resource is read and updated none of the fields will be lost in the process. + /// + [JsonExtensionData] + internal IDictionary AdditionalProperties { get; private set; } + } +} diff --git a/Microsoft.Azure.Cosmos/src/Resource/Settings/DedicatedGatewayRequestOptions.cs b/Microsoft.Azure.Cosmos/src/Resource/Settings/DedicatedGatewayRequestOptions.cs index 9ca854388c..31f82644a9 100644 --- a/Microsoft.Azure.Cosmos/src/Resource/Settings/DedicatedGatewayRequestOptions.cs +++ b/Microsoft.Azure.Cosmos/src/Resource/Settings/DedicatedGatewayRequestOptions.cs @@ -14,7 +14,7 @@ namespace Microsoft.Azure.Cosmos public class DedicatedGatewayRequestOptions { /// - /// Gets or sets the staleness value associated with the request in the Azure CosmosDB service. + /// Gets or sets the staleness value associated with the request in the Azure Cosmos DB service. /// /// Default value is null. /// @@ -24,7 +24,7 @@ public class DedicatedGatewayRequestOptions public TimeSpan? MaxIntegratedCacheStaleness { get; set; } /// - /// Gets or sets if bypass the integrated cache or not associated with the request in the Azure CosmosDB service. + /// Gets or sets if bypass the integrated cache or not associated with the request in the Azure Cosmos DB service. /// When set this value to true, the request will not be served from the integrated cache, and the response will not be cached either. /// /// Default value is false. diff --git a/Microsoft.Azure.Cosmos/src/Resource/Settings/TriggerOperation.cs b/Microsoft.Azure.Cosmos/src/Resource/Settings/TriggerOperation.cs index 1f1aa61ab2..d877671f5a 100644 --- a/Microsoft.Azure.Cosmos/src/Resource/Settings/TriggerOperation.cs +++ b/Microsoft.Azure.Cosmos/src/Resource/Settings/TriggerOperation.cs @@ -32,6 +32,11 @@ public enum TriggerOperation : short /// /// Specifies replace operations only. /// - Replace = 0x4 + Replace = 0x4, + + /// + /// Specifies upsert operations only. + /// + Upsert = 0x5 } } diff --git a/Microsoft.Azure.Cosmos/src/RetryOptions.cs b/Microsoft.Azure.Cosmos/src/RetryOptions.cs index 8384df8105..5577b4b0d6 100644 --- a/Microsoft.Azure.Cosmos/src/RetryOptions.cs +++ b/Microsoft.Azure.Cosmos/src/RetryOptions.cs @@ -56,7 +56,7 @@ public RetryOptions() /// retry after the time has elapsed. /// /// - /// For more information, see Handle rate limiting/request rate too large. + /// For more information, see Handle rate limiting/request rate too large. /// /// public int MaxRetryAttemptsOnThrottledRequests @@ -91,7 +91,7 @@ public int MaxRetryAttemptsOnThrottledRequests /// If the cumulative wait time exceeds the this value, the client will stop retrying and return the error to the application. /// /// - /// For more information, see Handle rate limiting/request rate too large. + /// For more information, see Handle rate limiting/request rate too large. /// /// public int MaxRetryWaitTimeInSeconds diff --git a/Microsoft.Azure.Cosmos/src/Routing/ClientCollectionCache.cs b/Microsoft.Azure.Cosmos/src/Routing/ClientCollectionCache.cs index 530bbfceb5..534a0b8a22 100644 --- a/Microsoft.Azure.Cosmos/src/Routing/ClientCollectionCache.cs +++ b/Microsoft.Azure.Cosmos/src/Routing/ClientCollectionCache.cs @@ -9,6 +9,7 @@ namespace Microsoft.Azure.Cosmos.Routing using System.Threading.Tasks; using Microsoft.Azure.Cosmos.Common; using Microsoft.Azure.Cosmos.Telemetry; + using Microsoft.Azure.Cosmos.Telemetry.Collector; using Microsoft.Azure.Cosmos.Tracing; using Microsoft.Azure.Cosmos.Tracing.TraceData; using Microsoft.Azure.Documents; @@ -25,20 +26,20 @@ internal class ClientCollectionCache : CollectionCache private readonly ICosmosAuthorizationTokenProvider tokenProvider; private readonly IRetryPolicyFactory retryPolicy; private readonly ISessionContainer sessionContainer; - private readonly ClientTelemetry clientTelemetry; + private readonly TelemetryToServiceHelper telemetryToServiceHelper; public ClientCollectionCache( ISessionContainer sessionContainer, IStoreModel storeModel, ICosmosAuthorizationTokenProvider tokenProvider, IRetryPolicyFactory retryPolicy, - ClientTelemetry clientTelemetry) + TelemetryToServiceHelper telemetryToServiceHelper) { this.storeModel = storeModel ?? throw new ArgumentNullException("storeModel"); this.tokenProvider = tokenProvider; this.retryPolicy = retryPolicy; this.sessionContainer = sessionContainer; - this.clientTelemetry = clientTelemetry; + this.telemetryToServiceHelper = telemetryToServiceHelper; } protected override Task GetByRidAsync(string apiVersion, @@ -214,21 +215,19 @@ private async Task ReadCollectionAsync( await this.storeModel.ProcessMessageAsync(request)) { ContainerProperties containerProperties = CosmosResource.FromStream(response); - - if (this.clientTelemetry != null) - { - ClientCollectionCache.GetDatabaseAndCollectionName(collectionLink, out string databaseName, out string collectionName); - this.clientTelemetry.CollectCacheInfo( - cacheRefreshSource: ClientCollectionCache.TelemetrySourceName, - regionsContactedList: response.RequestStats.RegionsContacted, - requestLatency: response.RequestStats.RequestLatency, - statusCode: response.StatusCode, - containerId: collectionName, - operationType: request.OperationType, - resourceType: request.ResourceType, - subStatusCode: response.SubStatusCode, - databaseId: databaseName); - } + + this.telemetryToServiceHelper.GetCollector().CollectCacheInfo( + ClientCollectionCache.TelemetrySourceName, + () => new TelemetryInformation + { + RegionsContactedList = response.RequestStats.RegionsContacted, + RequestLatency = response.RequestStats.RequestLatency, + StatusCode = response.StatusCode, + OperationType = request.OperationType, + ResourceType = request.ResourceType, + SubStatusCode = response.SubStatusCode, + CollectionLink = collectionLink + }); return containerProperties; } @@ -242,12 +241,5 @@ await this.storeModel.ProcessMessageAsync(request)) } } } - - private static void GetDatabaseAndCollectionName(string path, out string databaseName, out string collectionName) - { - string[] segments = path.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries); - - PathsHelper.ParseDatabaseNameAndCollectionNameFromUrlSegments(segments, out databaseName, out collectionName); - } } } \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Routing/GatewayAddressCache.cs b/Microsoft.Azure.Cosmos/src/Routing/GatewayAddressCache.cs index a4dbb1d8a3..8bc429070e 100644 --- a/Microsoft.Azure.Cosmos/src/Routing/GatewayAddressCache.cs +++ b/Microsoft.Azure.Cosmos/src/Routing/GatewayAddressCache.cs @@ -302,14 +302,27 @@ public async Task TryGetAddressesAsync( .ReplicaTransportAddressUris .Any(x => x.ShouldRefreshHealthStatus())) { - Task refreshAddressesInBackgroundTask = Task.Run(async () => await this.serverPartitionAddressCache.RefreshAsync( - key: partitionKeyRangeIdentity, - singleValueInitFunc: (currentCachedValue) => this.GetAddressesForRangeIdAsync( - request, - cachedAddresses: currentCachedValue, + Task refreshAddressesInBackgroundTask = Task.Run(async () => + { + try + { + await this.serverPartitionAddressCache.RefreshAsync( + key: partitionKeyRangeIdentity, + singleValueInitFunc: (currentCachedValue) => this.GetAddressesForRangeIdAsync( + request, + cachedAddresses: currentCachedValue, + partitionKeyRangeIdentity.CollectionRid, + partitionKeyRangeIdentity.PartitionKeyRangeId, + forceRefresh: true)); + } + catch (Exception ex) + { + DefaultTrace.TraceWarning("Failed to refresh addresses in the background for the collection rid: {0} with exception: {1}. '{2}'", partitionKeyRangeIdentity.CollectionRid, - partitionKeyRangeIdentity.PartitionKeyRangeId, - forceRefresh: true))); + ex, + System.Diagnostics.Trace.CorrelationManager.ActivityId); + } + }); } return addresses; diff --git a/Microsoft.Azure.Cosmos/src/Routing/PartitionKeyHash.cs b/Microsoft.Azure.Cosmos/src/Routing/PartitionKeyHash.cs index 42ef970915..0d7189abb2 100644 --- a/Microsoft.Azure.Cosmos/src/Routing/PartitionKeyHash.cs +++ b/Microsoft.Azure.Cosmos/src/Routing/PartitionKeyHash.cs @@ -5,7 +5,7 @@ namespace Microsoft.Azure.Cosmos.Routing { using System; - using System.Runtime.CompilerServices; + using System.Collections.Generic; using System.Runtime.InteropServices; using System.Text; using Microsoft.Azure.Documents.Routing; @@ -35,12 +35,34 @@ namespace Microsoft.Azure.Cosmos.Routing /// internal readonly struct PartitionKeyHash : IComparable, IEquatable { + private readonly IReadOnlyList values; + public PartitionKeyHash(UInt128 value) + : this(new UInt128[] { value }) { - this.Value = value; } - public UInt128 Value { get; } + public PartitionKeyHash(UInt128[] values) + { + StringBuilder stringBuilder = new StringBuilder(); + foreach (UInt128 value in values) + { + if (stringBuilder.Length > 0) + { + stringBuilder.Append('-'); + } + stringBuilder.Append(value.ToString()); + } + + this.Value = stringBuilder.ToString(); + this.values = values; + } + + public readonly static PartitionKeyHash None = new PartitionKeyHash(0); + + public string Value { get; } + + internal readonly IReadOnlyList HashValues => this.values; public int CompareTo(PartitionKeyHash other) { @@ -66,7 +88,7 @@ public override bool Equals(object obj) public override int GetHashCode() => this.Value.GetHashCode(); - public override string ToString() => this.Value.ToString(); + public override string ToString() => this.Value; public static bool TryParse(string value, out PartitionKeyHash parsedValue) { diff --git a/Microsoft.Azure.Cosmos/src/Routing/PartitionKeyHashRange.cs b/Microsoft.Azure.Cosmos/src/Routing/PartitionKeyHashRange.cs index 21e257b49a..7e8265e470 100644 --- a/Microsoft.Azure.Cosmos/src/Routing/PartitionKeyHashRange.cs +++ b/Microsoft.Azure.Cosmos/src/Routing/PartitionKeyHashRange.cs @@ -181,4 +181,4 @@ public override string ToString() return stringBuilder.ToString(); } } -} +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Routing/PartitionKeyHashRanges.cs b/Microsoft.Azure.Cosmos/src/Routing/PartitionKeyHashRanges.cs index a927fcba87..f15556a23d 100644 --- a/Microsoft.Azure.Cosmos/src/Routing/PartitionKeyHashRanges.cs +++ b/Microsoft.Azure.Cosmos/src/Routing/PartitionKeyHashRanges.cs @@ -132,9 +132,9 @@ public static CreateOutcome TryCreate( { if (partitionKeyHashRange.StartInclusive.HasValue) { - if (partitionKeyHashRange.StartInclusive.Value.Value < minStart) + if (partitionKeyHashRange.StartInclusive.Value.HashValues[0] < minStart) { - minStart = partitionKeyHashRange.StartInclusive.Value.Value; + minStart = partitionKeyHashRange.StartInclusive.Value.HashValues[0]; } } else @@ -144,9 +144,9 @@ public static CreateOutcome TryCreate( if (partitionKeyHashRange.EndExclusive.HasValue) { - if (partitionKeyHashRange.EndExclusive.Value.Value > maxEnd) + if (partitionKeyHashRange.EndExclusive.Value.HashValues[0] > maxEnd) { - maxEnd = partitionKeyHashRange.EndExclusive.Value.Value; + maxEnd = partitionKeyHashRange.EndExclusive.Value.HashValues[0]; } } else @@ -154,8 +154,8 @@ public static CreateOutcome TryCreate( maxEnd = UInt128.MaxValue; } - UInt128 width = partitionKeyHashRange.EndExclusive.GetValueOrDefault(new PartitionKeyHash(UInt128.MaxValue)).Value - - partitionKeyHashRange.StartInclusive.GetValueOrDefault(new PartitionKeyHash(UInt128.MinValue)).Value; + UInt128 width = partitionKeyHashRange.EndExclusive.GetValueOrDefault(new PartitionKeyHash(UInt128.MaxValue)).HashValues[0] + - partitionKeyHashRange.StartInclusive.GetValueOrDefault(new PartitionKeyHash(UInt128.MinValue)).HashValues[0]; sumOfWidth += width; if (sumOfWidth < width) { @@ -223,4 +223,4 @@ public enum CreateOutcome Success, } } -} +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Serializer/CosmosLinqSerializerOptions.cs b/Microsoft.Azure.Cosmos/src/Serializer/CosmosLinqSerializerOptions.cs index b7523b2c6a..3b215a9cc8 100644 --- a/Microsoft.Azure.Cosmos/src/Serializer/CosmosLinqSerializerOptions.cs +++ b/Microsoft.Azure.Cosmos/src/Serializer/CosmosLinqSerializerOptions.cs @@ -4,10 +4,6 @@ namespace Microsoft.Azure.Cosmos { - using System; - using System.Collections.Generic; - using System.Text; - /// /// This class provides a way to configure Linq Serialization Properties /// diff --git a/Microsoft.Azure.Cosmos/src/SqlObjects/SqlFunctionCallScalarExpression.cs b/Microsoft.Azure.Cosmos/src/SqlObjects/SqlFunctionCallScalarExpression.cs index bcb38257c6..651ad5726d 100644 --- a/Microsoft.Azure.Cosmos/src/SqlObjects/SqlFunctionCallScalarExpression.cs +++ b/Microsoft.Azure.Cosmos/src/SqlObjects/SqlFunctionCallScalarExpression.cs @@ -112,6 +112,7 @@ sealed class SqlFunctionCallScalarExpression : SqlScalarExpression { Names.Power, Identifiers.Power }, { Names.Radians, Identifiers.Radians }, { Names.Rand, Identifiers.Rand }, + { Names.RegexMatch, Identifiers.RegexMatch }, { Names.Replace, Identifiers.Replace }, { Names.Replicate, Identifiers.Replicate }, { Names.Reverse, Identifiers.Reverse }, @@ -332,6 +333,7 @@ public static class Names public const string Power = "POWER"; public const string Radians = "RADIANS"; public const string Rand = "RAND"; + public const string RegexMatch = "RegexMatch"; public const string Replace = "REPLACE"; public const string Replicate = "REPLICATE"; public const string Reverse = "REVERSE"; @@ -474,6 +476,7 @@ public static class Identifiers public static readonly SqlIdentifier Power = SqlIdentifier.Create(Names.Power); public static readonly SqlIdentifier Radians = SqlIdentifier.Create(Names.Radians); public static readonly SqlIdentifier Rand = SqlIdentifier.Create(Names.Rand); + public static readonly SqlIdentifier RegexMatch = SqlIdentifier.Create(Names.RegexMatch); public static readonly SqlIdentifier Replace = SqlIdentifier.Create(Names.Replace); public static readonly SqlIdentifier Replicate = SqlIdentifier.Create(Names.Replicate); public static readonly SqlIdentifier Reverse = SqlIdentifier.Create(Names.Reverse); diff --git a/Microsoft.Azure.Cosmos/src/Telemetry/ClientTelemetry.cs b/Microsoft.Azure.Cosmos/src/Telemetry/ClientTelemetry.cs index dde7d5a7c5..8460998711 100644 --- a/Microsoft.Azure.Cosmos/src/Telemetry/ClientTelemetry.cs +++ b/Microsoft.Azure.Cosmos/src/Telemetry/ClientTelemetry.cs @@ -7,18 +7,16 @@ namespace Microsoft.Azure.Cosmos.Telemetry using System; using System.Collections.Concurrent; using System.Collections.Generic; - using System.Net; using System.Threading; using System.Threading.Tasks; using Handler; using HdrHistogram; using Microsoft.Azure.Cosmos.Core.Trace; using Microsoft.Azure.Cosmos.Routing; + using Microsoft.Azure.Cosmos.Telemetry.Collector; using Microsoft.Azure.Cosmos.Telemetry.Models; - using Microsoft.Azure.Cosmos.Tracing; - using Microsoft.Azure.Cosmos.Tracing.TraceData; - using Microsoft.Azure.Documents; using Util; + using static Microsoft.Azure.Cosmos.Tracing.TraceData.ClientSideRequestStatisticsTraceDatum; /// /// This class collects and send all the telemetry information. @@ -28,11 +26,12 @@ namespace Microsoft.Azure.Cosmos.Telemetry /// internal class ClientTelemetry : IDisposable { - private static readonly TimeSpan observingWindow = ClientTelemetryOptions.GetScheduledTimeSpan(); + private static readonly TimeSpan observingWindow = ClientTelemetryOptions.DefaultIntervalForTelemetryJob; private readonly ClientTelemetryProperties clientTelemetryInfo; private readonly ClientTelemetryProcessor processor; private readonly DiagnosticsHandlerHelper diagnosticsHelper; + private readonly string endpointUrl; private readonly NetworkDataRecorder networkDataRecorder; private readonly CancellationTokenSource cancellationTokenSource; @@ -65,6 +64,7 @@ internal ClientTelemetry() /// /// /// + /// /// ClientTelemetry public static ClientTelemetry CreateAndStartBackgroundTelemetry( string clientId, @@ -74,7 +74,8 @@ public static ClientTelemetry CreateAndStartBackgroundTelemetry( AuthorizationTokenProvider authorizationTokenProvider, DiagnosticsHandlerHelper diagnosticsHelper, IReadOnlyList preferredRegions, - GlobalEndpointManager globalEndpointManager) + GlobalEndpointManager globalEndpointManager, + string endpointUrl ) { DefaultTrace.TraceInformation("Initiating telemetry with background task."); @@ -86,7 +87,8 @@ public static ClientTelemetry CreateAndStartBackgroundTelemetry( authorizationTokenProvider, diagnosticsHelper, preferredRegions, - globalEndpointManager); + globalEndpointManager, + endpointUrl); clientTelemetry.StartObserverTask(); @@ -101,9 +103,12 @@ internal ClientTelemetry( AuthorizationTokenProvider authorizationTokenProvider, DiagnosticsHandlerHelper diagnosticsHelper, IReadOnlyList preferredRegions, - GlobalEndpointManager globalEndpointManager) + GlobalEndpointManager globalEndpointManager, + string endpointUrl) { this.diagnosticsHelper = diagnosticsHelper ?? throw new ArgumentNullException(nameof(diagnosticsHelper)); + this.endpointUrl = endpointUrl ?? throw new ArgumentNullException(nameof(endpointUrl)); + this.globalEndpointManager = globalEndpointManager; this.processor = new ClientTelemetryProcessor(httpClient, authorizationTokenProvider); @@ -179,6 +184,7 @@ ConcurrentDictionary cacheRefreshInfo operationInfoSnapshot: operationInfoSnapshot, cacheRefreshInfoSnapshot: cacheRefreshInfoSnapshot, requestInfoSnapshot: requestInfoSnapshot, + endpointUrl: this.endpointUrl, cancellationToken: cancellationToken.Token), cancellationToken.Token); // Initiating Telemetry Data Processor task which will serialize and send telemetry information to Client Telemetry Service @@ -215,9 +221,9 @@ internal static async Task RunProcessorTaskAsync(string telemetryDate, Task proc Task resultTask = await Task.WhenAny(processingTask, delayTask); if (resultTask == delayTask) { - DefaultTrace.TraceVerbose($"Processor task with date as {telemetryDate} is canceled as it did not finish in {timeout}"); + DefaultTrace.TraceVerbose($"Processor task with date as {0} is canceled as it did not finish in {1}", telemetryDate, timeout); // Operation cancelled - throw new OperationCanceledException($"Processor task with date as {telemetryDate} is canceled as it did not finish in {timeout}"); + throw new OperationCanceledException(string.Format($"Processor task with date as {0} is canceled as it did not finish in {1}", telemetryDate, timeout)); } else { @@ -230,38 +236,36 @@ internal static async Task RunProcessorTaskAsync(string telemetryDate, Task proc /// /// Collects Cache Telemetry Information. /// - internal void CollectCacheInfo(string cacheRefreshSource, - HashSet<(string regionName, Uri uri)> regionsContactedList, - TimeSpan? requestLatency, - HttpStatusCode statusCode, - string containerId, - OperationType operationType, - ResourceType resourceType, - SubStatusCodes subStatusCode, - string databaseId, - long responseSizeInBytes = 0, - string consistencyLevel = null ) + internal void PushCacheDatapoint(string cacheName, TelemetryInformation data) { - if (string.IsNullOrEmpty(cacheRefreshSource)) + if (string.IsNullOrEmpty(cacheName)) + { + throw new ArgumentNullException(nameof(cacheName)); + } + + // If latency information is not available. Ignore this datapoint. It is not expected but putting this safety check + if (!data.RequestLatency.HasValue) { - throw new ArgumentNullException(nameof(cacheRefreshSource)); + DefaultTrace.TraceWarning($"Latency data point is not available for {0} cache call", cacheName); + + return; } - DefaultTrace.TraceVerbose($"Collecting cacheRefreshSource {0} data for Telemetry.", cacheRefreshSource); + DefaultTrace.TraceVerbose($"Collecting cacheRefreshSource {0} data for Telemetry.", cacheName); - string regionsContacted = ClientTelemetryHelper.GetContactedRegions(regionsContactedList); + string regionsContacted = ClientTelemetryHelper.GetContactedRegions(data.RegionsContactedList); // Recording Request Latency - CacheRefreshInfo payloadKey = new CacheRefreshInfo(cacheRefreshSource: cacheRefreshSource, + CacheRefreshInfo payloadKey = new CacheRefreshInfo(cacheRefreshSource: cacheName, regionsContacted: regionsContacted?.ToString(), - responseSizeInBytes: responseSizeInBytes, - consistency: consistencyLevel, - databaseName: databaseId, - containerName: containerId, - operation: operationType, - resource: resourceType, - statusCode: (int)statusCode, - subStatusCode: (int)subStatusCode); + responseSizeInBytes: data.ResponseSizeInBytes, + consistency: data.ConsistencyLevel, + databaseName: data.DatabaseId, + containerName: data.ContainerId, + operation: data.OperationType, + resource: data.ResourceType, + statusCode: (int)data.StatusCode, + subStatusCode: (int)data.SubStatusCode); LongConcurrentHistogram latency = this.cacheRefreshInfoMap .GetOrAdd(payloadKey, new LongConcurrentHistogram(ClientTelemetryOptions.RequestLatencyMin, @@ -269,7 +273,7 @@ internal void CollectCacheInfo(string cacheRefreshSource, ClientTelemetryOptions.RequestLatencyPrecision)); try { - latency.RecordValue(requestLatency.Value.Ticks); + latency.RecordValue(data.RequestLatency.Value.Ticks); } catch (Exception ex) { @@ -280,52 +284,22 @@ internal void CollectCacheInfo(string cacheRefreshSource, /// /// Collects Telemetry Information. /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - internal void CollectOperationInfo(CosmosDiagnostics cosmosDiagnostics, - HttpStatusCode statusCode, - long responseSizeInBytes, - string containerId, - string databaseId, - OperationType operationType, - ResourceType resourceType, - string consistencyLevel, - double requestCharge, - SubStatusCodes subStatusCode, - ITrace trace) + internal void PushOperationDatapoint(TelemetryInformation data) { DefaultTrace.TraceVerbose("Collecting Operation data for Telemetry."); - if (cosmosDiagnostics == null) - { - throw new ArgumentNullException(nameof(cosmosDiagnostics)); - } - - // Record Network/Replica Information - SummaryDiagnostics summaryDiagnostics = new SummaryDiagnostics(trace); - this.networkDataRecorder.Record(summaryDiagnostics.StoreResponseStatistics.Value, databaseId, containerId); - - string regionsContacted = ClientTelemetryHelper.GetContactedRegions(cosmosDiagnostics.GetContactedRegions()); + string regionsContacted = ClientTelemetryHelper.GetContactedRegions(data.RegionsContactedList); // Recording Request Latency and Request Charge OperationInfo payloadKey = new OperationInfo(regionsContacted: regionsContacted?.ToString(), - responseSizeInBytes: responseSizeInBytes, - consistency: consistencyLevel, - databaseName: databaseId, - containerName: containerId, - operation: operationType, - resource: resourceType, - statusCode: (int)statusCode, - subStatusCode: (int)subStatusCode); + responseSizeInBytes: data.ResponseSizeInBytes, + consistency: data.ConsistencyLevel, + databaseName: data.DatabaseId, + containerName: data.ContainerId, + operation: data.OperationType, + resource: data.ResourceType, + statusCode: (int)data.StatusCode, + subStatusCode: (int)data.SubStatusCode); (LongConcurrentHistogram latency, LongConcurrentHistogram requestcharge) = this.operationInfoMap .GetOrAdd(payloadKey, x => (latency: new LongConcurrentHistogram(ClientTelemetryOptions.RequestLatencyMin, @@ -334,16 +308,26 @@ internal void CollectOperationInfo(CosmosDiagnostics cosmosDiagnostics, requestcharge: new LongConcurrentHistogram(ClientTelemetryOptions.RequestChargeMin, ClientTelemetryOptions.RequestChargeMax, ClientTelemetryOptions.RequestChargePrecision))); - try + + // If latency information is not available. Ignore this datapoint. It is not expected but putting this safety check + if (data.RequestLatency.HasValue) { - latency.RecordValue(cosmosDiagnostics.GetClientElapsedTime().Ticks); + try + { + latency.RecordValue(data.RequestLatency.Value.Ticks); + } + catch (Exception ex) + { + DefaultTrace.TraceError("Latency Recording Failed by Telemetry. Exception : {0}", ex); + } + } - catch (Exception ex) + else { - DefaultTrace.TraceError("Latency Recording Failed by Telemetry. Exception : {0}", ex); + DefaultTrace.TraceWarning($"Latency data point is not available for an operation"); } - - long requestChargeToRecord = (long)(requestCharge * ClientTelemetryOptions.HistogramPrecisionFactor); + + long requestChargeToRecord = (long)(data.RequestCharge * ClientTelemetryOptions.HistogramPrecisionFactor); try { requestcharge.RecordValue(requestChargeToRecord); @@ -354,6 +338,19 @@ internal void CollectOperationInfo(CosmosDiagnostics cosmosDiagnostics, } } + /// + /// Record Network Request Telemetry Information + /// + /// + /// + /// + public void PushNetworkDataPoint(List storeResponseStatistics, string databaseId, string containerId) + { + // Record Network/Replica Information + this.networkDataRecorder.Record(storeResponseStatistics, databaseId, containerId); + + } + /// /// Dispose of cosmos client.It will get disposed with client so not making it thread safe. /// diff --git a/Microsoft.Azure.Cosmos/src/Telemetry/ClientTelemetryOptions.cs b/Microsoft.Azure.Cosmos/src/Telemetry/ClientTelemetryOptions.cs index 2aeaadca63..84a47e1081 100644 --- a/Microsoft.Azure.Cosmos/src/Telemetry/ClientTelemetryOptions.cs +++ b/Microsoft.Azure.Cosmos/src/Telemetry/ClientTelemetryOptions.cs @@ -72,17 +72,13 @@ internal static class ClientTelemetryOptions internal const string IsThreadStarvingName = "SystemPool_IsThreadStarving_True"; internal const string IsThreadStarvingUnit = "Count"; - internal const double DefaultTimeStampInSeconds = 600; internal const double Percentile50 = 50.0; internal const double Percentile90 = 90.0; internal const double Percentile95 = 95.0; internal const double Percentile99 = 99.0; internal const double Percentile999 = 99.9; internal const string DateFormat = "yyyy-MM-ddTHH:mm:ssZ"; - internal const string EnvPropsClientTelemetrySchedulingInSeconds = "COSMOS.CLIENT_TELEMETRY_SCHEDULING_IN_SECONDS"; - internal const string EnvPropsClientTelemetryEnabled = "COSMOS.CLIENT_TELEMETRY_ENABLED"; - internal const string EnvPropsClientTelemetryVmMetadataUrl = "COSMOS.VM_METADATA_URL"; - internal const string EnvPropsClientTelemetryEndpoint = "COSMOS.CLIENT_TELEMETRY_ENDPOINT"; + internal const string EnvPropsClientTelemetryEnvironmentName = "COSMOS.ENVIRONMENT_NAME"; internal static readonly ResourceType AllowedResourceTypes = ResourceType.Document; @@ -99,53 +95,11 @@ internal static class ClientTelemetryOptions internal static readonly List ExcludedStatusCodes = new List { 404, 409, 412 }; internal static readonly int NetworkTelemetrySampleSize = 200; + internal static TimeSpan DefaultIntervalForTelemetryJob = TimeSpan.FromMinutes(10); internal static int PayloadSizeThreshold = 1024 * 1024 * 2; // 2MB internal static TimeSpan ClientTelemetryProcessorTimeOut = TimeSpan.FromMinutes(5); - private static Uri clientTelemetryEndpoint; private static string environmentName; - private static TimeSpan scheduledTimeSpan = TimeSpan.Zero; - - internal static bool IsClientTelemetryEnabled() - { - bool isTelemetryEnabled = ConfigurationManager - .GetEnvironmentVariable(ClientTelemetryOptions - .EnvPropsClientTelemetryEnabled, false); - - DefaultTrace.TraceInformation($"Telemetry Flag is set to {isTelemetryEnabled}"); - - return isTelemetryEnabled; - } - - internal static TimeSpan GetScheduledTimeSpan() - { - if (scheduledTimeSpan.Equals(TimeSpan.Zero)) - { - double scheduledTimeInSeconds = ClientTelemetryOptions.DefaultTimeStampInSeconds; - try - { - scheduledTimeInSeconds = ConfigurationManager - .GetEnvironmentVariable( - ClientTelemetryOptions.EnvPropsClientTelemetrySchedulingInSeconds, - ClientTelemetryOptions.DefaultTimeStampInSeconds); - - if (scheduledTimeInSeconds <= 0) - { - throw new ArgumentException("Telemetry Scheduled time can not be less than or equal to 0."); - } - } - catch (Exception ex) - { - DefaultTrace.TraceError($"Error while getting telemetry scheduling configuration : {ex.Message}. Falling back to default configuration i.e. {scheduledTimeInSeconds}" ); - } - - scheduledTimeSpan = TimeSpan.FromSeconds(scheduledTimeInSeconds); - - DefaultTrace.TraceInformation($"Telemetry Scheduled in Seconds {scheduledTimeSpan.TotalSeconds}"); - - } - return scheduledTimeSpan; - } internal static string GetHostInformation(Compute vmInformation) { @@ -155,23 +109,6 @@ internal static string GetHostInformation(Compute vmInformation) vmInformation?.AzEnvironment); } - internal static Uri GetClientTelemetryEndpoint() - { - if (clientTelemetryEndpoint == null) - { - string uriProp = ConfigurationManager - .GetEnvironmentVariable( - ClientTelemetryOptions.EnvPropsClientTelemetryEndpoint, null); - if (!String.IsNullOrEmpty(uriProp)) - { - clientTelemetryEndpoint = new Uri(uriProp); - } - - DefaultTrace.TraceInformation($"Telemetry Endpoint URL is {uriProp}"); - } - return clientTelemetryEndpoint; - } - internal static string GetEnvironmentName() { if (String.IsNullOrEmpty(environmentName)) diff --git a/Microsoft.Azure.Cosmos/src/Telemetry/ClientTelemetryProcessor.cs b/Microsoft.Azure.Cosmos/src/Telemetry/ClientTelemetryProcessor.cs index c9511cb4e4..ffa74c2466 100644 --- a/Microsoft.Azure.Cosmos/src/Telemetry/ClientTelemetryProcessor.cs +++ b/Microsoft.Azure.Cosmos/src/Telemetry/ClientTelemetryProcessor.cs @@ -19,8 +19,6 @@ namespace Microsoft.Azure.Cosmos.Telemetry internal class ClientTelemetryProcessor { - private static readonly Uri endpointUrl = ClientTelemetryOptions.GetClientTelemetryEndpoint(); - private readonly AuthorizationTokenProvider tokenProvider; private readonly CosmosHttpClient httpClient; @@ -39,6 +37,7 @@ internal async Task ProcessAndSendAsync( ConcurrentDictionary operationInfoSnapshot, ConcurrentDictionary cacheRefreshInfoSnapshot, IReadOnlyList requestInfoSnapshot, + string endpointUrl, CancellationToken cancellationToken) { try @@ -48,7 +47,7 @@ await ClientTelemetryPayloadWriter.SerializedPayloadChunksAsync( operationInfoSnapshot: operationInfoSnapshot, cacheRefreshInfoSnapshot: cacheRefreshInfoSnapshot, sampledRequestInfo: requestInfoSnapshot, - callback: async (payload) => await this.SendAsync(clientTelemetryInfo.GlobalDatabaseAccountName, payload, cancellationToken)); + callback: async (payload) => await this.SendAsync(clientTelemetryInfo.GlobalDatabaseAccountName, payload, endpointUrl, cancellationToken)); } catch (Exception ex) { @@ -67,6 +66,7 @@ await ClientTelemetryPayloadWriter.SerializedPayloadChunksAsync( private async Task SendAsync( string globalDatabaseAccountName, string jsonPayload, + string endpointUrl, CancellationToken cancellationToken) { if (endpointUrl == null) @@ -77,12 +77,12 @@ private async Task SendAsync( try { - DefaultTrace.TraceInformation("Sending Telemetry Data to {0}", endpointUrl.AbsoluteUri); + DefaultTrace.TraceInformation("Sending Telemetry Data to {0}", endpointUrl); using HttpRequestMessage request = new HttpRequestMessage { Method = HttpMethod.Post, - RequestUri = endpointUrl, + RequestUri = new Uri(endpointUrl), Content = new StringContent(jsonPayload, Encoding.UTF8, "application/json") }; @@ -91,7 +91,7 @@ async ValueTask CreateRequestMessage() INameValueCollection headersCollection = new StoreResponseNameValueCollection(); await this.tokenProvider.AddAuthorizationHeaderAsync( headersCollection, - endpointUrl, + new Uri(endpointUrl), "POST", AuthorizationTokenType.PrimaryMasterKey); diff --git a/Microsoft.Azure.Cosmos/src/Telemetry/Collector/ITelemetryCollector.cs b/Microsoft.Azure.Cosmos/src/Telemetry/Collector/ITelemetryCollector.cs new file mode 100644 index 0000000000..aef7a5efc4 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Telemetry/Collector/ITelemetryCollector.cs @@ -0,0 +1,25 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Telemetry +{ + using System; + using Microsoft.Azure.Cosmos.Telemetry.Collector; + + internal interface ITelemetryCollector + { + /// + /// Collect information required to collect the telemetry information for the cache. + /// + /// Cache Name + /// delegate that encapsulates a method that returns a CacheTelemetryInformation object + public void CollectCacheInfo(string cacheName, Func functionFordata); + + /// + /// Collect information required to collect the telemetry information for the operation. + /// + /// delegate that encapsulates a method that returns a OperationTelemetryInformation object + public void CollectOperationAndNetworkInfo(Func functionFordata); + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Telemetry/Collector/TelemetryCollector.cs b/Microsoft.Azure.Cosmos/src/Telemetry/Collector/TelemetryCollector.cs new file mode 100644 index 0000000000..9570fcd56a --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Telemetry/Collector/TelemetryCollector.cs @@ -0,0 +1,77 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Telemetry.Collector +{ + using System; + using Microsoft.Azure.Cosmos; + using Microsoft.Azure.Cosmos.Core.Trace; + using Microsoft.Azure.Cosmos.Telemetry; + using Microsoft.Azure.Cosmos.Tracing.TraceData; + using Microsoft.Azure.Documents; + + internal class TelemetryCollector : ITelemetryCollector + { + private readonly ClientTelemetry clientTelemetry = null; + private readonly ConnectionPolicy connectionPolicy = null; + + internal TelemetryCollector( + ClientTelemetry clientTelemetry, + ConnectionPolicy connectionPolicy) + { + this.clientTelemetry = clientTelemetry; + this.connectionPolicy = connectionPolicy; + } + + public void CollectCacheInfo(string cacheName, Func functionFordata) + { + try + { + TelemetryInformation data = functionFordata(); + + if (data.CollectionLink != null) + { + GetDatabaseAndCollectionName(data.CollectionLink, out string databaseName, out string collectionName); + + data.DatabaseId = databaseName; + data.ContainerId = collectionName; + } + + this.clientTelemetry?.PushCacheDatapoint(cacheName, data); + } + catch (Exception ex) + { + DefaultTrace.TraceError($"Error while collecting cache {0} telemetry. Exception : {1}", cacheName, ex); + } + } + + public void CollectOperationAndNetworkInfo(Func functionFordata) + { + try + { + TelemetryInformation data = functionFordata(); + + this.clientTelemetry?.PushOperationDatapoint(data); + + // Collect network level telemetry only in Direct Mode + if (this.connectionPolicy.ConnectionMode == ConnectionMode.Direct) + { + SummaryDiagnostics summaryDiagnostics = new SummaryDiagnostics(data.Trace); + this.clientTelemetry?.PushNetworkDataPoint(summaryDiagnostics.StoreResponseStatistics.Value, data.DatabaseId, data.ContainerId); + } + } + catch (Exception ex) + { + DefaultTrace.TraceError($"Error while collecting operation telemetry. Exception : {1}", ex); + } + } + + private static void GetDatabaseAndCollectionName(string path, out string databaseName, out string collectionName) + { + string[] segments = path.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries); + + PathsHelper.ParseDatabaseNameAndCollectionNameFromUrlSegments(segments, out databaseName, out collectionName); + } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Telemetry/Collector/TelemetryCollectorNoOp.cs b/Microsoft.Azure.Cosmos/src/Telemetry/Collector/TelemetryCollectorNoOp.cs new file mode 100644 index 0000000000..a1d286fe94 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Telemetry/Collector/TelemetryCollectorNoOp.cs @@ -0,0 +1,21 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Telemetry.Collector +{ + using System; + + internal class TelemetryCollectorNoOp : ITelemetryCollector + { + public void CollectCacheInfo(string cacheName, Func functionFordata) + { + //NoOps + } + + public void CollectOperationAndNetworkInfo(Func functionFordata) + { + //NoOps + } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Telemetry/Collector/TelemetryInformation.cs b/Microsoft.Azure.Cosmos/src/Telemetry/Collector/TelemetryInformation.cs new file mode 100644 index 0000000000..a8210fb0a4 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Telemetry/Collector/TelemetryInformation.cs @@ -0,0 +1,30 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Telemetry.Collector +{ + using System; + using System.Collections.Generic; + using System.Net; + using Microsoft.Azure.Cosmos.Tracing; + using Microsoft.Azure.Documents; + + internal class TelemetryInformation + { + internal HttpStatusCode StatusCode { get; set; } + internal SubStatusCodes SubStatusCode { get; set; } + internal OperationType OperationType { get; set; } + internal ResourceType ResourceType { get; set; } + internal string ContainerId { get; set; } + internal string DatabaseId { get; set; } + internal long ResponseSizeInBytes { get; set; } = 0; + internal string ConsistencyLevel { get; set; } = null; + internal IReadOnlyCollection<(string regionName, Uri uri)> RegionsContactedList { get; set; } + internal TimeSpan? RequestLatency { get; set; } + + internal double RequestCharge { get; set; } // Required only for operation level telemetry + internal string CollectionLink { get; set; } = null; // Required only for collection cache telemetry + internal ITrace Trace { get; set; } // Required to fetch network level telemetry out of the trace object + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Telemetry/OpenTelemetry/CosmosDbEventSource.cs b/Microsoft.Azure.Cosmos/src/Telemetry/OpenTelemetry/CosmosDbEventSource.cs index 9e8028c0d8..f7fe0c307f 100644 --- a/Microsoft.Azure.Cosmos/src/Telemetry/OpenTelemetry/CosmosDbEventSource.cs +++ b/Microsoft.Azure.Cosmos/src/Telemetry/OpenTelemetry/CosmosDbEventSource.cs @@ -31,12 +31,12 @@ public static bool IsEnabled(EventLevel level) [NonEvent] public static void RecordDiagnosticsForRequests( - DistributedTracingOptions config, + CosmosThresholdOptions config, Documents.OperationType operationType, OpenTelemetryAttributes response) { if (!DiagnosticsFilterHelper.IsSuccessfulResponse( - response: response) && CosmosDbEventSource.IsEnabled(EventLevel.Warning)) + response.StatusCode, response.SubStatusCode) && CosmosDbEventSource.IsEnabled(EventLevel.Warning)) { CosmosDbEventSource.Singleton.FailedRequest(response.Diagnostics.ToString()); } diff --git a/Microsoft.Azure.Cosmos/src/Telemetry/OpenTelemetry/DistributedTracingOptions.cs b/Microsoft.Azure.Cosmos/src/Telemetry/OpenTelemetry/DistributedTracingOptions.cs deleted file mode 100644 index 6c44f06bf2..0000000000 --- a/Microsoft.Azure.Cosmos/src/Telemetry/OpenTelemetry/DistributedTracingOptions.cs +++ /dev/null @@ -1,30 +0,0 @@ -// ------------------------------------------------------------ -// Copyright (c) Microsoft Corporation. All rights reserved. -// ------------------------------------------------------------ - -namespace Microsoft.Azure.Cosmos -{ - using System; - - /// - /// Options for configuring the distributed tracing and event tracing - /// - internal sealed class DistributedTracingOptions - { - /// - /// Default Latency threshold for other than query Operation - /// - internal static readonly TimeSpan DefaultCrudLatencyThreshold = TimeSpan.FromMilliseconds(100); - - /// - /// Default Latency threshold for QUERY operation - /// - internal static readonly TimeSpan DefaultQueryTimeoutThreshold = TimeSpan.FromMilliseconds(500); - - /// - /// SDK generates (Event Source Name is "Azure-Cosmos-Operation-Request-Diagnostics") with Request Diagnostics String, If Operation level distributed tracing is not disabled i.e. - /// - /// If it is not set then, by default, it will generate for query operation which are taking more than 500 ms and non-query operations taking more than 100 ms. - public TimeSpan? LatencyThresholdForDiagnosticEvent { get; set; } - } -} diff --git a/Microsoft.Azure.Cosmos/src/Telemetry/OpenTelemetry/Filters/DiagnosticsFilterHelper.cs b/Microsoft.Azure.Cosmos/src/Telemetry/OpenTelemetry/Filters/DiagnosticsFilterHelper.cs index 60fb86fa5c..3c0646f101 100644 --- a/Microsoft.Azure.Cosmos/src/Telemetry/OpenTelemetry/Filters/DiagnosticsFilterHelper.cs +++ b/Microsoft.Azure.Cosmos/src/Telemetry/OpenTelemetry/Filters/DiagnosticsFilterHelper.cs @@ -5,44 +5,63 @@ namespace Microsoft.Azure.Cosmos.Telemetry.Diagnostics { using System; + using System.Net; using Documents; internal static class DiagnosticsFilterHelper { + private static readonly CosmosThresholdOptions defaultThresholdOptions = new CosmosThresholdOptions(); + /// /// Allow only when Latency is not more than 100 (non-query) /250 (query) ms /// /// true or false public static bool IsLatencyThresholdCrossed( - DistributedTracingOptions config, + CosmosThresholdOptions config, OperationType operationType, OpenTelemetryAttributes response) { - TimeSpan latencyThreshold; - - if (config?.LatencyThresholdForDiagnosticEvent != null) - { - latencyThreshold = config.LatencyThresholdForDiagnosticEvent.Value; - } - else - { - latencyThreshold = operationType == OperationType.Query ? DistributedTracingOptions.DefaultQueryTimeoutThreshold : DistributedTracingOptions.DefaultCrudLatencyThreshold; - } - - return response.Diagnostics.GetClientElapsedTime() > latencyThreshold; + return response.Diagnostics.GetClientElapsedTime() > DiagnosticsFilterHelper.DefaultThreshold(operationType, config); } /// /// Check if response HTTP status code is returning successful /// /// true or false - public static bool IsSuccessfulResponse(OpenTelemetryAttributes response) - { - return response.StatusCode.IsSuccess() - || (response.StatusCode == System.Net.HttpStatusCode.NotFound && response.SubStatusCode == 0) - || (response.StatusCode == System.Net.HttpStatusCode.NotModified && response.SubStatusCode == 0) - || (response.StatusCode == System.Net.HttpStatusCode.Conflict && response.SubStatusCode == 0) - || (response.StatusCode == System.Net.HttpStatusCode.PreconditionFailed && response.SubStatusCode == 0); + public static bool IsSuccessfulResponse(HttpStatusCode statusCode, int substatusCode) + { + return statusCode.IsSuccess() + || (statusCode == System.Net.HttpStatusCode.NotFound && substatusCode == 0) + || (statusCode == System.Net.HttpStatusCode.NotModified && substatusCode == 0) + || (statusCode == System.Net.HttpStatusCode.Conflict && substatusCode == 0) + || (statusCode == System.Net.HttpStatusCode.PreconditionFailed && substatusCode == 0); + } + + /// + /// Get default threshold value based on operation type + /// + /// + /// + internal static TimeSpan DefaultThreshold(OperationType operationType, CosmosThresholdOptions config) + { + config ??= DiagnosticsFilterHelper.defaultThresholdOptions; + return DiagnosticsFilterHelper.IsPointOperation(operationType) ? + config.PointOperationLatencyThreshold : + config.NonPointOperationLatencyThreshold; + } + + /// + /// Check if passed operation type is a point operation + /// + /// + internal static bool IsPointOperation(OperationType operationType) + { + return operationType == OperationType.Create || + operationType == OperationType.Delete || + operationType == OperationType.Replace || + operationType == OperationType.Upsert || + operationType == OperationType.Patch || + operationType == OperationType.Read; } } } diff --git a/Microsoft.Azure.Cosmos/src/Telemetry/OpenTelemetry/OpenTelemetryCoreRecorder.cs b/Microsoft.Azure.Cosmos/src/Telemetry/OpenTelemetry/OpenTelemetryCoreRecorder.cs index 2ef929ca8c..2928685d97 100644 --- a/Microsoft.Azure.Cosmos/src/Telemetry/OpenTelemetry/OpenTelemetryCoreRecorder.cs +++ b/Microsoft.Azure.Cosmos/src/Telemetry/OpenTelemetry/OpenTelemetryCoreRecorder.cs @@ -8,6 +8,7 @@ namespace Microsoft.Azure.Cosmos.Telemetry using System.Collections.Generic; using System.Diagnostics; using global::Azure.Core; + using Microsoft.Azure.Cosmos.Telemetry.Diagnostics; /// /// This class is used to add information in an Activity tags ref. https://github.com/Azure/azure-cosmos-dotnet-v3/issues/3058 @@ -17,7 +18,7 @@ internal struct OpenTelemetryCoreRecorder : IDisposable private const string CosmosDb = "cosmosdb"; private readonly DiagnosticScope scope = default; - private readonly DistributedTracingOptions config = null; + private readonly CosmosThresholdOptions config = null; private readonly Activity activity = null; private readonly Documents.OperationType operationType = Documents.OperationType.Invalid; @@ -50,7 +51,7 @@ private OpenTelemetryCoreRecorder( string containerName, string databaseName, Documents.OperationType operationType, - CosmosClientContext clientContext, DistributedTracingOptions config) + CosmosClientContext clientContext, CosmosThresholdOptions config) { this.scope = scope; this.config = config; @@ -95,7 +96,7 @@ public static OpenTelemetryCoreRecorder CreateOperationLevelParentActivity( string databaseName, Documents.OperationType operationType, CosmosClientContext clientContext, - DistributedTracingOptions config) + CosmosThresholdOptions config) { return new OpenTelemetryCoreRecorder( operationScope, @@ -177,7 +178,12 @@ public void MarkFailed(Exception exception) this.scope.AddAttribute(OpenTelemetryAttributeKeys.ExceptionMessage, exception.Message); } - this.scope.Failed(exception); + if (exception is not CosmosException || (exception is CosmosException cosmosException + && !DiagnosticsFilterHelper + .IsSuccessfulResponse(cosmosException.StatusCode, cosmosException.SubStatusCode))) + { + this.scope.Failed(exception); + } } } @@ -205,7 +211,7 @@ internal static bool IsExceptionRegistered(Exception exception, DiagnosticScope public void Dispose() { - if (this.scope.IsEnabled) + if (this.IsEnabled) { Documents.OperationType operationType = (this.response == null || this.response?.OperationType == Documents.OperationType.Invalid) ? this.operationType : this.response.OperationType; @@ -217,7 +223,7 @@ Documents.OperationType operationType this.scope.AddAttribute(OpenTelemetryAttributeKeys.RequestContentLength, this.response.RequestContentLength); this.scope.AddAttribute(OpenTelemetryAttributeKeys.ResponseContentLength, this.response.ResponseContentLength); this.scope.AddAttribute(OpenTelemetryAttributeKeys.StatusCode, (int)this.response.StatusCode); - this.scope.AddAttribute(OpenTelemetryAttributeKeys.SubStatusCode, (int)this.response.SubStatusCode); + this.scope.AddAttribute(OpenTelemetryAttributeKeys.SubStatusCode, this.response.SubStatusCode); this.scope.AddAttribute(OpenTelemetryAttributeKeys.RequestCharge, this.response.RequestCharge); this.scope.AddAttribute(OpenTelemetryAttributeKeys.ItemCount, this.response.ItemCount); this.scope.AddAttribute(OpenTelemetryAttributeKeys.ActivityId, this.response.ActivityId); @@ -228,6 +234,11 @@ Documents.OperationType operationType this.scope.AddAttribute(OpenTelemetryAttributeKeys.Region, ClientTelemetryHelper.GetContactedRegions(this.response.Diagnostics.GetContactedRegions())); CosmosDbEventSource.RecordDiagnosticsForRequests(this.config, operationType, this.response); } + + if (!DiagnosticsFilterHelper.IsSuccessfulResponse(this.response.StatusCode, this.response.SubStatusCode)) + { + this.scope.Failed(); + } } this.scope.Dispose(); diff --git a/Microsoft.Azure.Cosmos/src/Telemetry/OpenTelemetry/OpenTelemetryRecorderFactory.cs b/Microsoft.Azure.Cosmos/src/Telemetry/OpenTelemetry/OpenTelemetryRecorderFactory.cs index ca0b864d2f..b8babd37da 100644 --- a/Microsoft.Azure.Cosmos/src/Telemetry/OpenTelemetry/OpenTelemetryRecorderFactory.cs +++ b/Microsoft.Azure.Cosmos/src/Telemetry/OpenTelemetry/OpenTelemetryRecorderFactory.cs @@ -42,13 +42,15 @@ public static OpenTelemetryCoreRecorder CreateRecorder(string operationName, CosmosClientContext clientContext) { OpenTelemetryCoreRecorder openTelemetryRecorder = default; - if (clientContext is { ClientOptions.IsDistributedTracingEnabled: true }) + if (clientContext is { ClientOptions.CosmosClientTelemetryOptions.DisableDistributedTracing: false }) { // If there is no source then it will return default otherwise a valid diagnostic scope DiagnosticScope scope = LazyOperationScopeFactory.Value.CreateScope(name: operationName, kind: clientContext.ClientOptions.ConnectionMode == ConnectionMode.Gateway ? DiagnosticScope.ActivityKind.Internal : DiagnosticScope.ActivityKind.Client); - // Record values only when we have a valid Diagnostic Scope + // Need a parent activity id associated with the operation which is logged in diagnostics and used for tracing purpose. + // If there are listeners at operation level then scope is enabled and it tries to create activity. + // However, if available listeners are not subscribed to operation level event then it will lead to scope being enabled but no activity is created. if (scope.IsEnabled) { scope.SetDisplayName($"{operationName} {containerName}"); @@ -60,17 +62,31 @@ public static OpenTelemetryCoreRecorder CreateRecorder(string operationName, databaseName: databaseName, operationType: operationType, clientContext: clientContext, - config: requestOptions?.DistributedTracingOptions ?? clientContext.ClientOptions?.DistributedTracingOptions); + config: requestOptions?.CosmosThresholdOptions ?? clientContext.ClientOptions?.CosmosClientTelemetryOptions.CosmosThresholdOptions); } #if !INTERNAL - else if (Activity.Current is null) + // Need a parent activity which groups all network activities under it and is logged in diagnostics and used for tracing purpose. + // If there are listeners at network level then scope is enabled and it tries to create activity. + // However, if available listeners are not subscribed to network event then it will lead to scope being enabled but no activity is created. + else { DiagnosticScope requestScope = LazyNetworkScopeFactory.Value.CreateScope(name: operationName); + openTelemetryRecorder = requestScope.IsEnabled ? OpenTelemetryCoreRecorder.CreateNetworkLevelParentActivity(networkScope: requestScope) : openTelemetryRecorder; + } - openTelemetryRecorder = requestScope.IsEnabled ? OpenTelemetryCoreRecorder.CreateNetworkLevelParentActivity(networkScope: requestScope) : OpenTelemetryCoreRecorder.CreateParentActivity(operationName); + // If there are no listeners at operation level and network level and no parent activity created. + // Then create a dummy activity as there should be a parent level activity always to send a traceid to the backend services through context propagation. + // The parent activity id is logged in diagnostics and used for tracing purpose. + if (Activity.Current is null) + { + openTelemetryRecorder = OpenTelemetryCoreRecorder.CreateParentActivity(operationName); } #endif - trace.AddDatum("DistributedTraceId", Activity.Current?.TraceId); + // Safety check as diagnostic logs should not break the code. + if (Activity.Current?.TraceId != null) + { + trace.AddDatum("DistributedTraceId", Activity.Current.TraceId); + } } return openTelemetryRecorder; } diff --git a/Microsoft.Azure.Cosmos/src/Telemetry/OpenTelemetry/OpenTelemetryResponse.cs b/Microsoft.Azure.Cosmos/src/Telemetry/OpenTelemetry/OpenTelemetryResponse.cs index c9aba10ee6..09d43c6965 100644 --- a/Microsoft.Azure.Cosmos/src/Telemetry/OpenTelemetry/OpenTelemetryResponse.cs +++ b/Microsoft.Azure.Cosmos/src/Telemetry/OpenTelemetry/OpenTelemetryResponse.cs @@ -4,8 +4,10 @@ namespace Microsoft.Azure.Cosmos { + using System; using System.IO; using System.Net; + using Microsoft.Azure.Cosmos.Core.Trace; using Telemetry; internal sealed class OpenTelemetryResponse : OpenTelemetryAttributes @@ -13,28 +15,28 @@ internal sealed class OpenTelemetryResponse : OpenTelemetryAttributes internal OpenTelemetryResponse(TransactionalBatchResponse responseMessage) : this( statusCode: responseMessage.StatusCode, - requestCharge: responseMessage.Headers?.RequestCharge, + requestCharge: OpenTelemetryResponse.GetHeader(responseMessage)?.RequestCharge, responseContentLength: null, diagnostics: responseMessage.Diagnostics, - itemCount: responseMessage.Headers?.ItemCount, + itemCount: OpenTelemetryResponse.GetHeader(responseMessage)?.ItemCount, requestMessage: null, - subStatusCode: (int)responseMessage.Headers?.SubStatusCode, - activityId: responseMessage.Headers?.ActivityId, - correlationId: responseMessage.Headers?.CorrelatedActivityId) + subStatusCode: OpenTelemetryResponse.GetHeader(responseMessage)?.SubStatusCode, + activityId: OpenTelemetryResponse.GetHeader(responseMessage)?.ActivityId, + correlationId: OpenTelemetryResponse.GetHeader(responseMessage)?.CorrelatedActivityId) { } internal OpenTelemetryResponse(ResponseMessage responseMessage) : this( statusCode: responseMessage.StatusCode, - requestCharge: responseMessage.Headers?.RequestCharge, + requestCharge: OpenTelemetryResponse.GetHeader(responseMessage)?.RequestCharge, responseContentLength: OpenTelemetryResponse.GetPayloadSize(responseMessage), diagnostics: responseMessage.Diagnostics, - itemCount: responseMessage.Headers?.ItemCount, + itemCount: OpenTelemetryResponse.GetHeader(responseMessage)?.ItemCount, requestMessage: responseMessage.RequestMessage, - subStatusCode: (int)responseMessage.Headers?.SubStatusCode, - activityId: responseMessage.Headers?.ActivityId, - correlationId: responseMessage.Headers?.CorrelatedActivityId, + subStatusCode: OpenTelemetryResponse.GetHeader(responseMessage)?.SubStatusCode, + activityId: OpenTelemetryResponse.GetHeader(responseMessage)?.ActivityId, + correlationId: OpenTelemetryResponse.GetHeader(responseMessage)?.CorrelatedActivityId, operationType: responseMessage is QueryResponse ? Documents.OperationType.Query : Documents.OperationType.Invalid ) { @@ -47,7 +49,7 @@ private OpenTelemetryResponse( CosmosDiagnostics diagnostics, string itemCount, RequestMessage requestMessage, - int subStatusCode, + Documents.SubStatusCodes? subStatusCode, string activityId, string correlationId, Documents.OperationType operationType = Documents.OperationType.Invalid) @@ -58,7 +60,7 @@ private OpenTelemetryResponse( this.ResponseContentLength = responseContentLength; this.Diagnostics = diagnostics; this.ItemCount = itemCount; - this.SubStatusCode = subStatusCode; + this.SubStatusCode = (int)(subStatusCode ?? Documents.SubStatusCodes.Unknown); this.ActivityId = activityId; this.CorrelatedActivityId = correlationId; this.OperationType = operationType; @@ -74,5 +76,31 @@ private static string GetPayloadSize(ResponseMessage response) } return response?.Headers?.ContentLength; } + + private static Headers GetHeader(TransactionalBatchResponse responseMessage) + { + try + { + return responseMessage?.Headers; + } + catch (NotImplementedException ex) + { + DefaultTrace.TraceVerbose("Failed to get headers from TransactionalBatchResponse. Exception: {0}", ex); + return null; + } + } + + private static Headers GetHeader(ResponseMessage responseMessage) + { + try + { + return responseMessage?.Headers; + } + catch (NotImplementedException ex) + { + DefaultTrace.TraceVerbose("Failed to get headers from ResponseMessage. Exception: {0}", ex); + return null; + } + } } } diff --git a/Microsoft.Azure.Cosmos/src/Telemetry/OpenTelemetry/OpenTelemetryResponse{T}.cs b/Microsoft.Azure.Cosmos/src/Telemetry/OpenTelemetry/OpenTelemetryResponse{T}.cs index 4c96306a30..976b68173a 100644 --- a/Microsoft.Azure.Cosmos/src/Telemetry/OpenTelemetry/OpenTelemetryResponse{T}.cs +++ b/Microsoft.Azure.Cosmos/src/Telemetry/OpenTelemetry/OpenTelemetryResponse{T}.cs @@ -4,7 +4,9 @@ namespace Microsoft.Azure.Cosmos { + using System; using System.Net; + using Microsoft.Azure.Cosmos.Core.Trace; using Telemetry; internal sealed class OpenTelemetryResponse : OpenTelemetryAttributes @@ -12,14 +14,14 @@ internal sealed class OpenTelemetryResponse : OpenTelemetryAttributes internal OpenTelemetryResponse(FeedResponse responseMessage) : this( statusCode: responseMessage.StatusCode, - requestCharge: responseMessage.Headers?.RequestCharge, - responseContentLength: responseMessage?.Headers?.ContentLength, + requestCharge: OpenTelemetryResponse.GetHeader(responseMessage)?.RequestCharge, + responseContentLength: OpenTelemetryResponse.GetHeader(responseMessage)?.ContentLength, diagnostics: responseMessage.Diagnostics, - itemCount: responseMessage.Headers?.ItemCount, + itemCount: OpenTelemetryResponse.GetHeader(responseMessage)?.ItemCount, requestMessage: responseMessage.RequestMessage, - subStatusCode: (int)responseMessage.Headers?.SubStatusCode, - activityId: responseMessage.Headers?.ActivityId, - correlatedActivityId: responseMessage.Headers?.CorrelatedActivityId, + subStatusCode: OpenTelemetryResponse.GetHeader(responseMessage)?.SubStatusCode, + activityId: OpenTelemetryResponse.GetHeader(responseMessage)?.ActivityId, + correlatedActivityId: OpenTelemetryResponse.GetHeader(responseMessage)?.CorrelatedActivityId, operationType: responseMessage is QueryResponse ? Documents.OperationType.Query : Documents.OperationType.Invalid) { } @@ -27,14 +29,14 @@ internal OpenTelemetryResponse(FeedResponse responseMessage) internal OpenTelemetryResponse(Response responseMessage) : this( statusCode: responseMessage.StatusCode, - requestCharge: responseMessage.Headers?.RequestCharge, - responseContentLength: responseMessage?.Headers?.ContentLength, + requestCharge: OpenTelemetryResponse.GetHeader(responseMessage)?.RequestCharge, + responseContentLength: OpenTelemetryResponse.GetHeader(responseMessage)?.ContentLength, diagnostics: responseMessage.Diagnostics, - itemCount: responseMessage.Headers?.ItemCount, + itemCount: OpenTelemetryResponse.GetHeader(responseMessage)?.ItemCount, requestMessage: responseMessage.RequestMessage, - subStatusCode: (int)responseMessage.Headers?.SubStatusCode, - activityId: responseMessage.Headers?.ActivityId, - correlatedActivityId: responseMessage.Headers?.CorrelatedActivityId, + subStatusCode: OpenTelemetryResponse.GetHeader(responseMessage)?.SubStatusCode, + activityId: OpenTelemetryResponse.GetHeader(responseMessage)?.ActivityId, + correlatedActivityId: OpenTelemetryResponse.GetHeader(responseMessage)?.CorrelatedActivityId, operationType: responseMessage is QueryResponse ? Documents.OperationType.Query : Documents.OperationType.Invalid) { } @@ -46,7 +48,7 @@ private OpenTelemetryResponse( CosmosDiagnostics diagnostics, string itemCount, RequestMessage requestMessage, - int subStatusCode, + Documents.SubStatusCodes? subStatusCode, string activityId, string correlatedActivityId, Documents.OperationType operationType) @@ -57,10 +59,36 @@ private OpenTelemetryResponse( this.ResponseContentLength = responseContentLength; this.Diagnostics = diagnostics; this.ItemCount = itemCount; - this.SubStatusCode = subStatusCode; + this.SubStatusCode = (int)(subStatusCode ?? Documents.SubStatusCodes.Unknown); this.ActivityId = activityId; this.CorrelatedActivityId = correlatedActivityId; this.OperationType = operationType; } + + private static Headers GetHeader(FeedResponse responseMessage) + { + try + { + return responseMessage?.Headers; + } + catch (NotImplementedException ex) + { + DefaultTrace.TraceWarning("Failed to get headers from FeedResponse. Exception: {0}", ex); + return null; + } + } + + private static Headers GetHeader(Response responseMessage) + { + try + { + return responseMessage?.Headers; + } + catch (NotImplementedException ex) + { + DefaultTrace.TraceWarning("Failed to get headers from Response. Exception: {0}", ex); + return null; + } + } } } diff --git a/Microsoft.Azure.Cosmos/src/Telemetry/TelemetryToServiceHelper.cs b/Microsoft.Azure.Cosmos/src/Telemetry/TelemetryToServiceHelper.cs new file mode 100644 index 0000000000..2d0e79071f --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Telemetry/TelemetryToServiceHelper.cs @@ -0,0 +1,256 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Telemetry +{ + using System; + using System.Net.Http; + using System.Threading; + using System.Threading.Tasks; + using Microsoft.Azure.Cosmos.Core.Trace; + using Microsoft.Azure.Cosmos.Handler; + using Microsoft.Azure.Cosmos.Query.Core.Monads; + using Microsoft.Azure.Cosmos.Routing; + using Microsoft.Azure.Cosmos.Telemetry.Collector; + using Microsoft.Azure.Cosmos.Tracing; + using Microsoft.Azure.Documents; + using Microsoft.Azure.Documents.Collections; + + internal class TelemetryToServiceHelper : IDisposable + { + private ITelemetryCollector collector = new TelemetryCollectorNoOp(); + + internal static TimeSpan DefaultBackgroundRefreshClientConfigTimeInterval + = TimeSpan.FromMinutes(10); + + private readonly AuthorizationTokenProvider cosmosAuthorization; + private readonly CosmosHttpClient httpClient; + private readonly Uri serviceEnpoint; + private readonly ConnectionPolicy connectionPolicy; + private readonly string clientId; + private readonly GlobalEndpointManager globalEndpointManager; + private readonly CancellationTokenSource cancellationTokenSource; + + private ClientTelemetry clientTelemetry = null; + + private TelemetryToServiceHelper() + { + //NoOpConstructor + } + + private TelemetryToServiceHelper( + string clientId, + ConnectionPolicy connectionPolicy, + AuthorizationTokenProvider cosmosAuthorization, + CosmosHttpClient httpClient, + Uri serviceEndpoint, + GlobalEndpointManager globalEndpointManager, + CancellationTokenSource cancellationTokenSource) + { + this.clientId = clientId; + this.cosmosAuthorization = cosmosAuthorization; + this.httpClient = httpClient; + this.connectionPolicy = connectionPolicy; + this.serviceEnpoint = serviceEndpoint; + this.globalEndpointManager = globalEndpointManager; + this.cancellationTokenSource = cancellationTokenSource; + } + + public static TelemetryToServiceHelper CreateAndInitializeClientConfigAndTelemetryJob(string clientId, + ConnectionPolicy connectionPolicy, + AuthorizationTokenProvider cosmosAuthorization, + CosmosHttpClient httpClient, + Uri serviceEndpoint, + GlobalEndpointManager globalEndpointManager, + CancellationTokenSource cancellationTokenSource) + { +#if INTERNAL + return new TelemetryToServiceHelper(); +#else + if (connectionPolicy.CosmosClientTelemetryOptions.DisableSendingMetricsToService) + { + return new TelemetryToServiceHelper(); + } + + TelemetryToServiceHelper helper = new TelemetryToServiceHelper( + clientId: clientId, + connectionPolicy: connectionPolicy, + cosmosAuthorization: cosmosAuthorization, + httpClient: httpClient, + serviceEndpoint: serviceEndpoint, + globalEndpointManager: globalEndpointManager, + cancellationTokenSource: cancellationTokenSource); + + _ = helper.RetrieveConfigAndInitiateTelemetryAsync(); // Let it run in backgroud + + return helper; +#endif + } + + private async Task RetrieveConfigAndInitiateTelemetryAsync() + { + try + { + Uri serviceEndpointWithPath = new Uri(this.serviceEnpoint + Paths.ClientConfigPathSegment); + while (!this.cancellationTokenSource.IsCancellationRequested) + { + TryCatch databaseAccountClientConfigs = await this.GetDatabaseAccountClientConfigAsync( + cosmosAuthorization: this.cosmosAuthorization, + httpClient: this.httpClient, + clientConfigEndpoint: serviceEndpointWithPath); + + if (databaseAccountClientConfigs.Succeeded) + { + this.InitializeClientTelemetry( + clientConfig: databaseAccountClientConfigs.Result); + } + else if (databaseAccountClientConfigs.Exception is ObjectDisposedException) + { + DefaultTrace.TraceWarning("Client is being disposed for {0} at {1}", serviceEndpointWithPath, DateTime.UtcNow); + break; + } + else if (!this.cancellationTokenSource.IsCancellationRequested) + { + DefaultTrace.TraceWarning("Exception while calling client config {0} ", databaseAccountClientConfigs.Exception); + } + + await Task.Delay( + delay: TelemetryToServiceHelper.DefaultBackgroundRefreshClientConfigTimeInterval, + cancellationToken: this.cancellationTokenSource.Token); + } + } + catch (Exception ex) + { + DefaultTrace.TraceWarning("Exception while running client config job: {0}", ex); + } + } + + private async Task> GetDatabaseAccountClientConfigAsync(AuthorizationTokenProvider cosmosAuthorization, + CosmosHttpClient httpClient, + Uri clientConfigEndpoint) + { + INameValueCollection headers = new RequestNameValueCollection(); + await cosmosAuthorization.AddAuthorizationHeaderAsync( + headersCollection: headers, + clientConfigEndpoint, + HttpConstants.HttpMethods.Get, + AuthorizationTokenType.PrimaryMasterKey); + + using (ITrace trace = Trace.GetRootTrace("Account Client Config Read", TraceComponent.Transport, TraceLevel.Info)) + { + try + { + using (HttpResponseMessage responseMessage = await httpClient.GetAsync( + uri: clientConfigEndpoint, + additionalHeaders: headers, + resourceType: ResourceType.DatabaseAccount, + timeoutPolicy: HttpTimeoutPolicyControlPlaneRead.Instance, + clientSideRequestStatistics: null, + cancellationToken: default)) + { + // It means feature flag is off at gateway, then log the exception and retry after defined interval. + // If feature flag is OFF at gateway, SDK won't refresh the latest state of the flag. + if (responseMessage.StatusCode == System.Net.HttpStatusCode.BadRequest) + { + string responseFromGateway = await responseMessage.Content.ReadAsStringAsync(); + return TryCatch.FromException( + new InvalidOperationException($"Client Config API is not enabled at compute gateway. Response is {responseFromGateway}")); + } + + using (DocumentServiceResponse documentServiceResponse = await ClientExtensions.ParseResponseAsync(responseMessage)) + { + return TryCatch.FromResult( + CosmosResource.FromStream(documentServiceResponse)); + } + } + } + catch (Exception ex) + { + return TryCatch.FromException(ex); + } + } + } + + public ITelemetryCollector GetCollector() + { + return this.collector; + } + + public bool IsClientTelemetryJobRunning() + { + return this.clientTelemetry != null; + } + + /// + /// Trigger Client Telemetry job when it is enabled and not already running. + /// + private void InitializeClientTelemetry(AccountClientConfiguration clientConfig) + { + // If state of the job is same as state of the flag, then no need to do anything. + if (clientConfig.IsClientTelemetryEnabled() == this.IsClientTelemetryJobRunning()) + { + return; + } + + DiagnosticsHandlerHelper.Refresh(clientConfig.IsClientTelemetryEnabled()); + + if (clientConfig.IsClientTelemetryEnabled()) + { + try + { + this.clientTelemetry = ClientTelemetry.CreateAndStartBackgroundTelemetry( + clientId: this.clientId, + httpClient: this.httpClient, + userAgent: this.connectionPolicy.UserAgentContainer.BaseUserAgent, + connectionMode: this.connectionPolicy.ConnectionMode, + authorizationTokenProvider: this.cosmosAuthorization, + diagnosticsHelper: DiagnosticsHandlerHelper.GetInstance(), + preferredRegions: this.connectionPolicy.PreferredLocations, + globalEndpointManager: this.globalEndpointManager, + endpointUrl: clientConfig.ClientTelemetryConfiguration.Endpoint); + + this.collector = new TelemetryCollector(this.clientTelemetry, this.connectionPolicy); + + DefaultTrace.TraceVerbose("Client Telemetry Enabled."); + } + catch (Exception ex) + { + DefaultTrace.TraceWarning($"Error While starting Telemetry Job : {0}. Hence disabling Client Telemetry", ex); + this.connectionPolicy.CosmosClientTelemetryOptions.DisableSendingMetricsToService = true; + } + } + else + { + this.StopClientTelemetry(); + DefaultTrace.TraceVerbose("Client Telemetry Disabled."); + } + } + + public void Dispose() + { + this.StopClientTelemetry(); + } + + /// + /// Stopping a client telemetry job means now there shouldn't be any valid collector available, Hence switch it to NoOp collector. + /// Along with it, send a signal to stop client telemetry job. + /// + private void StopClientTelemetry() + { + try + { + this.collector = new TelemetryCollectorNoOp(); + + this.clientTelemetry?.Dispose(); + this.clientTelemetry = null; + + DiagnosticsHandlerHelper.Refresh(isClientTelemetryEnabled: false); + } + catch (Exception ex) + { + DefaultTrace.TraceWarning($"Error While stopping Telemetry Job : {0}", ex); + } + } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Telemetry/VmMetadataApiHandler.cs b/Microsoft.Azure.Cosmos/src/Telemetry/VmMetadataApiHandler.cs index ed5ad111d7..b9d9c60d36 100644 --- a/Microsoft.Azure.Cosmos/src/Telemetry/VmMetadataApiHandler.cs +++ b/Microsoft.Azure.Cosmos/src/Telemetry/VmMetadataApiHandler.cs @@ -85,11 +85,11 @@ static ValueTask CreateRequestMessage() azMetadata = await VmMetadataApiHandler.ProcessResponseAsync(response); - DefaultTrace.TraceInformation($"Succesfully get Instance Metadata Response : {azMetadata.Compute.VMId}"); + DefaultTrace.TraceInformation($"Succesfully get Instance Metadata Response : {0}", azMetadata.Compute.VMId); } catch (Exception e) { - DefaultTrace.TraceInformation($"Azure Environment metadata information not available. {e.Message}"); + DefaultTrace.TraceInformation($"Azure Environment metadata information not available. {0}", e.Message); } } @@ -154,7 +154,7 @@ internal static string GetCloudInformation() } catch (Exception ex) { - DefaultTrace.TraceWarning("Error while generating hashed machine name " + ex.Message); + DefaultTrace.TraceWarning($"Error while generating hashed machine name {0}", ex.Message); } return $"{VmMetadataApiHandler.UuidPrefix}{Guid.NewGuid()}"; diff --git a/Microsoft.Azure.Cosmos/src/Tracing/TraceData/ClientSideRequestStatisticsTraceDatum.cs b/Microsoft.Azure.Cosmos/src/Tracing/TraceData/ClientSideRequestStatisticsTraceDatum.cs index def12c8262..829899c4b1 100644 --- a/Microsoft.Azure.Cosmos/src/Tracing/TraceData/ClientSideRequestStatisticsTraceDatum.cs +++ b/Microsoft.Azure.Cosmos/src/Tracing/TraceData/ClientSideRequestStatisticsTraceDatum.cs @@ -419,7 +419,7 @@ public void UpdateSystemUsage() this.systemUsageHistory.Values.Count == 0 || this.systemUsageHistory.LastTimestamp + DiagnosticsHandlerHelper.DiagnosticsRefreshInterval < DateTime.UtcNow) { - this.systemUsageHistory = DiagnosticsHandlerHelper.Instance.GetDiagnosticsSystemHistory(); + this.systemUsageHistory = DiagnosticsHandlerHelper.GetInstance().GetDiagnosticsSystemHistory(); } #endif } diff --git a/Microsoft.Azure.Cosmos/src/Util/ConfigurationManager.cs b/Microsoft.Azure.Cosmos/src/Util/ConfigurationManager.cs index 216e1295b5..748f81833a 100644 --- a/Microsoft.Azure.Cosmos/src/Util/ConfigurationManager.cs +++ b/Microsoft.Azure.Cosmos/src/Util/ConfigurationManager.cs @@ -38,9 +38,7 @@ public static bool IsReplicaAddressValidationEnabled( ConnectionPolicy connectionPolicy) { bool replicaValidationDefaultValue = false; -#if PREVIEW - replicaValidationDefaultValue = true; -#endif + if (connectionPolicy != null && connectionPolicy.EnableAdvancedReplicaSelectionForTcp.HasValue) { diff --git a/Microsoft.Azure.Cosmos/src/direct/AddressEnumerator.cs b/Microsoft.Azure.Cosmos/src/direct/AddressEnumerator.cs index 132b000d10..96fa1671eb 100644 --- a/Microsoft.Azure.Cosmos/src/direct/AddressEnumerator.cs +++ b/Microsoft.Azure.Cosmos/src/direct/AddressEnumerator.cs @@ -243,22 +243,18 @@ private static IEnumerable ReorderAddressesWhenReplicaValid IEnumerable addresses, HashSet failedReplicasPerRequest) { - List unknownReplicas = null, failedReplicas = null, pendingReplicas = null; + List failedReplicas = null, pendingReplicas = null; foreach (TransportAddressUri transportAddressUri in addresses) { TransportAddressHealthState.HealthStatus status = AddressEnumerator.GetEffectiveStatus( addressUri: transportAddressUri, failedEndpoints: failedReplicasPerRequest); - if (status == TransportAddressHealthState.HealthStatus.Connected) + if (status == TransportAddressHealthState.HealthStatus.Connected + || status == TransportAddressHealthState.HealthStatus.Unknown) { yield return transportAddressUri; } - else if (status == TransportAddressHealthState.HealthStatus.Unknown) - { - unknownReplicas ??= new (); - unknownReplicas.Add(transportAddressUri); - } else if (status == TransportAddressHealthState.HealthStatus.UnhealthyPending) { pendingReplicas ??= new (); @@ -271,14 +267,6 @@ private static IEnumerable ReorderAddressesWhenReplicaValid } } - if (unknownReplicas != null) - { - foreach (TransportAddressUri transportAddressUri in unknownReplicas) - { - yield return transportAddressUri; - } - } - if (pendingReplicas != null) { foreach (TransportAddressUri transportAddressUri in pendingReplicas) diff --git a/Microsoft.Azure.Cosmos/src/direct/Channel.cs b/Microsoft.Azure.Cosmos/src/direct/Channel.cs index e4679e4ec7..689d5eba27 100644 --- a/Microsoft.Azure.Cosmos/src/direct/Channel.cs +++ b/Microsoft.Azure.Cosmos/src/direct/Channel.cs @@ -5,10 +5,10 @@ namespace Microsoft.Azure.Documents.Rntbd { using System; using System.Diagnostics; - using System.Net.NetworkInformation; using System.Threading; using System.Threading.Tasks; using Microsoft.Azure.Cosmos.Core.Trace; + using Microsoft.Azure.Documents.FaultInjection; #if NETSTANDARD15 || NETSTANDARD16 using Trace = Microsoft.Azure.Documents.Trace; @@ -32,8 +32,15 @@ internal sealed class Channel : IChannel, IDisposable private ChannelOpenArguments openArguments; private readonly SemaphoreSlim openingSlim; - - public Channel(Guid activityId, Uri serverUri, ChannelProperties channelProperties, bool localRegionRequest, SemaphoreSlim openingSlim) + private readonly IChaosInterceptor chaosInterceptor; + + public Channel( + Guid activityId, + Uri serverUri, + ChannelProperties channelProperties, + bool localRegionRequest, SemaphoreSlim openingSlim, + IChaosInterceptor chaosInterceptor = null, + Action onChannelOpen = null) { Debug.Assert(channelProperties != null); this.dispatcher = new Dispatcher(serverUri, @@ -47,11 +54,13 @@ public Channel(Guid activityId, Uri serverUri, ChannelProperties channelProperti channelProperties.EnableChannelMultiplexing, channelProperties.MemoryStreamPool, channelProperties.RemoteCertificateValidationCallback, - channelProperties.DnsResolutionFunction); + channelProperties.DnsResolutionFunction, + chaosInterceptor); this.timerPool = channelProperties.RequestTimerPool; this.requestTimeoutSeconds = (int) channelProperties.RequestTimeout.TotalSeconds; this.serverUri = serverUri; this.localRegionRequest = localRegionRequest; + this.chaosInterceptor = chaosInterceptor; TimeSpan openTimeout = localRegionRequest ? channelProperties.LocalRegionOpenTimeout : channelProperties.OpenTimeout; @@ -63,7 +72,21 @@ public Channel(Guid activityId, Uri serverUri, ChannelProperties channelProperti channelProperties.CallerId); this.openingSlim = openingSlim; - this.Initialize(); + this.Initialize(activityId, onChannelOpen); + } + + public void InjectFaultInjectionConnectionError(TransportException transportException) + { + if (!this.disposed) + { + this.dispatcher.InjectFaultInjectionConnectionError(transportException); + } + } + + public Uri GetServerUri() + { + this.ThrowIfDisposed(); + return this.serverUri; } [DebuggerBrowsable(DebuggerBrowsableState.Never)] @@ -111,7 +134,7 @@ public bool Healthy private Guid ConnectionCorrelationId { get => this.dispatcher.ConnectionCorrelationId; } - private void Initialize() + private void Initialize(Guid activityId, Action onChannelOpen = null) { this.ThrowIfDisposed(); this.stateLock.EnterWriteLock(); @@ -133,7 +156,7 @@ private void Initialize() Debug.Assert(this.openArguments != null); Debug.Assert(this.openArguments.CommonArguments != null); Trace.CorrelationManager.ActivityId = this.openArguments.CommonArguments.ActivityId; - await this.InitializeAsync(); + await this.InitializeAsync(activityId, onChannelOpen); this.isInitializationComplete = true; this.TestOnInitializeComplete?.Invoke(); }); @@ -171,7 +194,9 @@ public async Task RequestAsync( // be chattier: // - Serialization errors are handled differently from channel errors. // - Timeouts only apply to the call (send+recv), not to everything preceding it. - using ChannelCallArguments callArguments = new ChannelCallArguments(activityId); + using ChannelCallArguments callArguments = this.chaosInterceptor == null + ? new ChannelCallArguments(activityId) + : new ChannelCallArguments(activityId, request.OperationType, request.ResourceType, request.RequestContext.ResolvedCollectionRid, request.Headers); try { callArguments.PreparedCall = this.dispatcher.PrepareCall( @@ -262,6 +287,7 @@ public void Close() void IDisposable.Dispose() { + this.chaosInterceptor?.OnChannelDispose(this.ConnectionCorrelationId); this.ThrowIfDisposed(); this.disposed = true; DefaultTrace.TraceInformation("[RNTBD Channel {0}] Disposing RNTBD Channel {1}", this.ConnectionCorrelationId, this); @@ -336,11 +362,13 @@ private void ThrowIfDisposed() } } - private async Task InitializeAsync() + private async Task InitializeAsync(Guid activityId, Action onChannelOpen = null) { bool slimAcquired = false; try { + onChannelOpen?.Invoke(activityId, this.serverUri, this); + this.openArguments.CommonArguments.SetTimeoutCode(TransportErrorCode.ChannelWaitingToOpenTimeout); slimAcquired = await this.openingSlim.WaitAsync(this.openArguments.OpenTimeout).ConfigureAwait(false); if (!slimAcquired) diff --git a/Microsoft.Azure.Cosmos/src/direct/ChannelCallArguments.cs b/Microsoft.Azure.Cosmos/src/direct/ChannelCallArguments.cs index 2f48db6cf9..435dca3f6a 100644 --- a/Microsoft.Azure.Cosmos/src/direct/ChannelCallArguments.cs +++ b/Microsoft.Azure.Cosmos/src/direct/ChannelCallArguments.cs @@ -4,10 +4,16 @@ namespace Microsoft.Azure.Documents.Rntbd { using System; + using Microsoft.Azure.Documents.Collections; + using Microsoft.Azure.Documents.FaultInjection; internal sealed class ChannelCallArguments : IDisposable { private readonly ChannelCommonArguments commonArguments; + private readonly OperationType operationType; + private readonly ResourceType resourceType; + private readonly string resolvedCollectionRid; + private readonly INameValueCollection requestHeaders; public ChannelCallArguments (Guid activityId) { @@ -16,10 +22,34 @@ public ChannelCallArguments (Guid activityId) userPayload: true); } + public ChannelCallArguments( + Guid activityId, + OperationType operationType, + ResourceType resourceType, + string resolvedCollectionRid, + INameValueCollection requestHeaders) + { + this.commonArguments = new ChannelCommonArguments( + activityId, TransportErrorCode.RequestTimeout, + userPayload: true); + this.operationType = operationType; + this.resourceType = resourceType; + this.resolvedCollectionRid = resolvedCollectionRid; + this.requestHeaders = requestHeaders; + } + public ChannelCommonArguments CommonArguments { get { return this.commonArguments; } } public Dispatcher.PrepareCallResult PreparedCall { get; set; } + public OperationType OperationType { get { return this.operationType; } } + + public ResourceType ResourceType { get { return this.resourceType; } } + + public string ResolvedCollectionRid { get { return this.resolvedCollectionRid; } } + + public INameValueCollection RequestHeaders { get { return this.requestHeaders; } } + /// public void Dispose() { diff --git a/Microsoft.Azure.Cosmos/src/direct/ChannelDictionary.cs b/Microsoft.Azure.Cosmos/src/direct/ChannelDictionary.cs index f41c11a788..7d8b8280b9 100644 --- a/Microsoft.Azure.Cosmos/src/direct/ChannelDictionary.cs +++ b/Microsoft.Azure.Cosmos/src/direct/ChannelDictionary.cs @@ -6,11 +6,11 @@ namespace Microsoft.Azure.Documents.Rntbd using System; using System.Collections.Concurrent; using System.Diagnostics; - using System.Threading.Tasks; + using Microsoft.Azure.Documents.FaultInjection; // ChannelDictionary maps server keys to load-balanced channels. There is // one load-balanced channel per back-end server. - internal sealed class ChannelDictionary : IDisposable + internal sealed class ChannelDictionary : IChannelDictionary, IDisposable { private readonly ChannelProperties channelProperties; private bool disposed = false; @@ -18,13 +18,24 @@ internal sealed class ChannelDictionary : IDisposable private ConcurrentDictionary channels = new ConcurrentDictionary(); - public ChannelDictionary(ChannelProperties channelProperties) + private readonly IChaosInterceptor chaosInterceptor; + + public ChannelDictionary(ChannelProperties channelProperties, IChaosInterceptor chaosInterceptor = null) { Debug.Assert(channelProperties != null); this.channelProperties = channelProperties; + this.chaosInterceptor = chaosInterceptor; } - public IChannel GetChannel(Uri requestUri, bool localRegionRequest) + /// + /// Creates or gets an instance of using the server's physical uri. + /// + /// An instance of containing the backend server URI. + /// A boolean flag indicating if the request is targeting the local region. + /// An instance of containing the . + public IChannel GetChannel( + Uri requestUri, + bool localRegionRequest) { this.ThrowIfDisposed(); ServerKey key = new ServerKey(requestUri); @@ -37,7 +48,9 @@ public IChannel GetChannel(Uri requestUri, bool localRegionRequest) value = new LoadBalancingChannel( new Uri(requestUri.GetLeftPart(UriPartial.Authority)), this.channelProperties, - localRegionRequest); + localRegionRequest, + this.chaosInterceptor); + if (this.channels.TryAdd(key, value)) { return value; @@ -48,24 +61,11 @@ public IChannel GetChannel(Uri requestUri, bool localRegionRequest) return value; } - /// - /// Opens the Rntbd context negotiation channel to the backend replica node, using the server's physical uri. - /// - /// An instance of containing the backend server URI. - /// A boolean flag indicating if the request is targeting the local region. - /// An unique identifier indicating the current activity id. - /// An instance of indicating the channel has opened successfully. - public Task OpenChannelAsync( - Uri physicalAddress, - bool localRegionRequest, - Guid activityId) + public bool TryGetChannel(Uri requestUri, out IChannel channel) { this.ThrowIfDisposed(); - IChannel channel = this.GetChannel( - physicalAddress, - localRegionRequest); - - return channel.OpenChannelAsync(activityId); + ServerKey key = new ServerKey(requestUri); + return this.channels.TryGetValue(key, out channel); } public void Dispose() diff --git a/Microsoft.Azure.Cosmos/src/direct/ClientSideRequestStatistics.cs b/Microsoft.Azure.Cosmos/src/direct/ClientSideRequestStatistics.cs index 589dd91d2d..71ec5a0a55 100644 --- a/Microsoft.Azure.Cosmos/src/direct/ClientSideRequestStatistics.cs +++ b/Microsoft.Azure.Cosmos/src/direct/ClientSideRequestStatistics.cs @@ -533,5 +533,4 @@ public void AppendToBuilder(StringBuilder stringBuilder) } } } -} - +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/direct/CustomTypeExtensions.cs b/Microsoft.Azure.Cosmos/src/direct/CustomTypeExtensions.cs index 40be3a5cc5..45b43e8ad6 100644 --- a/Microsoft.Azure.Cosmos/src/direct/CustomTypeExtensions.cs +++ b/Microsoft.Azure.Cosmos/src/direct/CustomTypeExtensions.cs @@ -35,7 +35,7 @@ internal static class CustomTypeExtensions #if COSMOSCLIENT public const string SDKName = "cosmos-netstandard-sdk"; - public const string SDKVersion = "3.31.3"; + public const string SDKVersion = "3.31.5"; #else public const string SDKName = "documentdb-netcore-sdk"; public const string SDKVersion = "2.14.0"; diff --git a/Microsoft.Azure.Cosmos/src/direct/Dispatcher.cs b/Microsoft.Azure.Cosmos/src/direct/Dispatcher.cs index 425e7b4025..6824830d73 100644 --- a/Microsoft.Azure.Cosmos/src/direct/Dispatcher.cs +++ b/Microsoft.Azure.Cosmos/src/direct/Dispatcher.cs @@ -13,6 +13,7 @@ namespace Microsoft.Azure.Documents.Rntbd using System.Threading; using System.Threading.Tasks; using Microsoft.Azure.Cosmos.Core.Trace; + using Microsoft.Azure.Documents.FaultInjection; #if COSMOSCLIENT using Microsoft.Azure.Cosmos.Rntbd; #endif @@ -64,6 +65,10 @@ internal sealed class Dispatcher : IDisposable private PooledTimer idleTimer; // Guarded by connectionLock private Task idleTimerTask; // Guarded by connectionLock + private readonly IChaosInterceptor chaosInterceptor; + private TransportException faultInjectionTransportException; + private bool isFaultInjectionedConnectionError; + public Guid ConnectionCorrelationId { get => this.connection.ConnectionCorrelationId; } public Dispatcher( @@ -78,7 +83,8 @@ public Dispatcher( bool enableChannelMultiplexing, MemoryStreamPool memoryStreamPool, RemoteCertificateValidationCallback remoteCertificateValidationCallback, - Func> dnsResolutionFunction) + Func> dnsResolutionFunction, + IChaosInterceptor chaosInterceptor) { this.connection = new Connection( serverUri, hostNameCertificateOverride, @@ -92,6 +98,7 @@ public Dispatcher( this.serverUri = serverUri; this.idleTimerPool = idleTimerPool; this.enableChannelMultiplexing = enableChannelMultiplexing; + this.chaosInterceptor = chaosInterceptor; } #region Test hook. @@ -228,6 +235,15 @@ async delegate } } + public void InjectFaultInjectionConnectionError(TransportException transportException) + { + if (!this.disposed) + { + this.isFaultInjectionedConnectionError = true; + this.faultInjectionTransportException = transportException; + } + } + public sealed class PrepareCallResult : IDisposable { private bool disposed = false; @@ -317,11 +333,19 @@ public async Task CallAsync(ChannelCallArguments args, TransportR { try { + this.chaosInterceptor?.OnBeforeConnectionWrite(args); + if (this.chaosInterceptor != null && this.chaosInterceptor.OnRequestCall(args, out StoreResponse faultyResponse)) + { + return faultyResponse; + } + await this.connection.WriteRequestAsync( args.CommonArguments, args.PreparedCall.SerializedRequest, transportRequestStats); transportRequestStats.RecordState(TransportRequestStats.RequestStage.Sent); + this.chaosInterceptor?.OnAfterConnectionWrite(args); + } catch (Exception e) { @@ -725,6 +749,12 @@ private async Task ReceiveLoopAsync() bool hasTransportErrors = false; while (!hasTransportErrors && !cancellationToken.IsCancellationRequested) { + if (this.isFaultInjectionedConnectionError) + { + hasTransportErrors = true; + throw this.faultInjectionTransportException; + } + args.ActivityId = Guid.Empty; responseMd = await this.connection.ReadResponseMetadataAsync(args); ArraySegment metadata = responseMd.Metadata; diff --git a/Microsoft.Azure.Cosmos/src/direct/DocumentCollection.cs b/Microsoft.Azure.Cosmos/src/direct/DocumentCollection.cs index d22ad23d1f..f3a84a8600 100644 --- a/Microsoft.Azure.Cosmos/src/direct/DocumentCollection.cs +++ b/Microsoft.Azure.Cosmos/src/direct/DocumentCollection.cs @@ -285,10 +285,12 @@ internal byte UniqueIndexNameEncodingMode } set { +#pragma warning disable CS0472 // The result of the expression is always the same since a value of this type is never equal to 'null' if(value == null) { throw new ArgumentNullException(string.Format(CultureInfo.CurrentCulture, RMResources.PropertyCannotBeNull, "UniqueIndexNameEncodingMode")); } +#pragma warning restore CS0472 // The result of the expression is always the same since a value of this type is never equal to 'null' this.uniqueIndexNameEncodingMode = value; this.SetValue(Constants.Properties.UniqueIndexNameEncodingMode, value); } diff --git a/Microsoft.Azure.Cosmos/src/direct/DocumentServiceRequestContext.cs b/Microsoft.Azure.Cosmos/src/direct/DocumentServiceRequestContext.cs index 28529bd3c8..283fdd3742 100644 --- a/Microsoft.Azure.Cosmos/src/direct/DocumentServiceRequestContext.cs +++ b/Microsoft.Azure.Cosmos/src/direct/DocumentServiceRequestContext.cs @@ -106,6 +106,11 @@ public IClientSideRequestStatistics ClientRequestStatistics /// public bool IsRetry { get; set; } + /// + /// A list of regions to exclude routing to, used for per-request level routing exclusion + /// + public List ExcludeRegions { get; set; } + /// /// Set of all failed enpoints for a DSR. Used for prioritizing replica selection /// @@ -231,6 +236,7 @@ public DocumentServiceRequestContext Clone() requestContext.LocalRegionRequest = this.LocalRegionRequest; requestContext.FailedEndpoints = this.FailedEndpoints; requestContext.LastPartitionAddressInformationHashCode = this.LastPartitionAddressInformationHashCode; + requestContext.ExcludeRegions = this.ExcludeRegions; return requestContext; } diff --git a/Microsoft.Azure.Cosmos/src/direct/FaultInjection/IChaosInterceptor.cs b/Microsoft.Azure.Cosmos/src/direct/FaultInjection/IChaosInterceptor.cs new file mode 100644 index 0000000000..7e20f26105 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/direct/FaultInjection/IChaosInterceptor.cs @@ -0,0 +1,56 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ +namespace Microsoft.Azure.Documents.FaultInjection +{ + using Microsoft.Azure.Documents.Rntbd; + using System; + + /// + /// Interface for Chaos Interceptor + /// + internal interface IChaosInterceptor + { + /// + /// Used to inject faults on request call + /// + /// + /// + /// + public bool OnRequestCall(ChannelCallArguments args, out StoreResponse faultyResponse); + + /// + /// Used to inject faults on channel open + /// + /// + /// + /// + /// + public void OnChannelOpen(Guid activityId, Uri serverUri, DocumentServiceRequest openingRequest, Channel channel); + + /// + /// Used to update internal active channel store on channel close + /// + /// + public void OnChannelDispose(Guid connectionCorrelationId); + + /// + /// Used to inject faults before connection writes + /// + /// + public void OnBeforeConnectionWrite(ChannelCallArguments args); + + /// + /// Used to inject faults after connection writes + /// + /// + public void OnAfterConnectionWrite(ChannelCallArguments args); + + /// + /// Gets the fault injection rule id for the given activity id + /// + /// + /// the fault injection rule id + public string GetFaultInjectionRuleId(Guid activityId); + } +} diff --git a/Microsoft.Azure.Cosmos/src/direct/GoneAndRetryWithRetryPolicy.cs b/Microsoft.Azure.Cosmos/src/direct/GoneAndRetryWithRetryPolicy.cs index f85a722255..d7d4d971aa 100644 --- a/Microsoft.Azure.Cosmos/src/direct/GoneAndRetryWithRetryPolicy.cs +++ b/Microsoft.Azure.Cosmos/src/direct/GoneAndRetryWithRetryPolicy.cs @@ -189,8 +189,6 @@ exception is PartitionKeyRangeGoneException || { DefaultTrace.TraceError("{0}. Will fail the request. {1}", message, exception.ToStringWithData()); SubStatusCodes exceptionSubStatus = DocumentClientException.GetExceptionSubStatusForGoneRetryPolicy(exception); - - if (this.detectConnectivityIssues && this.request.RequestContext.ClientRequestStatistics != null && this.request.RequestContext.ClientRequestStatistics.IsCpuHigh.GetValueOrDefault(false)) @@ -219,7 +217,6 @@ exception is PartitionKeyRangeGoneException || this.request.RequestContext.ClientRequestStatistics != null && this.request.RequestContext.ClientRequestStatistics.FailedReplicas.Count >= GoneAndRetryWithRetryPolicy.minFailedReplicaCountToConsiderConnectivityIssue) { - exceptionToThrow = new ServiceUnavailableException( string.Format( RMResources.ClientUnavailable, diff --git a/Microsoft.Azure.Cosmos/src/direct/IChannelDictionary.cs b/Microsoft.Azure.Cosmos/src/direct/IChannelDictionary.cs new file mode 100644 index 0000000000..f4c29f79c1 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/direct/IChannelDictionary.cs @@ -0,0 +1,20 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ +namespace Microsoft.Azure.Documents.Rntbd +{ + using System; + + internal interface IChannelDictionary + { + /// + /// Creates or gets an instance of using the server's physical uri. + /// + /// An instance of containing the backend server URI. + /// A boolean flag indicating if the request is targeting the local region. + /// An instance of containing the . + IChannel GetChannel( + Uri requestUri, + bool localRegionRequest); + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/direct/IClientSideRequestStatistics.cs b/Microsoft.Azure.Cosmos/src/direct/IClientSideRequestStatistics.cs index 7359b0e856..ca302839c0 100644 --- a/Microsoft.Azure.Cosmos/src/direct/IClientSideRequestStatistics.cs +++ b/Microsoft.Azure.Cosmos/src/direct/IClientSideRequestStatistics.cs @@ -12,9 +12,9 @@ internal interface IClientSideRequestStatistics { List ContactedReplicas { get; set; } - HashSet FailedReplicas { get;} + HashSet FailedReplicas { get; } - HashSet<(string, Uri)> RegionsContacted { get;} + HashSet<(string, Uri)> RegionsContacted { get; } bool? IsCpuHigh { get; } @@ -53,5 +53,4 @@ void RecordHttpException(HttpRequestMessage request, ResourceType resourceType, DateTime requestStartTimeUtc); } -} - +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/direct/LinuxSystemUtilizationReader.cs b/Microsoft.Azure.Cosmos/src/direct/LinuxSystemUtilizationReader.cs index 20103cc8e3..3ba0499ba5 100644 --- a/Microsoft.Azure.Cosmos/src/direct/LinuxSystemUtilizationReader.cs +++ b/Microsoft.Azure.Cosmos/src/direct/LinuxSystemUtilizationReader.cs @@ -237,8 +237,6 @@ public ProcMemInfoFileParser() : this(DefaultProcMemInfoFilePath) /// /// Allows customization of the proc stat file path to allow testing this on Non-Linux machines /// - /// - /// internal ProcMemInfoFileParser(string procMemInfoFilePath) { if (String.IsNullOrWhiteSpace(procMemInfoFilePath)) diff --git a/Microsoft.Azure.Cosmos/src/direct/LoadBalancingChannel.cs b/Microsoft.Azure.Cosmos/src/direct/LoadBalancingChannel.cs index 08279df7c8..d9556435fa 100644 --- a/Microsoft.Azure.Cosmos/src/direct/LoadBalancingChannel.cs +++ b/Microsoft.Azure.Cosmos/src/direct/LoadBalancingChannel.cs @@ -6,6 +6,7 @@ namespace Microsoft.Azure.Documents.Rntbd using System; using System.Diagnostics; using System.Threading.Tasks; + using Microsoft.Azure.Documents.FaultInjection; // LoadBalancingChannel encapsulates the management of channels that connect to a single // back-end server. It assigns load to each channel, decides when to open more @@ -22,7 +23,11 @@ internal sealed class LoadBalancingChannel : IChannel, IDisposable private bool disposed = false; - public LoadBalancingChannel(Uri serverUri, ChannelProperties channelProperties, bool localRegionRequest) + public LoadBalancingChannel( + Uri serverUri, + ChannelProperties channelProperties, + bool localRegionRequest, + IChaosInterceptor chaosInterceptor = null) { this.serverUri = serverUri; @@ -66,14 +71,20 @@ public LoadBalancingChannel(Uri serverUri, ChannelProperties channelProperties, for (int i = 0; i < this.partitions.Length; i++) { this.partitions[i] = new LoadBalancingPartition( - serverUri, partitionProperties, localRegionRequest); + serverUri, + partitionProperties, + localRegionRequest, + chaosInterceptor: chaosInterceptor); } } else { Debug.Assert(channelProperties.PartitionCount == 1); this.singlePartition = new LoadBalancingPartition( - serverUri, channelProperties, localRegionRequest); + serverUri, + channelProperties, + localRegionRequest, + chaosInterceptor: chaosInterceptor); } } diff --git a/Microsoft.Azure.Cosmos/src/direct/LoadBalancingPartition.cs b/Microsoft.Azure.Cosmos/src/direct/LoadBalancingPartition.cs index 0bd4cf67ca..cf4d749424 100644 --- a/Microsoft.Azure.Cosmos/src/direct/LoadBalancingPartition.cs +++ b/Microsoft.Azure.Cosmos/src/direct/LoadBalancingPartition.cs @@ -9,6 +9,7 @@ namespace Microsoft.Azure.Documents.Rntbd using System.Threading; using System.Threading.Tasks; using Microsoft.Azure.Cosmos.Core.Trace; + using Microsoft.Azure.Documents.FaultInjection; internal sealed class LoadBalancingPartition : IDisposable { @@ -31,15 +32,18 @@ internal sealed class LoadBalancingPartition : IDisposable private readonly SemaphoreSlim concurrentOpeningChannelSlim; + private readonly IChaosInterceptor chaosInterceptor; + // This channel factory delegate is meant for unit testing only and a default implementation is provided. // However it can be extended to support the main line code path if needed. - private readonly Func channelFactory; + private readonly Func, IChannel> channelFactory; public LoadBalancingPartition( Uri serverUri, ChannelProperties channelProperties, bool localRegionRequest, - Func channelFactory = null) + Func, IChannel> channelFactory = null, + IChaosInterceptor chaosInterceptor = null) { Debug.Assert(serverUri != null); this.serverUri = serverUri; @@ -56,6 +60,8 @@ public LoadBalancingPartition( this.channelFactory = channelFactory != null ? channelFactory : CreateAndInitializeChannel; + + this.chaosInterceptor = chaosInterceptor; } public async Task RequestAsync( @@ -181,11 +187,15 @@ public async Task RequestAsync( { channelsCreated = targetChannels - this.openChannels.Count; } + + Action onChannelOpen = + (Guid createId, Uri serverUri, Channel createdChannel) => this.chaosInterceptor?.OnChannelOpen(createId, serverUri, request, createdChannel); + while (this.openChannels.Count < targetChannels) - { - await this.OpenChannelAndIncrementCapacity( + { + this.OpenChannelAndIncrementCapacity( activityId: activityId, - waitForBackgroundInitializationComplete: false); + onChannelOpen: onChannelOpen); } Debug.Assert( this.capacity == @@ -219,15 +229,30 @@ await this.OpenChannelAndIncrementCapacity( /// An unique identifier indicating the current activity id. internal Task OpenChannelAsync(Guid activityId) { - this.capacityLock.EnterWriteLock(); + IChannel channel = null; + this.capacityLock.EnterUpgradeableReadLock(); try { if (this.capacity < this.maxCapacity) { - return this.OpenChannelAndIncrementCapacity( - activityId: activityId, - waitForBackgroundInitializationComplete: true); + foreach (LbChannelState channelState in this.openChannels) + { + if (channelState.DeepHealthy) + { + return Task.FromResult(0); + } + } + this.capacityLock.EnterWriteLock(); + try + { + channel = this.OpenChannelAndIncrementCapacity( + activityId: activityId); + } + finally + { + this.capacityLock.ExitWriteLock(); + } } else { @@ -243,8 +268,16 @@ internal Task OpenChannelAsync(Guid activityId) } finally { - this.capacityLock.ExitWriteLock(); + this.capacityLock.ExitUpgradeableReadLock(); + } + + if (channel == null) + { + throw new InvalidOperationException( + message: $"Could not open a channel to server {this.serverUri} because a channel instance didn't get created."); } + + return channel.OpenChannelAsync(activityId); } public void Dispose() @@ -280,11 +313,11 @@ public void Dispose() /// and increment the currrent channel capacity. /// /// An unique identifier indicating the current activity id. - /// A boolean flag to indicate if the caller thread should - /// wait until all the background tasks have finished. - private async Task OpenChannelAndIncrementCapacity( + /// An action to be invoked when the channel is opened. + /// An instance of . + private IChannel OpenChannelAndIncrementCapacity( Guid activityId, - bool waitForBackgroundInitializationComplete) + Action onChannelOpen = null) { Debug.Assert(this.capacityLock.IsWriteLockHeld); @@ -293,7 +326,9 @@ private async Task OpenChannelAndIncrementCapacity( this.serverUri, this.channelProperties, this.localRegionRequest, - this.concurrentOpeningChannelSlim); + this.concurrentOpeningChannelSlim, + this.chaosInterceptor, + onChannelOpen); if (newChannel == null) { @@ -302,16 +337,13 @@ private async Task OpenChannelAndIncrementCapacity( message: "Channel can't be null."); } - if (waitForBackgroundInitializationComplete) - { - await newChannel.OpenChannelAsync(activityId); - } - this.openChannels.Add( new LbChannelState( newChannel, this.channelProperties.MaxRequestsPerChannel)); this.capacity += this.channelProperties.MaxRequestsPerChannel; + + return newChannel; } /// @@ -322,20 +354,26 @@ private async Task OpenChannelAndIncrementCapacity( /// An instance of . /// A boolean flag indicating if the request is intendent for local region. /// An instance of . - /// + /// The Interceptor for fault injection. Null if not using fault injection + /// An action to be invoked when the channel is opened. + /// An instance of . private static IChannel CreateAndInitializeChannel( Guid activityId, Uri serverUri, ChannelProperties channelProperties, bool localRegionRequest, - SemaphoreSlim concurrentOpeningChannelSlim) + SemaphoreSlim concurrentOpeningChannelSlim, + IChaosInterceptor chaosInterceptor = null, + Action onChannelOpen = null) { return new Channel( activityId, serverUri, channelProperties, localRegionRequest, - concurrentOpeningChannelSlim); + concurrentOpeningChannelSlim, + chaosInterceptor, + onChannelOpen); } private sealed class SequenceGenerator diff --git a/Microsoft.Azure.Cosmos/src/direct/Snapshot.cs b/Microsoft.Azure.Cosmos/src/direct/Snapshot.cs index 375aa6efd1..ba5b7001a3 100644 --- a/Microsoft.Azure.Cosmos/src/direct/Snapshot.cs +++ b/Microsoft.Azure.Cosmos/src/direct/Snapshot.cs @@ -39,7 +39,9 @@ namespace Microsoft.Azure.Documents #endif class Snapshot : Resource { +#pragma warning disable CS0108 // Member hides inherited member; missing new keyword private static DateTime UnixStartTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); +#pragma warning restore CS0108 // Member hides inherited member; missing new keyword private SnapshotContent snapshotContent; diff --git a/Microsoft.Azure.Cosmos/src/direct/StoreClientFactory.cs b/Microsoft.Azure.Cosmos/src/direct/StoreClientFactory.cs index dc206ad642..7764a9d0f9 100644 --- a/Microsoft.Azure.Cosmos/src/direct/StoreClientFactory.cs +++ b/Microsoft.Azure.Cosmos/src/direct/StoreClientFactory.cs @@ -10,6 +10,7 @@ namespace Microsoft.Azure.Documents using System.Threading.Tasks; using Microsoft.Azure.Cosmos.Core.Trace; using Microsoft.Azure.Documents.Client; + using Microsoft.Azure.Documents.FaultInjection; using Microsoft.Azure.Documents.Telemetry; internal sealed class StoreClientFactory : IStoreClientFactory @@ -51,7 +52,8 @@ public StoreClientFactory( MemoryStreamPool memoryStreamPool = null, RemoteCertificateValidationCallback remoteCertificateValidationCallback = null, Func> dnsResolutionFunction = null, // optional override - DistributedTracingOptions distributedTracingOptions = null) // Distributed Tracing Configuration + DistributedTracingOptions distributedTracingOptions = null, // Distributed Tracing Configuration + IChaosInterceptor chaosInterceptor = null) // Fault Injection { // <=0 means idle timeout is disabled. // valid value: >= 10 minutes @@ -224,7 +226,8 @@ public StoreClientFactory( RemoteCertificateValidationCallback = remoteCertificateValidationCallback, DnsResolutionFunction = dnsResolutionFunction, DistributedTracingOptions = distributedTracingOptions - }); + }, + chaosInterceptor); this.fallbackTransportClient = new Rntbd.TransportClient( new Rntbd.TransportClient.Options(TimeSpan.FromSeconds(requestTimeoutInSeconds)) @@ -251,7 +254,8 @@ public StoreClientFactory( RemoteCertificateValidationCallback = remoteCertificateValidationCallback, DnsResolutionFunction = dnsResolutionFunction, DistributedTracingOptions = distributedTracingOptions - }); + }, + chaosInterceptor); } else { diff --git a/Microsoft.Azure.Cosmos/src/direct/TimerPool.cs b/Microsoft.Azure.Cosmos/src/direct/TimerPool.cs index 3c8d6166a5..8d9304997a 100644 --- a/Microsoft.Azure.Cosmos/src/direct/TimerPool.cs +++ b/Microsoft.Azure.Cosmos/src/direct/TimerPool.cs @@ -199,7 +199,6 @@ public PooledTimer GetPooledTimer(int timeoutInSeconds) /// /// get a timer with timeout specified as a TimeSpan /// - /// /// public PooledTimer GetPooledTimer(TimeSpan timeout) { diff --git a/Microsoft.Azure.Cosmos/src/direct/ValueStopwatch.cs b/Microsoft.Azure.Cosmos/src/direct/ValueStopwatch.cs index 852456c5e3..962f01779b 100644 --- a/Microsoft.Azure.Cosmos/src/direct/ValueStopwatch.cs +++ b/Microsoft.Azure.Cosmos/src/direct/ValueStopwatch.cs @@ -27,7 +27,9 @@ internal struct ValueStopwatch /// public static readonly bool IsHighResolution = Stopwatch.IsHighResolution; - /// +#pragma warning disable CS1570 // XML comment has badly formed XML +#pragma warning disable CS1570 // XML comment has badly formed XML +/// /// We pack everything into a single long, so using this doesn't inflate any objects with it as a field. /// /// State is interpreted as follows @@ -45,6 +47,8 @@ internal struct ValueStopwatch /// to account for any existing duration. /// private long state; +#pragma warning restore CS1570 // XML comment has badly formed XML +#pragma warning restore CS1570 // XML comment has badly formed XML /// public readonly bool IsRunning diff --git a/Microsoft.Azure.Cosmos/src/direct/WindowsSystemUtilizationReader.cs b/Microsoft.Azure.Cosmos/src/direct/WindowsSystemUtilizationReader.cs index 35c64dd1cf..6baffbcaa0 100644 --- a/Microsoft.Azure.Cosmos/src/direct/WindowsSystemUtilizationReader.cs +++ b/Microsoft.Azure.Cosmos/src/direct/WindowsSystemUtilizationReader.cs @@ -85,8 +85,6 @@ private static class NativeMethods /// /// https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-globalmemorystatusex /// - /// - /// /// /// [DllImport("kernel32.dll", SetLastError = true)] diff --git a/Microsoft.Azure.Cosmos/src/direct/rntbd2/TransportClient.cs b/Microsoft.Azure.Cosmos/src/direct/rntbd2/TransportClient.cs index aa2eedcbe8..e6c61819f8 100644 --- a/Microsoft.Azure.Cosmos/src/direct/rntbd2/TransportClient.cs +++ b/Microsoft.Azure.Cosmos/src/direct/rntbd2/TransportClient.cs @@ -11,6 +11,7 @@ namespace Microsoft.Azure.Documents.Rntbd using System.Threading; using System.Threading.Tasks; using Microsoft.Azure.Cosmos.Core.Trace; + using Microsoft.Azure.Documents.FaultInjection; using Microsoft.Azure.Documents.Telemetry; #if NETSTANDARD15 || NETSTANDARD16 using Trace = Microsoft.Azure.Documents.Trace; @@ -44,7 +45,7 @@ private enum TransportResponseStatusCode #endregion - public TransportClient(Options clientOptions) + public TransportClient(Options clientOptions, IChaosInterceptor chaosInterceptor = null) { if (clientOptions == null) { @@ -96,10 +97,11 @@ public TransportClient(Options clientOptions) clientOptions.EnableChannelMultiplexing, clientOptions.MemoryStreamPool, clientOptions.RemoteCertificateValidationCallback, - clientOptions.DnsResolutionFunction)); + clientOptions.DnsResolutionFunction), + chaosInterceptor); } - internal override Task InvokeStoreAsync( + internal override Task InvokeStoreAsync( Uri physicalAddress, ResourceOperation resourceOperation, DocumentServiceRequest request) @@ -342,11 +344,12 @@ private static void DecrementCounters() internal override Task OpenConnectionAsync( Uri physicalAddress) { - Guid activityId = Trace.CorrelationManager.ActivityId; - return this.channelDictionary.OpenChannelAsync( - physicalAddress: physicalAddress, - localRegionRequest: false, - activityId: activityId); + IChannel channel = this.channelDictionary.GetChannel( + requestUri: physicalAddress, + localRegionRequest: false); + + return channel.OpenChannelAsync( + activityId: Trace.CorrelationManager.ActivityId); } #region RNTBD Transition diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/BaselineTest/TestBaseline/EndToEndTraceWriterBaselineTests.BatchOperationsAsync.xml b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/BaselineTest/TestBaseline/EndToEndTraceWriterBaselineTests.BatchOperationsAsync.xml index fd097032d9..fb6a5fb720 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/BaselineTest/TestBaseline/EndToEndTraceWriterBaselineTests.BatchOperationsAsync.xml +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/BaselineTest/TestBaseline/EndToEndTraceWriterBaselineTests.BatchOperationsAsync.xml @@ -50,14 +50,15 @@ │ │ [System Info] │ │ Redacted To Not Change The Baselines From Run To Run │ │ ) - │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ ( - │ [Client Side Request Stats] - │ Redacted To Not Change The Baselines From Run To Run - │ ) + │ └── Microsoft.Azure.Cosmos.Handlers.TelemetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ ( + │ [Client Side Request Stats] + │ Redacted To Not Change The Baselines From Run To Run + │ ) └── Create Trace(00000000-0000-0000-0000-000000000000) Batch-Component 00:00:00:000 0.00 milliseconds ]]> @@ -116,23 +117,29 @@ }, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.TelemetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", "duration in milliseconds": 0, - "data": { - "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" - } + "children": [ + { + "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "duration in milliseconds": 0, + "data": { + "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" + } + } + ] } ] } @@ -454,14 +461,15 @@ │ │ │ [System Info] │ │ │ Redacted To Not Change The Baselines From Run To Run │ │ │ ) - │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ │ ( - │ │ [Client Side Request Stats] - │ │ Redacted To Not Change The Baselines From Run To Run - │ │ ) + │ │ └── Microsoft.Azure.Cosmos.Handlers.TelemetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ │ ( + │ │ [Client Side Request Stats] + │ │ Redacted To Not Change The Baselines From Run To Run + │ │ ) │ └── Create Trace(00000000-0000-0000-0000-000000000000) Batch-Component 00:00:00:000 0.00 milliseconds └── Response Serialization(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds ]]> @@ -503,23 +511,29 @@ }, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.TelemetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", "duration in milliseconds": 0, - "data": { - "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" - } + "children": [ + { + "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "duration in milliseconds": 0, + "data": { + "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" + } + } + ] } ] } @@ -841,14 +855,15 @@ │ │ │ [System Info] │ │ │ Redacted To Not Change The Baselines From Run To Run │ │ │ ) - │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ │ ( - │ │ [Client Side Request Stats] - │ │ Redacted To Not Change The Baselines From Run To Run - │ │ ) + │ │ └── Microsoft.Azure.Cosmos.Handlers.TelemetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ │ ( + │ │ [Client Side Request Stats] + │ │ Redacted To Not Change The Baselines From Run To Run + │ │ ) │ └── Create Trace(00000000-0000-0000-0000-000000000000) Batch-Component 00:00:00:000 0.00 milliseconds └── Response Serialization(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds ]]> @@ -890,23 +905,29 @@ }, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.TelemetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", "duration in milliseconds": 0, - "data": { - "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" - } + "children": [ + { + "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "duration in milliseconds": 0, + "data": { + "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" + } + } + ] } ] } @@ -1228,14 +1249,15 @@ │ │ │ [System Info] │ │ │ Redacted To Not Change The Baselines From Run To Run │ │ │ ) - │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ │ ( - │ │ [Client Side Request Stats] - │ │ Redacted To Not Change The Baselines From Run To Run - │ │ ) + │ │ └── Microsoft.Azure.Cosmos.Handlers.TelemetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ │ ( + │ │ [Client Side Request Stats] + │ │ Redacted To Not Change The Baselines From Run To Run + │ │ ) │ └── Create Trace(00000000-0000-0000-0000-000000000000) Batch-Component 00:00:00:000 0.00 milliseconds └── Response Serialization(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds ]]> @@ -1277,23 +1299,29 @@ }, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.TelemetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", "duration in milliseconds": 0, - "data": { - "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" - } + "children": [ + { + "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "duration in milliseconds": 0, + "data": { + "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" + } + } + ] } ] } @@ -1615,14 +1643,15 @@ │ │ │ [System Info] │ │ │ Redacted To Not Change The Baselines From Run To Run │ │ │ ) - │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ │ ( - │ │ [Client Side Request Stats] - │ │ Redacted To Not Change The Baselines From Run To Run - │ │ ) + │ │ └── Microsoft.Azure.Cosmos.Handlers.TelemetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ │ ( + │ │ [Client Side Request Stats] + │ │ Redacted To Not Change The Baselines From Run To Run + │ │ ) │ └── Create Trace(00000000-0000-0000-0000-000000000000) Batch-Component 00:00:00:000 0.00 milliseconds └── Response Serialization(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds ]]> @@ -1664,23 +1693,29 @@ }, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.TelemetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", "duration in milliseconds": 0, - "data": { - "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" - } + "children": [ + { + "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "duration in milliseconds": 0, + "data": { + "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" + } + } + ] } ] } @@ -2002,14 +2037,15 @@ │ │ │ [System Info] │ │ │ Redacted To Not Change The Baselines From Run To Run │ │ │ ) - │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ │ ( - │ │ [Client Side Request Stats] - │ │ Redacted To Not Change The Baselines From Run To Run - │ │ ) + │ │ └── Microsoft.Azure.Cosmos.Handlers.TelemetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ │ ( + │ │ [Client Side Request Stats] + │ │ Redacted To Not Change The Baselines From Run To Run + │ │ ) │ └── Create Trace(00000000-0000-0000-0000-000000000000) Batch-Component 00:00:00:000 0.00 milliseconds └── Response Serialization(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds ]]> @@ -2051,23 +2087,29 @@ }, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.TelemetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", "duration in milliseconds": 0, - "data": { - "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" - } + "children": [ + { + "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "duration in milliseconds": 0, + "data": { + "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" + } + } + ] } ] } @@ -2389,14 +2431,15 @@ │ │ │ [System Info] │ │ │ Redacted To Not Change The Baselines From Run To Run │ │ │ ) - │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ │ ( - │ │ [Client Side Request Stats] - │ │ Redacted To Not Change The Baselines From Run To Run - │ │ ) + │ │ └── Microsoft.Azure.Cosmos.Handlers.TelemetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ │ ( + │ │ [Client Side Request Stats] + │ │ Redacted To Not Change The Baselines From Run To Run + │ │ ) │ └── Create Trace(00000000-0000-0000-0000-000000000000) Batch-Component 00:00:00:000 0.00 milliseconds └── Response Serialization(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds ]]> @@ -2438,23 +2481,29 @@ }, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.TelemetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", "duration in milliseconds": 0, - "data": { - "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" - } + "children": [ + { + "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "duration in milliseconds": 0, + "data": { + "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" + } + } + ] } ] } @@ -2776,14 +2825,15 @@ │ │ │ [System Info] │ │ │ Redacted To Not Change The Baselines From Run To Run │ │ │ ) - │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ │ ( - │ │ [Client Side Request Stats] - │ │ Redacted To Not Change The Baselines From Run To Run - │ │ ) + │ │ └── Microsoft.Azure.Cosmos.Handlers.TelemetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ │ ( + │ │ [Client Side Request Stats] + │ │ Redacted To Not Change The Baselines From Run To Run + │ │ ) │ └── Create Trace(00000000-0000-0000-0000-000000000000) Batch-Component 00:00:00:000 0.00 milliseconds └── Response Serialization(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds ]]> @@ -2825,23 +2875,29 @@ }, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.TelemetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", "duration in milliseconds": 0, - "data": { - "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" - } + "children": [ + { + "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "duration in milliseconds": 0, + "data": { + "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" + } + } + ] } ] } @@ -3163,14 +3219,15 @@ │ │ │ [System Info] │ │ │ Redacted To Not Change The Baselines From Run To Run │ │ │ ) - │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ │ ( - │ │ [Client Side Request Stats] - │ │ Redacted To Not Change The Baselines From Run To Run - │ │ ) + │ │ └── Microsoft.Azure.Cosmos.Handlers.TelemetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ │ ( + │ │ [Client Side Request Stats] + │ │ Redacted To Not Change The Baselines From Run To Run + │ │ ) │ └── Create Trace(00000000-0000-0000-0000-000000000000) Batch-Component 00:00:00:000 0.00 milliseconds └── Response Serialization(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds ]]> @@ -3212,23 +3269,29 @@ }, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.TelemetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", "duration in milliseconds": 0, - "data": { - "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" - } + "children": [ + { + "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "duration in milliseconds": 0, + "data": { + "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" + } + } + ] } ] } @@ -3550,14 +3613,15 @@ │ │ │ [System Info] │ │ │ Redacted To Not Change The Baselines From Run To Run │ │ │ ) - │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ │ ( - │ │ [Client Side Request Stats] - │ │ Redacted To Not Change The Baselines From Run To Run - │ │ ) + │ │ └── Microsoft.Azure.Cosmos.Handlers.TelemetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ │ ( + │ │ [Client Side Request Stats] + │ │ Redacted To Not Change The Baselines From Run To Run + │ │ ) │ └── Create Trace(00000000-0000-0000-0000-000000000000) Batch-Component 00:00:00:000 0.00 milliseconds └── Response Serialization(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds ]]> @@ -3599,23 +3663,29 @@ }, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.TelemetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", "duration in milliseconds": 0, - "data": { - "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" - } + "children": [ + { + "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "duration in milliseconds": 0, + "data": { + "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" + } + } + ] } ] } @@ -3899,9 +3969,14 @@ maxRetryWaitTimeOnThrottledRequests: TimeSpan.FromSeconds(1), maxRetryAttemptsOnThrottledRequests: 3) .WithBulkExecution(true) - .WithDistributedTracingOptions(new DistributedTracingOptions() + .WithClientTelemetryOptions(new CosmosClientTelemetryOptions() { - LatencyThresholdForDiagnosticEvent = TimeSpan.FromMilliseconds(0) + DisableDistributedTracing = false, + CosmosThresholdOptions = new CosmosThresholdOptions() + { + PointOperationLatencyThreshold = TimeSpan.Zero, + NonPointOperationLatencyThreshold = TimeSpan.Zero + } }) .WithTransportClientHandlerFactory(transportClient => new TransportClientWrapper( transportClient, @@ -3959,35 +4034,36 @@ │ │ │ [System Info] │ │ │ Redacted To Not Change The Baselines From Run To Run │ │ │ ) - │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ ├── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ │ │ ( - │ │ │ [Client Side Request Stats] - │ │ │ Redacted To Not Change The Baselines From Run To Run - │ │ │ ) - │ │ ├── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ │ │ ( - │ │ │ [Client Side Request Stats] - │ │ │ Redacted To Not Change The Baselines From Run To Run - │ │ │ ) - │ │ ├── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ │ │ ( - │ │ │ [Client Side Request Stats] - │ │ │ Redacted To Not Change The Baselines From Run To Run - │ │ │ ) - │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ │ ( - │ │ [Client Side Request Stats] - │ │ Redacted To Not Change The Baselines From Run To Run - │ │ ) + │ │ └── Microsoft.Azure.Cosmos.Handlers.TelemetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ ├── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ │ │ ( + │ │ │ [Client Side Request Stats] + │ │ │ Redacted To Not Change The Baselines From Run To Run + │ │ │ ) + │ │ ├── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ │ │ ( + │ │ │ [Client Side Request Stats] + │ │ │ Redacted To Not Change The Baselines From Run To Run + │ │ │ ) + │ │ ├── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ │ │ ( + │ │ │ [Client Side Request Stats] + │ │ │ Redacted To Not Change The Baselines From Run To Run + │ │ │ ) + │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ │ ( + │ │ [Client Side Request Stats] + │ │ Redacted To Not Change The Baselines From Run To Run + │ │ ) │ └── Create Trace(00000000-0000-0000-0000-000000000000) Batch-Component 00:00:00:000 0.00 milliseconds ├── Batch Retry Async(00000000-0000-0000-0000-000000000000) Batch-Component 00:00:00:000 0.00 milliseconds │ └── Get Collection Cache(00000000-0000-0000-0000-000000000000) Routing-Component 00:00:00:000 0.00 milliseconds @@ -3999,35 +4075,36 @@ │ │ │ [System Info] │ │ │ Redacted To Not Change The Baselines From Run To Run │ │ │ ) - │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ ├── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ │ │ ( - │ │ │ [Client Side Request Stats] - │ │ │ Redacted To Not Change The Baselines From Run To Run - │ │ │ ) - │ │ ├── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ │ │ ( - │ │ │ [Client Side Request Stats] - │ │ │ Redacted To Not Change The Baselines From Run To Run - │ │ │ ) - │ │ ├── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ │ │ ( - │ │ │ [Client Side Request Stats] - │ │ │ Redacted To Not Change The Baselines From Run To Run - │ │ │ ) - │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ │ ( - │ │ [Client Side Request Stats] - │ │ Redacted To Not Change The Baselines From Run To Run - │ │ ) + │ │ └── Microsoft.Azure.Cosmos.Handlers.TelemetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ ├── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ │ │ ( + │ │ │ [Client Side Request Stats] + │ │ │ Redacted To Not Change The Baselines From Run To Run + │ │ │ ) + │ │ ├── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ │ │ ( + │ │ │ [Client Side Request Stats] + │ │ │ Redacted To Not Change The Baselines From Run To Run + │ │ │ ) + │ │ ├── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ │ │ ( + │ │ │ [Client Side Request Stats] + │ │ │ Redacted To Not Change The Baselines From Run To Run + │ │ │ ) + │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ │ ( + │ │ [Client Side Request Stats] + │ │ Redacted To Not Change The Baselines From Run To Run + │ │ ) │ └── Create Trace(00000000-0000-0000-0000-000000000000) Batch-Component 00:00:00:000 0.00 milliseconds ├── Batch Retry Async(00000000-0000-0000-0000-000000000000) Batch-Component 00:00:00:000 0.00 milliseconds │ └── Get Collection Cache(00000000-0000-0000-0000-000000000000) Routing-Component 00:00:00:000 0.00 milliseconds @@ -4039,35 +4116,36 @@ │ │ │ [System Info] │ │ │ Redacted To Not Change The Baselines From Run To Run │ │ │ ) - │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ ├── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ │ │ ( - │ │ │ [Client Side Request Stats] - │ │ │ Redacted To Not Change The Baselines From Run To Run - │ │ │ ) - │ │ ├── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ │ │ ( - │ │ │ [Client Side Request Stats] - │ │ │ Redacted To Not Change The Baselines From Run To Run - │ │ │ ) - │ │ ├── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ │ │ ( - │ │ │ [Client Side Request Stats] - │ │ │ Redacted To Not Change The Baselines From Run To Run - │ │ │ ) - │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ │ ( - │ │ [Client Side Request Stats] - │ │ Redacted To Not Change The Baselines From Run To Run - │ │ ) + │ │ └── Microsoft.Azure.Cosmos.Handlers.TelemetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ ├── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ │ │ ( + │ │ │ [Client Side Request Stats] + │ │ │ Redacted To Not Change The Baselines From Run To Run + │ │ │ ) + │ │ ├── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ │ │ ( + │ │ │ [Client Side Request Stats] + │ │ │ Redacted To Not Change The Baselines From Run To Run + │ │ │ ) + │ │ ├── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ │ │ ( + │ │ │ [Client Side Request Stats] + │ │ │ Redacted To Not Change The Baselines From Run To Run + │ │ │ ) + │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ │ ( + │ │ [Client Side Request Stats] + │ │ Redacted To Not Change The Baselines From Run To Run + │ │ ) │ └── Create Trace(00000000-0000-0000-0000-000000000000) Batch-Component 00:00:00:000 0.00 milliseconds ├── Batch Retry Async(00000000-0000-0000-0000-000000000000) Batch-Component 00:00:00:000 0.00 milliseconds │ └── Get Collection Cache(00000000-0000-0000-0000-000000000000) Routing-Component 00:00:00:000 0.00 milliseconds @@ -4079,35 +4157,36 @@ │ │ [System Info] │ │ Redacted To Not Change The Baselines From Run To Run │ │ ) - │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ ├── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ │ ( - │ │ [Client Side Request Stats] - │ │ Redacted To Not Change The Baselines From Run To Run - │ │ ) - │ ├── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ │ ( - │ │ [Client Side Request Stats] - │ │ Redacted To Not Change The Baselines From Run To Run - │ │ ) - │ ├── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ │ ( - │ │ [Client Side Request Stats] - │ │ Redacted To Not Change The Baselines From Run To Run - │ │ ) - │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ ( - │ [Client Side Request Stats] - │ Redacted To Not Change The Baselines From Run To Run - │ ) + │ └── Microsoft.Azure.Cosmos.Handlers.TelemetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ ├── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ │ ( + │ │ [Client Side Request Stats] + │ │ Redacted To Not Change The Baselines From Run To Run + │ │ ) + │ ├── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ │ ( + │ │ [Client Side Request Stats] + │ │ Redacted To Not Change The Baselines From Run To Run + │ │ ) + │ ├── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ │ ( + │ │ [Client Side Request Stats] + │ │ Redacted To Not Change The Baselines From Run To Run + │ │ ) + │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ ( + │ [Client Side Request Stats] + │ Redacted To Not Change The Baselines From Run To Run + │ ) └── Create Trace(00000000-0000-0000-0000-000000000000) Batch-Component 00:00:00:000 0.00 milliseconds ]]> @@ -369,23 +377,29 @@ }, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.TelemetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", "duration in milliseconds": 0, - "data": { - "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" - } + "children": [ + { + "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "duration in milliseconds": 0, + "data": { + "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" + } + } + ] } ] } @@ -459,23 +473,29 @@ }, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.TelemetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", "duration in milliseconds": 0, - "data": { - "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" - } + "children": [ + { + "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "duration in milliseconds": 0, + "data": { + "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" + } + } + ] } ] } @@ -547,23 +567,29 @@ }, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.TelemetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", "duration in milliseconds": 0, - "data": { - "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" - } + "children": [ + { + "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "duration in milliseconds": 0, + "data": { + "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" + } + } + ] } ] } @@ -635,23 +661,29 @@ }, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.TelemetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", "duration in milliseconds": 0, - "data": { - "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" - } + "children": [ + { + "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "duration in milliseconds": 0, + "data": { + "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" + } + } + ] } ] } @@ -723,23 +755,29 @@ }, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.TelemetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", "duration in milliseconds": 0, - "data": { - "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" - } + "children": [ + { + "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "duration in milliseconds": 0, + "data": { + "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" + } + } + ] } ] } @@ -791,23 +829,29 @@ }, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.TelemetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", "duration in milliseconds": 0, - "data": { - "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" - } + "children": [ + { + "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "duration in milliseconds": 0, + "data": { + "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" + } + } + ] } ] } @@ -855,23 +899,29 @@ }, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.TelemetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", "duration in milliseconds": 0, - "data": { - "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" - } + "children": [ + { + "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "duration in milliseconds": 0, + "data": { + "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" + } + } + ] } ] } @@ -919,23 +969,29 @@ }, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.TelemetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", "duration in milliseconds": 0, - "data": { - "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" - } + "children": [ + { + "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "duration in milliseconds": 0, + "data": { + "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" + } + } + ] } ] } @@ -1165,14 +1221,15 @@ │ │ │ [System Info] │ │ │ Redacted To Not Change The Baselines From Run To Run │ │ │ ) - │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ │ ( - │ │ [Client Side Request Stats] - │ │ Redacted To Not Change The Baselines From Run To Run - │ │ ) + │ │ └── Microsoft.Azure.Cosmos.Handlers.TelemetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ │ ( + │ │ [Client Side Request Stats] + │ │ Redacted To Not Change The Baselines From Run To Run + │ │ ) │ ├── Get RID(00000000-0000-0000-0000-000000000000) Routing-Component 00:00:00:000 0.00 milliseconds │ ├── Get Collection Cache(00000000-0000-0000-0000-000000000000) Routing-Component 00:00:00:000 0.00 milliseconds │ └── ChangeFeed Response Serialization(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds @@ -1195,14 +1252,15 @@ │ │ │ [System Info] │ │ │ Redacted To Not Change The Baselines From Run To Run │ │ │ ) - │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ │ ( - │ │ [Client Side Request Stats] - │ │ Redacted To Not Change The Baselines From Run To Run - │ │ ) + │ │ └── Microsoft.Azure.Cosmos.Handlers.TelemetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ │ ( + │ │ [Client Side Request Stats] + │ │ Redacted To Not Change The Baselines From Run To Run + │ │ ) │ ├── Get RID(00000000-0000-0000-0000-000000000000) Routing-Component 00:00:00:000 0.00 milliseconds │ ├── Get Collection Cache(00000000-0000-0000-0000-000000000000) Routing-Component 00:00:00:000 0.00 milliseconds │ └── ChangeFeed Response Serialization(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds @@ -1225,14 +1283,15 @@ │ │ │ [System Info] │ │ │ Redacted To Not Change The Baselines From Run To Run │ │ │ ) - │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ │ ( - │ │ [Client Side Request Stats] - │ │ Redacted To Not Change The Baselines From Run To Run - │ │ ) + │ │ └── Microsoft.Azure.Cosmos.Handlers.TelemetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ │ ( + │ │ [Client Side Request Stats] + │ │ Redacted To Not Change The Baselines From Run To Run + │ │ ) │ ├── Get RID(00000000-0000-0000-0000-000000000000) Routing-Component 00:00:00:000 0.00 milliseconds │ ├── Get Collection Cache(00000000-0000-0000-0000-000000000000) Routing-Component 00:00:00:000 0.00 milliseconds │ └── ChangeFeed Response Serialization(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds @@ -1255,14 +1314,15 @@ │ │ [System Info] │ │ Redacted To Not Change The Baselines From Run To Run │ │ ) - │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ ( - │ [Client Side Request Stats] - │ Redacted To Not Change The Baselines From Run To Run - │ ) + │ └── Microsoft.Azure.Cosmos.Handlers.TelemetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ ( + │ [Client Side Request Stats] + │ Redacted To Not Change The Baselines From Run To Run + │ ) ├── Get RID(00000000-0000-0000-0000-000000000000) Routing-Component 00:00:00:000 0.00 milliseconds ├── Get Collection Cache(00000000-0000-0000-0000-000000000000) Routing-Component 00:00:00:000 0.00 milliseconds └── ChangeFeed Response Serialization(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds @@ -1391,23 +1451,29 @@ }, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.TelemetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", "duration in milliseconds": 0, - "data": { - "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" - } + "children": [ + { + "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "duration in milliseconds": 0, + "data": { + "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" + } + } + ] } ] } @@ -1485,23 +1551,29 @@ }, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.TelemetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", "duration in milliseconds": 0, - "data": { - "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" - } + "children": [ + { + "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "duration in milliseconds": 0, + "data": { + "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" + } + } + ] } ] } @@ -1577,23 +1649,29 @@ }, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.TelemetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", "duration in milliseconds": 0, - "data": { - "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" - } + "children": [ + { + "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "duration in milliseconds": 0, + "data": { + "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" + } + } + ] } ] } @@ -1669,23 +1747,29 @@ }, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.TelemetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", "duration in milliseconds": 0, - "data": { - "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" - } + "children": [ + { + "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "duration in milliseconds": 0, + "data": { + "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" + } + } + ] } ] } @@ -1918,14 +2002,15 @@ │ │ │ [System Info] │ │ │ Redacted To Not Change The Baselines From Run To Run │ │ │ ) - │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ │ ( - │ │ [Client Side Request Stats] - │ │ Redacted To Not Change The Baselines From Run To Run - │ │ ) + │ │ └── Microsoft.Azure.Cosmos.Handlers.TelemetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ │ ( + │ │ [Client Side Request Stats] + │ │ Redacted To Not Change The Baselines From Run To Run + │ │ ) │ ├── Get RID(00000000-0000-0000-0000-000000000000) Routing-Component 00:00:00:000 0.00 milliseconds │ └── Get Collection Cache(00000000-0000-0000-0000-000000000000) Routing-Component 00:00:00:000 0.00 milliseconds ├── Change Feed Iterator Read Next Async(00000000-0000-0000-0000-000000000000) ChangeFeed-Component 00:00:00:000 0.00 milliseconds @@ -1947,14 +2032,15 @@ │ │ │ [System Info] │ │ │ Redacted To Not Change The Baselines From Run To Run │ │ │ ) - │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ │ ( - │ │ [Client Side Request Stats] - │ │ Redacted To Not Change The Baselines From Run To Run - │ │ ) + │ │ └── Microsoft.Azure.Cosmos.Handlers.TelemetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ │ ( + │ │ [Client Side Request Stats] + │ │ Redacted To Not Change The Baselines From Run To Run + │ │ ) │ ├── Get RID(00000000-0000-0000-0000-000000000000) Routing-Component 00:00:00:000 0.00 milliseconds │ └── Get Collection Cache(00000000-0000-0000-0000-000000000000) Routing-Component 00:00:00:000 0.00 milliseconds ├── Change Feed Iterator Read Next Async(00000000-0000-0000-0000-000000000000) ChangeFeed-Component 00:00:00:000 0.00 milliseconds @@ -1976,14 +2062,15 @@ │ │ │ [System Info] │ │ │ Redacted To Not Change The Baselines From Run To Run │ │ │ ) - │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ │ ( - │ │ [Client Side Request Stats] - │ │ Redacted To Not Change The Baselines From Run To Run - │ │ ) + │ │ └── Microsoft.Azure.Cosmos.Handlers.TelemetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ │ ( + │ │ [Client Side Request Stats] + │ │ Redacted To Not Change The Baselines From Run To Run + │ │ ) │ ├── Get RID(00000000-0000-0000-0000-000000000000) Routing-Component 00:00:00:000 0.00 milliseconds │ └── Get Collection Cache(00000000-0000-0000-0000-000000000000) Routing-Component 00:00:00:000 0.00 milliseconds └── Change Feed Iterator Read Next Async(00000000-0000-0000-0000-000000000000) ChangeFeed-Component 00:00:00:000 0.00 milliseconds @@ -2005,14 +2092,15 @@ │ │ [System Info] │ │ Redacted To Not Change The Baselines From Run To Run │ │ ) - │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ ( - │ [Client Side Request Stats] - │ Redacted To Not Change The Baselines From Run To Run - │ ) + │ └── Microsoft.Azure.Cosmos.Handlers.TelemetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ ( + │ [Client Side Request Stats] + │ Redacted To Not Change The Baselines From Run To Run + │ ) ├── Get RID(00000000-0000-0000-0000-000000000000) Routing-Component 00:00:00:000 0.00 milliseconds └── Get Collection Cache(00000000-0000-0000-0000-000000000000) Routing-Component 00:00:00:000 0.00 milliseconds ]]> @@ -2140,23 +2228,29 @@ }, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.TelemetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", "duration in milliseconds": 0, - "data": { - "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" - } + "children": [ + { + "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "duration in milliseconds": 0, + "data": { + "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" + } + } + ] } ] } @@ -2230,23 +2324,29 @@ }, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.TelemetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", "duration in milliseconds": 0, - "data": { - "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" - } + "children": [ + { + "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "duration in milliseconds": 0, + "data": { + "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" + } + } + ] } ] } @@ -2318,23 +2418,29 @@ }, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.TelemetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", "duration in milliseconds": 0, - "data": { - "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" - } + "children": [ + { + "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "duration in milliseconds": 0, + "data": { + "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" + } + } + ] } ] } @@ -2406,23 +2512,29 @@ }, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.TelemetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", "duration in milliseconds": 0, - "data": { - "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" - } + "children": [ + { + "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "duration in milliseconds": 0, + "data": { + "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" + } + } + ] } ] } @@ -2651,14 +2763,15 @@ │ │ │ [System Info] │ │ │ Redacted To Not Change The Baselines From Run To Run │ │ │ ) - │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ │ ( - │ │ [Client Side Request Stats] - │ │ Redacted To Not Change The Baselines From Run To Run - │ │ ) + │ │ └── Microsoft.Azure.Cosmos.Handlers.TelemetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ │ ( + │ │ [Client Side Request Stats] + │ │ Redacted To Not Change The Baselines From Run To Run + │ │ ) │ ├── Get RID(00000000-0000-0000-0000-000000000000) Routing-Component 00:00:00:000 0.00 milliseconds │ ├── Get Collection Cache(00000000-0000-0000-0000-000000000000) Routing-Component 00:00:00:000 0.00 milliseconds │ └── ChangeFeed Response Serialization(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds @@ -2681,14 +2794,15 @@ │ │ │ [System Info] │ │ │ Redacted To Not Change The Baselines From Run To Run │ │ │ ) - │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ │ ( - │ │ [Client Side Request Stats] - │ │ Redacted To Not Change The Baselines From Run To Run - │ │ ) + │ │ └── Microsoft.Azure.Cosmos.Handlers.TelemetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ │ ( + │ │ [Client Side Request Stats] + │ │ Redacted To Not Change The Baselines From Run To Run + │ │ ) │ ├── Get RID(00000000-0000-0000-0000-000000000000) Routing-Component 00:00:00:000 0.00 milliseconds │ ├── Get Collection Cache(00000000-0000-0000-0000-000000000000) Routing-Component 00:00:00:000 0.00 milliseconds │ └── ChangeFeed Response Serialization(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds @@ -2711,14 +2825,15 @@ │ │ │ [System Info] │ │ │ Redacted To Not Change The Baselines From Run To Run │ │ │ ) - │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ │ ( - │ │ [Client Side Request Stats] - │ │ Redacted To Not Change The Baselines From Run To Run - │ │ ) + │ │ └── Microsoft.Azure.Cosmos.Handlers.TelemetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ │ ( + │ │ [Client Side Request Stats] + │ │ Redacted To Not Change The Baselines From Run To Run + │ │ ) │ ├── Get RID(00000000-0000-0000-0000-000000000000) Routing-Component 00:00:00:000 0.00 milliseconds │ ├── Get Collection Cache(00000000-0000-0000-0000-000000000000) Routing-Component 00:00:00:000 0.00 milliseconds │ └── ChangeFeed Response Serialization(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds @@ -2741,14 +2856,15 @@ │ │ [System Info] │ │ Redacted To Not Change The Baselines From Run To Run │ │ ) - │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ ( - │ [Client Side Request Stats] - │ Redacted To Not Change The Baselines From Run To Run - │ ) + │ └── Microsoft.Azure.Cosmos.Handlers.TelemetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ ( + │ [Client Side Request Stats] + │ Redacted To Not Change The Baselines From Run To Run + │ ) ├── Get RID(00000000-0000-0000-0000-000000000000) Routing-Component 00:00:00:000 0.00 milliseconds ├── Get Collection Cache(00000000-0000-0000-0000-000000000000) Routing-Component 00:00:00:000 0.00 milliseconds └── ChangeFeed Response Serialization(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds @@ -2877,23 +2993,29 @@ }, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.TelemetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", "duration in milliseconds": 0, - "data": { - "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" - } + "children": [ + { + "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "duration in milliseconds": 0, + "data": { + "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" + } + } + ] } ] } @@ -2971,23 +3093,29 @@ }, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.TelemetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", "duration in milliseconds": 0, - "data": { - "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" - } + "children": [ + { + "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "duration in milliseconds": 0, + "data": { + "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" + } + } + ] } ] } @@ -3063,23 +3191,29 @@ }, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.TelemetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", "duration in milliseconds": 0, - "data": { - "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" - } + "children": [ + { + "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "duration in milliseconds": 0, + "data": { + "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" + } + } + ] } ] } @@ -3155,23 +3289,29 @@ }, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.TelemetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", "duration in milliseconds": 0, - "data": { - "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" - } + "children": [ + { + "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "duration in milliseconds": 0, + "data": { + "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" + } + } + ] } ] } @@ -3379,56 +3519,60 @@ │ │ [System Info] │ │ Redacted To Not Change The Baselines From Run To Run │ │ ) - │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ ( - │ [Client Side Request Stats] - │ Redacted To Not Change The Baselines From Run To Run - │ ) + │ └── Microsoft.Azure.Cosmos.Handlers.TelemetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ ( + │ [Client Side Request Stats] + │ Redacted To Not Change The Baselines From Run To Run + │ ) ├── Microsoft.Azure.Cosmos.Handlers.RequestInvokerHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds │ └── Microsoft.Azure.Cosmos.Handlers.DiagnosticsHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds │ │ ( │ │ [System Info] │ │ Redacted To Not Change The Baselines From Run To Run │ │ ) - │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ ( - │ [Client Side Request Stats] - │ Redacted To Not Change The Baselines From Run To Run - │ ) + │ └── Microsoft.Azure.Cosmos.Handlers.TelemetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ ( + │ [Client Side Request Stats] + │ Redacted To Not Change The Baselines From Run To Run + │ ) ├── Microsoft.Azure.Cosmos.Handlers.RequestInvokerHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds │ └── Microsoft.Azure.Cosmos.Handlers.DiagnosticsHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds │ │ ( │ │ [System Info] │ │ Redacted To Not Change The Baselines From Run To Run │ │ ) - │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ ( - │ [Client Side Request Stats] - │ Redacted To Not Change The Baselines From Run To Run - │ ) + │ └── Microsoft.Azure.Cosmos.Handlers.TelemetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ ( + │ [Client Side Request Stats] + │ Redacted To Not Change The Baselines From Run To Run + │ ) └── Microsoft.Azure.Cosmos.Handlers.RequestInvokerHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds └── Microsoft.Azure.Cosmos.Handlers.DiagnosticsHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds │ ( │ [System Info] │ Redacted To Not Change The Baselines From Run To Run │ ) - └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - ( - [Client Side Request Stats] - Redacted To Not Change The Baselines From Run To Run - ) + └── Microsoft.Azure.Cosmos.Handlers.TelemetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + ( + [Client Side Request Stats] + Redacted To Not Change The Baselines From Run To Run + ) ]]> builder - .WithDistributedTracingOptions(new DistributedTracingOptions() + .WithClientTelemetryOptions(new CosmosClientTelemetryOptions() { - LatencyThresholdForDiagnosticEvent = TimeSpan.FromMilliseconds(0) + DisableDistributedTracing = false, + CosmosThresholdOptions = new CosmosThresholdOptions() + { + PointOperationLatencyThreshold = TimeSpan.Zero, + NonPointOperationLatencyThreshold = TimeSpan.Zero + } }) .WithThrottlingRetryOptions( maxRetryWaitTimeOnThrottledRequests: TimeSpan.FromSeconds(1), @@ -244,35 +256,36 @@ │ │ [System Info] │ │ Redacted To Not Change The Baselines From Run To Run │ │ ) - │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ ├── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ │ ( - │ │ [Client Side Request Stats] - │ │ Redacted To Not Change The Baselines From Run To Run - │ │ ) - │ ├── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ │ ( - │ │ [Client Side Request Stats] - │ │ Redacted To Not Change The Baselines From Run To Run - │ │ ) - │ ├── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ │ ( - │ │ [Client Side Request Stats] - │ │ Redacted To Not Change The Baselines From Run To Run - │ │ ) - │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ ( - │ [Client Side Request Stats] - │ Redacted To Not Change The Baselines From Run To Run - │ ) + │ └── Microsoft.Azure.Cosmos.Handlers.TelemetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ ├── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ │ ( + │ │ [Client Side Request Stats] + │ │ Redacted To Not Change The Baselines From Run To Run + │ │ ) + │ ├── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ │ ( + │ │ [Client Side Request Stats] + │ │ Redacted To Not Change The Baselines From Run To Run + │ │ ) + │ ├── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ │ ( + │ │ [Client Side Request Stats] + │ │ Redacted To Not Change The Baselines From Run To Run + │ │ ) + │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ ( + │ [Client Side Request Stats] + │ Redacted To Not Change The Baselines From Run To Run + │ ) └── Get Collection Cache(00000000-0000-0000-0000-000000000000) Routing-Component 00:00:00:000 0.00 milliseconds ]]> @@ -958,23 +990,29 @@ }, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.TelemetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", "duration in milliseconds": 0, - "data": { - "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" - } + "children": [ + { + "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "duration in milliseconds": 0, + "data": { + "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" + } + } + ] } ] } @@ -1056,23 +1094,29 @@ }, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.TelemetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", "duration in milliseconds": 0, - "data": { - "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" - } + "children": [ + { + "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "duration in milliseconds": 0, + "data": { + "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" + } + } + ] } ] } @@ -1154,23 +1198,29 @@ }, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.TelemetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", "duration in milliseconds": 0, - "data": { - "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" - } + "children": [ + { + "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "duration in milliseconds": 0, + "data": { + "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" + } + } + ] } ] } @@ -1252,23 +1302,29 @@ }, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.TelemetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", "duration in milliseconds": 0, - "data": { - "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" - } + "children": [ + { + "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "duration in milliseconds": 0, + "data": { + "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" + } + } + ] } ] } @@ -1461,14 +1517,15 @@ │ │ │ [System Info] │ │ │ Redacted To Not Change The Baselines From Run To Run │ │ │ ) - │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ │ ( - │ │ [Client Side Request Stats] - │ │ Redacted To Not Change The Baselines From Run To Run - │ │ ) + │ │ └── Microsoft.Azure.Cosmos.Handlers.TelemetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ │ ( + │ │ [Client Side Request Stats] + │ │ Redacted To Not Change The Baselines From Run To Run + │ │ ) │ └── Get Cosmos Element Response(00000000-0000-0000-0000-000000000000) Json-Component 00:00:00:000 0.00 milliseconds ├── FeedIterator Read Next Async(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds │ │ ( @@ -1496,14 +1553,15 @@ │ │ │ [System Info] │ │ │ Redacted To Not Change The Baselines From Run To Run │ │ │ ) - │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ │ ( - │ │ [Client Side Request Stats] - │ │ Redacted To Not Change The Baselines From Run To Run - │ │ ) + │ │ └── Microsoft.Azure.Cosmos.Handlers.TelemetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ │ ( + │ │ [Client Side Request Stats] + │ │ Redacted To Not Change The Baselines From Run To Run + │ │ ) │ └── Get Cosmos Element Response(00000000-0000-0000-0000-000000000000) Json-Component 00:00:00:000 0.00 milliseconds ├── FeedIterator Read Next Async(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds │ │ ( @@ -1531,14 +1589,15 @@ │ │ │ [System Info] │ │ │ Redacted To Not Change The Baselines From Run To Run │ │ │ ) - │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ │ ( - │ │ [Client Side Request Stats] - │ │ Redacted To Not Change The Baselines From Run To Run - │ │ ) + │ │ └── Microsoft.Azure.Cosmos.Handlers.TelemetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ │ ( + │ │ [Client Side Request Stats] + │ │ Redacted To Not Change The Baselines From Run To Run + │ │ ) │ └── Get Cosmos Element Response(00000000-0000-0000-0000-000000000000) Json-Component 00:00:00:000 0.00 milliseconds └── FeedIterator Read Next Async(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds │ ( @@ -1566,14 +1625,15 @@ │ │ [System Info] │ │ Redacted To Not Change The Baselines From Run To Run │ │ ) - │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ ( - │ [Client Side Request Stats] - │ Redacted To Not Change The Baselines From Run To Run - │ ) + │ └── Microsoft.Azure.Cosmos.Handlers.TelemetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ ( + │ [Client Side Request Stats] + │ Redacted To Not Change The Baselines From Run To Run + │ ) └── Get Cosmos Element Response(00000000-0000-0000-0000-000000000000) Json-Component 00:00:00:000 0.00 milliseconds ]]> @@ -2366,23 +2454,29 @@ }, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.TelemetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", "duration in milliseconds": 0, - "data": { - "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" - } + "children": [ + { + "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "duration in milliseconds": 0, + "data": { + "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" + } + } + ] } ] } @@ -2464,23 +2558,29 @@ }, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.TelemetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", "duration in milliseconds": 0, - "data": { - "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" - } + "children": [ + { + "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "duration in milliseconds": 0, + "data": { + "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" + } + } + ] } ] } @@ -2562,23 +2662,29 @@ }, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.TelemetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", "duration in milliseconds": 0, - "data": { - "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" - } + "children": [ + { + "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "duration in milliseconds": 0, + "data": { + "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" + } + } + ] } ] } @@ -2660,23 +2766,29 @@ }, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.TelemetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", "duration in milliseconds": 0, - "data": { - "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" - } + "children": [ + { + "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "duration in milliseconds": 0, + "data": { + "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" + } + } + ] } ] } @@ -2862,16 +2974,17 @@ │ │ │ │ [System Info] │ │ │ │ Redacted To Not Change The Baselines From Run To Run │ │ │ │ ) - │ │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ │ └── Microsoft.Azure.Cosmos.GatewayStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ │ │ ( - │ │ │ [Client Side Request Stats] - │ │ │ Redacted To Not Change The Baselines From Run To Run - │ │ │ [PointOperationStatisticsTraceDatum] - │ │ │ Redacted To Not Change The Baselines From Run To Run - │ │ │ ) + │ │ │ └── Microsoft.Azure.Cosmos.Handlers.TelemetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ │ └── Microsoft.Azure.Cosmos.GatewayStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ │ │ ( + │ │ │ [Client Side Request Stats] + │ │ │ Redacted To Not Change The Baselines From Run To Run + │ │ │ [PointOperationStatisticsTraceDatum] + │ │ │ Redacted To Not Change The Baselines From Run To Run + │ │ │ ) │ │ └── Get Partition Key Ranges(00000000-0000-0000-0000-000000000000) Routing-Component 00:00:00:000 0.00 milliseconds │ │ └── Try Get Overlapping Ranges(00000000-0000-0000-0000-000000000000) Routing-Component 00:00:00:000 0.00 milliseconds │ ├── MoveNextAsync(00000000-0000-0000-0000-000000000000) Pagination-Component 00:00:00:000 0.00 milliseconds @@ -2892,14 +3005,15 @@ │ │ │ │ [System Info] │ │ │ │ Redacted To Not Change The Baselines From Run To Run │ │ │ │ ) - │ │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ │ │ ( - │ │ │ [Client Side Request Stats] - │ │ │ Redacted To Not Change The Baselines From Run To Run - │ │ │ ) + │ │ │ └── Microsoft.Azure.Cosmos.Handlers.TelemetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ │ │ ( + │ │ │ [Client Side Request Stats] + │ │ │ Redacted To Not Change The Baselines From Run To Run + │ │ │ ) │ │ └── Get Cosmos Element Response(00000000-0000-0000-0000-000000000000) Json-Component 00:00:00:000 0.00 milliseconds │ └── Query Response Serialization(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds ├── Typed FeedIterator ReadNextAsync(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds @@ -2928,14 +3042,15 @@ │ │ │ │ [System Info] │ │ │ │ Redacted To Not Change The Baselines From Run To Run │ │ │ │ ) - │ │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ │ │ ( - │ │ │ [Client Side Request Stats] - │ │ │ Redacted To Not Change The Baselines From Run To Run - │ │ │ ) + │ │ │ └── Microsoft.Azure.Cosmos.Handlers.TelemetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ │ │ ( + │ │ │ [Client Side Request Stats] + │ │ │ Redacted To Not Change The Baselines From Run To Run + │ │ │ ) │ │ └── Get Cosmos Element Response(00000000-0000-0000-0000-000000000000) Json-Component 00:00:00:000 0.00 milliseconds │ └── Query Response Serialization(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds ├── Typed FeedIterator ReadNextAsync(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds @@ -2964,14 +3079,15 @@ │ │ │ │ [System Info] │ │ │ │ Redacted To Not Change The Baselines From Run To Run │ │ │ │ ) - │ │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ │ │ ( - │ │ │ [Client Side Request Stats] - │ │ │ Redacted To Not Change The Baselines From Run To Run - │ │ │ ) + │ │ │ └── Microsoft.Azure.Cosmos.Handlers.TelemetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ │ │ ( + │ │ │ [Client Side Request Stats] + │ │ │ Redacted To Not Change The Baselines From Run To Run + │ │ │ ) │ │ └── Get Cosmos Element Response(00000000-0000-0000-0000-000000000000) Json-Component 00:00:00:000 0.00 milliseconds │ └── Query Response Serialization(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds └── Typed FeedIterator ReadNextAsync(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds @@ -3000,14 +3116,15 @@ │ │ │ [System Info] │ │ │ Redacted To Not Change The Baselines From Run To Run │ │ │ ) - │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ │ ( - │ │ [Client Side Request Stats] - │ │ Redacted To Not Change The Baselines From Run To Run - │ │ ) + │ │ └── Microsoft.Azure.Cosmos.Handlers.TelemetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ │ ( + │ │ [Client Side Request Stats] + │ │ Redacted To Not Change The Baselines From Run To Run + │ │ ) │ └── Get Cosmos Element Response(00000000-0000-0000-0000-000000000000) Json-Component 00:00:00:000 0.00 milliseconds └── Query Response Serialization(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds ]]> @@ -3059,24 +3176,30 @@ }, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.TelemetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.GatewayStoreModel Transport Request", + "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", "duration in milliseconds": 0, - "data": { - "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run", - "PointOperationStatisticsTraceDatum": "Redacted To Not Change The Baselines From Run To Run" - } + "children": [ + { + "name": "Microsoft.Azure.Cosmos.GatewayStoreModel Transport Request", + "duration in milliseconds": 0, + "data": { + "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run", + "PointOperationStatisticsTraceDatum": "Redacted To Not Change The Baselines From Run To Run" + } + } + ] } ] } @@ -3147,23 +3270,29 @@ }, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.TelemetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", "duration in milliseconds": 0, - "data": { - "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" - } + "children": [ + { + "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "duration in milliseconds": 0, + "data": { + "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" + } + } + ] } ] } @@ -3245,23 +3374,29 @@ }, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.TelemetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", "duration in milliseconds": 0, - "data": { - "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" - } + "children": [ + { + "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "duration in milliseconds": 0, + "data": { + "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" + } + } + ] } ] } @@ -3343,23 +3478,29 @@ }, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.TelemetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", "duration in milliseconds": 0, - "data": { - "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" - } + "children": [ + { + "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "duration in milliseconds": 0, + "data": { + "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" + } + } + ] } ] } @@ -3441,23 +3582,29 @@ }, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.TelemetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", "duration in milliseconds": 0, - "data": { - "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" - } + "children": [ + { + "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "duration in milliseconds": 0, + "data": { + "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" + } + } + ] } ] } @@ -3653,14 +3800,15 @@ │ │ │ [System Info] │ │ │ Redacted To Not Change The Baselines From Run To Run │ │ │ ) - │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ │ ( - │ │ [Client Side Request Stats] - │ │ Redacted To Not Change The Baselines From Run To Run - │ │ ) + │ │ └── Microsoft.Azure.Cosmos.Handlers.TelemetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ │ ( + │ │ [Client Side Request Stats] + │ │ Redacted To Not Change The Baselines From Run To Run + │ │ ) │ └── Get Cosmos Element Response(00000000-0000-0000-0000-000000000000) Json-Component 00:00:00:000 0.00 milliseconds ├── FeedIterator Read Next Async(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds │ │ ( @@ -3688,14 +3836,15 @@ │ │ │ [System Info] │ │ │ Redacted To Not Change The Baselines From Run To Run │ │ │ ) - │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ │ ( - │ │ [Client Side Request Stats] - │ │ Redacted To Not Change The Baselines From Run To Run - │ │ ) + │ │ └── Microsoft.Azure.Cosmos.Handlers.TelemetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ │ ( + │ │ [Client Side Request Stats] + │ │ Redacted To Not Change The Baselines From Run To Run + │ │ ) │ └── Get Cosmos Element Response(00000000-0000-0000-0000-000000000000) Json-Component 00:00:00:000 0.00 milliseconds ├── FeedIterator Read Next Async(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds │ │ ( @@ -3723,14 +3872,15 @@ │ │ │ [System Info] │ │ │ Redacted To Not Change The Baselines From Run To Run │ │ │ ) - │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ │ ( - │ │ [Client Side Request Stats] - │ │ Redacted To Not Change The Baselines From Run To Run - │ │ ) + │ │ └── Microsoft.Azure.Cosmos.Handlers.TelemetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ │ ( + │ │ [Client Side Request Stats] + │ │ Redacted To Not Change The Baselines From Run To Run + │ │ ) │ └── Get Cosmos Element Response(00000000-0000-0000-0000-000000000000) Json-Component 00:00:00:000 0.00 milliseconds └── FeedIterator Read Next Async(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds │ ( @@ -3758,14 +3908,15 @@ │ │ [System Info] │ │ Redacted To Not Change The Baselines From Run To Run │ │ ) - │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ ( - │ [Client Side Request Stats] - │ Redacted To Not Change The Baselines From Run To Run - │ ) + │ └── Microsoft.Azure.Cosmos.Handlers.TelemetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ ( + │ [Client Side Request Stats] + │ Redacted To Not Change The Baselines From Run To Run + │ ) └── Get Cosmos Element Response(00000000-0000-0000-0000-000000000000) Json-Component 00:00:00:000 0.00 milliseconds ]]> @@ -4573,23 +4752,29 @@ }, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.TelemetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", "duration in milliseconds": 0, - "data": { - "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" - } + "children": [ + { + "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "duration in milliseconds": 0, + "data": { + "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" + } + } + ] } ] } @@ -4671,23 +4856,29 @@ }, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.TelemetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", "duration in milliseconds": 0, - "data": { - "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" - } + "children": [ + { + "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "duration in milliseconds": 0, + "data": { + "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" + } + } + ] } ] } @@ -4769,23 +4960,29 @@ }, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.TelemetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", "duration in milliseconds": 0, - "data": { - "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" - } + "children": [ + { + "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "duration in milliseconds": 0, + "data": { + "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" + } + } + ] } ] } @@ -4867,23 +5064,29 @@ }, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.TelemetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RetryHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", + "name": "Microsoft.Azure.Cosmos.Handlers.RouterHandler", "duration in milliseconds": 0, "children": [ { - "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "name": "Microsoft.Azure.Cosmos.Handlers.TransportHandler", "duration in milliseconds": 0, - "data": { - "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" - } + "children": [ + { + "name": "Microsoft.Azure.Documents.ServerStoreModel Transport Request", + "duration in milliseconds": 0, + "data": { + "Client Side Request Stats": "Redacted To Not Change The Baselines From Run To Run" + } + } + ] } ] } diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/BaselineTest/TestBaseline/EndToEndTraceWriterBaselineTests.ReadFeedAsync.xml b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/BaselineTest/TestBaseline/EndToEndTraceWriterBaselineTests.ReadFeedAsync.xml index 86f16841b5..60f1b42df3 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/BaselineTest/TestBaseline/EndToEndTraceWriterBaselineTests.ReadFeedAsync.xml +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/BaselineTest/TestBaseline/EndToEndTraceWriterBaselineTests.ReadFeedAsync.xml @@ -54,14 +54,15 @@ │ │ [System Info] │ │ Redacted To Not Change The Baselines From Run To Run │ │ ) - │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ ( - │ [Client Side Request Stats] - │ Redacted To Not Change The Baselines From Run To Run - │ ) + │ └── Microsoft.Azure.Cosmos.Handlers.TelemetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ ( + │ [Client Side Request Stats] + │ Redacted To Not Change The Baselines From Run To Run + │ ) ├── FeedIterator Read Next Async(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds │ │ ( │ │ [Client Configuration] @@ -81,14 +82,15 @@ │ │ [System Info] │ │ Redacted To Not Change The Baselines From Run To Run │ │ ) - │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ ( - │ [Client Side Request Stats] - │ Redacted To Not Change The Baselines From Run To Run - │ ) + │ └── Microsoft.Azure.Cosmos.Handlers.TelemetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ ( + │ [Client Side Request Stats] + │ Redacted To Not Change The Baselines From Run To Run + │ ) ├── FeedIterator Read Next Async(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds │ │ ( │ │ [Client Configuration] @@ -108,14 +110,15 @@ │ │ [System Info] │ │ Redacted To Not Change The Baselines From Run To Run │ │ ) - │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - │ ( - │ [Client Side Request Stats] - │ Redacted To Not Change The Baselines From Run To Run - │ ) + │ └── Microsoft.Azure.Cosmos.Handlers.TelemetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + │ └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + │ ( + │ [Client Side Request Stats] + │ Redacted To Not Change The Baselines From Run To Run + │ ) └── FeedIterator Read Next Async(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds │ ( │ [Client Configuration] @@ -135,14 +138,15 @@ │ [System Info] │ Redacted To Not Change The Baselines From Run To Run │ ) - └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds - └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds - ( - [Client Side Request Stats] - Redacted To Not Change The Baselines From Run To Run - ) + └── Microsoft.Azure.Cosmos.Handlers.TelemetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + └── Microsoft.Azure.Cosmos.Handlers.RetryHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + └── Microsoft.Azure.Cosmos.Handlers.RouterHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + └── Microsoft.Azure.Cosmos.Handlers.TransportHandler(00000000-0000-0000-0000-000000000000) RequestHandler-Component 00:00:00:000 0.00 milliseconds + └── Microsoft.Azure.Documents.ServerStoreModel Transport Request(00000000-0000-0000-0000-000000000000) Transport-Component 00:00:00:000 0.00 milliseconds + ( + [Client Side Request Stats] + Redacted To Not Change The Baselines From Run To Run + ) ]]> + + + + doc.StringField.RegexMatch("abcd"))]]> + + + + + + + + + doc.StringField.RegexMatch("abcd", "i"))]]> + + + + + + + + + doc.StringField.RegexMatch(doc.StringField2))]]> + + + + + + + + + doc.StringField.RegexMatch(doc.IntField.ToString()))]]> + + + + + + + + + doc.StringField.RegexMatch(doc.StringField2.ToUpper()))]]> + + + + + + + + + doc.StringField.RegexMatch(doc.StringField2.ToLower()))]]> + + + + + + + + + doc.StringField.RegexMatch(Concat(doc.StringField, "str")))]]> + + + + + + + + + doc.IntField.ToString().RegexMatch(doc.StringField))]]> + + + + + + + + + doc.IntField.ToString().RegexMatch(doc.StringField, doc.StringField2.ToString()))]]> + + + + + + + + + (doc.StringField.RegexMatch("abc") AndAlso doc.StringField2.RegexMatch("def")))]]> + + + + + + + + + (doc.StringField.RegexMatch("abc") OrElse doc.StringField2.RegexMatch("def")))]]> + + + + + + + + + doc.StringField.RegexMatch("abc")).Where(doc => doc.StringField2.RegexMatch("abc"))]]> + + + + + + + + + doc.StringField.RegexMatch("abc")).Where(doc => Not(doc.StringField2.RegexMatch("abc")))]]> + + + + + + + + + doc.StringField.RegexMatch("abcd", "this should error out on the back end"))]]> + + + + + + \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/BaselineTest/TestBaseline/LinqTranslationBaselineTests.TestStringCompare.xml b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/BaselineTest/TestBaseline/LinqTranslationBaselineTests.TestStringCompare.xml index 17538ff1d8..e737413eed 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/BaselineTest/TestBaseline/LinqTranslationBaselineTests.TestStringCompare.xml +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/BaselineTest/TestBaseline/LinqTranslationBaselineTests.TestStringCompare.xml @@ -5,11 +5,9 @@ (Compare(doc.StringField, doc.StringField2) == 0))]]> - - - + @@ -18,11 +16,9 @@ FROM root]]> (Compare(doc.StringField, doc.StringField2) > 0))]]> - - root["StringField2"]) -FROM root]]> - + root["StringField2"]) +FROM root]]> @@ -31,11 +27,9 @@ FROM root]]> (Compare(doc.StringField, doc.StringField2) >= 0))]]> - - = root["StringField2"]) -FROM root]]> - + = root["StringField2"]) +FROM root]]> @@ -44,11 +38,9 @@ FROM root]]> (Compare(doc.StringField, doc.StringField2) < 0))]]> - - - + @@ -57,11 +49,9 @@ FROM root]]> (Compare(doc.StringField, doc.StringField2) <= 0))]]> - - - + @@ -70,11 +60,9 @@ FROM root]]> (Compare(doc.StringField, "str") == 0))]]> - - - + @@ -83,11 +71,9 @@ FROM root]]> (Compare(doc.StringField, "str") > 0))]]> - - "str") -FROM root]]> - + "str") +FROM root]]> @@ -96,11 +82,9 @@ FROM root]]> (Compare(doc.StringField, "str") >= 0))]]> - - = "str") -FROM root]]> - + = "str") +FROM root]]> @@ -109,11 +93,9 @@ FROM root]]> (Compare(doc.StringField, "str") < 0))]]> - - - + @@ -122,11 +104,9 @@ FROM root]]> (Compare(doc.StringField, "str") <= 0))]]> - - - + @@ -135,11 +115,9 @@ FROM root]]> (0 == Compare(doc.StringField, doc.StringField2)))]]> - - - + @@ -148,11 +126,9 @@ FROM root]]> (0 < Compare(doc.StringField, doc.StringField2)))]]> - - root["StringField2"]) -FROM root]]> - + root["StringField2"]) +FROM root]]> @@ -161,11 +137,9 @@ FROM root]]> (0 <= Compare(doc.StringField, doc.StringField2)))]]> - - = root["StringField2"]) -FROM root]]> - + = root["StringField2"]) +FROM root]]> @@ -174,11 +148,9 @@ FROM root]]> (0 > Compare(doc.StringField, doc.StringField2)))]]> - - - + @@ -187,11 +159,9 @@ FROM root]]> (0 >= Compare(doc.StringField, doc.StringField2)))]]> - - - + diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/BaselineTest/TestBaseline/LinqTranslationWithCustomSerializerBaseline.TestMemberInitializerDataMember.xml b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/BaselineTest/TestBaseline/LinqTranslationWithCustomSerializerBaseline.TestMemberInitializerDataMember.xml new file mode 100644 index 0000000000..6734a125fa --- /dev/null +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/BaselineTest/TestBaseline/LinqTranslationWithCustomSerializerBaseline.TestMemberInitializerDataMember.xml @@ -0,0 +1,236 @@ + + + + + (doc.NumericField == 1))]]> + + + + + + + + + + + (doc == new DataObjectDataMember() {NumericField = 1, StringField = "1"}))]]> + + + + + + + + + + + new DataObjectDataMember() {NumericField = 1, StringField = "1"})]]> + + + + + + + + + + + IIF((doc.NumericField > 1), new DataObjectDataMember() {NumericField = 1, StringField = "1"}, new DataObjectDataMember() {NumericField = 1, StringField = "1"}))]]> + + + 1) ? {"NumericFieldDataMember": 1, "StringFieldDataMember": "1", "id": null, "Pk": null} : {"NumericFieldDataMember": 1, "StringFieldDataMember": "1", "id": null, "Pk": null}) +FROM root]]> + + + + + + + + (doc == new DataObjectDataMember() {NumericField = doc.NumericField, StringField = doc.StringField})).Select(b => "A")]]> + + + + + + + + + + + (doc.NumericField == 1))]]> + + + + + + + + + + + (doc == new DataObjectDataMember() {NumericField = 1, StringField = "1"}))]]> + + + + + + + + + + + new DataObjectDataMember() {NumericField = 1, StringField = "1"})]]> + + + + + + + + + + + IIF((doc.NumericField > 1), new DataObjectDataMember() {NumericField = 1, StringField = "1"}, new DataObjectDataMember() {NumericField = 1, StringField = "1"}))]]> + + + 1) ? {"NumericFieldDataMember": 1, "StringFieldDataMember": "1", "id": null, "Pk": null} : {"NumericFieldDataMember": 1, "StringFieldDataMember": "1", "id": null, "Pk": null}) +FROM root]]> + + + + + + + + (doc == new DataObjectDataMember() {NumericField = doc.NumericField, StringField = doc.StringField})).Select(b => "A")]]> + + + + + + + + \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/BaselineTest/TestBaseline/LinqTranslationWithCustomSerializerBaseline.TestMemberInitializerDotNet.xml b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/BaselineTest/TestBaseline/LinqTranslationWithCustomSerializerBaseline.TestMemberInitializerDotNet.xml new file mode 100644 index 0000000000..b381e2b651 --- /dev/null +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/BaselineTest/TestBaseline/LinqTranslationWithCustomSerializerBaseline.TestMemberInitializerDotNet.xml @@ -0,0 +1,236 @@ + + + + + (doc.NumericField == 1))]]> + + + + + + + + + + + (doc == new DataObjectDotNet() {NumericField = 1, StringField = "1"}))]]> + + + + + + + + + + + new DataObjectDotNet() {NumericField = 1, StringField = "1"})]]> + + + + + + + + + + + IIF((doc.NumericField > 1), new DataObjectDotNet() {NumericField = 1, StringField = "1"}, new DataObjectDotNet() {NumericField = 1, StringField = "1"}))]]> + + + 1) ? {"NumericField": 1, "StringField": "1", "id": null, "Pk": null} : {"NumericField": 1, "StringField": "1", "id": null, "Pk": null}) +FROM root]]> + + + + + + + + (doc == new DataObjectDotNet() {NumericField = doc.NumericField, StringField = doc.StringField})).Select(b => "A")]]> + + + + + + + + + + + (doc.NumericField == 1))]]> + + + + + + + + + + + (doc == new DataObjectDotNet() {NumericField = 1, StringField = "1"}))]]> + + + + + + + + + + + new DataObjectDotNet() {NumericField = 1, StringField = "1"})]]> + + + + + + + + + + + IIF((doc.NumericField > 1), new DataObjectDotNet() {NumericField = 1, StringField = "1"}, new DataObjectDotNet() {NumericField = 1, StringField = "1"}))]]> + + + 1) ? {"NumericField": 1, "StringField": "1", "id": null, "Pk": null} : {"NumericField": 1, "StringField": "1", "id": null, "Pk": null}) +FROM root]]> + + + + + + + + (doc == new DataObjectDotNet() {NumericField = doc.NumericField, StringField = doc.StringField})).Select(b => "A")]]> + + + + + + + + \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/BaselineTest/TestBaseline/LinqTranslationWithCustomSerializerBaseline.TestMemberInitializerMultiSerializer.xml b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/BaselineTest/TestBaseline/LinqTranslationWithCustomSerializerBaseline.TestMemberInitializerMultiSerializer.xml new file mode 100644 index 0000000000..704eb39807 --- /dev/null +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/BaselineTest/TestBaseline/LinqTranslationWithCustomSerializerBaseline.TestMemberInitializerMultiSerializer.xml @@ -0,0 +1,236 @@ + + + + + (doc.NumericField == 1))]]> + + + + + + + + + + + (doc == new DataObjectMultiSerializer() {NumericField = 1, StringField = "1"}))]]> + + + + + + + + + + + new DataObjectMultiSerializer() {NumericField = 1, StringField = "1"})]]> + + + + + + + + + + + IIF((doc.NumericField > 1), new DataObjectMultiSerializer() {NumericField = 1, StringField = "1"}, new DataObjectMultiSerializer() {NumericField = 1, StringField = "1"}))]]> + + + 1) ? {"NumberValueNewtonsoft": 1, "StringValueNewtonsoft": "1", "id": null, "Pk": null} : {"NumberValueNewtonsoft": 1, "StringValueNewtonsoft": "1", "id": null, "Pk": null}) +FROM root]]> + + + + + + + + (doc == new DataObjectMultiSerializer() {NumericField = doc.NumericField, StringField = doc.StringField})).Select(b => "A")]]> + + + + + + + + + + + (doc.NumericField == 1))]]> + + + + + + + + + + + (doc == new DataObjectMultiSerializer() {NumericField = 1, StringField = "1"}))]]> + + + + + + + + + + + new DataObjectMultiSerializer() {NumericField = 1, StringField = "1"})]]> + + + + + + + + + + + IIF((doc.NumericField > 1), new DataObjectMultiSerializer() {NumericField = 1, StringField = "1"}, new DataObjectMultiSerializer() {NumericField = 1, StringField = "1"}))]]> + + + 1) ? {"NumberValueNewtonsoft": 1, "StringValueNewtonsoft": "1", "id": null, "Pk": null} : {"NumberValueNewtonsoft": 1, "StringValueNewtonsoft": "1", "id": null, "Pk": null}) +FROM root]]> + + + + + + + + (doc == new DataObjectMultiSerializer() {NumericField = doc.NumericField, StringField = doc.StringField})).Select(b => "A")]]> + + + + + + + + \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/BaselineTest/TestBaseline/LinqTranslationWithCustomSerializerBaseline.TestMemberInitializerNewtonsoft.xml b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/BaselineTest/TestBaseline/LinqTranslationWithCustomSerializerBaseline.TestMemberInitializerNewtonsoft.xml new file mode 100644 index 0000000000..b5b16752cc --- /dev/null +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/BaselineTest/TestBaseline/LinqTranslationWithCustomSerializerBaseline.TestMemberInitializerNewtonsoft.xml @@ -0,0 +1,236 @@ + + + + + (doc.NumericField == 1))]]> + + + + + + + + + + + (doc == new DataObjectNewtonsoft() {NumericField = 1, StringField = "1"}))]]> + + + + + + + + + + + new DataObjectNewtonsoft() {NumericField = 1, StringField = "1"})]]> + + + + + + + + + + + IIF((doc.NumericField > 1), new DataObjectNewtonsoft() {NumericField = 1, StringField = "1"}, new DataObjectNewtonsoft() {NumericField = 1, StringField = "1"}))]]> + + + 1) ? {"NumberValueNewtonsoft": 1, "StringValueNewtonsoft": "1", "id": null, "Pk": null} : {"NumberValueNewtonsoft": 1, "StringValueNewtonsoft": "1", "id": null, "Pk": null}) +FROM root]]> + + + + + + + + (doc == new DataObjectNewtonsoft() {NumericField = doc.NumericField, StringField = doc.StringField})).Select(b => "A")]]> + + + + + + + + + + + (doc.NumericField == 1))]]> + + + + + + + + + + + (doc == new DataObjectNewtonsoft() {NumericField = 1, StringField = "1"}))]]> + + + + + + + + + + + new DataObjectNewtonsoft() {NumericField = 1, StringField = "1"})]]> + + + + + + + + + + + IIF((doc.NumericField > 1), new DataObjectNewtonsoft() {NumericField = 1, StringField = "1"}, new DataObjectNewtonsoft() {NumericField = 1, StringField = "1"}))]]> + + + 1) ? {"NumberValueNewtonsoft": 1, "StringValueNewtonsoft": "1", "id": null, "Pk": null} : {"NumberValueNewtonsoft": 1, "StringValueNewtonsoft": "1", "id": null, "Pk": null}) +FROM root]]> + + + + + + + + (doc == new DataObjectNewtonsoft() {NumericField = doc.NumericField, StringField = doc.StringField})).Select(b => "A")]]> + + + + + + + + \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/ClientCreateAndInitializeTest.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/ClientCreateAndInitializeTest.cs index e07fe85a7e..8bbb7f5d54 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/ClientCreateAndInitializeTest.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/ClientCreateAndInitializeTest.cs @@ -276,10 +276,9 @@ public async Task CreateAndInitializeAsync_WithValidDatabaseAndContainer_ShouldO .GetValue(loadBalancingPartition); Assert.IsNotNull(openChannels); - Assert.AreEqual(48, openChannels.Count, "Here the expected value 48 rather explains how many time we call the" + - "LoadBalancingPartition.OpenChannelAsync(). The emulator by default returns 12 partitions, and each partition has 4 replicas," + - "and by behavior the emulator uses the same URI for eac of these replica, hence 12 * 4 = 48 times we call the OpenChannelAsync()." + - "In ideal world, the value should be 1, because for each unique URI, the OpenChannelAsync() call will just be 1."); + Assert.AreEqual(1, openChannels.Count, "Here the expected value 1 explains how many TCP connections were opened by the LoadBalancingPartition.OpenChannelAsync()." + + "The emulator by default returns 12 partitions, and each partition has 4 replicas, and by behavior the emulator uses the same URI for each of these replica," + + "hence 12 * 4 = 48 times we call the OpenChannelAsync(). However, the number of TCP connections established would be just one per each unique endpoint."); Assert.AreEqual(openChannels.Count * maxRequestsPerConnection, channelCapacity); Documents.Rntbd.LbChannelState channelState = openChannels.First(); diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/ClientTelemetryConfigurationTest.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/ClientTelemetryConfigurationTest.cs new file mode 100644 index 0000000000..9447191a90 --- /dev/null +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/ClientTelemetryConfigurationTest.cs @@ -0,0 +1,274 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.SDK.EmulatorTests +{ + using System.Net.Http; + using System.Net; + using System.Text; + using System.Threading.Tasks; + using Microsoft.VisualStudio.TestTools.UnitTesting; + using Newtonsoft.Json; + using Microsoft.Azure.Cosmos.Fluent; + using System; + using Microsoft.Azure.Cosmos.Routing; + using System.Reflection; + using System.Threading; + using Microsoft.Azure.Cosmos.Telemetry; + + [TestClass] + public class ClientTelemetryConfigurationTest : BaseCosmosClientHelper + { + private const string EndpointUrl = "http://dummy.test.com/"; + private CosmosClientBuilder cosmosClientBuilder; + + private readonly TimeSpan OriginalDefaultBackgroundRefreshClientConfigTimeInterval = TelemetryToServiceHelper.DefaultBackgroundRefreshClientConfigTimeInterval; + + [TestInitialize] + public void TestInitialize() + { + TelemetryToServiceHelper.DefaultBackgroundRefreshClientConfigTimeInterval + = TimeSpan.FromMilliseconds(100); + + this.cosmosClientBuilder = TestCommon.GetDefaultConfiguration(); + } + + [TestCleanup] + public async Task Cleanup() + { + await base.TestCleanup(); + + // Resetting time intervals + TelemetryToServiceHelper.DefaultBackgroundRefreshClientConfigTimeInterval + = this.OriginalDefaultBackgroundRefreshClientConfigTimeInterval; + } + + [TestMethod] + public async Task Validate_ClientTelemetryJob_Status_if_Disabled_At_Instance_LevelAsync() + { + HttpClientHandlerHelper httpHandler = new HttpClientHandlerHelper + { + RequestCallBack = (request, cancellation) => + { + if (request.RequestUri.AbsoluteUri.Equals(EndpointUrl)) + { + HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK); + return Task.FromResult(result); + } + else if (request.RequestUri.AbsoluteUri.Contains(Documents.Paths.ClientConfigPathSegment)) + { + HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK); + + AccountClientConfiguration clientConfigProperties = new AccountClientConfiguration + { + ClientTelemetryConfiguration = new ClientTelemetryConfiguration + { + IsEnabled = true, + Endpoint = EndpointUrl + } + }; + + string payload = JsonConvert.SerializeObject(clientConfigProperties); + result.Content = new StringContent(payload, Encoding.UTF8, "application/json"); + + return Task.FromResult(result); + } + return null; + } + }; + + this.cosmosClientBuilder + .WithHttpClientFactory(() => new HttpClient(httpHandler)) + .WithClientTelemetryOptions(new CosmosClientTelemetryOptions() + { + DisableSendingMetricsToService = true + }); + + this.SetClient(this.cosmosClientBuilder.Build()); + + this.database = await this.GetClient().CreateDatabaseAsync(Guid.NewGuid().ToString()); + + DocumentClient documentClient = this.GetClient().DocumentClient; + + Assert.IsNotNull(documentClient.telemetryToServiceHelper); + Assert.IsFalse(documentClient.telemetryToServiceHelper.IsClientTelemetryJobRunning()); + + ClientCollectionCache collCache = (ClientCollectionCache)documentClient + .GetType() + .GetField("collectionCache", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static) + .GetValue(documentClient); + + TelemetryToServiceHelper telemetryToServiceHelper = (TelemetryToServiceHelper)collCache + .GetType() + .GetField("telemetryToServiceHelper", BindingFlags.Instance | BindingFlags.NonPublic) + .GetValue(collCache); + + Assert.IsNotNull(telemetryToServiceHelper); + Assert.IsFalse(telemetryToServiceHelper.IsClientTelemetryJobRunning()); + } + + [TestMethod] + [DataRow(true, HttpStatusCode.OK)] + [DataRow(false, HttpStatusCode.OK)] + [DataRow(false, HttpStatusCode.BadRequest)] // Errored Client Config API + public async Task Validate_ClientTelemetryJob_Status_with_Client_Config_Api_States_Async(bool clientTelemetryFlagEnabled, HttpStatusCode clientConfigApiStatus) + { + HttpClientHandlerHelper httpHandler = new HttpClientHandlerHelper + { + RequestCallBack = (request, cancellation) => + { + if (request.RequestUri.AbsoluteUri.Equals(EndpointUrl)) + { + HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK); + return Task.FromResult(result); + } + else if (request.RequestUri.AbsoluteUri.Contains(Documents.Paths.ClientConfigPathSegment)) + { + HttpResponseMessage result = new HttpResponseMessage(clientConfigApiStatus); + + AccountClientConfiguration clientConfigProperties = new AccountClientConfiguration + { + ClientTelemetryConfiguration = new ClientTelemetryConfiguration + { + IsEnabled = clientTelemetryFlagEnabled, + Endpoint = clientTelemetryFlagEnabled ? EndpointUrl : null + } + }; + + string payload = JsonConvert.SerializeObject(clientConfigProperties); + result.Content = new StringContent(payload, Encoding.UTF8, "application/json"); + + return Task.FromResult(result); + } + return null; + } + }; + + this.cosmosClientBuilder + .WithHttpClientFactory(() => new HttpClient(httpHandler)) + .WithClientTelemetryOptions(new CosmosClientTelemetryOptions() + { + DisableSendingMetricsToService = false + }); + + this.SetClient(this.cosmosClientBuilder.Build()); + + this.database = await this.GetClient().CreateDatabaseAsync(Guid.NewGuid().ToString()); + + DocumentClient documentClient = this.GetClient().DocumentClient; + + ClientCollectionCache collCache = (ClientCollectionCache)documentClient + .GetType() + .GetField("collectionCache", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static) + .GetValue(documentClient); + + TelemetryToServiceHelper telemetryToServiceHelperFromCollectionCache = (TelemetryToServiceHelper)collCache + .GetType() + .GetField("telemetryToServiceHelper", BindingFlags.Instance | BindingFlags.NonPublic) + .GetValue(collCache); + + Assert.AreEqual(clientTelemetryFlagEnabled, documentClient.telemetryToServiceHelper.IsClientTelemetryJobRunning()); + Assert.AreEqual(clientTelemetryFlagEnabled, telemetryToServiceHelperFromCollectionCache.IsClientTelemetryJobRunning()); + } + + [TestMethod] + [DataRow(true, false, HttpStatusCode.OK)] + [DataRow(false, true, HttpStatusCode.OK)] + [DataRow(true, false, HttpStatusCode.BadRequest)] + [DataRow(false, true, HttpStatusCode.BadRequest)] + public async Task Validate_ClientTelemetryJob_When_Flag_Is_Switched(bool flagState1, bool flagState2, HttpStatusCode clientConfigApiStatusAfterSwitch) + { + using ManualResetEvent manualResetEvent = new ManualResetEvent(false); + + int counter = 0; + HttpClientHandlerHelper httpHandler = new HttpClientHandlerHelper + { + RequestCallBack = (request, cancellation) => + { + if (request.RequestUri.AbsoluteUri.Contains(Documents.Paths.ClientConfigPathSegment)) + { + if (counter == 10) + { + manualResetEvent.Set(); + } + + counter++; + + bool isEnabled = counter < 5 ? flagState1 : flagState2; + HttpStatusCode apiStatusCode = counter < 5 ? HttpStatusCode.OK : clientConfigApiStatusAfterSwitch; + + HttpResponseMessage result = new HttpResponseMessage(apiStatusCode); + string payload = JsonConvert.SerializeObject(new AccountClientConfiguration + { + ClientTelemetryConfiguration = new ClientTelemetryConfiguration + { + IsEnabled = isEnabled, + Endpoint = isEnabled ? EndpointUrl : null + } + }); + result.Content = new StringContent(payload, Encoding.UTF8, "application/json"); + + return Task.FromResult(result); + } + + return null; + } + }; + + this.cosmosClientBuilder + .WithHttpClientFactory(() => new HttpClient(httpHandler)) + .WithClientTelemetryOptions(new CosmosClientTelemetryOptions() + { + DisableSendingMetricsToService = false + }); + + this.SetClient(this.cosmosClientBuilder.Build()); + + this.database = await this.GetClient() + .CreateDatabaseAsync(Guid.NewGuid().ToString()); + + DocumentClient documentClient = this.GetClient().DocumentClient; + + ClientCollectionCache collCache = (ClientCollectionCache)documentClient + .GetType() + .GetField("collectionCache", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static) + .GetValue(documentClient); + + TelemetryToServiceHelper telemetryToServiceHelperFromCollectionCache + = (TelemetryToServiceHelper)collCache + .GetType() + .GetField("telemetryToServiceHelper", BindingFlags.Instance | BindingFlags.NonPublic) + .GetValue(collCache); + + Assert.AreEqual(flagState1, documentClient.telemetryToServiceHelper.IsClientTelemetryJobRunning()); + Assert.AreEqual(flagState1, telemetryToServiceHelperFromCollectionCache.IsClientTelemetryJobRunning()); + + manualResetEvent.WaitOne(TimeSpan.FromSeconds(1)); + + collCache = (ClientCollectionCache)documentClient + .GetType() + .GetField("collectionCache", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static) + .GetValue(documentClient); + + telemetryToServiceHelperFromCollectionCache = (TelemetryToServiceHelper)collCache + .GetType() + .GetField("telemetryToServiceHelper", BindingFlags.Instance | BindingFlags.NonPublic) + .GetValue(collCache); + + if (clientConfigApiStatusAfterSwitch == HttpStatusCode.OK) + { + Assert.AreEqual(flagState2, documentClient.telemetryToServiceHelper.IsClientTelemetryJobRunning()); + Assert.AreEqual(flagState2, telemetryToServiceHelperFromCollectionCache.IsClientTelemetryJobRunning()); + } + else + { + // If the client config api errored out, the flag should not be changed + Assert.AreEqual(flagState1, documentClient.telemetryToServiceHelper.IsClientTelemetryJobRunning()); + Assert.AreEqual(flagState1, telemetryToServiceHelperFromCollectionCache.IsClientTelemetryJobRunning()); + } + + + } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/ClientTelemetryReleaseTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/ClientTelemetryReleaseTests.cs new file mode 100644 index 0000000000..07230e63a8 --- /dev/null +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/ClientTelemetryReleaseTests.cs @@ -0,0 +1,157 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.SDK.EmulatorTests +{ + using System.Net.Http; + using System.Threading.Tasks; + using Microsoft.Azure.Cosmos.Fluent; + using Microsoft.VisualStudio.TestTools.UnitTesting; + + /// + /// In Release pipeline, no need to mock Client Telemetry Service Call and Test will talk to the real database account. + /// If you are making changes in this file please make sure you are adding similar test in also. + /// + [TestClass] + [TestCategory("ClientTelemetryRelease")] + public class ClientTelemetryReleaseTests : ClientTelemetryTestsBase + { + public override CosmosClientBuilder GetBuilder() + { + string connectionString = ConfigurationManager.GetEnvironmentVariable("COSMOSDB_ACCOUNT_CONNECTION_STRING", null); + return new CosmosClientBuilder(connectionString: connectionString); + } + + /// + /// Returing null means do not return any hard codd response for any HTTP call. + /// + /// + /// + public override Task HttpHandlerRequestCallbackChecks(HttpRequestMessage request) + { + return null; + } + + [ClassInitialize] + public static void ClassInit(TestContext context) + { + ClientTelemetryTestsBase.ClassInitialize(context); + } + + [ClassCleanup] + public static void ClassCleanUp() + { + ClientTelemetryTestsBase.ClassCleanup(); + } + + [TestInitialize] + public override void TestInitialize() + { + base.TestInitialize(); + } + + [TestCleanup] + public override async Task Cleanup() + { + await base.Cleanup(); + } + + [TestMethod] + [DataRow(ConnectionMode.Direct, true)] + [DataRow(ConnectionMode.Gateway, true)] + [DataRow(ConnectionMode.Direct, false)] + [DataRow(ConnectionMode.Gateway, false)] + public override async Task PointSuccessOperationsTest(ConnectionMode mode, bool isAzureInstance) + { + await base.PointSuccessOperationsTest(mode, isAzureInstance); + } + + [TestMethod] + [DataRow(ConnectionMode.Direct)] + [DataRow(ConnectionMode.Gateway)] + public override async Task PointReadFailureOperationsTest(ConnectionMode mode) + { + await base.PointReadFailureOperationsTest(mode); + } + + [TestMethod] + [DataRow(ConnectionMode.Direct)] + [DataRow(ConnectionMode.Gateway)] + public override async Task StreamReadFailureOperationsTest(ConnectionMode mode) + { + await base.StreamReadFailureOperationsTest(mode); + } + + [TestMethod] + [DataRow(ConnectionMode.Direct)] + [DataRow(ConnectionMode.Gateway)] + public override async Task StreamOperationsTest(ConnectionMode mode) + { + await base.StreamOperationsTest(mode); + } + + [TestMethod] + [DataRow(ConnectionMode.Direct)] + [DataRow(ConnectionMode.Gateway)] + public override async Task BatchOperationsTest(ConnectionMode mode) + { + await base.BatchOperationsTest(mode); + } + + [TestMethod] + [DataRow(ConnectionMode.Direct)] + [DataRow(ConnectionMode.Gateway)] + public override async Task SingleOperationMultipleTimesTest(ConnectionMode mode) + { + await base.SingleOperationMultipleTimesTest(mode); + } + + [TestMethod] + [DataRow(ConnectionMode.Direct)] + [DataRow(ConnectionMode.Gateway)] + public override async Task QueryOperationSinglePartitionTest(ConnectionMode mode) + { + await base.QueryOperationSinglePartitionTest(mode); + } + + [TestMethod] + [DataRow(ConnectionMode.Direct)] + [DataRow(ConnectionMode.Gateway)] + public override async Task QueryMultiPageSinglePartitionOperationTest(ConnectionMode mode) + { + await base.QueryMultiPageSinglePartitionOperationTest(mode); + } + + [TestMethod] + [DataRow(ConnectionMode.Direct)] + [DataRow(ConnectionMode.Gateway)] + public override async Task QueryOperationCrossPartitionTest(ConnectionMode mode) + { + await base.QueryOperationCrossPartitionTest(mode); + } + + [TestMethod] + [DataRow(ConnectionMode.Direct)] + [DataRow(ConnectionMode.Gateway)] + public override async Task QueryOperationMutiplePageCrossPartitionTest(ConnectionMode mode) + { + await base.QueryOperationMutiplePageCrossPartitionTest(mode); + } + + [TestMethod] + [DataRow(ConnectionMode.Direct)] + [DataRow(ConnectionMode.Gateway)] + public override async Task QueryOperationInvalidContinuationTokenTest(ConnectionMode mode) + { + await base.QueryOperationInvalidContinuationTokenTest(mode); + } + + [TestMethod] + [DataRow(ConnectionMode.Direct)] + public override async Task CreateItemWithSubStatusCodeTest(ConnectionMode mode) + { + await base.CreateItemWithSubStatusCodeTest(mode); + } + } +} diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/ClientTelemetryTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/ClientTelemetryTests.cs index 58ce4851a0..aacdffa7ae 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/ClientTelemetryTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/ClientTelemetryTests.cs @@ -4,1121 +4,172 @@ namespace Microsoft.Azure.Cosmos.SDK.EmulatorTests { - using System; - using System.Collections.Generic; - using System.Text; - using System.Threading.Tasks; - using System.Net; - using System.Net.Http; - using System.Reflection; using Microsoft.Azure.Cosmos.Fluent; + using System.Net.Http; + using System.Net; + using System.Threading.Tasks; using Microsoft.VisualStudio.TestTools.UnitTesting; - using Microsoft.Azure.Cosmos.Tracing; - using Microsoft.Azure.Cosmos.Telemetry; - using Microsoft.Azure.Cosmos.Handler; - using Microsoft.Azure.Documents; - using Newtonsoft.Json.Linq; using Newtonsoft.Json; - using Documents.Rntbd; - using System.Globalization; - using System.Linq; - using Cosmos.Util; - using Microsoft.Azure.Cosmos.Telemetry.Models; + using System.Text; + using Microsoft.Azure.Documents; + /// + /// In Emulator Mode, Run test against emulator and mock client telemetry service calls. + /// If you are making changes in this file please make sure you are adding similar test in also. + /// [TestClass] - public class ClientTelemetryTests : BaseCosmosClientHelper + [TestCategory("ClientTelemetryEmulator")] + public class ClientTelemetryTests : ClientTelemetryTestsBase { - private const int scheduledInSeconds = 1; - private static readonly object jsonObject = JsonConvert.DeserializeObject("{\"compute\":{\"azEnvironment\":\"AzurePublicCloud\",\"customData\":\"\",\"isHostCompatibilityLayerVm\":\"false\",\"licenseType\":\"\",\"location\":\"eastus\",\"name\":\"sourabh-testing\",\"offer\":\"UbuntuServer\",\"osProfile\":{\"adminUsername\":\"azureuser\",\"computerName\":\"sourabh-testing\"},\"osType\":\"Linux\",\"placementGroupId\":\"\",\"plan\":{\"name\":\"\",\"product\":\"\",\"publisher\":\"\"},\"platformFaultDomain\":\"0\",\"platformUpdateDomain\":\"0\",\"provider\":\"Microsoft.Compute\",\"publicKeys\":[{\"keyData\":\"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC5uCeOAm3ehmhI+2PbMoMl17Eo\r\nqfHKCycSaBJsv9qxlmBOuFheSJc1XknJleXUSsuTO016/d1PyWpevnqOZNRksWoa\r\nJvQ23sDTxcK+X2OP3QlCUeX4cMjPXqlL8z1UYzU4Bx3fFvf8fs67G3N72sxWBw5P\r\nZyuXyhBm0NCe/2NYMKgEDT4ma8XszO0ikbhoPKbMbgHAQk/ktWQHNcqYOPQKEWqp\r\nEK1R0rjS2nmtovfScP/ZGXcvOpJ1/NDBo4dh1K+OxOGM/4PSH/F448J5Zy4eAyEk\r\nscys+IpeIOTOlRUy/703SNIX0LEWlnYqbyL9c1ypcYLQqF76fKkDfzzFI/OWVlGw\r\nhj/S9uP8iMsR+fhGIbn6MAa7O4DWPWLuedSp7KDYyjY09gqNJsfuaAJN4LiC6bPy\r\nhknm0PVLK3ux7EUOt+cZrHCdIFWbdOtxiPNIl1tkv9kV5aE5Aj2gJm4MeB9uXYhS\r\nOuksboBc0wyUGrl9+XZJ1+NlZOf7IjVi86CieK8= generated-by-azure\r\n\",\"path\":\"/home/azureuser/.ssh/authorized_keys\"}],\"publisher\":\"Canonical\",\"resourceGroupName\":\"sourabh-telemetry-sdk\",\"resourceId\":\"/subscriptions/8fba6d4f-7c37-4d13-9063-fd58ad2b86e2/resourceGroups/sourabh-telemetry-sdk/providers/Microsoft.Compute/virtualMachines/sourabh-testing\",\"securityProfile\":{\"secureBootEnabled\":\"false\",\"virtualTpmEnabled\":\"false\"},\"sku\":\"18.04-LTS\",\"storageProfile\":{\"dataDisks\":[],\"imageReference\":{\"id\":\"\",\"offer\":\"UbuntuServer\",\"publisher\":\"Canonical\",\"sku\":\"18.04-LTS\",\"version\":\"latest\"},\"osDisk\":{\"caching\":\"ReadWrite\",\"createOption\":\"FromImage\",\"diffDiskSettings\":{\"option\":\"\"},\"diskSizeGB\":\"30\",\"encryptionSettings\":{\"enabled\":\"false\"},\"image\":{\"uri\":\"\"},\"managedDisk\":{\"id\":\"/subscriptions/8fba6d4f-7c37-4d13-9063-fd58ad2b86e2/resourceGroups/sourabh-telemetry-sdk/providers/Microsoft.Compute/disks/sourabh-testing_OsDisk_1_9a54abfc5ba149c6a106bd9e5b558c2a\",\"storageAccountType\":\"Premium_LRS\"},\"name\":\"sourabh-testing_OsDisk_1_9a54abfc5ba149c6a106bd9e5b558c2a\",\"osType\":\"Linux\",\"vhd\":{\"uri\":\"\"},\"writeAcceleratorEnabled\":\"false\"}},\"subscriptionId\":\"8fba6d4f-7c37-4d13-9063-fd58ad2b86e2\",\"tags\":\"azsecpack:nonprod;platformsettings.host_environment.service.platform_optedin_for_rootcerts:true\",\"tagsList\":[{\"name\":\"azsecpack\",\"value\":\"nonprod\"},{\"name\":\"platformsettings.host_environment.service.platform_optedin_for_rootcerts\",\"value\":\"true\"}],\"version\":\"18.04.202103250\",\"vmId\":\"d0cb93eb-214b-4c2b-bd3d-cc93e90d9efd\",\"vmScaleSetName\":\"\",\"vmSize\":\"Standard_D2s_v3\",\"zone\":\"1\"},\"network\":{\"interface\":[{\"ipv4\":{\"ipAddress\":[{\"privateIpAddress\":\"10.0.7.5\",\"publicIpAddress\":\"\"}],\"subnet\":[{\"address\":\"10.0.7.0\",\"prefix\":\"24\"}]},\"ipv6\":{\"ipAddress\":[]},\"macAddress\":\"000D3A8F8BA0\"}]}}"); - - private CosmosClientBuilder cosmosClientBuilder; - private static SystemUsageMonitor systemUsageMonitor; - - private List actualInfo; - private List preferredRegionList; - - private IDictionary expectedMetricNameUnitMap; - - private HttpClientHandlerHelper httpHandler; - private HttpClientHandlerHelper httpHandlerForNonAzureInstance; - - [ClassInitialize] - public static void ClassInitialize(TestContext _) - { - SystemUsageMonitor oldSystemUsageMonitor = (SystemUsageMonitor)typeof(DiagnosticsHandlerHelper) - .GetField("systemUsageMonitor", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(DiagnosticsHandlerHelper.Instance); - oldSystemUsageMonitor.Stop(); - - ClientTelemetryTests.ResetSystemUsageMonitor(true); - } - - [TestInitialize] - public void TestInitialize() + public override Task HttpHandlerRequestCallbackChecks(HttpRequestMessage request) { - Util.EnableClientTelemetryEnvironmentVariables(); - - this.actualInfo = new List(); - - this.httpHandler = new HttpClientHandlerHelper + if (request.RequestUri.AbsoluteUri.Equals(telemetryServiceEndpoint.AbsoluteUri)) { - RequestCallBack = (request, cancellation) => - { - if (request.RequestUri.AbsoluteUri.Equals(ClientTelemetryOptions.GetClientTelemetryEndpoint().AbsoluteUri)) - { - HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK); - - string jsonObject = request.Content.ReadAsStringAsync().GetAwaiter().GetResult(); - - lock (this.actualInfo) - { - this.actualInfo.Add(JsonConvert.DeserializeObject(jsonObject)); - } - - return Task.FromResult(result); - } - else if (request.RequestUri.AbsoluteUri.Equals(VmMetadataApiHandler.vmMetadataEndpointUrl.AbsoluteUri)) - { - HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK); - - string payload = JsonConvert.SerializeObject(ClientTelemetryTests.jsonObject); - result.Content = new StringContent(payload, Encoding.UTF8, "application/json"); - - return Task.FromResult(result); - } - return null; - } - }; - - this.httpHandlerForNonAzureInstance = new HttpClientHandlerHelper + return Task.FromResult(new HttpResponseMessage(HttpStatusCode.NoContent)); // In Emulator test, send hardcoded response status code as there is no real communication happens with client telemetry service + } + else if (request.RequestUri.AbsoluteUri.Contains(Paths.ClientConfigPathSegment)) { - RequestCallBack = (request, cancellation) => + HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK); + AccountClientConfiguration clientConfigProperties = new AccountClientConfiguration { - if (request.RequestUri.AbsoluteUri.Equals(ClientTelemetryOptions.GetClientTelemetryEndpoint().AbsoluteUri)) + ClientTelemetryConfiguration = new ClientTelemetryConfiguration { - HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK); - - string jsonObject = request.Content.ReadAsStringAsync().GetAwaiter().GetResult(); - - lock (this.actualInfo) - { - this.actualInfo.Add(JsonConvert.DeserializeObject(jsonObject)); - } - - return Task.FromResult(result); + IsEnabled = true, + Endpoint = telemetryServiceEndpoint.AbsoluteUri } - return null; - } - }; - - this.preferredRegionList = new List - { - "region1", - "region2" - }; - - this.expectedMetricNameUnitMap = new Dictionary() - { - { ClientTelemetryOptions.CpuName, ClientTelemetryOptions.CpuUnit }, - { ClientTelemetryOptions.MemoryName, ClientTelemetryOptions.MemoryUnit }, - { ClientTelemetryOptions.AvailableThreadsName, ClientTelemetryOptions.AvailableThreadsUnit }, - { ClientTelemetryOptions.IsThreadStarvingName, ClientTelemetryOptions.IsThreadStarvingUnit }, - { ClientTelemetryOptions.ThreadWaitIntervalInMsName, ClientTelemetryOptions.ThreadWaitIntervalInMsUnit } - }; + }; + string payload = JsonConvert.SerializeObject(clientConfigProperties); + result.Content = new StringContent(payload, Encoding.UTF8, "application/json"); + return Task.FromResult(result); + } - this.cosmosClientBuilder = TestCommon.GetDefaultConfiguration() - .WithApplicationPreferredRegions(this.preferredRegionList); + return null; } - private static void ResetSystemUsageMonitor(bool isTelemetryEnabled) + public override CosmosClientBuilder GetBuilder() { - ClientTelemetryTests.systemUsageMonitor?.Stop(); - - FieldInfo diagnosticsHandlerHelperInstance = typeof(DiagnosticsHandlerHelper) - .GetField("isTelemetryMonitoringEnabled", BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic); - diagnosticsHandlerHelperInstance.SetValue(null, isTelemetryEnabled); - - List recorders = new List() - { - (SystemUsageRecorder)typeof(DiagnosticsHandlerHelper) - .GetField("diagnosticSystemUsageRecorder", - BindingFlags.Instance | BindingFlags.NonPublic) - .GetValue(DiagnosticsHandlerHelper.Instance) - }; - - if (isTelemetryEnabled) - { - recorders.Add( - (SystemUsageRecorder)typeof(DiagnosticsHandlerHelper) - .GetField("telemetrySystemUsageRecorder", - BindingFlags.Instance | BindingFlags.NonPublic) - .GetValue(DiagnosticsHandlerHelper.Instance)); - } - - ClientTelemetryTests.systemUsageMonitor = SystemUsageMonitor.CreateAndStart(recorders); + return TestCommon.GetDefaultConfiguration(); } - [TestCleanup] - public async Task Cleanup() + [ClassInitialize] + public static void ClassInit(TestContext context) { - FieldInfo isInitializedField = typeof(VmMetadataApiHandler).GetField("isInitialized", - BindingFlags.Static | - BindingFlags.NonPublic); - isInitializedField.SetValue(null, false); - - FieldInfo azMetadataField = typeof(VmMetadataApiHandler).GetField("azMetadata", - BindingFlags.Static | - BindingFlags.NonPublic); - azMetadataField.SetValue(null, null); + ClientTelemetryTestsBase.ClassInitialize(context); + } - await base.TestCleanup(); + [ClassCleanup] + public static void ClassCleanUp() + { + ClientTelemetryTestsBase.ClassCleanup(); + } - Util.DisableClientTelemetryEnvironmentVariables(); + [TestInitialize] + public override void TestInitialize() + { + base.TestInitialize(); } - [ClassCleanup] - public static void FinalCleanup() + [TestCleanup] + public override async Task Cleanup() { - ClientTelemetryTests.ResetSystemUsageMonitor(false); + await base.Cleanup(); } - + [TestMethod] [DataRow(ConnectionMode.Direct, true)] [DataRow(ConnectionMode.Gateway, true)] [DataRow(ConnectionMode.Direct, false)] [DataRow(ConnectionMode.Gateway, false)] - public async Task PointSuccessOperationsTest(ConnectionMode mode, bool isAzureInstance) + public override async Task PointSuccessOperationsTest(ConnectionMode mode, bool isAzureInstance) { - Container container = await this.CreateClientAndContainer( - mode: mode, - isAzureInstance: isAzureInstance); - - // Create an item - ToDoActivity testItem = ToDoActivity.CreateRandomToDoActivity("MyTestPkValue"); - ItemResponse createResponse = await container.CreateItemAsync(testItem); - ToDoActivity testItemCreated = createResponse.Resource; - - // Read an Item - await container.ReadItemAsync(testItem.id, new Cosmos.PartitionKey(testItem.id)); - - // Upsert an Item - await container.UpsertItemAsync(testItem); - - // Replace an Item - await container.ReplaceItemAsync(testItemCreated, testItemCreated.id.ToString()); - - // Patch an Item - List patch = new List() - { - PatchOperation.Add("/new", "patched") - }; - await ((ContainerInternal)container).PatchItemAsync( - testItem.id, - new Cosmos.PartitionKey(testItem.id), - patch); - - // Delete an Item - await container.DeleteItemAsync(testItem.id, new Cosmos.PartitionKey(testItem.id)); - - IDictionary expectedRecordCountInOperation = new Dictionary - { - { Documents.OperationType.Create.ToString(), 1}, - { Documents.OperationType.Upsert.ToString(), 1}, - { Documents.OperationType.Read.ToString(), 1}, - { Documents.OperationType.Replace.ToString(), 1}, - { Documents.OperationType.Patch.ToString(), 1}, - { Documents.OperationType.Delete.ToString(), 1} - }; - - await this.WaitAndAssert(expectedOperationCount: 12, - expectedOperationRecordCountMap: expectedRecordCountInOperation, - isAzureInstance: isAzureInstance); + await base.PointSuccessOperationsTest(mode, isAzureInstance); } [TestMethod] [DataRow(ConnectionMode.Direct)] [DataRow(ConnectionMode.Gateway)] - public async Task PointReadFailureOperationsTest(ConnectionMode mode) + public override async Task PointReadFailureOperationsTest(ConnectionMode mode) { - // Fail Read - try - { - Container container = await this.CreateClientAndContainer(mode, Microsoft.Azure.Cosmos.ConsistencyLevel.ConsistentPrefix); - - await container.ReadItemAsync( - new Guid().ToString(), - new Cosmos.PartitionKey(new Guid().ToString()), - new ItemRequestOptions() - { - BaseConsistencyLevel = Microsoft.Azure.Cosmos.ConsistencyLevel.Eventual // overriding client level consistency - }); - } - catch (CosmosException ce) when (ce.StatusCode == HttpStatusCode.NotFound) - { - string message = ce.ToString(); - Assert.IsNotNull(message); - } - - IDictionary expectedRecordCountInOperation = new Dictionary - { - { Documents.OperationType.Read.ToString(), 1} - }; - - await this.WaitAndAssert(expectedOperationCount: 2, - expectedConsistencyLevel: Microsoft.Azure.Cosmos.ConsistencyLevel.Eventual, - expectedOperationRecordCountMap: expectedRecordCountInOperation, - expectedCacheSource: null, - isExpectedNetworkTelemetry: false); + await base.PointReadFailureOperationsTest(mode); } [TestMethod] [DataRow(ConnectionMode.Direct)] [DataRow(ConnectionMode.Gateway)] - public async Task StreamReadFailureOperationsTest(ConnectionMode mode) + public override async Task StreamReadFailureOperationsTest(ConnectionMode mode) { - Container container = await this.CreateClientAndContainer(mode); - - // Fail Read - try - { - await container.ReadItemStreamAsync( - new Guid().ToString(), - new Cosmos.PartitionKey(new Guid().ToString()), - new ItemRequestOptions() - { - BaseConsistencyLevel = Microsoft.Azure.Cosmos.ConsistencyLevel.ConsistentPrefix // Request level consistency - }); - } - catch (CosmosException ce) when (ce.StatusCode == HttpStatusCode.NotFound) - { - string message = ce.ToString(); - Assert.IsNotNull(message); - } - - IDictionary expectedRecordCountInOperation = new Dictionary - { - { Documents.OperationType.Read.ToString(), 1} - }; - - await this.WaitAndAssert(expectedOperationCount: 2, - expectedConsistencyLevel: Microsoft.Azure.Cosmos.ConsistencyLevel.ConsistentPrefix, - expectedOperationRecordCountMap: expectedRecordCountInOperation, - expectedCacheSource: null, - isExpectedNetworkTelemetry: false); + await base.StreamReadFailureOperationsTest(mode); } [TestMethod] [DataRow(ConnectionMode.Direct)] [DataRow(ConnectionMode.Gateway)] - public async Task StreamOperationsTest(ConnectionMode mode) + public override async Task StreamOperationsTest(ConnectionMode mode) { - Container container = await this.CreateClientAndContainer(mode); - - // Create an item - var testItem = new { id = "MyTestItemId", partitionKeyPath = "MyTestPkValue", details = "it's working", status = "done" }; - await container - .CreateItemStreamAsync(TestCommon.SerializerCore.ToStream(testItem), - new Cosmos.PartitionKey(testItem.id)); - - //Upsert an Item - await container.UpsertItemStreamAsync(TestCommon.SerializerCore.ToStream(testItem), new Cosmos.PartitionKey(testItem.id)); - - //Read an Item - await container.ReadItemStreamAsync(testItem.id, new Cosmos.PartitionKey(testItem.id)); - - //Replace an Item - await container.ReplaceItemStreamAsync(TestCommon.SerializerCore.ToStream(testItem), testItem.id, new Cosmos.PartitionKey(testItem.id)); - - // Patch an Item - List patch = new List() - { - PatchOperation.Add("/new", "patched") - }; - await ((ContainerInternal)container).PatchItemStreamAsync( - partitionKey: new Cosmos.PartitionKey(testItem.id), - id: testItem.id, - patchOperations: patch); - - //Delete an Item - await container.DeleteItemStreamAsync(testItem.id, new Cosmos.PartitionKey(testItem.id)); - - IDictionary expectedRecordCountInOperation = new Dictionary - { - { Documents.OperationType.Create.ToString(), 1}, - { Documents.OperationType.Upsert.ToString(), 1}, - { Documents.OperationType.Read.ToString(), 1}, - { Documents.OperationType.Replace.ToString(), 1}, - { Documents.OperationType.Patch.ToString(), 1}, - { Documents.OperationType.Delete.ToString(), 1} - }; - - await this.WaitAndAssert(expectedOperationCount: 12, - expectedOperationRecordCountMap: expectedRecordCountInOperation, - expectedCacheSource: null); + await base.StreamOperationsTest(mode); } [TestMethod] [DataRow(ConnectionMode.Direct)] [DataRow(ConnectionMode.Gateway)] - public async Task BatchOperationsTest(ConnectionMode mode) + public override async Task BatchOperationsTest(ConnectionMode mode) { - Container container = await this.CreateClientAndContainer(mode, Microsoft.Azure.Cosmos.ConsistencyLevel.Eventual); // Client level consistency - using (BatchAsyncContainerExecutor executor = - new BatchAsyncContainerExecutor( - (ContainerInlineCore)container, - ((ContainerInlineCore)container).ClientContext, - 20, - Documents.Constants.MaxDirectModeBatchRequestBodySizeInBytes) - ) - { - List> tasks = new List>(); - for (int i = 0; i < 10; i++) - { - tasks.Add(executor.AddAsync(CreateItem(i.ToString()), NoOpTrace.Singleton, default)); - } - - await Task.WhenAll(tasks); - } - - IDictionary expectedRecordCountInOperation = new Dictionary - { - { Documents.OperationType.Batch.ToString(), 1} - }; - - await this.WaitAndAssert(expectedOperationCount: 2, - expectedConsistencyLevel: Microsoft.Azure.Cosmos.ConsistencyLevel.Eventual, - expectedOperationRecordCountMap: expectedRecordCountInOperation); + await base.BatchOperationsTest(mode); } [TestMethod] [DataRow(ConnectionMode.Direct)] [DataRow(ConnectionMode.Gateway)] - public async Task SingleOperationMultipleTimesTest(ConnectionMode mode) + public override async Task SingleOperationMultipleTimesTest(ConnectionMode mode) { - Container container = await this.CreateClientAndContainer(mode); - - // Create an item - ToDoActivity testItem = ToDoActivity.CreateRandomToDoActivity(); - - await container.CreateItemAsync(testItem, requestOptions: new ItemRequestOptions()); - - for (int count = 0; count < 50; count++) - { - // Read an Item - await container.ReadItemAsync(testItem.id, new Cosmos.PartitionKey(testItem.id)); - } - - IDictionary expectedRecordCountInOperation = new Dictionary - { - { Documents.OperationType.Read.ToString(), 50}, - { Documents.OperationType.Create.ToString(), 1} - }; - - await this.WaitAndAssert( - expectedOperationCount: 4,// 2 (read, requetLatency + requestCharge) + 2 (create, requestLatency + requestCharge) - expectedOperationRecordCountMap: expectedRecordCountInOperation); + await base.SingleOperationMultipleTimesTest(mode); } [TestMethod] [DataRow(ConnectionMode.Direct)] [DataRow(ConnectionMode.Gateway)] - public async Task QueryOperationSinglePartitionTest(ConnectionMode mode) + public override async Task QueryOperationSinglePartitionTest(ConnectionMode mode) { - Environment.SetEnvironmentVariable(ClientTelemetryOptions.EnvPropsClientTelemetrySchedulingInSeconds, "20"); - - Container container = await this.CreateClientAndContainer(mode); - - ToDoActivity testItem = ToDoActivity.CreateRandomToDoActivity("MyTestPkValue", "MyTestItemId"); - ItemRequestOptions requestOptions = new ItemRequestOptions() - { - ConsistencyLevel = Microsoft.Azure.Cosmos.ConsistencyLevel.ConsistentPrefix - }; - - ItemResponse createResponse = await container.CreateItemAsync( - item: testItem, - requestOptions: requestOptions); - - QueryRequestOptions queryRequestOptions = new QueryRequestOptions() - { - ConsistencyLevel = Microsoft.Azure.Cosmos.ConsistencyLevel.ConsistentPrefix, - }; - - List families = new List(); - if (createResponse.StatusCode == HttpStatusCode.Created) - { - string sqlQueryText = "SELECT * FROM c"; - - QueryDefinition queryDefinition = new QueryDefinition(sqlQueryText); - using (FeedIterator queryResultSetIterator = container.GetItemQueryIterator( - queryDefinition: queryDefinition, - requestOptions: queryRequestOptions)) - { - while (queryResultSetIterator.HasMoreResults) - { - FeedResponse currentResultSet = await queryResultSetIterator.ReadNextAsync(); - foreach (object family in currentResultSet) - { - families.Add(family); - } - } - } - - Assert.AreEqual(1, families.Count); - - } - - IDictionary expectedRecordCountInOperation = new Dictionary - { - { Documents.OperationType.Query.ToString(), 1}, - { Documents.OperationType.Create.ToString(), 1} - }; - - await this.WaitAndAssert(expectedOperationCount: 4, - expectedOperationRecordCountMap: expectedRecordCountInOperation, - expectedConsistencyLevel: Microsoft.Azure.Cosmos.ConsistencyLevel.ConsistentPrefix); + await base.QueryOperationSinglePartitionTest(mode); } [TestMethod] [DataRow(ConnectionMode.Direct)] [DataRow(ConnectionMode.Gateway)] - public async Task QueryMultiPageSinglePartitionOperationTest(ConnectionMode mode) + public override async Task QueryMultiPageSinglePartitionOperationTest(ConnectionMode mode) { - Environment.SetEnvironmentVariable(ClientTelemetryOptions.EnvPropsClientTelemetrySchedulingInSeconds, "20"); - Container container = await this.CreateClientAndContainer(mode: mode); - - ItemRequestOptions requestOptions = new ItemRequestOptions() - { - ConsistencyLevel = Microsoft.Azure.Cosmos.ConsistencyLevel.ConsistentPrefix - }; - - ToDoActivity testItem1 = ToDoActivity.CreateRandomToDoActivity("MyTestPkValue1", "MyTestItemId1"); - ItemResponse createResponse1 = await container.CreateItemAsync( - item: testItem1, - requestOptions: requestOptions); - ToDoActivity testItem2 = ToDoActivity.CreateRandomToDoActivity("MyTestPkValue2", "MyTestItemId2"); - ItemResponse createResponse2 = await container.CreateItemAsync( - item: testItem2, - requestOptions: requestOptions); - - if (createResponse1.StatusCode == HttpStatusCode.Created && - createResponse2.StatusCode == HttpStatusCode.Created) - { - string sqlQueryText = "SELECT * FROM c"; - - List families = new List(); - QueryDefinition queryDefinition = new QueryDefinition(sqlQueryText); - using (FeedIterator queryResultSetIterator = container.GetItemQueryIterator( - queryDefinition: queryDefinition, - requestOptions: new QueryRequestOptions() - { - ConsistencyLevel = Microsoft.Azure.Cosmos.ConsistencyLevel.ConsistentPrefix, - MaxItemCount = 1 - })) - { - while (queryResultSetIterator.HasMoreResults) - { - FeedResponse currentResultSet = await queryResultSetIterator.ReadNextAsync(); - foreach (object family in currentResultSet) - { - families.Add(family); - } - } - } - - Assert.AreEqual(2, families.Count); - - } - - IDictionary expectedRecordCountInOperation = new Dictionary - { - { Documents.OperationType.Query.ToString(), 3}, - { Documents.OperationType.Create.ToString(), 2} - }; - - await this.WaitAndAssert( - expectedOperationCount: 4, - expectedOperationRecordCountMap: expectedRecordCountInOperation, - expectedConsistencyLevel: Microsoft.Azure.Cosmos.ConsistencyLevel.ConsistentPrefix); + await base.QueryMultiPageSinglePartitionOperationTest(mode); } [TestMethod] [DataRow(ConnectionMode.Direct)] [DataRow(ConnectionMode.Gateway)] - public async Task QueryOperationCrossPartitionTest(ConnectionMode mode) + public override async Task QueryOperationCrossPartitionTest(ConnectionMode mode) { - Environment.SetEnvironmentVariable(ClientTelemetryOptions.EnvPropsClientTelemetrySchedulingInSeconds, "20"); - - ContainerInternal itemsCore = (ContainerInternal)await this.CreateClientAndContainer( - mode: mode, - isLargeContainer: true); - - // Verify container has multiple partitions - int pkRangesCount = (await itemsCore.ClientContext.DocumentClient.ReadPartitionKeyRangeFeedAsync(itemsCore.LinkUri)).Count; - Assert.IsTrue(pkRangesCount > 1, "Should have created a multi partition container."); - - Container container = (Container)itemsCore; - - await ToDoActivity.CreateRandomItems( - container: container, - pkCount: 2, - perPKItemCount: 5); - - string sqlQueryText = "SELECT * FROM c"; - - List families = new List(); - - QueryDefinition queryDefinition = new QueryDefinition(sqlQueryText); - using (FeedIterator queryResultSetIterator = container.GetItemQueryIterator(queryDefinition)) - { - while (queryResultSetIterator.HasMoreResults) - { - FeedResponse currentResultSet = await queryResultSetIterator.ReadNextAsync(); - foreach (object family in currentResultSet) - { - families.Add(family); - } - } - } - - Assert.AreEqual(10, families.Count); - - IDictionary expectedRecordCountInOperation = new Dictionary - { - { Documents.OperationType.Query.ToString(), pkRangesCount}, - { Documents.OperationType.Create.ToString(), 10} - }; - - await this.WaitAndAssert( - expectedOperationCount: 4, - expectedOperationRecordCountMap: expectedRecordCountInOperation); + await base.QueryOperationCrossPartitionTest(mode); } [TestMethod] [DataRow(ConnectionMode.Direct)] [DataRow(ConnectionMode.Gateway)] - public async Task QueryOperationMutiplePageCrossPartitionTest(ConnectionMode mode) + public override async Task QueryOperationMutiplePageCrossPartitionTest(ConnectionMode mode) { - Environment.SetEnvironmentVariable(ClientTelemetryOptions.EnvPropsClientTelemetrySchedulingInSeconds, "20"); - - ContainerInternal itemsCore = (ContainerInternal)await this.CreateClientAndContainer( - mode: mode, - isLargeContainer: true); - - // Verify container has multiple partitions - int pkRangesCount = (await itemsCore.ClientContext.DocumentClient.ReadPartitionKeyRangeFeedAsync(itemsCore.LinkUri)).Count; - Assert.IsTrue(pkRangesCount > 1, "Should have created a multi partition container."); - - Container container = (Container)itemsCore; - - await ToDoActivity.CreateRandomItems( - container: container, - pkCount: 2, - perPKItemCount: 5); - - string sqlQueryText = "SELECT * FROM c"; - - List families = new List(); - QueryDefinition queryDefinition = new QueryDefinition(sqlQueryText); - using (FeedIterator queryResultSetIterator = container.GetItemQueryIterator( - queryDefinition: queryDefinition, - requestOptions: new QueryRequestOptions() - { - MaxItemCount = 1 - })) - { - while (queryResultSetIterator.HasMoreResults) - { - FeedResponse currentResultSet = await queryResultSetIterator.ReadNextAsync(); - foreach (object family in currentResultSet) - { - families.Add(family); - } - } - } - - Assert.AreEqual(10, families.Count); - - IDictionary expectedRecordCountInOperation = new Dictionary - { - { Documents.OperationType.Query.ToString(), pkRangesCount + 10}, // 10 is number of items - { Documents.OperationType.Create.ToString(), 10} - }; - - await this.WaitAndAssert( - expectedOperationCount: 4, - expectedOperationRecordCountMap: expectedRecordCountInOperation); + await base.QueryOperationMutiplePageCrossPartitionTest(mode); } [TestMethod] [DataRow(ConnectionMode.Direct)] [DataRow(ConnectionMode.Gateway)] - public async Task QueryOperationInvalidContinuationTokenTest(ConnectionMode mode) + public override async Task QueryOperationInvalidContinuationTokenTest(ConnectionMode mode) { - Container container = await this.CreateClientAndContainer(mode); - - // Create an item : First successful request to load Cache - ToDoActivity testItem = ToDoActivity.CreateRandomToDoActivity("MyTestPkValue"); - await container.CreateItemAsync(testItem); - - List results = new List(); - using (FeedIterator resultSetIterator = container.GetItemQueryIterator( - "SELECT * FROM c", - continuationToken: "dummy token")) - { - try - { - while (resultSetIterator.HasMoreResults) - { - FeedResponse response = await resultSetIterator.ReadNextAsync(); - results.AddRange(response); - } - } - catch (CosmosException ce) when (ce.StatusCode == HttpStatusCode.BadRequest) - { - string message = ce.ToString(); - Assert.IsNotNull(message); - } - } - - IDictionary expectedRecordCountInOperation = new Dictionary - { - { Documents.OperationType.Create.ToString(), 1} - }; - - await this.WaitAndAssert(expectedOperationCount: 2, - expectedOperationRecordCountMap: expectedRecordCountInOperation); + await base.QueryOperationInvalidContinuationTokenTest(mode); } [TestMethod] [DataRow(ConnectionMode.Direct)] - public async Task CreateItemWithSubStatusCodeTest(ConnectionMode mode) - { - HttpClientHandlerHelper httpHandler = new HttpClientHandlerHelper(); - HttpClient httpClient = new HttpClient(httpHandler); - - httpHandler.RequestCallBack = (request, cancellation) => - { - if (request.RequestUri.AbsoluteUri.Equals(ClientTelemetryOptions.GetClientTelemetryEndpoint().AbsoluteUri)) - { - HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK); - - string jsonObject = request.Content.ReadAsStringAsync().GetAwaiter().GetResult(); - - lock (this.actualInfo) - { - this.actualInfo.Add(JsonConvert.DeserializeObject(jsonObject)); - } - - return Task.FromResult(result); - } - else if (request.RequestUri.AbsoluteUri.Equals(VmMetadataApiHandler.vmMetadataEndpointUrl.AbsoluteUri)) - { - HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK); - - string payload = JsonConvert.SerializeObject(ClientTelemetryTests.jsonObject); - result.Content = new StringContent(payload, Encoding.UTF8, "application/json"); - - return Task.FromResult(result); - } - else if (request.Method == HttpMethod.Get && request.RequestUri.AbsolutePath == "//addresses/") - { - HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.Forbidden); - - // Add a substatus code that is not part of the enum. - // This ensures that if the backend adds a enum the status code is not lost. - result.Headers.Add(WFConstants.BackendHeaders.SubStatus, 999999.ToString(CultureInfo.InvariantCulture)); - - string payload = JsonConvert.SerializeObject(new Error() { Message = "test message" }); - result.Content = new StringContent(payload, Encoding.UTF8, "application/json"); - - return Task.FromResult(result); - } - - return null; - }; - - // Replacing originally initialized cosmos Builder with this one with new handler - this.cosmosClientBuilder = this.cosmosClientBuilder - .WithHttpClientFactory(() => new HttpClient(httpHandler)); - - Container container = await this.CreateClientAndContainer( - mode: mode, - customHttpHandler: httpHandler); - try - { - ToDoActivity testItem = ToDoActivity.CreateRandomToDoActivity("MyTestPkValue"); - ItemResponse createResponse = await container.CreateItemAsync(testItem); - Assert.Fail("Request should throw exception."); - } - catch (CosmosException ce) when (ce.StatusCode == HttpStatusCode.Forbidden) - { - Assert.AreEqual(999999, ce.SubStatusCode); - } - - IDictionary expectedRecordCountInOperation = new Dictionary - { - { Documents.OperationType.Create.ToString(), 1} - }; - - await this.WaitAndAssert(expectedOperationCount: 2, - expectedOperationRecordCountMap: expectedRecordCountInOperation, - expectedSubstatuscode: 999999, - isExpectedNetworkTelemetry: false); - - } - - /// - /// This method wait for the expected operations to get recorded by telemetry and assert the values - /// - /// Expected number of unique OperationInfo irrespective of response size. - /// Expected Consistency level of the operation recorded by telemetry - /// Expected number of requests recorded for each operation - /// - private async Task WaitAndAssert( - int expectedOperationCount = 0, - Microsoft.Azure.Cosmos.ConsistencyLevel? expectedConsistencyLevel = null, - IDictionary expectedOperationRecordCountMap = null, - int expectedSubstatuscode = 0, - bool? isAzureInstance = null, - string expectedCacheSource = "ClientCollectionCache", - bool isExpectedNetworkTelemetry = true) - { - Assert.IsNotNull(this.actualInfo, "Telemetry Information not available"); - - // As this feature is thread based execution so wait for the results to avoid test flakiness - List localCopyOfActualInfo = null; - ValueStopwatch stopwatch = ValueStopwatch.StartNew(); - - HashSet cacheRefreshInfoSet = new HashSet(); - do - { - await Task.Delay(TimeSpan.FromMilliseconds(1500)); // wait at least for 1 round of telemetry - - HashSet actualOperationSet = new HashSet(); - HashSet requestInfoSet = new HashSet(); - - lock (this.actualInfo) - { - // Setting the number of unique OperationInfo irrespective of response size as response size is varying in case of queries. - this.actualInfo - .ForEach(x => - { - if (x.CacheRefreshInfo != null && x.CacheRefreshInfo.Count > 0) - { - x.CacheRefreshInfo - .ForEach(y => - { - y.GreaterThan1Kb = false; - cacheRefreshInfoSet.Add(y); - }); - - } - - x.OperationInfo - .ForEach(y => - { - y.GreaterThan1Kb = false; - actualOperationSet.Add(y); - }); - }); - - if (actualOperationSet.Count == expectedOperationCount / 2) - { - // Copy the list to avoid it being modified while validating - localCopyOfActualInfo = new List(this.actualInfo); - break; - } - - Assert.IsTrue(stopwatch.Elapsed.TotalMinutes < 1, $"The expected operation count({expectedOperationCount}) was never hit, Actual Operation Count is {actualOperationSet.Count}. ActualInfo:{JsonConvert.SerializeObject(this.actualInfo)}"); - } - } - while (localCopyOfActualInfo == null); - - List actualOperationList = new List(); - List actualSystemInformation = new List(); - List actualRequestInformation = new List(); - - if (localCopyOfActualInfo[0].ConnectionMode == ConnectionMode.Direct.ToString().ToUpperInvariant()) - { - this.expectedMetricNameUnitMap.Add(ClientTelemetryOptions.NumberOfTcpConnectionName, ClientTelemetryOptions.NumberOfTcpConnectionUnit); - } - - ClientTelemetryTests.AssertAccountLevelInformation( - localCopyOfActualInfo: localCopyOfActualInfo, - actualOperationList: actualOperationList, - actualSystemInformation: actualSystemInformation, - actualRequestInformation: actualRequestInformation, - isAzureInstance: isAzureInstance); - - ClientTelemetryTests.AssertOperationLevelInformation( - expectedConsistencyLevel: expectedConsistencyLevel, - expectedOperationRecordCountMap: expectedOperationRecordCountMap, - actualOperationList: actualOperationList, - expectedSubstatuscode: expectedSubstatuscode); - - if(!string.IsNullOrEmpty(expectedCacheSource)) - { - Assert.IsTrue(cacheRefreshInfoSet.Count > 0, "Cache Refresh Information is not there"); - - ClientTelemetryTests.AssertCacheRefreshInfoInformation( - cacheRefreshInfoSet: cacheRefreshInfoSet, - expectedCacheSource: expectedCacheSource); - } - - ClientTelemetryTests.AssertSystemLevelInformation(actualSystemInformation, this.expectedMetricNameUnitMap); - if (localCopyOfActualInfo.First().ConnectionMode == ConnectionMode.Direct.ToString().ToUpperInvariant() - && isExpectedNetworkTelemetry) - { - ClientTelemetryTests.AssertNetworkLevelInformation(actualRequestInformation); - } - else - { - Assert.IsTrue(actualRequestInformation == null || actualRequestInformation.Count == 0, "Request Information is not expected in Gateway mode"); - } - } - - private static void AssertNetworkLevelInformation(List actualRequestInformation) - { - Assert.IsNotNull(actualRequestInformation); - Assert.IsTrue(actualRequestInformation.Count > 0); - - foreach(RequestInfo requestInfo in actualRequestInformation) - { - Assert.IsNotNull(requestInfo.Uri); - Assert.IsNotNull(requestInfo.DatabaseName); - Assert.IsNotNull(requestInfo.ContainerName); - Assert.IsNotNull(requestInfo.Operation); - Assert.IsNotNull(requestInfo.Resource); - Assert.IsNotNull(requestInfo.StatusCode); - Assert.AreNotEqual(0, requestInfo.StatusCode); - Assert.IsNotNull(requestInfo.SubStatusCode); - - Assert.IsNotNull(requestInfo.Metrics, "MetricInfo is null"); - } - } - - private static void AssertSystemLevelInformation(List actualSystemInformation, IDictionary expectedMetricNameUnitMap) - { - IDictionary actualMetricNameUnitMap = new Dictionary(); - - // Asserting If system information list is as expected - foreach (SystemInfo systemInfo in actualSystemInformation) - { - Assert.AreEqual("HostMachine", systemInfo.Resource); - Assert.IsNotNull(systemInfo.MetricInfo, "MetricInfo is null"); - - if(!actualMetricNameUnitMap.TryAdd(systemInfo.MetricInfo.MetricsName, systemInfo.MetricInfo.UnitName)) - { - Assert.AreEqual(systemInfo.MetricInfo.UnitName, actualMetricNameUnitMap[systemInfo.MetricInfo.MetricsName]); - } - - if(!systemInfo.MetricInfo.MetricsName.Equals(ClientTelemetryOptions.IsThreadStarvingName) && - !systemInfo.MetricInfo.MetricsName.Equals(ClientTelemetryOptions.ThreadWaitIntervalInMsName)) - { - Assert.IsTrue(systemInfo.MetricInfo.Count > 0, $"MetricInfo ({systemInfo.MetricInfo.MetricsName}) Count is not greater than 0"); - Assert.IsNotNull(systemInfo.MetricInfo.Percentiles, $"Percentiles is null for metrics ({systemInfo.MetricInfo.MetricsName})"); - } - Assert.IsTrue(systemInfo.MetricInfo.Mean >= 0, $"MetricInfo ({systemInfo.MetricInfo.MetricsName}) Mean is not greater than or equal to 0"); - Assert.IsTrue(systemInfo.MetricInfo.Max >= 0, $"MetricInfo ({systemInfo.MetricInfo.MetricsName}) Max is not greater than or equal to 0"); - Assert.IsTrue(systemInfo.MetricInfo.Min >= 0, $"MetricInfo ({systemInfo.MetricInfo.MetricsName}) Min is not greater than or equal to 0"); - if (systemInfo.MetricInfo.MetricsName.Equals(ClientTelemetryOptions.CpuName)) - { - Assert.IsTrue(systemInfo.MetricInfo.Mean <= 100, $"MetricInfo ({systemInfo.MetricInfo.MetricsName}) Mean is not greater than 100 for CPU Usage"); - Assert.IsTrue(systemInfo.MetricInfo.Max <= 100, $"MetricInfo ({systemInfo.MetricInfo.MetricsName}) Max is not greater than 100 for CPU Usage"); - Assert.IsTrue(systemInfo.MetricInfo.Min <= 100, $"MetricInfo ({systemInfo.MetricInfo.MetricsName}) Min is not greater than 100 for CPU Usage"); - }; - } - - Assert.IsTrue(expectedMetricNameUnitMap.EqualsTo(actualMetricNameUnitMap), $"Actual System Information metric i.e {string.Join(", ", actualMetricNameUnitMap)} is not matching with expected System Information Metric i.e. {string.Join(", ", expectedMetricNameUnitMap)}"); - - } - - private static void AssertOperationLevelInformation( - Microsoft.Azure.Cosmos.ConsistencyLevel? expectedConsistencyLevel, - IDictionary expectedOperationRecordCountMap, - List actualOperationList, - int expectedSubstatuscode = 0) - { - IDictionary actualOperationRecordCountMap = new Dictionary(); - // Asserting If operation list is as expected - foreach (OperationInfo operation in actualOperationList) - { - Assert.IsNotNull(operation.Operation, "Operation Type is null"); - Assert.IsNotNull(operation.Resource, "Resource Type is null"); - - Assert.AreEqual(expectedSubstatuscode, operation.SubStatusCode); - Assert.AreEqual(expectedConsistencyLevel?.ToString(), operation.Consistency, $"Consistency is not {expectedConsistencyLevel}"); - - Assert.IsNotNull(operation.MetricInfo, "MetricInfo is null"); - Assert.IsNotNull(operation.MetricInfo.MetricsName, "MetricsName is null"); - Assert.IsNotNull(operation.MetricInfo.UnitName, "UnitName is null"); - Assert.IsNotNull(operation.MetricInfo.Percentiles, "Percentiles is null"); - Assert.IsTrue(operation.MetricInfo.Count > 0, "MetricInfo Count is not greater than 0"); - Assert.IsTrue(operation.MetricInfo.Mean >= 0, "MetricInfo Mean is not greater than or equal to 0"); - Assert.IsTrue(operation.MetricInfo.Max >= 0, "MetricInfo Max is not greater than or equal to 0"); - Assert.IsTrue(operation.MetricInfo.Min >= 0, "MetricInfo Min is not greater than or equal to 0"); - if (operation.MetricInfo.MetricsName.Equals(ClientTelemetryOptions.RequestLatencyName)) // putting this condition to avoid doubling of count as we have same information for each metrics - { - if (!actualOperationRecordCountMap.TryGetValue(operation.Operation.ToString(), out long recordCount)) - { - actualOperationRecordCountMap.Add(operation.Operation.ToString(), operation.MetricInfo.Count); - } - else - { - actualOperationRecordCountMap.Remove(operation.Operation.ToString()); - actualOperationRecordCountMap.Add(operation.Operation.ToString(), recordCount + operation.MetricInfo.Count); - } - } - } - - if (expectedOperationRecordCountMap != null) - { - Assert.IsTrue(expectedOperationRecordCountMap.EqualsTo(actualOperationRecordCountMap), $"actual record i.e. ({actualOperationRecordCountMap}) for operation does not match with expected record i.e. ({expectedOperationRecordCountMap})"); - } - } - - private static void AssertAccountLevelInformation( - List localCopyOfActualInfo, - List actualOperationList, - List actualSystemInformation, - List actualRequestInformation, - bool? isAzureInstance) - { - ISet machineId = new HashSet(); - - // Asserting If basic client telemetry object is as expected - foreach (ClientTelemetryProperties telemetryInfo in localCopyOfActualInfo) - { - if (telemetryInfo.OperationInfo != null) - { - actualOperationList.AddRange(telemetryInfo.OperationInfo); - } - - if (telemetryInfo.SystemInfo != null) - { - foreach (SystemInfo sysInfo in telemetryInfo.SystemInfo) - { - actualSystemInformation.Add(sysInfo); - } - } - - if (telemetryInfo.RequestInfo != null) - { - actualRequestInformation.AddRange(telemetryInfo.RequestInfo); - } - - if (telemetryInfo.ConnectionMode == ConnectionMode.Direct.ToString().ToUpperInvariant()) - { - Assert.AreEqual(6, telemetryInfo.SystemInfo.Count, $"System Information Count doesn't Match; {JsonConvert.SerializeObject(telemetryInfo.SystemInfo)}"); - } - else - { - Assert.AreEqual(5, telemetryInfo.SystemInfo.Count, $"System Information Count doesn't Match; {JsonConvert.SerializeObject(telemetryInfo.SystemInfo)}"); - } - - Assert.IsNotNull(telemetryInfo.GlobalDatabaseAccountName, "GlobalDatabaseAccountName is null"); - Assert.IsNotNull(telemetryInfo.DateTimeUtc, "Timestamp is null"); - Assert.AreEqual(2, telemetryInfo.PreferredRegions.Count); - Assert.AreEqual("region1", telemetryInfo.PreferredRegions[0]); - Assert.AreEqual("region2", telemetryInfo.PreferredRegions[1]); - Assert.AreEqual(1, telemetryInfo.AggregationIntervalInSec); - Assert.IsNull(telemetryInfo.AcceleratedNetworking); - Assert.IsNotNull(telemetryInfo.ClientId); - Assert.IsNotNull(telemetryInfo.ProcessId); - Assert.AreEqual(HashingExtension.ComputeHash(System.Diagnostics.Process.GetCurrentProcess().ProcessName), telemetryInfo.ProcessId); - Assert.IsNotNull(telemetryInfo.UserAgent); - Assert.IsFalse(telemetryInfo.UserAgent.Contains("userAgentSuffix"), "Useragent should not have suffix appended"); // Useragent should not contain useragentsuffix as it can have PII - Assert.IsNotNull(telemetryInfo.ConnectionMode); - - if(!string.IsNullOrEmpty(telemetryInfo.MachineId)) - { - machineId.Add(telemetryInfo.MachineId); - } - } - - if(isAzureInstance.HasValue) - { - if (isAzureInstance.Value) - { - Assert.AreEqual($"{VmMetadataApiHandler.VmIdPrefix}{"d0cb93eb-214b-4c2b-bd3d-cc93e90d9efd"}", machineId.First(), $"Generated Machine id is : {machineId.First()}"); - } - else - { - Assert.AreNotEqual($"{VmMetadataApiHandler.VmIdPrefix}{"d0cb93eb-214b-4c2b-bd3d-cc93e90d9efd"}", machineId.First(), $"Generated Machine id is : {machineId.First()}"); - Assert.AreEqual(1, machineId.Count, $"Multiple Machine Id has been generated i.e {JsonConvert.SerializeObject(machineId)}"); - } - } - } - - - private static void AssertCacheRefreshInfoInformation( - HashSet cacheRefreshInfoSet, - string expectedCacheSource) - { - foreach(CacheRefreshInfo cacheRefreshInfo in cacheRefreshInfoSet) - { - Assert.IsNotNull(cacheRefreshInfo.CacheRefreshSource); - Assert.IsTrue(expectedCacheSource.Contains(cacheRefreshInfo.CacheRefreshSource)); - Assert.IsNotNull(cacheRefreshInfo.Operation, "Operation Type is null"); - Assert.IsNotNull(cacheRefreshInfo.Resource, "Resource Type is null"); - Assert.IsNotNull(cacheRefreshInfo.StatusCode, "StatusCode is null"); - Assert.IsNotNull(cacheRefreshInfo.SubStatusCode); - Assert.IsNull(cacheRefreshInfo.Consistency); - Assert.IsNotNull(cacheRefreshInfo.ContainerName, "ContainerName is null"); - Assert.IsNotNull(cacheRefreshInfo.MetricInfo, "MetricInfo is null"); - Assert.IsNotNull(cacheRefreshInfo.MetricInfo.MetricsName, "MetricsName is null"); - Assert.IsNotNull(cacheRefreshInfo.MetricInfo.UnitName, "UnitName is null"); - Assert.IsNotNull(cacheRefreshInfo.MetricInfo.Percentiles, "Percentiles is null"); - Assert.IsTrue(cacheRefreshInfo.MetricInfo.Count >= 0, "MetricInfo Count is not greater than 0"); - Assert.IsTrue(cacheRefreshInfo.MetricInfo.Mean >= 0, "MetricInfo Mean is not greater than or equal to 0"); - Assert.IsTrue(cacheRefreshInfo.MetricInfo.Max >= 0, "MetricInfo Max is not greater than or equal to 0"); - Assert.IsTrue(cacheRefreshInfo.MetricInfo.Min >= 0, "MetricInfo Min is not greater than or equal to 0"); - } - } - - private static ItemBatchOperation CreateItem(string itemId) + public override async Task CreateItemWithSubStatusCodeTest(ConnectionMode mode) { - var testItem = new { id = itemId, Status = itemId }; - return new ItemBatchOperation(Documents.OperationType.Create, 0, new Cosmos.PartitionKey(itemId), itemId, TestCommon.SerializerCore.ToStream(testItem)); - } - - private async Task CreateClientAndContainer(ConnectionMode mode, - Microsoft.Azure.Cosmos.ConsistencyLevel? consistency = null, - bool isLargeContainer = false, - bool isAzureInstance = false, - HttpClientHandlerHelper customHttpHandler = null) - { - if (consistency.HasValue) - { - this.cosmosClientBuilder = this.cosmosClientBuilder - .WithConsistencyLevel(consistency.Value); - } - - HttpClientHandlerHelper handlerHelper; - if (customHttpHandler == null) - { - handlerHelper = isAzureInstance ? this.httpHandler : this.httpHandlerForNonAzureInstance; - } - else - { - handlerHelper = customHttpHandler; - } - - this.cosmosClientBuilder = this.cosmosClientBuilder - .WithHttpClientFactory(() => new HttpClient(handlerHelper)) - .WithApplicationName("userAgentSuffix"); - - this.SetClient(mode == ConnectionMode.Gateway - ? this.cosmosClientBuilder.WithConnectionModeGateway().Build() - : this.cosmosClientBuilder.Build()); - - this.database = await this.GetClient().CreateDatabaseAsync(Guid.NewGuid().ToString()); - - return await this.database.CreateContainerAsync( - id: Guid.NewGuid().ToString(), - partitionKeyPath: "/id", - throughput: isLargeContainer? 15000 : 400); - + await base.CreateItemWithSubStatusCodeTest(mode); } - } } diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/ClientTelemetryTestsBase.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/ClientTelemetryTestsBase.cs new file mode 100644 index 0000000000..85e3496731 --- /dev/null +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/ClientTelemetryTestsBase.cs @@ -0,0 +1,1057 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.SDK.EmulatorTests +{ + using System; + using System.Collections.Generic; + using System.Text; + using System.Threading.Tasks; + using System.Net; + using System.Net.Http; + using System.Reflection; + using Microsoft.Azure.Cosmos.Fluent; + using Microsoft.VisualStudio.TestTools.UnitTesting; + using Microsoft.Azure.Cosmos.Tracing; + using Microsoft.Azure.Cosmos.Telemetry; + using Microsoft.Azure.Documents; + using Newtonsoft.Json.Linq; + using Newtonsoft.Json; + using System.Globalization; + using System.Linq; + using Cosmos.Util; + using Microsoft.Azure.Cosmos.Telemetry.Models; + + public abstract class ClientTelemetryTestsBase : BaseCosmosClientHelper + { + protected static readonly Uri telemetryServiceEndpoint = new Uri(ConfigurationManager.GetEnvironmentVariable("CLIENT_TELEMETRY_SERVICE_ENDPOINT", "https://dummy.url/api/clienttelemetry")); + + private static readonly List preferredRegionList = new List + { + Regions.EastUS, + Regions.WestUS2 + }; + + private static readonly IDictionary expectedMetricNameUnitMap = new Dictionary() + { + { ClientTelemetryOptions.CpuName, ClientTelemetryOptions.CpuUnit }, + { ClientTelemetryOptions.MemoryName, ClientTelemetryOptions.MemoryUnit }, + { ClientTelemetryOptions.AvailableThreadsName, ClientTelemetryOptions.AvailableThreadsUnit }, + { ClientTelemetryOptions.IsThreadStarvingName, ClientTelemetryOptions.IsThreadStarvingUnit }, + { ClientTelemetryOptions.ThreadWaitIntervalInMsName, ClientTelemetryOptions.ThreadWaitIntervalInMsUnit } + }; + + private List actualInfo; + protected CosmosClientBuilder cosmosClientBuilder; + + protected HttpClientHandlerHelper httpHandler; + protected HttpClientHandlerHelper httpHandlerForNonAzureInstance; + + private bool isClientTelemetryAPICallFailed = false; + + public static void ClassInitialize(TestContext _) + { + ClientTelemetryOptions.DefaultIntervalForTelemetryJob = TimeSpan.FromSeconds(1); + } + + public static void ClassCleanup() + { + //undone the changes done in ClassInitialize + ClientTelemetryOptions.DefaultIntervalForTelemetryJob = TimeSpan.FromMinutes(10); + } + + public virtual void TestInitialize() + { + this.actualInfo = new List(); + + this.httpHandler = new HttpClientHandlerHelper + { + RequestCallBack = (request, cancellation) => + { + if (request.RequestUri.AbsoluteUri.Equals(telemetryServiceEndpoint.AbsoluteUri)) + { + string jsonObject = request.Content.ReadAsStringAsync().GetAwaiter().GetResult(); + + lock (this.actualInfo) + { + this.actualInfo.Add(JsonConvert.DeserializeObject(jsonObject)); + } + } + return this.HttpHandlerRequestCallbackChecks(request); + }, + ResponseIntercepter = (response) => + { + if (response.RequestMessage != null && response.RequestMessage.RequestUri.AbsoluteUri.Equals(telemetryServiceEndpoint.AbsoluteUri)) + { + Assert.AreEqual(HttpStatusCode.NoContent, response.StatusCode); + } + + return Task.FromResult(response); + }, + ExceptionIntercepter = (request, exception) => + { + if (request.RequestUri.AbsoluteUri.Equals(telemetryServiceEndpoint.AbsoluteUri)) + { + this.isClientTelemetryAPICallFailed = true; + } + } + }; + + this.httpHandlerForNonAzureInstance = new HttpClientHandlerHelper + { + RequestCallBack = (request, cancellation) => + { + if (request.RequestUri.AbsoluteUri.Equals(VmMetadataApiHandler.vmMetadataEndpointUrl.AbsoluteUri)) + { + HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.NotFound); + return Task.FromResult(result); + } + + if (request.RequestUri.AbsoluteUri.Equals(telemetryServiceEndpoint.AbsoluteUri)) + { + string jsonObject = request.Content.ReadAsStringAsync().GetAwaiter().GetResult(); + + lock(this.actualInfo) + { + this.actualInfo.Add(JsonConvert.DeserializeObject(jsonObject)); + } + } + + return this.HttpHandlerRequestCallbackChecks(request); + }, + ResponseIntercepter = (response) => + { + if (response.RequestMessage != null && response.RequestMessage.RequestUri.AbsoluteUri.Equals(telemetryServiceEndpoint.AbsoluteUri)) + { + Assert.AreEqual(HttpStatusCode.NoContent, response.StatusCode); + } + return Task.FromResult(response); + }, + ExceptionIntercepter = (request, exception) => + { + if (request.RequestUri.AbsoluteUri.Equals(telemetryServiceEndpoint.AbsoluteUri)) + { + this.isClientTelemetryAPICallFailed = true; + } + } + }; + + this.cosmosClientBuilder = this.GetBuilder() + .WithClientTelemetryOptions(new CosmosClientTelemetryOptions() + { + DisableSendingMetricsToService = false + }) + .WithApplicationPreferredRegions(ClientTelemetryTestsBase.preferredRegionList); + } + + public abstract Task HttpHandlerRequestCallbackChecks(HttpRequestMessage request); + + public abstract CosmosClientBuilder GetBuilder(); + + public virtual async Task Cleanup() + { + FieldInfo isInitializedField = typeof(VmMetadataApiHandler).GetField("isInitialized", + BindingFlags.Static | + BindingFlags.NonPublic); + isInitializedField.SetValue(null, false); + + FieldInfo azMetadataField = typeof(VmMetadataApiHandler).GetField("azMetadata", + BindingFlags.Static | + BindingFlags.NonPublic); + azMetadataField.SetValue(null, null); + + await base.TestCleanup(); + + Assert.IsFalse(this.isClientTelemetryAPICallFailed, $"Call to client telemetry service endpoint (i.e. {telemetryServiceEndpoint}) failed"); + } + + public virtual async Task PointSuccessOperationsTest(ConnectionMode mode, bool isAzureInstance) + { + Container container = await this.CreateClientAndContainer( + mode: mode, + isAzureInstance: isAzureInstance); + + // Create an item + ToDoActivity testItem = ToDoActivity.CreateRandomToDoActivity("MyTestPkValue"); + ItemResponse createResponse = await container.CreateItemAsync(testItem); + ToDoActivity testItemCreated = createResponse.Resource; + + // Read an Item + await container.ReadItemAsync(testItem.id, new Cosmos.PartitionKey(testItem.id)); + + // Upsert an Item + await container.UpsertItemAsync(testItem); + + // Replace an Item + await container.ReplaceItemAsync(testItemCreated, testItemCreated.id.ToString()); + + // Patch an Item + List patch = new List() + { + PatchOperation.Add("/new", "patched") + }; + await ((ContainerInternal)container).PatchItemAsync( + testItem.id, + new Cosmos.PartitionKey(testItem.id), + patch); + + // Delete an Item + await container.DeleteItemAsync(testItem.id, new Cosmos.PartitionKey(testItem.id)); + + IDictionary expectedRecordCountInOperation = new Dictionary + { + { Documents.OperationType.Create.ToString(), 1}, + { Documents.OperationType.Upsert.ToString(), 1}, + { Documents.OperationType.Read.ToString(), 1}, + { Documents.OperationType.Replace.ToString(), 1}, + { Documents.OperationType.Patch.ToString(), 1}, + { Documents.OperationType.Delete.ToString(), 1} + }; + + await this.WaitAndAssert(expectedOperationCount: 12, + expectedOperationRecordCountMap: expectedRecordCountInOperation, + isAzureInstance: isAzureInstance); + } + + public virtual async Task PointReadFailureOperationsTest(ConnectionMode mode) + { + // Fail Read + try + { + Container container = await this.CreateClientAndContainer(mode, Microsoft.Azure.Cosmos.ConsistencyLevel.ConsistentPrefix); + + await container.ReadItemAsync( + new Guid().ToString(), + new Cosmos.PartitionKey(new Guid().ToString()), + new ItemRequestOptions() + { + BaseConsistencyLevel = Microsoft.Azure.Cosmos.ConsistencyLevel.Eventual // overriding client level consistency + }); + } + catch (CosmosException ce) when (ce.StatusCode == HttpStatusCode.NotFound) + { + string message = ce.ToString(); + Assert.IsNotNull(message); + } + + IDictionary expectedRecordCountInOperation = new Dictionary + { + { Documents.OperationType.Read.ToString(), 1} + }; + + await this.WaitAndAssert(expectedOperationCount: 2, + expectedConsistencyLevel: Microsoft.Azure.Cosmos.ConsistencyLevel.Eventual, + expectedOperationRecordCountMap: expectedRecordCountInOperation, + expectedCacheSource: null, + isExpectedNetworkTelemetry: false); + } + + public virtual async Task StreamReadFailureOperationsTest(ConnectionMode mode) + { + Container container = await this.CreateClientAndContainer(mode); + + // Fail Read + try + { + await container.ReadItemStreamAsync( + new Guid().ToString(), + new Cosmos.PartitionKey(new Guid().ToString()), + new ItemRequestOptions() + { + BaseConsistencyLevel = Microsoft.Azure.Cosmos.ConsistencyLevel.ConsistentPrefix // Request level consistency + }); + } + catch (CosmosException ce) when (ce.StatusCode == HttpStatusCode.NotFound) + { + string message = ce.ToString(); + Assert.IsNotNull(message); + } + + IDictionary expectedRecordCountInOperation = new Dictionary + { + { Documents.OperationType.Read.ToString(), 1} + }; + + await this.WaitAndAssert(expectedOperationCount: 2, + expectedConsistencyLevel: Microsoft.Azure.Cosmos.ConsistencyLevel.ConsistentPrefix, + expectedOperationRecordCountMap: expectedRecordCountInOperation, + expectedCacheSource: null, + isExpectedNetworkTelemetry: false); + } + + public virtual async Task StreamOperationsTest(ConnectionMode mode) + { + Container container = await this.CreateClientAndContainer(mode); + + // Create an item + var testItem = new { id = "MyTestItemId", partitionKeyPath = "MyTestPkValue", details = "it's working", status = "done" }; + await container + .CreateItemStreamAsync(TestCommon.SerializerCore.ToStream(testItem), + new Cosmos.PartitionKey(testItem.id)); + + //Upsert an Item + await container.UpsertItemStreamAsync(TestCommon.SerializerCore.ToStream(testItem), new Cosmos.PartitionKey(testItem.id)); + + //Read an Item + await container.ReadItemStreamAsync(testItem.id, new Cosmos.PartitionKey(testItem.id)); + + //Replace an Item + await container.ReplaceItemStreamAsync(TestCommon.SerializerCore.ToStream(testItem), testItem.id, new Cosmos.PartitionKey(testItem.id)); + + // Patch an Item + List patch = new List() + { + PatchOperation.Add("/new", "patched") + }; + await ((ContainerInternal)container).PatchItemStreamAsync( + partitionKey: new Cosmos.PartitionKey(testItem.id), + id: testItem.id, + patchOperations: patch); + + //Delete an Item + await container.DeleteItemStreamAsync(testItem.id, new Cosmos.PartitionKey(testItem.id)); + + IDictionary expectedRecordCountInOperation = new Dictionary + { + { Documents.OperationType.Create.ToString(), 1}, + { Documents.OperationType.Upsert.ToString(), 1}, + { Documents.OperationType.Read.ToString(), 1}, + { Documents.OperationType.Replace.ToString(), 1}, + { Documents.OperationType.Patch.ToString(), 1}, + { Documents.OperationType.Delete.ToString(), 1} + }; + + await this.WaitAndAssert(expectedOperationCount: 12, + expectedOperationRecordCountMap: expectedRecordCountInOperation, + expectedCacheSource: null); + } + + public virtual async Task BatchOperationsTest(ConnectionMode mode) + { + Container container = await this.CreateClientAndContainer(mode, Microsoft.Azure.Cosmos.ConsistencyLevel.Eventual); // Client level consistency + using (BatchAsyncContainerExecutor executor = + new BatchAsyncContainerExecutor( + (ContainerInlineCore)container, + ((ContainerInlineCore)container).ClientContext, + 20, + Documents.Constants.MaxDirectModeBatchRequestBodySizeInBytes) + ) + { + List> tasks = new List>(); + for (int i = 0; i < 10; i++) + { + tasks.Add(executor.AddAsync(CreateItem(i.ToString()), NoOpTrace.Singleton, default)); + } + + await Task.WhenAll(tasks); + } + + IDictionary expectedRecordCountInOperation = new Dictionary + { + { Documents.OperationType.Batch.ToString(), 1} + }; + + await this.WaitAndAssert(expectedOperationCount: 2, + expectedConsistencyLevel: Microsoft.Azure.Cosmos.ConsistencyLevel.Eventual, + expectedOperationRecordCountMap: expectedRecordCountInOperation); + } + + public virtual async Task SingleOperationMultipleTimesTest(ConnectionMode mode) + { + Container container = await this.CreateClientAndContainer(mode); + + // Create an item + ToDoActivity testItem = ToDoActivity.CreateRandomToDoActivity(); + + await container.CreateItemAsync(testItem, requestOptions: new ItemRequestOptions()); + + for (int count = 0; count < 50; count++) + { + // Read an Item + await container.ReadItemAsync(testItem.id, new Cosmos.PartitionKey(testItem.id)); + } + + IDictionary expectedRecordCountInOperation = new Dictionary + { + { Documents.OperationType.Read.ToString(), 50}, + { Documents.OperationType.Create.ToString(), 1} + }; + + await this.WaitAndAssert( + expectedOperationCount: 4,// 2 (read, requestLatency + requestCharge) + 2 (create, requestLatency + requestCharge) + expectedOperationRecordCountMap: expectedRecordCountInOperation); + } + + public virtual async Task QueryOperationSinglePartitionTest(ConnectionMode mode) + { + Container container = await this.CreateClientAndContainer(mode); + + ToDoActivity testItem = ToDoActivity.CreateRandomToDoActivity("MyTestPkValue", "MyTestItemId"); + ItemRequestOptions requestOptions = new ItemRequestOptions() + { + ConsistencyLevel = Microsoft.Azure.Cosmos.ConsistencyLevel.ConsistentPrefix + }; + + ItemResponse createResponse = await container.CreateItemAsync( + item: testItem, + requestOptions: requestOptions); + + QueryRequestOptions queryRequestOptions = new QueryRequestOptions() + { + EnableOptimisticDirectExecution = false, + ConsistencyLevel = Microsoft.Azure.Cosmos.ConsistencyLevel.ConsistentPrefix, + }; + + List families = new List(); + if (createResponse.StatusCode == HttpStatusCode.Created) + { + string sqlQueryText = "SELECT * FROM c"; + + QueryDefinition queryDefinition = new QueryDefinition(sqlQueryText); + using (FeedIterator queryResultSetIterator = container.GetItemQueryIterator( + queryDefinition: queryDefinition, + requestOptions: queryRequestOptions)) + { + while (queryResultSetIterator.HasMoreResults) + { + FeedResponse currentResultSet = await queryResultSetIterator.ReadNextAsync(); + foreach (object family in currentResultSet) + { + families.Add(family); + } + } + } + + Assert.AreEqual(1, families.Count); + + } + + IDictionary expectedRecordCountInOperation = new Dictionary + { + { Documents.OperationType.Query.ToString(), 1}, + { Documents.OperationType.Create.ToString(), 1} + }; + + await this.WaitAndAssert(expectedOperationCount: 4, + expectedOperationRecordCountMap: expectedRecordCountInOperation, + expectedConsistencyLevel: Microsoft.Azure.Cosmos.ConsistencyLevel.ConsistentPrefix); + } + + public virtual async Task QueryMultiPageSinglePartitionOperationTest(ConnectionMode mode) + { + Container container = await this.CreateClientAndContainer(mode: mode); + + ItemRequestOptions requestOptions = new ItemRequestOptions() + { + ConsistencyLevel = Microsoft.Azure.Cosmos.ConsistencyLevel.ConsistentPrefix + }; + + ToDoActivity testItem1 = ToDoActivity.CreateRandomToDoActivity("MyTestPkValue1", "MyTestItemId1"); + ItemResponse createResponse1 = await container.CreateItemAsync( + item: testItem1, + requestOptions: requestOptions); + ToDoActivity testItem2 = ToDoActivity.CreateRandomToDoActivity("MyTestPkValue2", "MyTestItemId2"); + ItemResponse createResponse2 = await container.CreateItemAsync( + item: testItem2, + requestOptions: requestOptions); + + if (createResponse1.StatusCode == HttpStatusCode.Created && + createResponse2.StatusCode == HttpStatusCode.Created) + { + string sqlQueryText = "SELECT * FROM c"; + + List families = new List(); + QueryDefinition queryDefinition = new QueryDefinition(sqlQueryText); + using (FeedIterator queryResultSetIterator = container.GetItemQueryIterator( + queryDefinition: queryDefinition, + requestOptions: new QueryRequestOptions() + { + EnableOptimisticDirectExecution = false, + ConsistencyLevel = Microsoft.Azure.Cosmos.ConsistencyLevel.ConsistentPrefix, + MaxItemCount = 1 + })) + { + while (queryResultSetIterator.HasMoreResults) + { + FeedResponse currentResultSet = await queryResultSetIterator.ReadNextAsync(); + foreach (object family in currentResultSet) + { + families.Add(family); + } + } + } + + Assert.AreEqual(2, families.Count); + + } + + IDictionary expectedRecordCountInOperation = new Dictionary + { + { Documents.OperationType.Query.ToString(), 3}, + { Documents.OperationType.Create.ToString(), 2} + }; + + await this.WaitAndAssert( + expectedOperationCount: 4, + expectedOperationRecordCountMap: expectedRecordCountInOperation, + expectedConsistencyLevel: Microsoft.Azure.Cosmos.ConsistencyLevel.ConsistentPrefix); + } + + public virtual async Task QueryOperationCrossPartitionTest(ConnectionMode mode) + { + ContainerInternal itemsCore = (ContainerInternal)await this.CreateClientAndContainer( + mode: mode, + isLargeContainer: true); + + // Verify container has multiple partitions + int pkRangesCount = (await itemsCore.ClientContext.DocumentClient.ReadPartitionKeyRangeFeedAsync(itemsCore.LinkUri)).Count; + Assert.IsTrue(pkRangesCount > 1, "Should have created a multi partition container."); + + Container container = (Container)itemsCore; + + await ToDoActivity.CreateRandomItems( + container: container, + pkCount: 2, + perPKItemCount: 5); + + string sqlQueryText = "SELECT * FROM c"; + + List families = new List(); + + QueryDefinition queryDefinition = new QueryDefinition(sqlQueryText); + using (FeedIterator queryResultSetIterator = container.GetItemQueryIterator(queryDefinition)) + { + while (queryResultSetIterator.HasMoreResults) + { + FeedResponse currentResultSet = await queryResultSetIterator.ReadNextAsync(); + foreach (object family in currentResultSet) + { + families.Add(family); + } + } + } + + Assert.AreEqual(10, families.Count); + + IDictionary expectedRecordCountInOperation = new Dictionary + { + { Documents.OperationType.Query.ToString(), pkRangesCount}, + { Documents.OperationType.Create.ToString(), 10} + }; + + await this.WaitAndAssert( + expectedOperationCount: 4, + expectedOperationRecordCountMap: expectedRecordCountInOperation); + } + + public virtual async Task QueryOperationMutiplePageCrossPartitionTest(ConnectionMode mode) + { + ContainerInternal itemsCore = (ContainerInternal)await this.CreateClientAndContainer( + mode: mode, + isLargeContainer: true); + + // Verify container has multiple partitions + int pkRangesCount = (await itemsCore.ClientContext.DocumentClient.ReadPartitionKeyRangeFeedAsync(itemsCore.LinkUri)).Count; + Assert.IsTrue(pkRangesCount > 1, "Should have created a multi partition container."); + + Container container = (Container)itemsCore; + + await ToDoActivity.CreateRandomItems( + container: container, + pkCount: 2, + perPKItemCount: 5); + + string sqlQueryText = "SELECT * FROM c"; + + List families = new List(); + QueryDefinition queryDefinition = new QueryDefinition(sqlQueryText); + using (FeedIterator queryResultSetIterator = container.GetItemQueryIterator( + queryDefinition: queryDefinition, + requestOptions: new QueryRequestOptions() + { + MaxItemCount = 1 + })) + { + while (queryResultSetIterator.HasMoreResults) + { + FeedResponse currentResultSet = await queryResultSetIterator.ReadNextAsync(); + foreach (object family in currentResultSet) + { + families.Add(family); + } + } + } + + Assert.AreEqual(10, families.Count); + + IDictionary expectedRecordCountInOperation = new Dictionary + { + { Documents.OperationType.Query.ToString(), pkRangesCount + 10}, // 10 is number of items + { Documents.OperationType.Create.ToString(), 10} + }; + + await this.WaitAndAssert( + expectedOperationCount: 4, + expectedOperationRecordCountMap: expectedRecordCountInOperation); + } + + public virtual async Task QueryOperationInvalidContinuationTokenTest(ConnectionMode mode) + { + Container container = await this.CreateClientAndContainer(mode); + + // Create an item : First successful request to load Cache + ToDoActivity testItem = ToDoActivity.CreateRandomToDoActivity("MyTestPkValue"); + await container.CreateItemAsync(testItem); + + List results = new List(); + using (FeedIterator resultSetIterator = container.GetItemQueryIterator( + "SELECT * FROM c", + continuationToken: "dummy token")) + { + try + { + while (resultSetIterator.HasMoreResults) + { + FeedResponse response = await resultSetIterator.ReadNextAsync(); + results.AddRange(response); + } + } + catch (CosmosException ce) when (ce.StatusCode == HttpStatusCode.BadRequest) + { + string message = ce.ToString(); + Assert.IsNotNull(message); + } + } + + IDictionary expectedRecordCountInOperation = new Dictionary + { + { Documents.OperationType.Create.ToString(), 1} + }; + + await this.WaitAndAssert(expectedOperationCount: 2, + expectedOperationRecordCountMap: expectedRecordCountInOperation); + } + + public virtual async Task CreateItemWithSubStatusCodeTest(ConnectionMode mode) + { + HttpClientHandlerHelper httpHandler = new HttpClientHandlerHelper(); + HttpClient httpClient = new HttpClient(httpHandler); + + httpHandler.RequestCallBack = (request, cancellation) => + { + if (request.RequestUri.AbsoluteUri.Equals(telemetryServiceEndpoint.AbsoluteUri)) + { + string jsonObject = request.Content.ReadAsStringAsync().GetAwaiter().GetResult(); + + lock (this.actualInfo) + { + this.actualInfo.Add(JsonConvert.DeserializeObject(jsonObject)); + } + } + else if (request.Method == HttpMethod.Get && request.RequestUri.AbsolutePath == "//addresses/") + { + HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.Forbidden); + + // Add a substatus code that is not part of the enum. + // This ensures that if the backend adds a enum the status code is not lost. + result.Headers.Add(WFConstants.BackendHeaders.SubStatus, 999999.ToString(CultureInfo.InvariantCulture)); + + string payload = JsonConvert.SerializeObject(new Error() { Message = "test message" }); + result.Content = new StringContent(payload, Encoding.UTF8, "application/json"); + + return Task.FromResult(result); + } + return this.HttpHandlerRequestCallbackChecks(request); + }; + + // Replacing originally initialized cosmos Builder with this one with new handler + this.cosmosClientBuilder = this.cosmosClientBuilder + .WithClientTelemetryOptions(new CosmosClientTelemetryOptions() + { + DisableSendingMetricsToService = false + }) + .WithHttpClientFactory(() => new HttpClient(httpHandler)); + + Container container = await this.CreateClientAndContainer( + mode: mode, + customHttpHandler: httpHandler); + try + { + ToDoActivity testItem = ToDoActivity.CreateRandomToDoActivity("MyTestPkValue"); + ItemResponse createResponse = await container.CreateItemAsync(testItem); + Assert.Fail("Request should throw exception."); + } + catch (CosmosException ce) when (ce.StatusCode == HttpStatusCode.Forbidden) + { + Assert.AreEqual(999999, ce.SubStatusCode); + } + + IDictionary expectedRecordCountInOperation = new Dictionary + { + { Documents.OperationType.Create.ToString(), 1} + }; + + await this.WaitAndAssert(expectedOperationCount: 2, + expectedOperationRecordCountMap: expectedRecordCountInOperation, + expectedSubstatuscode: 999999, + isExpectedNetworkTelemetry: false); + + } + + /// + /// This method wait for the expected operations to get recorded by telemetry and assert the values + /// + /// Expected number of unique OperationInfo irrespective of response size. + /// Expected Consistency level of the operation recorded by telemetry + /// Expected number of requests recorded for each operation + /// + private async Task WaitAndAssert( + int expectedOperationCount = 0, + Microsoft.Azure.Cosmos.ConsistencyLevel? expectedConsistencyLevel = null, + IDictionary expectedOperationRecordCountMap = null, + int expectedSubstatuscode = 0, + bool? isAzureInstance = null, + string expectedCacheSource = "ClientCollectionCache", + bool isExpectedNetworkTelemetry = true) + { + Assert.IsNotNull(this.actualInfo, "Telemetry Information not available"); + + // As this feature is thread based execution so wait for the results to avoid test flakiness + List localCopyOfActualInfo = null; + ValueStopwatch stopwatch = ValueStopwatch.StartNew(); + + HashSet cacheRefreshInfoSet = new HashSet(); + do + { + await Task.Delay(TimeSpan.FromMilliseconds(1500)); // wait at least for 1 round of telemetry + + HashSet actualOperationSet = new HashSet(); + HashSet requestInfoSet = new HashSet(); + + lock (this.actualInfo) + { + // Setting the number of unique OperationInfo irrespective of response size as response size is varying in case of queries. + this.actualInfo + .ForEach(x => + { + if (x.CacheRefreshInfo != null && x.CacheRefreshInfo.Count > 0) + { + x.CacheRefreshInfo + .ForEach(y => + { + y.GreaterThan1Kb = false; + cacheRefreshInfoSet.Add(y); + }); + + } + + x.OperationInfo + .ForEach(y => + { + y.GreaterThan1Kb = false; + actualOperationSet.Add(y); + }); + }); + + if (actualOperationSet.Count == expectedOperationCount / 2) + { + // Copy the list to avoid it being modified while validating + localCopyOfActualInfo = new List(this.actualInfo); + break; + } + + Assert.IsTrue(stopwatch.Elapsed.TotalMinutes < 1, $"The expected operation count({expectedOperationCount}) was never hit, Actual Operation Count is {actualOperationSet.Count}. ActualInfo:{JsonConvert.SerializeObject(this.actualInfo)}"); + } + } + while (localCopyOfActualInfo == null); + + List actualOperationList = new List(); + List actualSystemInformation = new List(); + List actualRequestInformation = new List(); + + if (localCopyOfActualInfo[0].ConnectionMode == ConnectionMode.Direct.ToString().ToUpperInvariant()) + { + ClientTelemetryTestsBase.expectedMetricNameUnitMap.TryAdd(ClientTelemetryOptions.NumberOfTcpConnectionName, ClientTelemetryOptions.NumberOfTcpConnectionUnit); + } + else + { + ClientTelemetryTestsBase.expectedMetricNameUnitMap.Remove(ClientTelemetryOptions.NumberOfTcpConnectionName); + } + + ClientTelemetryTestsBase.AssertAccountLevelInformation( + localCopyOfActualInfo: localCopyOfActualInfo, + actualOperationList: actualOperationList, + actualSystemInformation: actualSystemInformation, + actualRequestInformation: actualRequestInformation, + isAzureInstance: isAzureInstance); + + ClientTelemetryTestsBase.AssertOperationLevelInformation( + expectedConsistencyLevel: expectedConsistencyLevel, + expectedOperationRecordCountMap: expectedOperationRecordCountMap, + actualOperationList: actualOperationList, + expectedSubstatuscode: expectedSubstatuscode); + + if(!string.IsNullOrEmpty(expectedCacheSource)) + { + Assert.IsTrue(cacheRefreshInfoSet.Count > 0, "Cache Refresh Information is not there"); + + ClientTelemetryTestsBase.AssertCacheRefreshInfoInformation( + cacheRefreshInfoSet: cacheRefreshInfoSet, + expectedCacheSource: expectedCacheSource); + } + + ClientTelemetryTestsBase.AssertSystemLevelInformation(actualSystemInformation, ClientTelemetryTestsBase.expectedMetricNameUnitMap); + if (localCopyOfActualInfo.First().ConnectionMode == ConnectionMode.Direct.ToString().ToUpperInvariant()) + { + if (isExpectedNetworkTelemetry) + { + ClientTelemetryTestsBase.AssertNetworkLevelInformation(actualRequestInformation); + } + } + else + { + Assert.IsTrue(actualRequestInformation == null || actualRequestInformation.Count == 0, $"Request Information is not expected in {localCopyOfActualInfo.First().ConnectionMode} mode"); + } + } + + private static void AssertNetworkLevelInformation(List actualRequestInformation) + { + Assert.IsNotNull(actualRequestInformation); + Assert.IsTrue(actualRequestInformation.Count > 0); + + foreach(RequestInfo requestInfo in actualRequestInformation) + { + Assert.IsNotNull(requestInfo.Uri); + Assert.IsNotNull(requestInfo.DatabaseName); + Assert.IsNotNull(requestInfo.ContainerName); + Assert.IsNotNull(requestInfo.Operation); + Assert.IsNotNull(requestInfo.Resource); + Assert.IsNotNull(requestInfo.StatusCode); + Assert.AreNotEqual(0, requestInfo.StatusCode); + Assert.IsNotNull(requestInfo.SubStatusCode); + + Assert.IsNotNull(requestInfo.Metrics, "MetricInfo is null"); + } + } + + private static void AssertSystemLevelInformation(List actualSystemInformation, IDictionary expectedMetricNameUnitMap) + { + IDictionary actualMetricNameUnitMap = new Dictionary(); + + // Asserting If system information list is as expected + foreach (SystemInfo systemInfo in actualSystemInformation) + { + Assert.AreEqual("HostMachine", systemInfo.Resource); + Assert.IsNotNull(systemInfo.MetricInfo, "MetricInfo is null"); + + if(!actualMetricNameUnitMap.TryAdd(systemInfo.MetricInfo.MetricsName, systemInfo.MetricInfo.UnitName)) + { + Assert.AreEqual(systemInfo.MetricInfo.UnitName, actualMetricNameUnitMap[systemInfo.MetricInfo.MetricsName]); + } + + if(!systemInfo.MetricInfo.MetricsName.Equals(ClientTelemetryOptions.IsThreadStarvingName) && + !systemInfo.MetricInfo.MetricsName.Equals(ClientTelemetryOptions.ThreadWaitIntervalInMsName)) + { + Assert.IsTrue(systemInfo.MetricInfo.Count > 0, $"MetricInfo ({systemInfo.MetricInfo.MetricsName}) Count is not greater than 0"); + Assert.IsNotNull(systemInfo.MetricInfo.Percentiles, $"Percentiles is null for metrics ({systemInfo.MetricInfo.MetricsName})"); + } + Assert.IsTrue(systemInfo.MetricInfo.Mean >= 0, $"MetricInfo ({systemInfo.MetricInfo.MetricsName}) Mean is not greater than or equal to 0"); + Assert.IsTrue(systemInfo.MetricInfo.Max >= 0, $"MetricInfo ({systemInfo.MetricInfo.MetricsName}) Max is not greater than or equal to 0"); + Assert.IsTrue(systemInfo.MetricInfo.Min >= 0, $"MetricInfo ({systemInfo.MetricInfo.MetricsName}) Min is not greater than or equal to 0"); + if (systemInfo.MetricInfo.MetricsName.Equals(ClientTelemetryOptions.CpuName)) + { + Assert.IsTrue(systemInfo.MetricInfo.Mean <= 100, $"MetricInfo ({systemInfo.MetricInfo.MetricsName}) Mean is not greater than 100 for CPU Usage"); + Assert.IsTrue(systemInfo.MetricInfo.Max <= 100, $"MetricInfo ({systemInfo.MetricInfo.MetricsName}) Max is not greater than 100 for CPU Usage"); + Assert.IsTrue(systemInfo.MetricInfo.Min <= 100, $"MetricInfo ({systemInfo.MetricInfo.MetricsName}) Min is not greater than 100 for CPU Usage"); + }; + } + + Assert.IsTrue(expectedMetricNameUnitMap.EqualsTo(actualMetricNameUnitMap), $"Actual System Information metric i.e {string.Join(", ", actualMetricNameUnitMap)} is not matching with expected System Information Metric i.e. {string.Join(", ", expectedMetricNameUnitMap)}"); + + } + + private static void AssertOperationLevelInformation( + Microsoft.Azure.Cosmos.ConsistencyLevel? expectedConsistencyLevel, + IDictionary expectedOperationRecordCountMap, + List actualOperationList, + int expectedSubstatuscode = 0) + { + IDictionary actualOperationRecordCountMap = new Dictionary(); + // Asserting If operation list is as expected + foreach (OperationInfo operation in actualOperationList) + { + Assert.IsNotNull(operation.Operation, "Operation Type is null"); + Assert.IsNotNull(operation.Resource, "Resource Type is null"); + + Assert.AreEqual(expectedSubstatuscode, operation.SubStatusCode); + Assert.AreEqual(expectedConsistencyLevel?.ToString(), operation.Consistency, $"Consistency is not {expectedConsistencyLevel}"); + + Assert.IsNotNull(operation.MetricInfo, "MetricInfo is null"); + Assert.IsNotNull(operation.MetricInfo.MetricsName, "MetricsName is null"); + Assert.IsNotNull(operation.MetricInfo.UnitName, "UnitName is null"); + Assert.IsNotNull(operation.MetricInfo.Percentiles, "Percentiles is null"); + Assert.IsTrue(operation.MetricInfo.Count > 0, "MetricInfo Count is not greater than 0"); + Assert.IsTrue(operation.MetricInfo.Mean >= 0, "MetricInfo Mean is not greater than or equal to 0"); + Assert.IsTrue(operation.MetricInfo.Max >= 0, "MetricInfo Max is not greater than or equal to 0"); + Assert.IsTrue(operation.MetricInfo.Min >= 0, "MetricInfo Min is not greater than or equal to 0"); + + if (operation.MetricInfo.MetricsName.Equals(ClientTelemetryOptions.RequestLatencyName)) // putting this condition to avoid doubling of count as we have same information for each metrics + { + if (!actualOperationRecordCountMap.TryGetValue(operation.Operation, out long recordCount)) + { + actualOperationRecordCountMap.Add(operation.Operation, operation.MetricInfo.Count); + } + else + { + actualOperationRecordCountMap.Remove(operation.Operation); + actualOperationRecordCountMap.Add(operation.Operation, recordCount + operation.MetricInfo.Count); + } + } + } + + if (expectedOperationRecordCountMap != null) + { + Assert.IsTrue(expectedOperationRecordCountMap.EqualsTo(actualOperationRecordCountMap), $"actual record i.e. ({string.Join(", ", actualOperationRecordCountMap)}) for operation does not match with expected record i.e. ({string.Join(", ", expectedOperationRecordCountMap)})"); + } + } + + private static void AssertAccountLevelInformation( + List localCopyOfActualInfo, + List actualOperationList, + List actualSystemInformation, + List actualRequestInformation, + bool? isAzureInstance) + { + ISet machineId = new HashSet(); + + // Asserting If basic client telemetry object is as expected + foreach (ClientTelemetryProperties telemetryInfo in localCopyOfActualInfo) + { + if (telemetryInfo.OperationInfo != null) + { + actualOperationList.AddRange(telemetryInfo.OperationInfo); + } + + if (telemetryInfo.SystemInfo != null) + { + foreach (SystemInfo sysInfo in telemetryInfo.SystemInfo) + { + actualSystemInformation.Add(sysInfo); + } + } + + if (telemetryInfo.RequestInfo != null) + { + actualRequestInformation.AddRange(telemetryInfo.RequestInfo); + } + + if (telemetryInfo.ConnectionMode == ConnectionMode.Direct.ToString().ToUpperInvariant()) + { + Assert.AreEqual(6, telemetryInfo.SystemInfo.Count, $"System Information Count doesn't Match; {JsonConvert.SerializeObject(telemetryInfo.SystemInfo)}"); + } + else + { + Assert.AreEqual(5, telemetryInfo.SystemInfo.Count, $"System Information Count doesn't Match; {JsonConvert.SerializeObject(telemetryInfo.SystemInfo)}"); + } + + Assert.IsNotNull(telemetryInfo.GlobalDatabaseAccountName, "GlobalDatabaseAccountName is null"); + Assert.IsNotNull(telemetryInfo.DateTimeUtc, "Timestamp is null"); + Assert.AreEqual(2, telemetryInfo.PreferredRegions.Count); + Assert.AreEqual(Regions.EastUS, telemetryInfo.PreferredRegions[0]); + Assert.AreEqual(Regions.WestUS2, telemetryInfo.PreferredRegions[1]); + Assert.AreEqual(1, telemetryInfo.AggregationIntervalInSec); + Assert.IsNull(telemetryInfo.AcceleratedNetworking); + Assert.IsNotNull(telemetryInfo.ClientId); + Assert.IsNotNull(telemetryInfo.ProcessId); + Assert.AreEqual(HashingExtension.ComputeHash(System.Diagnostics.Process.GetCurrentProcess().ProcessName), telemetryInfo.ProcessId); + Assert.IsNotNull(telemetryInfo.UserAgent); + Assert.IsFalse(telemetryInfo.UserAgent.Contains("userAgentSuffix"), "Useragent should not have suffix appended"); // Useragent should not contain useragentsuffix as it can have PII + Assert.IsNotNull(telemetryInfo.ConnectionMode); + + if (!string.IsNullOrEmpty(telemetryInfo.MachineId)) + { + machineId.Add(telemetryInfo.MachineId); + } + } + + if (isAzureInstance.HasValue) + { + if (isAzureInstance.Value) + { + Assert.IsTrue(machineId.First().StartsWith(VmMetadataApiHandler.VmIdPrefix), $"Generated Machine id is : {machineId.First()}"); + } + else + { + Assert.IsTrue(machineId.First().StartsWith(VmMetadataApiHandler.HashedMachineNamePrefix), $"Generated Machine id is : {machineId.First()}"); + } + } + + Assert.AreEqual(1, machineId.Count, $"Multiple Machine Id has been generated i.e {JsonConvert.SerializeObject(machineId)}"); + } + + private static void AssertCacheRefreshInfoInformation( + HashSet cacheRefreshInfoSet, + string expectedCacheSource) + { + foreach(CacheRefreshInfo cacheRefreshInfo in cacheRefreshInfoSet) + { + Assert.IsNotNull(cacheRefreshInfo.CacheRefreshSource); + Assert.IsTrue(expectedCacheSource.Contains(cacheRefreshInfo.CacheRefreshSource)); + Assert.IsNotNull(cacheRefreshInfo.Operation, "Operation Type is null"); + Assert.IsNotNull(cacheRefreshInfo.Resource, "Resource Type is null"); + Assert.IsNotNull(cacheRefreshInfo.StatusCode, "StatusCode is null"); + Assert.IsNotNull(cacheRefreshInfo.SubStatusCode); + Assert.IsNull(cacheRefreshInfo.Consistency); + Assert.IsNotNull(cacheRefreshInfo.ContainerName, "ContainerName is null"); + Assert.IsNotNull(cacheRefreshInfo.MetricInfo, "MetricInfo is null"); + Assert.IsNotNull(cacheRefreshInfo.MetricInfo.MetricsName, "MetricsName is null"); + Assert.IsNotNull(cacheRefreshInfo.MetricInfo.UnitName, "UnitName is null"); + Assert.IsNotNull(cacheRefreshInfo.MetricInfo.Percentiles, "Percentiles is null"); + Assert.IsTrue(cacheRefreshInfo.MetricInfo.Count >= 0, "MetricInfo Count is not greater than 0"); + Assert.IsTrue(cacheRefreshInfo.MetricInfo.Mean >= 0, "MetricInfo Mean is not greater than or equal to 0"); + Assert.IsTrue(cacheRefreshInfo.MetricInfo.Max >= 0, "MetricInfo Max is not greater than or equal to 0"); + Assert.IsTrue(cacheRefreshInfo.MetricInfo.Min >= 0, "MetricInfo Min is not greater than or equal to 0"); + } + } + + private static ItemBatchOperation CreateItem(string itemId) + { + var testItem = new { id = itemId, Status = itemId }; + return new ItemBatchOperation(Documents.OperationType.Create, 0, new Cosmos.PartitionKey(itemId), itemId, TestCommon.SerializerCore.ToStream(testItem)); + } + + private async Task CreateClientAndContainer(ConnectionMode mode, + Microsoft.Azure.Cosmos.ConsistencyLevel? consistency = null, + bool isLargeContainer = false, + bool isAzureInstance = true, + HttpClientHandlerHelper customHttpHandler = null) + { + if (consistency.HasValue) + { + this.cosmosClientBuilder = this.cosmosClientBuilder + .WithConsistencyLevel(consistency.Value); + } + + HttpClientHandlerHelper handlerHelper = customHttpHandler ?? (isAzureInstance ? this.httpHandler : this.httpHandlerForNonAzureInstance); + this.cosmosClientBuilder = this.cosmosClientBuilder + .WithHttpClientFactory(() => new HttpClient(handlerHelper)) + .WithApplicationName("userAgentSuffix"); + + this.SetClient(mode == ConnectionMode.Gateway + ? this.cosmosClientBuilder.WithConnectionModeGateway().Build() + : this.cosmosClientBuilder.Build()); + + // Making sure client telemetry is enabled + Assert.IsNotNull(this.GetClient().DocumentClient.telemetryToServiceHelper); + + this.database = await this.GetClient().CreateDatabaseAsync(Guid.NewGuid().ToString()); + + return await this.database.CreateContainerAsync( + id: Guid.NewGuid().ToString(), + partitionKeyPath: "/id", + throughput: isLargeContainer? 15000 : 400); + + } + } +} diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosBasicQueryTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosBasicQueryTests.cs index 25ac9a705f..bfd6366104 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosBasicQueryTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosBasicQueryTests.cs @@ -15,7 +15,6 @@ namespace Microsoft.Azure.Cosmos.SDK.EmulatorTests using Cosmos.Scripts; using Microsoft.Azure.Cosmos.Fluent; using Microsoft.Azure.Cosmos.Linq; - using Microsoft.Azure.Cosmos.Query.Core; using Microsoft.Azure.Cosmos.Tracing; using Microsoft.Azure.Documents.Collections; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -786,6 +785,58 @@ public async Task QueryActivityIdWithContinuationTokenAndTraceTest() } + //TODO: Remove Ignore flag once emulator is updated to 0415 + [Ignore] + [TestMethod] + public async Task TesOdeTokenCompatibilityWithNonOdePipeline() + { + string query = "select top 200 * from c"; + CosmosClient client = DirectCosmosClient; + Container container = client.GetContainer(DatabaseId, ContainerId); + + // Create items + for (int i = 0; i < 500; i++) + { + await container.CreateItemAsync(ToDoActivity.CreateRandomToDoActivity()); + } + + QueryRequestOptions queryRequestOptions = new QueryRequestOptions + { + MaxItemCount = 50, + EnableOptimisticDirectExecution = true + }; + + FeedIteratorInternal feedIterator = + (FeedIteratorInternal)container.GetItemQueryStreamIterator( + query, + null, + queryRequestOptions); + + ResponseMessage responseMessage = await feedIterator.ReadNextAsync(CancellationToken.None); + string continuationToken = responseMessage.ContinuationToken; + + QueryRequestOptions newQueryRequestOptions = new QueryRequestOptions + { + MaxItemCount = 50, + EnableOptimisticDirectExecution = false + }; + + // use Continuation Token to create new iterator and use same trace + FeedIterator feedIteratorNew = + container.GetItemQueryStreamIterator( + query, + continuationToken, + newQueryRequestOptions); + + while (feedIteratorNew.HasMoreResults) + { + responseMessage = await feedIteratorNew.ReadNextAsync(CancellationToken.None); + } + + string expectedErrorMessage = "The continuation token supplied requires the Optimistic Direct Execution flag to be enabled in QueryRequestOptions for the query execution to resume. "; + Assert.IsTrue(responseMessage.CosmosException.ToString().Contains(expectedErrorMessage)); + } + private class CustomHandler : RequestHandler { string correlatedActivityId; diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosItemLinqTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosItemLinqTests.cs index b3dc7afa41..efffeae1cb 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosItemLinqTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosItemLinqTests.cs @@ -878,9 +878,65 @@ async Task TestSearch(Expression> expression, string ex await TestSearch(x => x.description.Contains("todo"), "CONTAINS", false, 0); await TestSearch(x => x.description.Contains("tOdO", StringComparison.OrdinalIgnoreCase), "CONTAINS", true, 200); - } + [TestMethod] + public async Task LinqAggregatesWithContinuationTokenTest() + { + await ToDoActivity.CreateRandomItems(container: this.Container, pkCount: 1, perPKItemCount: 2, randomPartitionKey: true); + + QueryRequestOptions requestOptions = new QueryRequestOptions() + { + MaxItemCount = 1 + }; + + IOrderedQueryable firstQuery = this.Container.GetItemLinqQueryable(allowSynchronousQueryExecution: true, requestOptions: requestOptions); + + int count = await firstQuery.CountAsync(); + double average = firstQuery.Average(x => x.taskNum); + + string continuationToken = null; + + FeedIterator firstFeedIterator = firstQuery.ToFeedIterator(); + + // if instead of while loop in order to retrieve continuation token + if (firstFeedIterator.HasMoreResults) + { + FeedResponse firstFeedResponse = await firstFeedIterator.ReadNextAsync(); + + continuationToken = firstFeedResponse.ContinuationToken; + } + + Assert.AreEqual(2, count); + Assert.IsNotNull(continuationToken); + + IOrderedQueryable secondQuery = this.Container.GetItemLinqQueryable(allowSynchronousQueryExecution: true, continuationToken: continuationToken, requestOptions: requestOptions); + + try + { + count = await secondQuery.CountAsync(); + Assert.Fail("Expected Count query to return exception"); + } + catch (CosmosException exception) + { + Assert.IsTrue(exception.StatusCode == System.Net.HttpStatusCode.BadRequest); + Assert.IsTrue(exception.SubStatusCode == (int)Documents.SubStatusCodes.MalformedContinuationToken); + Assert.IsTrue(exception.Message.Contains("ParallelCrossPartitionQueryPipelineStage")); + } + + try + { + average = secondQuery.Average(x => x.taskNum); + Assert.Fail("Expected Average query to return exception"); + } + catch (CosmosException exception) + { + Assert.IsTrue(exception.StatusCode == System.Net.HttpStatusCode.BadRequest); + Assert.IsTrue(exception.SubStatusCode == (int)Documents.SubStatusCodes.MalformedContinuationToken); + Assert.IsTrue(exception.Message.Contains("ParallelCrossPartitionQueryPipelineStage")); + } + } + [TestMethod] public async Task LinqSelectEverythingWithoutQueryableTest() { @@ -911,7 +967,6 @@ private class NumberLinqItem public decimal decimaleValue; public bool booleanValue; public NumberLinqItem[] children; - } private async Task> FetchResults(QueryDefinition queryDefinition) diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosItemTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosItemTests.cs index b237c68c2a..75cf001b3b 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosItemTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosItemTests.cs @@ -33,6 +33,7 @@ namespace Microsoft.Azure.Cosmos.SDK.EmulatorTests using System.Reflection; using System.Text.RegularExpressions; using Microsoft.Azure.Cosmos.Diagnostics; + using Microsoft.Azure.Cosmos.Query.Core.Metrics; [TestClass] public class CosmosItemTests : BaseCosmosClientHelper @@ -141,6 +142,7 @@ public async Task CreateDropItemTest() Assert.IsFalse(string.IsNullOrEmpty(diagnostics.ToString())); Assert.IsTrue(diagnostics.GetClientElapsedTime() > TimeSpan.Zero); Assert.AreEqual(0, response.Diagnostics.GetFailedRequestCount()); + Assert.IsNull(response.Diagnostics.GetQueryMetrics()); response = await this.Container.ReadItemAsync(testItem.id, new Cosmos.PartitionKey(testItem.pk)); Assert.IsNotNull(response); @@ -158,6 +160,7 @@ public async Task CreateDropItemTest() Assert.IsNotNull(response.Diagnostics); Assert.IsFalse(string.IsNullOrEmpty(response.Diagnostics.ToString())); Assert.IsTrue(response.Diagnostics.GetClientElapsedTime() > TimeSpan.Zero); + Assert.IsNull(response.Diagnostics.GetQueryMetrics()); } [TestMethod] @@ -386,6 +389,7 @@ public async Task CreateDropItemMultiPartPartitionKeyTest() ItemResponse response = await multiPartPkContainer.CreateItemAsync(item: testItem); Assert.IsNotNull(response); Assert.AreEqual(HttpStatusCode.Created, response.StatusCode); + Assert.IsNull(response.Diagnostics.GetQueryMetrics()); ItemResponse readResponse = await multiPartPkContainer.ReadItemAsync(id: testItem.id, partitionKey: new Cosmos.PartitionKey("pk1")); Assert.IsNotNull(readResponse); @@ -603,6 +607,7 @@ public async Task UpsertItemTest() Assert.IsNotNull(response); Assert.AreEqual(HttpStatusCode.Created, response.StatusCode); Assert.IsNotNull(response.Headers.Session); + Assert.IsNull(response.Diagnostics.GetQueryMetrics()); } { @@ -613,6 +618,7 @@ public async Task UpsertItemTest() Assert.IsNotNull(response); Assert.AreEqual(HttpStatusCode.OK, response.StatusCode); Assert.IsNotNull(response.Headers.Session); + Assert.IsNull(response.Diagnostics.GetQueryMetrics()); } } @@ -703,6 +709,7 @@ await feedIterator.ReadNextAsync(this.cancellationToken)) } } + Assert.IsNull(responseMessage.Diagnostics.GetQueryMetrics()); } } @@ -774,7 +781,7 @@ public async Task PartitionKeyDeleteTestForSubpartitionedContainer() try { database = await client.CreateDatabaseIfNotExistsAsync("mydb"); - + ContainerProperties containerProperties = new ContainerProperties("subpartitionedcontainer", new List { "/Country", "/City" }); Container container = await database.CreateContainerAsync(containerProperties); ContainerInternal containerInternal = (ContainerInternal)container; @@ -805,7 +812,7 @@ public async Task PartitionKeyDeleteTestForSubpartitionedContainer() doc1.SetValue("Country", "USA"); doc1.SetValue("City", "Stonybrook"); documents[4] = await container.CreateItemAsync(doc1); - + Cosmos.PartitionKey partitionKey1 = new PartitionKeyBuilder().Add("USA").Add("Stonybrook").Build(); using (ResponseMessage pKDeleteResponse = await containerInternal.DeleteAllItemsByPartitionKeyStreamAsync(partitionKey1)) @@ -837,12 +844,12 @@ public async Task PartitionKeyDeleteTestForSubpartitionedContainer() finally { HttpConstants.Versions.CurrentVersion = currentVersion; - if(database != null) await database.DeleteAsync(); + if (database != null) await database.DeleteAsync(); } } [TestMethod] - public async Task ItemCustomSerialzierTest() + public async Task ItemCustomSerializerTest() { DateTime createDateTime = DateTime.UtcNow; Dictionary keyValuePairs = new Dictionary() @@ -966,7 +973,7 @@ public async Task ItemCustomSerialzierTest() // Each parameter in query spec should be a call to the custom serializer int parameterCount = queryDefinition.ToSqlQuerySpec().Parameters.Count; - Assert.AreEqual((parameterCount*pageCount)+parameterCount, toStreamCount, $"missing to stream call. Expected: {(parameterCount * pageCount) + parameterCount}, Actual: {toStreamCount} for query:{queryDefinition.ToSqlQuerySpec().QueryText}"); + Assert.AreEqual((parameterCount * pageCount) + parameterCount, toStreamCount, $"missing to stream call. Expected: {(parameterCount * pageCount) + parameterCount}, Actual: {toStreamCount} for query:{queryDefinition.ToSqlQuerySpec().QueryText}"); Assert.AreEqual(pageCount, fromStreamCount); } } @@ -1188,7 +1195,7 @@ public async Task QueryStreamValueTest() { Assert.AreEqual(3, pageCount); } - + IReadOnlyList<(string Name, object Value)> parameters1 = queryDefinition.GetQueryParameters(); @@ -1278,6 +1285,22 @@ public async Task QuerySinglePartitionItemStreamTest(int perPKItemCount, int max System.Diagnostics.Trace.TraceInformation($"ContinuationToken: {lastContinuationToken}"); Newtonsoft.Json.JsonSerializer serializer = new Newtonsoft.Json.JsonSerializer(); + ServerSideCumulativeMetrics metrics = response.Diagnostics.GetQueryMetrics(); + Assert.IsTrue(metrics.PartitionedMetrics.Count > 0); + Assert.IsTrue(metrics.CumulativeMetrics.TotalTime > TimeSpan.Zero); + Assert.IsTrue(metrics.CumulativeMetrics.QueryPreparationTime > TimeSpan.Zero); + + if (metrics.CumulativeMetrics.RetrievedDocumentCount >= 1) + { + Assert.IsTrue(metrics.CumulativeMetrics.RetrievedDocumentSize > 0); + Assert.IsTrue(metrics.CumulativeMetrics.DocumentLoadTime > TimeSpan.Zero); + Assert.IsTrue(metrics.CumulativeMetrics.RuntimeExecutionTime > TimeSpan.Zero); + } + else + { + Assert.AreEqual(0, metrics.CumulativeMetrics.RetrievedDocumentSize); + } + using (StreamReader sr = new StreamReader(response.Content)) using (JsonTextReader jtr = new JsonTextReader(sr)) { @@ -1317,9 +1340,9 @@ public async Task QuerySinglePartitionItemStreamTest(int perPKItemCount, int max [TestMethod] public async Task ItemMultiplePartitionQuery() { - IList deleteList = await ToDoActivity.CreateRandomItems(this.Container, 3, randomPartitionKey: true); + IList itemList = await ToDoActivity.CreateRandomItems(this.Container, 3, randomPartitionKey: true); - ToDoActivity find = deleteList.First(); + ToDoActivity find = itemList.First(); QueryDefinition sql = new QueryDefinition("select * from toDoActivity t where t.id = '" + find.id + "'"); QueryRequestOptions requestOptions = new QueryRequestOptions() @@ -1339,12 +1362,117 @@ public async Task ItemMultiplePartitionQuery() { FeedResponse iter = await feedIterator.ReadNextAsync(); Assert.IsTrue(iter.Count() <= 1); - if(iter.Count() == 1) + if (iter.Count() == 1) { found = true; ToDoActivity response = iter.First(); Assert.AreEqual(find.id, response.id); } + + ServerSideCumulativeMetrics metrics = iter.Diagnostics.GetQueryMetrics(); + + if (metrics != null) + { + Assert.IsTrue(metrics.PartitionedMetrics.Count == 3); + Assert.IsTrue(metrics.CumulativeMetrics.TotalTime > TimeSpan.Zero); + Assert.IsTrue(metrics.CumulativeMetrics.QueryPreparationTime > TimeSpan.Zero); + + foreach (ServerSidePartitionedMetrics partitionedMetrics in metrics.PartitionedMetrics) + { + Assert.IsNotNull(partitionedMetrics); + Assert.IsNotNull(partitionedMetrics.PartitionKeyRangeId); + } + + if (metrics.CumulativeMetrics.RetrievedDocumentCount >= 1) + { + Assert.IsTrue(metrics.CumulativeMetrics.RetrievedDocumentSize > 0); + Assert.IsTrue(metrics.CumulativeMetrics.DocumentLoadTime > TimeSpan.Zero); + Assert.IsTrue(metrics.CumulativeMetrics.RuntimeExecutionTime > TimeSpan.Zero); + } + else + { + Assert.AreEqual(0, metrics.CumulativeMetrics.RetrievedDocumentSize); + } + } + else + { + string diag = iter.Diagnostics.ToString(); + Assert.IsNotNull(diag); + } + } + + Assert.IsTrue(found); + } + + /// + /// Validate single partition query using gateway mode. + /// + [TestMethod] + public async Task ItemSinglePartitionQueryGateway() + { + ContainerResponse containerResponse = await this.database.CreateContainerAsync( + new ContainerProperties(id: Guid.NewGuid().ToString(), partitionKeyPath: "/pk")); + + Container createdContainer = (ContainerInlineCore)containerResponse; + CosmosClient client1 = TestCommon.CreateCosmosClient(useGateway: true); + + Container container = client1.GetContainer(this.database.Id, createdContainer.Id); + + string findId = "id2002"; + ToDoActivity item = ToDoActivity.CreateRandomToDoActivity("pk2002", findId); + await container.CreateItemAsync(item); + + QueryDefinition sql = new QueryDefinition("select * from toDoActivity t where t.id = '" + findId + "'"); + + QueryRequestOptions requestOptions = new QueryRequestOptions() + { + MaxBufferedItemCount = 10, + ResponseContinuationTokenLimitInKb = 500, + MaxItemCount = 1, + MaxConcurrency = 1, + }; + + FeedIterator feedIterator = container.GetItemQueryIterator( + sql, + requestOptions: requestOptions); + + bool found = false; + while (feedIterator.HasMoreResults) + { + FeedResponse iter = await feedIterator.ReadNextAsync(); + Assert.IsTrue(iter.Count() <= 1); + if (iter.Count() == 1) + { + found = true; + ToDoActivity response = iter.First(); + Assert.AreEqual(findId, response.id); + } + + ServerSideCumulativeMetrics metrics = iter.Diagnostics.GetQueryMetrics(); + + if (metrics != null) + { + Assert.IsTrue(metrics.PartitionedMetrics.Count == 1); + Assert.IsTrue(metrics.CumulativeMetrics.TotalTime > TimeSpan.Zero); + Assert.IsTrue(metrics.CumulativeMetrics.QueryPreparationTime > TimeSpan.Zero); + + foreach (ServerSidePartitionedMetrics partitionedMetrics in metrics.PartitionedMetrics) + { + Assert.IsNotNull(partitionedMetrics); + Assert.IsNull(partitionedMetrics.PartitionKeyRangeId); + } + + if (metrics.CumulativeMetrics.RetrievedDocumentCount >= 1) + { + Assert.IsTrue(metrics.CumulativeMetrics.RetrievedDocumentSize > 0); + Assert.IsTrue(metrics.CumulativeMetrics.DocumentLoadTime > TimeSpan.Zero); + Assert.IsTrue(metrics.CumulativeMetrics.RuntimeExecutionTime > TimeSpan.Zero); + } + else + { + Assert.AreEqual(0, metrics.CumulativeMetrics.RetrievedDocumentSize); + } + } } Assert.IsTrue(found); @@ -1365,8 +1493,8 @@ public async Task ItemMultiplePartitionOrderByQueryStream() }; IList deleteList = await ToDoActivity.CreateRandomItems( - this.Container, - 300, + this.Container, + 300, randomPartitionKey: true, randomTaskNumber: true); @@ -1536,7 +1664,6 @@ public async Task EpkPointReadTest() epk = new PartitionKey("test") .InternalKey .GetEffectivePartitionKeyString(this.containerSettings.PartitionKey); - properties = new Dictionary() { { WFConstants.BackendHeaders.EffectivePartitionKeyString, epk }, @@ -1586,9 +1713,11 @@ public async Task ItemEpkQuerySingleKeyRangeValidation() // If this fails the RUs of the container needs to be increased to ensure at least 2 partitions. Assert.IsTrue(ranges.Count > 1, " RUs of the container needs to be increased to ensure at least 2 partitions."); + ContainerQueryProperties containerQueryProperties = new ContainerQueryProperties( containerResponse.Resource.ResourceId, null, + //new List> { new Documents.Routing.Range("AA", "AA", true, true) }, containerResponse.Resource.PartitionKey, containerResponse.Resource.GeospatialConfig.GeospatialType); @@ -1606,6 +1735,7 @@ public async Task ItemEpkQuerySingleKeyRangeValidation() trace: NoOpTrace.Singleton); Assert.IsTrue(partitionKeyRanges.Count == 1, "Only 1 partition key range should be selected since the EPK option is set."); + } finally { @@ -1623,8 +1753,8 @@ public async Task ItemEpkQuerySingleKeyRangeValidation() public async Task ItemQueryStreamSerializationSetting() { IList deleteList = await ToDoActivity.CreateRandomItems( - container: this.Container, - pkCount: 101, + container: this.Container, + pkCount: 101, randomTaskNumber: true); QueryDefinition sql = new QueryDefinition("SELECT * FROM toDoActivity t ORDER BY t.taskNum"); @@ -2005,9 +2135,9 @@ public async Task ItemPatchSuccessTest() Assert.AreEqual(HttpStatusCode.OK, response.StatusCode); Assert.IsNotNull(response.Resource); Assert.AreEqual(null, response.Resource.children[0].id); - + patchOperations.Clear(); - patchOperations.Add(PatchOperation.Add("/children/1/description","Child#1")); + patchOperations.Add(PatchOperation.Add("/children/1/description", "Child#1")); patchOperations.Add(PatchOperation.Move("/children/0/description", "/description")); patchOperations.Add(PatchOperation.Move("/children/1/description", "/children/0/description")); // with content response @@ -3021,6 +3151,336 @@ public async Task HaLayerDoesNotThrowNullOnGoneExceptionTest() } } + /// + /// + /// + /// + [TestMethod] + [Owner("philipthomas")] + [Description("ReadItemStreamAsync is yielding a Newtonsoft.Json.JsonSerializationException whenever " + + "the item is not found and the MissingMemberHandling is set to MissingMemberHandling.Error. " + + "ReadItemStreamAsync should yield a CosmosException with a NotFound StatusCode.")] + public async Task GivenReadItemStreamAsyncWhenMissingMemberHandlingIsErrorThenExpectsCosmosExceptionTestAsync() + { + await CosmosItemTests.GivenItemStreamAsyncWhenMissingMemberHandlingIsErrorThenExpectsCosmosExceptionTestAsync( + itemStreamAsync: async (container, itemIdThatWillNotExist, partitionKeyValue, cancellationToken) => await container.ReadItemStreamAsync( + id: itemIdThatWillNotExist, + partitionKey: new Cosmos.PartitionKey(partitionKeyValue), + cancellationToken: cancellationToken)); + } + + /// + /// + /// + /// + [TestMethod] + [Owner("philipthomas")] + [Description("ReadItemAsync is yielding a Newtonsoft.Json.JsonSerializationException whenever " + + "the item is not found and MissingMemberHandling is set to MissingMemberHandling.Error. " + + "ReadItemAsync should yield a CosmosException with a NotFound StatusCode.")] + public async Task GivenReadItemAsyncWhenMissingMemberHandlingIsErrorThenExpectsCosmosExceptionTestAsync() + { + await CosmosItemTests.GivenItemAsyncWhenMissingMemberHandlingIsErrorThenExpectsCosmosExceptionTestAsync( + itemAsync: async (container, itemIdThatWillNotExist, partitionKeyValue, toDoActivity, cancellationToken) => await container.ReadItemAsync( + id: itemIdThatWillNotExist, + partitionKey: new Cosmos.PartitionKey(partitionKeyValue), + cancellationToken: cancellationToken)); + } + + /// + /// + /// + /// + [TestMethod] + [Owner("philipthomas")] + [Description("DeleteItemStreamAsync is yielding a Newtonsoft.Json.JsonSerializationException whenever " + + "the item is not found and the MissingMemberHandling is set to MissingMemberHandling.Error. " + + "DeleteItemStreamAsync should yield a CosmosException with a NotFound StatusCode.")] + public async Task GivenDeleteItemStreamAsyncWhenMissingMemberHandlingIsErrorThenExpectsCosmosExceptionTestAsync() + { + await CosmosItemTests.GivenItemStreamAsyncWhenMissingMemberHandlingIsErrorThenExpectsCosmosExceptionTestAsync( + itemStreamAsync: async (container, itemIdThatWillNotExist, partitionKeyValue, cancellationToken) => await container.DeleteItemStreamAsync( + id: itemIdThatWillNotExist, + partitionKey: new Cosmos.PartitionKey(partitionKeyValue), + cancellationToken: cancellationToken)); + } + + /// + /// + /// + /// + [TestMethod] + [Owner("philipthomas")] + [Description("DeleteItemAsync is yielding a Newtonsoft.Json.JsonSerializationException whenever " + + "the item is not found and MissingMemberHandling is set to MissingMemberHandling.Error. " + + "DeleteItemAsync should yield a CosmosException with a NotFound StatusCode.")] + public async Task GivenDeleteItemAsyncWhenMissingMemberHandlingIsErrorThenExpectsCosmosExceptionTestAsync() + { + await CosmosItemTests.GivenItemAsyncWhenMissingMemberHandlingIsErrorThenExpectsCosmosExceptionTestAsync( + itemAsync: async (container, itemIdThatWillNotExist, partitionKeyValue, toDoActivity, cancellationToken) => await container.DeleteItemAsync( + id: itemIdThatWillNotExist, + partitionKey: new Cosmos.PartitionKey(partitionKeyValue), + cancellationToken: cancellationToken)); + } + + /// + /// + /// + /// + [TestMethod] + [Owner("philipthomas")] + [Description("DeleteItemStreamAsync is yielding a Newtonsoft.Json.JsonSerializationException whenever " + + "the item is not found and the MissingMemberHandling is set to MissingMemberHandling.Error. " + + "DeleteItemStreamAsync should yield a CosmosException with a NotFound StatusCode.")] + public async Task GivenReplaceItemStreamAsyncWhenMissingMemberHandlingIsErrorThenExpectsCosmosExceptionTestAsync() + { + await CosmosItemTests.GivenItemStreamAsyncWhenMissingMemberHandlingIsErrorThenExpectsCosmosExceptionTestAsync( + itemStreamAsync: async (container, itemIdThatWillNotExist, partitionKeyValue, cancellationToken) => await container.ReplaceItemStreamAsync( + streamPayload: new MemoryStream(), + id: itemIdThatWillNotExist, + partitionKey: new Cosmos.PartitionKey(partitionKeyValue), + cancellationToken: cancellationToken)); + } + + /// + /// + /// + /// + [TestMethod] + [Owner("philipthomas")] + [Description("ReplaceItemAsync is yielding a Newtonsoft.Json.JsonSerializationException whenever " + + "the item is not found and MissingMemberHandling is set to MissingMemberHandling.Error. " + + "ReplaceItemAsync should yield a CosmosException with a NotFound StatusCode.")] + public async Task GivenReplaceItemAsyncWhenMissingMemberHandlingIsErrorThenExpectsCosmosExceptionTestAsync() + { + await CosmosItemTests.GivenItemAsyncWhenMissingMemberHandlingIsErrorThenExpectsCosmosExceptionTestAsync( + itemAsync: async (container, itemIdThatWillNotExist, partitionKeyValue, toDoActivity, cancellationToken) => await container.ReplaceItemAsync( + item: toDoActivity, + id: itemIdThatWillNotExist, + partitionKey: new Cosmos.PartitionKey(partitionKeyValue), + cancellationToken: cancellationToken)); + } + + /// + /// + /// + /// + [TestMethod] + [Owner("philipthomas")] + [Description("PatchItemStreamAsync is yielding a Newtonsoft.Json.JsonSerializationException whenever " + + "the item is not found and the MissingMemberHandling is set to MissingMemberHandling.Error. " + + "PatchItemStreamAsync should yield a CosmosException with a NotFound StatusCode.")] + public async Task GivenPatchItemStreamAsyncWhenMissingMemberHandlingIsErrorThenExpectsCosmosExceptionTestAsync() + { + List patchOperations = new() + { + PatchOperation.Add("/children/1/pk", "patched"), + PatchOperation.Remove("/description"), + PatchOperation.Replace("/taskNum", 1) + }; + + await CosmosItemTests.GivenItemStreamAsyncWhenMissingMemberHandlingIsErrorThenExpectsCosmosExceptionTestAsync( + itemStreamAsync: async (container, itemIdThatWillNotExist, partitionKeyValue, cancellationToken) => await container.PatchItemStreamAsync( + patchOperations: patchOperations, + id: itemIdThatWillNotExist, + partitionKey: new Cosmos.PartitionKey(partitionKeyValue), + cancellationToken: cancellationToken)); + } + + /// + /// + /// + /// + [TestMethod] + [Owner("philipthomas")] + [Description("PatchItemAsync is yielding a Newtonsoft.Json.JsonSerializationException whenever " + + "the item is not found and MissingMemberHandling is set to MissingMemberHandling.Error. " + + "PatchItemAsync should yield a CosmosException with a NotFound StatusCode.")] + public async Task GivenPatchItemAsyncWhenMissingMemberHandlingIsErrorThenExpectsCosmosExceptionTestAsync() + { + List patchOperations = new() + { + PatchOperation.Add("/children/1/pk", "patched"), + PatchOperation.Remove("/description"), + PatchOperation.Replace("/taskNum", 1) + }; + + await CosmosItemTests.GivenItemAsyncWhenMissingMemberHandlingIsErrorThenExpectsCosmosExceptionTestAsync( + itemAsync: async (container, itemIdThatWillNotExist, partitionKeyValue, toDoActivity, cancellationToken) => await container.PatchItemAsync( + patchOperations: patchOperations, + id: itemIdThatWillNotExist, + partitionKey: new Cosmos.PartitionKey(partitionKeyValue), + cancellationToken: cancellationToken)); + } + + private static async Task GivenItemStreamAsyncWhenMissingMemberHandlingIsErrorThenExpectsCosmosExceptionTestAsync( + Func> itemStreamAsync) + { + // AAA + // Arrange + CancellationTokenSource cancellationTokenSource = new(); + CancellationToken cancellationToken = cancellationTokenSource.Token; + + // Food for thought, actionable items. + // + // 1. Is there anything else that we should be concerned with that would give us the same behavior? + // 2. Are there other operations other than those that can yield an NotFound exception that we should be + // concerned with? + // 3. Can we also reset the DefaultSettings before we make the call, and reset it back once it is done? + + JsonConvert.DefaultSettings = () => new JsonSerializerSettings + { + MissingMemberHandling = MissingMemberHandling.Error + }; + + CosmosClient cosmosClient = TestCommon.CreateCosmosClient(); + + string databaseId = Guid.NewGuid().ToString(); + Cosmos.Database database = await cosmosClient.CreateDatabaseIfNotExistsAsync( + id: databaseId, + cancellationToken: cancellationToken); + + try + { + string containerId = Guid.NewGuid().ToString(); + Container container = await database.CreateContainerIfNotExistsAsync( + containerProperties: new ContainerProperties + { + Id = containerId, + PartitionKeyPath = "/pk", + }, + cancellationToken: cancellationToken); + + + // Act + string itemIdThatWillNotExist = Guid.NewGuid().ToString(); + string partitionKeyValue = Guid.NewGuid().ToString(); + + ResponseMessage response = await itemStreamAsync(container, itemIdThatWillNotExist, partitionKeyValue, cancellationToken); + + // Assert + Debug.Assert( + condition: response != null, + message: $"{response}"); + + Assert.AreEqual( + expected: HttpStatusCode.NotFound, + actual: response.StatusCode); + + string content = JsonConvert.SerializeObject(response.Content); + + Assert.AreEqual( + expected: "null", + actual: content); + + string errorMessage = JsonConvert.SerializeObject(response.ErrorMessage); + + Assert.IsNotNull(value: errorMessage); + + Debug.Assert( + condition: response.CosmosException != null, + message: $"{response.CosmosException}"); + + Assert.AreEqual( + expected: HttpStatusCode.NotFound, + actual: response.StatusCode); + + Debug.WriteLine(message: $"{nameof(response.CosmosException)}: {response.CosmosException}"); + + Assert.AreEqual( + actual: response.CosmosException.StatusCode, + expected: HttpStatusCode.NotFound); + } + finally + { + if (database != null) + { + // Remove the test database. Cleanup. + _ = await database.DeleteAsync(cancellationToken: cancellationToken); + + Debug.WriteLine($"The {nameof(database)} with id '{databaseId}' was removed."); + } + + // Setting this back because it blows up other serialization tests. + + JsonConvert.DefaultSettings = () => default; + } + } + + private static async Task GivenItemAsyncWhenMissingMemberHandlingIsErrorThenExpectsCosmosExceptionTestAsync( + Func>> itemAsync) + { + // AAA + // Arrange + CancellationTokenSource cancellationTokenSource = new(); + CancellationToken cancellationToken = cancellationTokenSource.Token; + + // Food for thought, actionable items. + // + // 1. Is there anything else that we should be concerned with that would give us the same behavior? + // 2. Are there other operations other than those that can yield an NotFound exception that we should be + // concerned with? + // 3. Can we also reset the DefaultSettings before we make the call, and reset it back once it is done? + + JsonConvert.DefaultSettings = () => new JsonSerializerSettings + { + MissingMemberHandling = MissingMemberHandling.Error + }; + + CosmosClient cosmosClient = TestCommon.CreateCosmosClient(); + + string databaseId = Guid.NewGuid().ToString(); + Cosmos.Database database = await cosmosClient.CreateDatabaseIfNotExistsAsync( + id: databaseId, + cancellationToken: cancellationToken); + + try + { + string containerId = Guid.NewGuid().ToString(); + Container container = await database.CreateContainerIfNotExistsAsync( + containerProperties: new ContainerProperties + { + Id = containerId, + PartitionKeyPath = "/pk", + }, + cancellationToken: cancellationToken); + + + // Act + // If any thing other than a CosmosException is thrown, the call to ReadItemAsync below will fail. + string itemIdThatWillNotExist = Guid.NewGuid().ToString(); + string partitionKeyValue = Guid.NewGuid().ToString(); + + CosmosException cosmosException = await Assert.ThrowsExceptionAsync(action: + async () => await itemAsync(container, itemIdThatWillNotExist, partitionKeyValue, new ToDoActivity { id = Guid.NewGuid().ToString(), pk = "Georgia" }, cancellationToken)) ; + + // Assert + Debug.Assert( + condition: cosmosException != null, + message: $"{cosmosException}"); + + Debug.WriteLine(message: $"{nameof(cosmosException)}: {cosmosException}"); + + Assert.AreEqual( + actual: cosmosException.StatusCode, + expected: HttpStatusCode.NotFound); + } + finally + { + if (database != null) + { + // Remove the test database. Cleanup. + _ = await database.DeleteAsync(cancellationToken: cancellationToken); + + Debug.WriteLine($"The {nameof(database)} with id '{databaseId}' was removed."); + } + + // Setting this back because it blows up other serialization tests. + + JsonConvert.DefaultSettings = () => default; + } + } + private async Task AutoGenerateIdPatternTest(Cosmos.PartitionKey pk, T itemWithoutId) { string autoId = Guid.NewGuid().ToString(); @@ -3144,4 +3604,4 @@ private static async Task TestNonePKForNonExistingContainer(Container container) } } } -} \ No newline at end of file +} diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosQueryClientCoreTest.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosQueryClientCoreTest.cs index 21a8b4ad59..3f325eef9a 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosQueryClientCoreTest.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosQueryClientCoreTest.cs @@ -51,7 +51,7 @@ public async Task TryGetOverlappingRangesAsyncTest() Assert.IsNotNull(containerProperties); Assert.IsNotNull(containerProperties.ResourceId); - Assert.IsNotNull(containerProperties.EffectivePartitionKeyString); + Assert.IsNotNull(containerProperties.EffectiveRangesForPartitionKey); IReadOnlyList pkRange = await this.queryClientCore.TryGetOverlappingRangesAsync( collectionResourceId: containerProperties.ResourceId, diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CustomSerializationTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CustomSerializationTests.cs index 5e6e2fe7bb..3334c201d1 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CustomSerializationTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CustomSerializationTests.cs @@ -14,7 +14,6 @@ namespace Microsoft.Azure.Cosmos.SDK.EmulatorTests using System.Runtime.Serialization; using System.Text; using System.Threading.Tasks; - using Microsoft.Azure.Cosmos.Linq; using Microsoft.Azure.Cosmos.Utils; using Microsoft.Azure.Documents; using Microsoft.Azure.Documents.Client; @@ -35,7 +34,7 @@ public abstract class CustomSerializationTests private Uri databaseUri; private Uri collectionUri; private Uri partitionedCollectionUri; - private PartitionKeyDefinition defaultPartitionKeyDefinition = new PartitionKeyDefinition { Paths = new System.Collections.ObjectModel.Collection(new[] { "/pk" }), Kind = PartitionKind.Hash }; + private readonly PartitionKeyDefinition defaultPartitionKeyDefinition = new PartitionKeyDefinition { Paths = new System.Collections.ObjectModel.Collection(new[] { "/pk" }), Kind = PartitionKind.Hash }; internal abstract DocumentClient CreateDocumentClient( Uri hostUri, @@ -77,7 +76,7 @@ public void TestSetup() { if (ex.StatusCode == System.Net.HttpStatusCode.ServiceUnavailable) { - // Emulator con sometimes fail under load, so we retry + // Emulator can sometimes fail under load, so we retry Task.Delay(1000); this.documentClient.CreateDocumentCollectionAsync(this.databaseUri, newCollection, new RequestOptions { OfferThroughput = 400 }).Wait(); } @@ -100,7 +99,7 @@ public void TestSetup() { if (ex.StatusCode == System.Net.HttpStatusCode.ServiceUnavailable) { - // Emulator con sometimes fail under load, so we retry + // Emulator can sometimes fail under load, so we retry Task.Delay(1000); this.documentClient.CreateDocumentCollectionAsync(this.databaseUri, partitionedCollection, new RequestOptions { OfferThroughput = 10000 }).Wait(); } @@ -136,13 +135,12 @@ public void TestDateParseHandlingOnReadDocument() // Verify round-trip create and read document RequestOptions applyRequestOptions = this.ApplyRequestOptions(new RequestOptions(), serializerSettings); - this.AssertPropertyOnReadDocument(client, this.collectionUri, createdDocument, applyRequestOptions, originalDocument, jsonProperty); - this.AssertPropertyOnReadDocument(client, this.partitionedCollectionUri, partitionedDocument, applyRequestOptions, originalDocument, jsonProperty); + this.AssertPropertyOnReadDocument(client, createdDocument, applyRequestOptions, originalDocument, jsonProperty); + this.AssertPropertyOnReadDocument(client, partitionedDocument, applyRequestOptions, originalDocument, jsonProperty); } private void AssertPropertyOnReadDocument( DocumentClient client, - Uri targetCollectionUri, Document createdDocument, RequestOptions requestOptions, Document originalDocument, @@ -311,26 +309,6 @@ public async Task TestJsonSerializerSettings(bool useGateway) } this.AssertEqual(testDocument, allDocuments.First()); - - //Will add LINQ test once it is available with new V3 OM - // // LINQ Lambda - // var query1 = client.CreateDocumentQuery(partitionedCollectionUri, options) - // .Where(_ => _.Id.CompareTo(String.Empty) > 0) - // .Select(_ => _.Id); - // string query1Str = query1.ToString(); - // var result = query1.ToList(); - // Assert.AreEqual(1, result.Count); - // Assert.AreEqual(testDocument.Id, result[0]); - - // // LINQ Query - // var query2 = - // from f in client.CreateDocumentQuery(partitionedCollectionUri, options) - // where f.Id.CompareTo(String.Empty) > 0 - // select f.Id; - // string query2Str = query2.ToString(); - // var result2 = query2.ToList(); - // Assert.AreEqual(1, result2.Count); - // Assert.AreEqual(testDocument.Id, result2[0]); } [TestMethod] diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/DistributedTracingOTelTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/DistributedTracingOTelTests.cs index 8b5825831c..43d9be341d 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/DistributedTracingOTelTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/DistributedTracingOTelTests.cs @@ -19,7 +19,7 @@ namespace Microsoft.Azure.Cosmos using System.Diagnostics; using Microsoft.Azure.Cosmos.Tracing; using System.Net.Http; - using System.ComponentModel; + using Microsoft.Azure.Cosmos.Tests; [VisualStudio.TestTools.UnitTesting.TestClass] public sealed class DistributedTracingOTelTests : BaseCosmosClientHelper @@ -34,7 +34,8 @@ public void TestInitialize() [DataTestMethod] [DataRow($"{OpenTelemetryAttributeKeys.DiagnosticNamespace}.Operation", $"{OpenTelemetryAttributeKeys.DiagnosticNamespace}.Request", DisplayName = "DirectMode and DistributedFlag On: Asserts activity creation at operation and network level with Diagnostic TraceId being added to logs")] [DataRow($"{OpenTelemetryAttributeKeys.DiagnosticNamespace}.Operation", null, DisplayName = "DirectMode and DistributedFlag On: Asserts activity creation at operation level with Diagnostic TraceId being added to logs")] - public async Task SourceEnabled_FlagOn_DirectMode_RecordsActivity_AssertLogTraceId_AssertTraceparent(string operationLevelSource, string networkLevelSource) + [DataRow(null, $"{OpenTelemetryAttributeKeys.DiagnosticNamespace}.Request", DisplayName = "DirectMode and DistributedFlag On: Asserts activity creation at network level with Diagnostic TraceId being added to logs")] + public async Task SourceEnabled_FlagOn_DirectMode_RecordsOperationNetworkActivity_AssertLogTraceId_AssertTraceparent(string operationLevelSource, string networkLevelSource) { string[] sources = new string[] { operationLevelSource, networkLevelSource }; sources = sources.Where(x => x != null).ToArray(); @@ -44,9 +45,12 @@ public async Task SourceEnabled_FlagOn_DirectMode_RecordsActivity_AssertLogTrace .AddSource(sources) .Build(); - await base.TestInit(validateSinglePartitionKeyRangeCacheCall: false, + await base.TestInit(validateSinglePartitionKeyRangeCacheCall: false, customizeClientBuilder: (builder) => builder - .WithDistributedTracing(true) + .WithClientTelemetryOptions(new CosmosClientTelemetryOptions() + { + DisableDistributedTracing = false + }) .WithConnectionModeDirect()); Container containerResponse = await this.database.CreateContainerAsync( @@ -104,7 +108,8 @@ await base.TestInit(validateSinglePartitionKeyRangeCacheCall: false, [DataTestMethod] [DataRow($"{OpenTelemetryAttributeKeys.DiagnosticNamespace}.Operation", $"{OpenTelemetryAttributeKeys.DiagnosticNamespace}.Request", DisplayName = "GatewayMode and DistributedFlag On: Asserts activity creation at operation and network level with Diagnostic TraceId being added to logs")] [DataRow($"{OpenTelemetryAttributeKeys.DiagnosticNamespace}.Operation", null, DisplayName = "GatewayMode and DistributedFlag On: Asserts activity creation at operation level with Diagnostic TraceId being added to logs")] - public async Task SourceEnabled_FlagOn_GatewayMode_RecordsActivity_AssertLogTraceId_AssertTraceparent(string operationLevelSource, string networkLevelSource) + [DataRow(null, $"{OpenTelemetryAttributeKeys.DiagnosticNamespace}.Request", DisplayName = "GatewayMode and DistributedFlag On: Asserts activity creation at network level with Diagnostic TraceId being added to logs")] + public async Task SourceEnabled_FlagOn_GatewayMode_RecordsOperationNetworkActivity_AssertLogTraceId_AssertTraceparent(string operationLevelSource, string networkLevelSource) { string[] sources = new string[] { operationLevelSource, networkLevelSource }; sources = sources.Where(x => x != null).ToArray(); @@ -126,9 +131,12 @@ public async Task SourceEnabled_FlagOn_GatewayMode_RecordsActivity_AssertLogTrac .AddSource(sources) .Build(); - await base.TestInit(validateSinglePartitionKeyRangeCacheCall: false, + await base.TestInit(validateSinglePartitionKeyRangeCacheCall: false, customizeClientBuilder: (builder) => builder - .WithDistributedTracing(true) + .WithClientTelemetryOptions(new CosmosClientTelemetryOptions() + { + DisableDistributedTracing = false + }) .WithHttpClientFactory(() => new HttpClient(httpClientHandlerHelper)) .WithConnectionModeGateway()); @@ -137,7 +145,6 @@ await base.TestInit(validateSinglePartitionKeyRangeCacheCall: false, partitionKeyPath: "/id", throughput: 20000); - List b = CustomOtelExporter.CollectedActivities.ToList(); //Assert traceId in Diagnostics logs string diagnosticsCreateContainer = containerResponse.Diagnostics.ToString(); JObject objDiagnosticsCreate = JObject.Parse(diagnosticsCreateContainer); @@ -158,13 +165,13 @@ await base.TestInit(validateSinglePartitionKeyRangeCacheCall: false, } [DataTestMethod] - [DataRow(false, true, "random.source.name", DisplayName = "DirectMode, DistributedFlag On, Random/No Source:Asserts no activity creation")] - [DataRow(true, true, "random.source.name", DisplayName = "GatewayMode, DistributedFlag On, Random/No Source:Asserts no activity creation")] - [DataRow(false, false, "random.source.name", DisplayName = "DirectMode, DistributedFlag Off, Random/No Source:Asserts no activity creation")] - [DataRow(true, false, "random.source.name", DisplayName = "GatewayMode, DistributedFlag Off, Random/No Source:Asserts no activity creation")] - [DataRow(false, false, $"{OpenTelemetryAttributeKeys.DiagnosticNamespace}.Operation", DisplayName = "DirectMode, DistributedFlag Off, OperationLevel Source:Asserts no activity creation")] - [DataRow(true, false, $"{OpenTelemetryAttributeKeys.DiagnosticNamespace}.Operation", DisplayName = "GatewayMode, DistributedFlag Off, OperationLevel Source:Asserts no activity creation")] - public async Task NoSourceEnabled_ResultsInNoSourceParentActivityCreation_AssertLogTraceId(bool useGateway, bool enableDistributingTracing, string source) + [DataRow(false, false, "random.source.name", DisplayName = "DirectMode, DistributedFlag On, Random/No Source:Asserts no activity creation")] + [DataRow(true, false, "random.source.name", DisplayName = "GatewayMode, DistributedFlag On, Random/No Source:Asserts no activity creation")] + [DataRow(false, true, "random.source.name", DisplayName = "DirectMode, DistributedFlag Off, Random/No Source:Asserts no activity creation")] + [DataRow(true, true, "random.source.name", DisplayName = "GatewayMode, DistributedFlag Off, Random/No Source:Asserts no activity creation")] + [DataRow(false, true, $"{OpenTelemetryAttributeKeys.DiagnosticNamespace}.Operation", DisplayName = "DirectMode, DistributedFlag Off, OperationLevel Source:Asserts no activity creation")] + [DataRow(true, true, $"{OpenTelemetryAttributeKeys.DiagnosticNamespace}.Operation", DisplayName = "GatewayMode, DistributedFlag Off, OperationLevel Source:Asserts no activity creation")] + public async Task NoSourceNoFlagEnabled_ResultsInNoOperationNetworkActivityCreation_AssertLogTraceId(bool useGateway, bool disableDistributingTracing, string source) { using TracerProvider provider = Sdk.CreateTracerProviderBuilder() .AddCustomOtelExporter() @@ -173,16 +180,22 @@ public async Task NoSourceEnabled_ResultsInNoSourceParentActivityCreation_Assert if (useGateway) { - await base.TestInit(validateSinglePartitionKeyRangeCacheCall: false, + await base.TestInit(validateSinglePartitionKeyRangeCacheCall: false, customizeClientBuilder: (builder) => builder - .WithDistributedTracing(enableDistributingTracing) + .WithClientTelemetryOptions(new CosmosClientTelemetryOptions() + { + DisableDistributedTracing = disableDistributingTracing + }) .WithConnectionModeGateway()); } else { - await base.TestInit(validateSinglePartitionKeyRangeCacheCall: false, + await base.TestInit(validateSinglePartitionKeyRangeCacheCall: false, customizeClientBuilder: (builder) => builder - .WithDistributedTracing(enableDistributingTracing)); + .WithClientTelemetryOptions(new CosmosClientTelemetryOptions() + { + DisableDistributedTracing = disableDistributingTracing + })); } ContainerResponse containerResponse = await this.database.CreateContainerAsync( @@ -194,7 +207,7 @@ await base.TestInit(validateSinglePartitionKeyRangeCacheCall: false, string diagnosticsCreateContainer = containerResponse.Diagnostics.ToString(); JObject objDiagnosticsCreate = JObject.Parse(diagnosticsCreateContainer); - if (enableDistributingTracing) + if (!disableDistributingTracing) { //DistributedTraceId present in logs string distributedTraceId = (string)objDiagnosticsCreate["data"]["DistributedTraceId"]; @@ -210,6 +223,49 @@ await base.TestInit(validateSinglePartitionKeyRangeCacheCall: false, Assert.AreEqual(0, CustomOtelExporter.CollectedActivities.Count()); } + + [DataTestMethod] + [DataRow(false)] + [DataRow(true)] + public async Task SuppressListenerEvents_ResultsInNoScopeActivityCreation_AssertTraceIdNotNull(bool useGateway) + { + // Initialize CustomListener with suppression + CustomListener customListener = new CustomListener($"{OpenTelemetryAttributeKeys.DiagnosticNamespace}.*", "Azure-Cosmos-Operation-Request-Diagnostics", true); + + if (useGateway) + { + await base.TestInit(validateSinglePartitionKeyRangeCacheCall: false, + customizeClientBuilder: (builder) => builder + .WithClientTelemetryOptions(new CosmosClientTelemetryOptions() + { + DisableDistributedTracing = false + }) + .WithConnectionModeGateway()); + } + else + { + await base.TestInit(validateSinglePartitionKeyRangeCacheCall: false, + customizeClientBuilder: (builder) => builder + .WithClientTelemetryOptions(new CosmosClientTelemetryOptions() + { + DisableDistributedTracing = false + })); + } + + ContainerResponse containerResponse = await this.database.CreateContainerAsync( + id: Guid.NewGuid().ToString(), + partitionKeyPath: "/id", + throughput: 20000); + + // Assert traceId in Diagnostics logs + string diagnosticsCreateContainer = containerResponse.Diagnostics.ToString(); + JObject objDiagnosticsCreate = JObject.Parse(diagnosticsCreateContainer); + Assert.IsNotNull(objDiagnosticsCreate["data"]["DistributedTraceId"], "Distributed Trace Id has value in diagnostics i.e. " + (string)objDiagnosticsCreate["data"]["DistributedTraceId"]); + + // Cleanup + customListener.Dispose(); + } + [TestCleanup] public async Task CleanUp() { diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/IndexMetricsParserBaselineTest.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/IndexMetricsParserBaselineTest.cs index 6ae91f1375..598ee51c9d 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/IndexMetricsParserBaselineTest.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/IndexMetricsParserBaselineTest.cs @@ -133,6 +133,7 @@ public void IndexUtilizationParse() public override IndexMetricsParserTestOutput ExecuteTest(IndexMetricsParserTestInput input) { + // V2 QueryRequestOptions requestOptions = new QueryRequestOptions() { PopulateIndexMetrics = true }; FeedIterator itemQuery = testContainer.GetItemQueryIterator( diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/LinqAggregateFunctionsBaselineTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Linq/LinqAggregateFunctionsBaselineTests.cs similarity index 98% rename from Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/LinqAggregateFunctionsBaselineTests.cs rename to Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Linq/LinqAggregateFunctionsBaselineTests.cs index 0734f4dfad..b957b0a740 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/LinqAggregateFunctionsBaselineTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Linq/LinqAggregateFunctionsBaselineTests.cs @@ -38,7 +38,7 @@ public async static Task Initialize(TestContext textContext) // Set a callback to get the handle of the last executed query to do the verification // This is neede because aggregate queries return type is a scalar so it can't be used // to verify the translated LINQ directly as other queries type. - client.DocumentClient.OnExecuteScalarQueryCallback = q => LinqAggregateFunctionBaselineTests.lastExecutedScalarQuery = q; + client.DocumentClient.OnExecuteScalarQueryCallback = q => lastExecutedScalarQuery = q; string dbName = $"{nameof(LinqAggregateFunctionBaselineTests)}-{Guid.NewGuid().ToString("N")}"; testDb = await client.CreateDatabaseAsync(dbName); @@ -501,7 +501,7 @@ public void TestAggregateAvg() public override LinqAggregateOutput ExecuteTest(LinqAggregateInput input) { - LinqAggregateFunctionBaselineTests.lastExecutedScalarQuery = null; + lastExecutedScalarQuery = null; Func compiledQuery = input.expression.Compile(); string errorMessage = null; @@ -515,10 +515,10 @@ public override LinqAggregateOutput ExecuteTest(LinqAggregateInput input) } finally { - Assert.IsNotNull(LinqAggregateFunctionBaselineTests.lastExecutedScalarQuery, "lastExecutedScalarQuery is not set"); + Assert.IsNotNull(lastExecutedScalarQuery, "lastExecutedScalarQuery is not set"); query = JObject - .Parse(LinqAggregateFunctionBaselineTests.lastExecutedScalarQuery.ToString()) + .Parse(lastExecutedScalarQuery.ToString()) .GetValue("query", StringComparison.Ordinal) .ToString(); } diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/LinqAttributeContractBaselineTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Linq/LinqAttributeContractBaselineTests.cs similarity index 100% rename from Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/LinqAttributeContractBaselineTests.cs rename to Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Linq/LinqAttributeContractBaselineTests.cs diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/LinqConstantFoldingBaselineTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Linq/LinqConstantFoldingBaselineTests.cs similarity index 100% rename from Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/LinqConstantFoldingBaselineTests.cs rename to Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Linq/LinqConstantFoldingBaselineTests.cs diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/LinqGeneralBaselineTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Linq/LinqGeneralBaselineTests.cs similarity index 98% rename from Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/LinqGeneralBaselineTests.cs rename to Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Linq/LinqGeneralBaselineTests.cs index 3fc3aff900..e76b2827be 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/LinqGeneralBaselineTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Linq/LinqGeneralBaselineTests.cs @@ -18,6 +18,7 @@ namespace Microsoft.Azure.Cosmos.Services.Management.Tests.LinqProviderTests using BaselineTest; using Microsoft.Azure.Documents; using Microsoft.Azure.Cosmos.Scripts; + using static Microsoft.Azure.Cosmos.Services.Management.Tests.LinqProviderTests.LinqGeneralBaselineTests; [Microsoft.Azure.Cosmos.SDK.EmulatorTests.TestClass] public class LinqGeneralBaselineTests : BaselineTests @@ -242,19 +243,19 @@ public void TestSubquery() inputs.Add(new LinqTestInput( "Select(OrderBy)", b => getQuery(b) .Select(f => f.Children.OrderBy(c => c.Pets.Count())))); - + inputs.Add(new LinqTestInput( "Select(Take)", b => getQuery(b) .Select(f => f.Children.Take(2)))); - + inputs.Add(new LinqTestInput( "Select(Where)", b => getQuery(b) .Select(f => f.Children.Where(c => c.Pets.Count() > 0)))); - + inputs.Add(new LinqTestInput( "Select(Distinct)", b => getQuery(b) .Select(f => f.Children.Distinct()))); - + inputs.Add(new LinqTestInput( "Select(Count)", b => getQuery(b) .Select(f => f.Children.Count(c => c.Grade > 80)))); @@ -378,7 +379,7 @@ public void TestSubquery() inputs.Add(new LinqTestInput( "Select(binary with Count)", b => getQuery(b) .Select(f => 5 + f.Children.Count(c => c.Pets.Count() > 0)))); - + inputs.Add(new LinqTestInput( "Select(constant + Where -> Count)", b => getQuery(b) .Select(f => 5 + f.Children.Where(c => c.Pets.Count() > 0).Count()))); @@ -473,7 +474,7 @@ public void TestSubquery() inputs.Add(new LinqTestInput( "Select(Select) -> Where", b => getQuery(b).Select(f => f.Children.Select(c => c.Pets.Count())).Where(x => x.Count() > 0))); - + // Customer requested scenario inputs.Add(new LinqTestInput( "Select(new w/ Where) -> Where -> OrderBy -> Take", b => getQuery(b) @@ -631,7 +632,7 @@ public void TestSubquery() inputs.Add(new LinqTestInput( "Take -> Select(Select)", b => getQuery(b) .Take(10).Select(f => f.Children.Select(c => c.Pets.Count())))); - + // ------------------ // Any in lambda // ------------------ @@ -639,23 +640,23 @@ public void TestSubquery() inputs.Add(new LinqTestInput( "Select(Any w const array)", b => getQuery(b) .Select(f => new int[] { 1, 2, 3 }.Any()))); - + inputs.Add(new LinqTestInput( "Select(Any)", b => getQuery(b) .Select(f => f.Children.Any()))); - + inputs.Add(new LinqTestInput( "Select(Any w lambda)", b => getQuery(b) .Select(f => f.Children.Any(c => c.Grade > 80)))); - + inputs.Add(new LinqTestInput( "Select(new Any)", b => getQuery(b) .Select(f => new { f.FamilyId, HasGoodChildren = f.Children.Any(c => c.Grade > 80) }))); - + inputs.Add(new LinqTestInput( "Select(new 2 Any)", b => getQuery(b) .Select(f => new { HasChildrenWithPets = f.Children.Any(c => c.Pets.Count() > 0), HasGoodChildren = f.Children.Any(c => c.Grade > 80) }))); - + inputs.Add(new LinqTestInput( "Select(Nested Any)", b => getQuery(b) .Select(f => f.Children.Any(c => c.Pets.Any(p => p.GivenName.Count() > 10))))); @@ -672,7 +673,7 @@ public void TestSubquery() inputs.Add(new LinqTestInput( "OrderBy(Any)", b => getQuery(b) .OrderBy(f => f.Children.Any(c => c.Pets.Count() > 3)))); - + // ------------------------------------------------ // SelectMany with Take and OrderBy in lambda // ------------------------------------------------ @@ -700,7 +701,7 @@ public void TestSubquery() [Ignore] public void DebuggingTest() { - + } [TestMethod] @@ -1929,7 +1930,7 @@ public void ValidateDynamicLinq() [TestMethod] public async Task ValidateLinqQueries() { - Container container = await testDb.CreateContainerAsync(new ContainerProperties (id : Guid.NewGuid().ToString("N"), partitionKeyPath : "/id" )); + Container container = await testDb.CreateContainerAsync(new ContainerProperties(id: Guid.NewGuid().ToString("N"), partitionKeyPath: "/id")); Parent mother = new Parent { FamilyName = "Wakefield", GivenName = "Robin" }; Parent father = new Parent { FamilyName = "Miller", GivenName = "Ben" }; @@ -1945,13 +1946,13 @@ public async Task ValidateLinqQueries() }; Address address = new Address { State = "NY", County = "Manhattan", City = "NY" }; - Family family = new Family { FamilyId = "WakefieldFamily", Parents = new Parent[] { mother, father }, Children = new Child[] { child }, IsRegistered = false, Int = 3, NullableInt = 5 , Id = "WakefieldFamily"}; + Family family = new Family { FamilyId = "WakefieldFamily", Parents = new Parent[] { mother, father }, Children = new Child[] { child }, IsRegistered = false, Int = 3, NullableInt = 5, Id = "WakefieldFamily" }; List fList = new List(); fList.Add(family); container.CreateItemAsync(family).Wait(); - IOrderedQueryable query = container.GetItemLinqQueryable(allowSynchronousQueryExecution : true); + IOrderedQueryable query = container.GetItemLinqQueryable(allowSynchronousQueryExecution: true); IEnumerable q1 = query.Select(f => f.Parents[0].FamilyName); Assert.AreEqual(q1.FirstOrDefault(), family.Parents[0].FamilyName); @@ -2009,7 +2010,7 @@ public async Task ValidateLinqQueries() ListArrayClass arrayObject = new ListArrayClass() { Id = "arrayObject", ArrayField = new int[] { 1, 2, 3 } }; container.CreateItemAsync(arrayObject).Wait(); - IOrderedQueryable listArrayQuery = container.GetItemLinqQueryable(allowSynchronousQueryExecution : true); + IOrderedQueryable listArrayQuery = container.GetItemLinqQueryable(allowSynchronousQueryExecution: true); IEnumerable q13 = listArrayQuery.Where(a => a.ArrayField == arrayObject.ArrayField); Assert.AreEqual(q13.FirstOrDefault().Id, arrayObject.Id); @@ -2061,9 +2062,9 @@ public async Task ValidateLinqQueries() Document doubleQoutesDocument = new Document() { Id = doc1Id }; container.CreateItemAsync(doubleQoutesDocument).Wait(); - IQueryable docQuery = from book in container.GetItemLinqQueryable(allowSynchronousQueryExecution : true) - where book.Id == doc1Id - select book; + IQueryable docQuery = from book in container.GetItemLinqQueryable(allowSynchronousQueryExecution: true) + where book.Id == doc1Id + select book; Assert.AreEqual(docQuery.AsEnumerable().Single().Id, doc1Id); @@ -2072,7 +2073,7 @@ public async Task ValidateLinqQueries() container.CreateItemAsync(greatGreatFamily).Wait(); List greatGreatFamilyData = new List() { greatGreatFamily }; - IOrderedQueryable queryable = container.GetItemLinqQueryable(allowSynchronousQueryExecution : true); + IOrderedQueryable queryable = container.GetItemLinqQueryable(allowSynchronousQueryExecution: true); IEnumerable q16 = queryable.SelectMany(gf => gf.GreatFamily.Family.Children.Where(c => c.GivenName == "Jesse").Select(c => gf)); @@ -2082,7 +2083,7 @@ public async Task ValidateLinqQueries() container.CreateItemAsync(sport).Wait(); List sportData = new List() { sport }; - IOrderedQueryable sportQuery = container.GetItemLinqQueryable(allowSynchronousQueryExecution : true); + IOrderedQueryable sportQuery = container.GetItemLinqQueryable(allowSynchronousQueryExecution: true); IEnumerable q17 = sportQuery.Where(s => s.SportName == "Tennis"); @@ -2178,8 +2179,8 @@ private async Task ValidateBasicQueryAsync() List queryResults = new List(); //Simple Equality IQueryable dbQuery = from db in client.CreateDatabaseQuery() - where db.Id == databaseName - select db; + where db.Id == databaseName + select db; IDocumentQuery documentQuery = dbQuery.AsDocumentQuery(); while (documentQuery.HasMoreResults) @@ -2288,32 +2289,32 @@ public void ValidateDynamicDocumentQuery() //Ensure query on custom property of }; //Unfiltered execution. - IOrderedQueryable bookDocQuery = testContainer.GetItemLinqQueryable(allowSynchronousQueryExecution : true); + IOrderedQueryable bookDocQuery = testContainer.GetItemLinqQueryable(allowSynchronousQueryExecution: true); Func> getBookQuery = useQuery => useQuery ? bookDocQuery : new List().AsQueryable(); List inputs = new List(); inputs.Add(new LinqTestInput("Simple Equality on custom property", b => from book in getBookQuery(b) - where book.Title == "My Book" - select book)); + where book.Title == "My Book" + select book)); inputs.Add(new LinqTestInput("Nested Property access", b => from book in getBookQuery(b) - where book.Author.Name == "Don" - select book)); + where book.Author.Name == "Don" + select book)); inputs.Add(new LinqTestInput("Array references & Project Author out..", b => from book in getBookQuery(b) - where book.Languages[0].Name == "English" - select book.Author)); + where book.Languages[0].Name == "English" + select book.Author)); inputs.Add(new LinqTestInput("SelectMany", b => getBookQuery(b).SelectMany(book => book.Languages).Where(lang => lang.Name == "French").Select(lang => lang.Copyright))); inputs.Add(new LinqTestInput("NumericRange query", b => from book in getBookQuery(b) - where book.Price < 10 - select book.Author)); + where book.Price < 10 + select book.Author)); inputs.Add(new LinqTestInput("Or query", b => from book in getBookQuery(b) - where book.Title == "My Book" || book.Author.Name == "Don" - select book)); + where book.Title == "My Book" || book.Author.Name == "Don" + select book)); inputs.Add(new LinqTestInput("SelectMany query on a List type.", b => getBookQuery(b).SelectMany(book => book.Editions).Select(ed => ed.Name))); // Below samples are strictly speaking not Any equivalent. But they join and filter "all" @@ -2334,7 +2335,7 @@ where book.Price < 10 [TestMethod] public void ValidateDynamicAttachmentQuery() //Ensure query on custom property of attachment. { - IOrderedQueryable attachmentQuery = testContainer.GetItemLinqQueryable(allowSynchronousQueryExecution : true); + IOrderedQueryable attachmentQuery = testContainer.GetItemLinqQueryable(allowSynchronousQueryExecution: true); Document myDocument = new Document(); Func> getAttachmentQuery = useQuery => useQuery ? attachmentQuery : new List().AsQueryable(); @@ -2401,7 +2402,7 @@ public QueryHelper(Container container) public IQueryable Query() where T : BaseDocument { - IQueryable query = this.container.GetItemLinqQueryable(allowSynchronousQueryExecution : true) + IQueryable query = this.container.GetItemLinqQueryable(allowSynchronousQueryExecution: true) .Where(d => d.TypeName == "Hello"); string queryString = query.ToString(); return query; @@ -2411,7 +2412,7 @@ public IQueryable Query() where T : BaseDocument [TestMethod] public async Task ValidateLinqOnDataDocumentType() { - Container container = await testDb.CreateContainerAsync(new ContainerProperties(id : nameof(ValidateLinqOnDataDocumentType), partitionKeyPath : "/id")); + Container container = await testDb.CreateContainerAsync(new ContainerProperties(id: nameof(ValidateLinqOnDataDocumentType), partitionKeyPath: "/id")); DataDocument doc = new DataDocument() { Id = Guid.NewGuid().ToString("N"), Number = 0, TypeName = "Hello" }; container.CreateItemAsync(doc).Wait(); @@ -2424,10 +2425,10 @@ public async Task ValidateLinqOnDataDocumentType() Assert.AreEqual(doc.Id, baseDocument.Id); BaseDocument iDocument = doc; - IOrderedQueryable q = container.GetItemLinqQueryable(allowSynchronousQueryExecution : true); + IOrderedQueryable q = container.GetItemLinqQueryable(allowSynchronousQueryExecution: true); IEnumerable iresult = from f in q - where f.Id == iDocument.Id + where f.Id == iDocument.Id select f; DataDocument id = iresult.FirstOrDefault(); Assert.AreEqual(doc.Id, id.Id); @@ -2504,7 +2505,7 @@ function callback(err, docCreated) { StoredProcedureExecuteResponse scriptResponse = null; int totalNumberOfDocuments = GatewayTests.CreateExecuteAndDeleteCosmosProcedure(collection, script, out scriptResponse, "My Book"); - IOrderedQueryable linqQueryable = collection.GetItemLinqQueryable(allowSynchronousQueryExecution : true); + IOrderedQueryable linqQueryable = collection.GetItemLinqQueryable(allowSynchronousQueryExecution: true); int totalHit = linqQueryable.Where(book => book.Title == "My Book").Count(); Assert.AreEqual(totalHit, totalNumberOfDocuments, "Didnt get all the documents"); diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/LinqSQLTranslationBaselineTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Linq/LinqSQLTranslationBaselineTests.cs similarity index 96% rename from Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/LinqSQLTranslationBaselineTests.cs rename to Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Linq/LinqSQLTranslationBaselineTests.cs index 230e2599a3..d38cede2b3 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/LinqSQLTranslationBaselineTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Linq/LinqSQLTranslationBaselineTests.cs @@ -16,6 +16,7 @@ namespace Microsoft.Azure.Cosmos.Services.Management.Tests using System.Threading.Tasks; using System.Net; using Microsoft.Azure.Cosmos.Query.Core; + using Microsoft.Azure.Cosmos.Services.Management.Tests.LinqProviderTests; [Microsoft.Azure.Cosmos.SDK.EmulatorTests.TestClass] public class LinqSQLTranslationBaselineTest : BaselineTests @@ -32,7 +33,8 @@ static Expression Lambda(Expression> func) [ClassInitialize] public async static Task Initialize(TestContext textContext) { - cosmosClient = TestCommon.CreateCosmosClient((cosmosClientBuilder) => { + cosmosClient = TestCommon.CreateCosmosClient((cosmosClientBuilder) => + { cosmosClientBuilder.WithCustomSerializer(new CustomJsonSerializer(new JsonSerializerSettings() { ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor, @@ -76,7 +78,7 @@ struct simple public string pk; public simple(int x, int y) - { this.x = x; this.y = y; this.id = Guid.NewGuid().ToString(); this.pk = "Test"; } + { this.x = x; this.y = y; this.id = Guid.NewGuid().ToString(); this.pk = "Test"; } } struct nested @@ -246,13 +248,13 @@ public void ValidateSQLTranslation() inputs.Add(new LinqTestInput("Select identity", b => dataQuery(b).Select(x => x))); inputs.Add(new LinqTestInput("Select simple property", b => dataQuery(b).Select(x => x.x))); inputs.Add(new LinqTestInput("Select extension data", b => dataQuery(b).Select(x => new complex() { - NewtonsoftExtensionData = new() { + NewtonsoftExtensionData = new() { { "test", 1.5 } }, - NetExtensionData = new() { + NetExtensionData = new() { { "OtherTest", 1.5 } } - } ))); + }))); this.ExecuteTestSuite(inputs); } @@ -280,9 +282,9 @@ public void ValidateSQLTranslationComplexData() obj.str = random.NextDouble() < 0.1 ? "5" : LinqTestsCommon.RandomString(random, random.Next(MaxStringLength)); obj.id = Guid.NewGuid().ToString(); obj.pk = "Test"; - obj.NewtonsoftExtensionData = new Dictionary() { + obj.NewtonsoftExtensionData = new Dictionary() { ["age"] = 32, - ["tags"] = new [] { "item-1", "item-2" } + ["tags"] = new[] { "item-1", "item-2" } }; return obj; }; @@ -307,11 +309,11 @@ public void ValidateSQLTranslationComplexData() inputs.Add(new LinqTestInput("SelectMany array", b => getQuery(b).SelectMany(x => x.dblArray))); inputs.Add(new LinqTestInput("Select where extensiondata", b => getQuery(b).Where(p => (int)p.NewtonsoftExtensionData["age"] > 18).Select(x => new { Age = (int)x.NewtonsoftExtensionData["age"] }))); - inputs.Add(new LinqTestInput("Select where extensiondata contains", b => getQuery(b).Where(p => ((string[])p.NewtonsoftExtensionData["tags"]).Contains("item-1")).Select(x => (string[])x.NewtonsoftExtensionData["tags"] ))); + inputs.Add(new LinqTestInput("Select where extensiondata contains", b => getQuery(b).Where(p => ((string[])p.NewtonsoftExtensionData["tags"]).Contains("item-1")).Select(x => (string[])x.NewtonsoftExtensionData["tags"]))); // TODO: SelectMany does not currently work with Dictionary objects, the snapshot represents // the current (broken) behavior - inputs.Add(new LinqTestInput("SelectMany where extensiondata contains", b => getQuery(b).Where(p => ((string[])p.NewtonsoftExtensionData["tags"]).Contains("item-1")).SelectMany(x => (object[])x.NewtonsoftExtensionData["tags"] ))); + inputs.Add(new LinqTestInput("SelectMany where extensiondata contains", b => getQuery(b).Where(p => ((string[])p.NewtonsoftExtensionData["tags"]).Contains("item-1")).SelectMany(x => (object[])x.NewtonsoftExtensionData["tags"]))); this.ExecuteTestSuite(inputs); } diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/LinqTestData.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Linq/LinqTestData.cs similarity index 98% rename from Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/LinqTestData.cs rename to Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Linq/LinqTestData.cs index f302655613..a543a00418 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/LinqTestData.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Linq/LinqTestData.cs @@ -71,7 +71,7 @@ public class Transaction : LinqTestObject { public DateTime Date; public long Amount; - public TransactionType Type; + public TransactionType Type; } public enum TransactionType diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/LinqTestsCommon.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Linq/LinqTestsCommon.cs similarity index 84% rename from Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/LinqTestsCommon.cs rename to Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Linq/LinqTestsCommon.cs index 87b33110e2..d825d2ec9f 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/LinqTestsCommon.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Linq/LinqTestsCommon.cs @@ -156,12 +156,11 @@ public static Boolean IsAnonymousType(Type type) } /// - /// Validate the results of CosmosDB query and the results of LinQ query on the original data - /// Using Assert, will fail the unit test if the two results list are not SequenceEqual + /// Gets the results of CosmosDB query and the results of LINQ query on the original data /// /// /// - public static void ValidateResults(IQueryable queryResults, IQueryable dataResults) + public static (List queryResults, List dataResults) GetResults(IQueryable queryResults, IQueryable dataResults) { // execution validation IEnumerator queryEnumerator = queryResults.GetEnumerator(); @@ -171,7 +170,19 @@ public static void ValidateResults(IQueryable queryResults, IQueryable dataResul queryResultsList.Add(queryEnumerator.Current); } - List dataResultsList = dataResults.Cast().ToList(); + List dataResultsList = dataResults?.Cast()?.ToList(); + + return (queryResultsList, dataResultsList); + } + + /// + /// Validates the results of CosmosDB query and the results of LINQ query on the original data + /// Using Assert, will fail the unit test if the two results list are not SequenceEqual + /// + /// + /// + private static void ValidateResults(List queryResultsList, List dataResultsList) + { bool resultMatched = true; string actualStr = null; string expectedStr = null; @@ -229,9 +240,8 @@ public static void ValidateResults(IQueryable queryResults, IQueryable dataResul string assertMsg = string.Empty; if (!resultMatched) { - if (actualStr == null) actualStr = JsonConvert.SerializeObject(queryResultsList); - - if (expectedStr == null) expectedStr = JsonConvert.SerializeObject(dataResultsList); + actualStr ??= JsonConvert.SerializeObject(queryResultsList); + expectedStr ??= JsonConvert.SerializeObject(dataResultsList); resultMatched |= actualStr.Equals(expectedStr); if (!resultMatched) @@ -271,7 +281,7 @@ public static DateTime RandomDateTime(Random random, DateTime midDateTime) } /// - /// Generate test data for most LinQ tests + /// Generate test data for most LINQ tests /// /// the object type /// the lamda to create an instance of test data @@ -315,6 +325,44 @@ public static Func> GenerateTestCosmosData(Func + /// Generate a non-random payload for serializer LINQ tests. + /// + /// the object type + /// the lamda to create an instance of test data + /// number of test data to be created + /// the target container + /// if theCosmosLinqSerializerOption of camelCaseSerialization should be applied + /// a lambda that takes a boolean which indicate where the query should run against CosmosDB or against original data, and return a query results as IQueryable. Also the serialized payload. + public static Func> GenerateSerializationTestCosmosData(Func func, int count, Container container, bool camelCaseSerialization = false) + { + List data = new List(); + for (int i = 0; i < count; i++) + { + data.Add(func(i, camelCaseSerialization)); + } + + foreach (T obj in data) + { + ItemResponse response = container.CreateItemAsync(obj, new Cosmos.PartitionKey("Test")).Result; + } + + FeedOptions feedOptions = new FeedOptions() { EnableScanInQuery = true, EnableCrossPartitionQuery = true }; + QueryRequestOptions requestOptions = new QueryRequestOptions() + { +#if PREVIEW + EnableOptimisticDirectExecution = false +#endif + }; + + CosmosLinqSerializerOptions linqSerializerOptions = new CosmosLinqSerializerOptions { PropertyNamingPolicy = camelCaseSerialization ? CosmosPropertyNamingPolicy.CamelCase : CosmosPropertyNamingPolicy.Default }; + IOrderedQueryable query = container.GetItemLinqQueryable(allowSynchronousQueryExecution: true, requestOptions: requestOptions, linqSerializerOptions: linqSerializerOptions); + + IQueryable getQuery(bool useQuery) => useQuery ? query : data.AsQueryable(); + + return getQuery; + } + public static Func> GenerateFamilyCosmosData( Cosmos.Database cosmosDatabase, out Container container) { @@ -434,7 +482,7 @@ Family createDataObj(Random random) for (int j = 0; j < random.Next(MaxThings) + 1; ++j) { obj.Children[i].Things.Add( - j == 0 ? "A" : $"{j}-{random.Next().ToString()}", + j == 0 ? "A" : $"{j}-{random.Next()}", LinqTestsCommon.RandomString(random, random.Next(MaxThingStringLength))); } } @@ -480,7 +528,7 @@ Cosmos.Database cosmosDatabase { Id = Guid.NewGuid().ToString(), Number = random.Next(-10000, 10000), - Flag = index % 2 == 0 ? true : false, + Flag = index % 2 == 0, Multiples = new int[] { index, index * 2, index * 3, index * 4 }, Pk = "Test" }; @@ -508,28 +556,35 @@ Cosmos.Database cosmosDatabase return getQuery; } - public static LinqTestOutput ExecuteTest(LinqTestInput input) + public static LinqTestOutput ExecuteTest(LinqTestInput input, bool serializeResultsInBaseline = false) { string querySqlStr = string.Empty; try { Func compiledQuery = input.Expression.Compile(); - IQueryable queryResults = compiledQuery(true); - querySqlStr = JObject.Parse(queryResults.ToString()).GetValue("query", StringComparison.Ordinal).ToString(); + IQueryable query = compiledQuery(true); + querySqlStr = JObject.Parse(query.ToString()).GetValue("query", StringComparison.Ordinal).ToString(); - // we skip unordered query because the LinQ results vs actual query results are non-deterministic + IQueryable dataQuery = input.skipVerification ? null : compiledQuery(false); + + (List queryResults, List dataResults) = GetResults(query, dataQuery); + + // we skip unordered query because the LINQ results vs actual query results are non-deterministic if (!input.skipVerification) { - IQueryable dataResults = compiledQuery(false); LinqTestsCommon.ValidateResults(queryResults, dataResults); } - return new LinqTestOutput(querySqlStr); + string serializedResults = serializeResultsInBaseline ? + JsonConvert.SerializeObject(queryResults.Select(item => item is LinqTestObject ? item.ToString() : item), new JsonSerializerSettings { Formatting = Newtonsoft.Json.Formatting.Indented}) : + null; + + return new LinqTestOutput(querySqlStr, serializedResults, errorMsg: null, input.inputData); } catch (Exception e) { - return new LinqTestOutput(querySqlStr, LinqTestsCommon.BuildExceptionMessageForTest(e)); + return new LinqTestOutput(querySqlStr, serializedResults: null, errorMsg: LinqTestsCommon.BuildExceptionMessageForTest(e), inputData: input.inputData); } } @@ -570,13 +625,15 @@ public class LinqTestObject { private string json; + protected virtual string SerializeForTestBaseline() + { + return JsonConvert.SerializeObject(this); + } + public override string ToString() { // simple cached serialization - if (this.json == null) - { - this.json = JsonConvert.SerializeObject(this); - } + this.json ??= this.SerializeForTestBaseline(); return this.json; } @@ -608,18 +665,25 @@ public class LinqTestInput : BaselineTestInput internal int randomSeed = -1; internal Expression> Expression { get; } internal string expressionStr; + internal string inputData; // We skip the verification between Cosmos DB and actual query restuls in the following cases // - unordered query since the results are not deterministics for LinQ results and actual query results // - scenarios not supported in LINQ, e.g. sequence doesn't contain element. internal bool skipVerification; - internal LinqTestInput(string description, Expression> expr, bool skipVerification = false, string expressionStr = null) + internal LinqTestInput( + string description, + Expression> expr, + bool skipVerification = false, + string expressionStr = null, + string inputData = null) : base(description) { this.Expression = expr ?? throw new ArgumentNullException($"{nameof(expr)} must not be null."); this.skipVerification = skipVerification; this.expressionStr = expressionStr; + this.inputData = inputData; } public static string FilterInputExpression(string input) @@ -656,11 +720,7 @@ public override void SerializeAsXml(XmlWriter xmlWriter) throw new ArgumentNullException($"{nameof(xmlWriter)} cannot be null."); } - if (this.expressionStr == null) - { - this.expressionStr = LinqTestInput.FilterInputExpression(this.Expression.Body.ToString()); - } - + this.expressionStr ??= LinqTestInput.FilterInputExpression(this.Expression.Body.ToString()); xmlWriter.WriteStartElement("Description"); xmlWriter.WriteCData(this.Description); @@ -678,7 +738,9 @@ public class LinqTestOutput : BaselineTestOutput internal static Regex newLine = new Regex("(\r\n|\r|\n)"); internal string SqlQuery { get; } - internal string ErrorMessage { get; private set; } + internal string ErrorMessage { get; } + internal string Results { get; } + internal string InputData { get; } private static readonly Dictionary newlineKeywords = new Dictionary() { { "SELECT", "\nSELECT" }, @@ -704,10 +766,12 @@ public static string FormatErrorMessage(string msg) return msg; } - internal LinqTestOutput(string sqlQuery, string errorMsg = null) + internal LinqTestOutput(string sqlQuery, string serializedResults, string errorMsg, string inputData) { this.SqlQuery = FormatSql(sqlQuery); + this.Results = serializedResults; this.ErrorMessage = errorMsg; + this.InputData = inputData; } public static String FormatSql(string sqlQuery) @@ -740,7 +804,7 @@ public static String FormatSql(string sqlQuery) } else if (tokens[i].StartsWith(endCue, StringComparison.OrdinalIgnoreCase)) { - indentSb.Length = indentSb.Length - oneTab.Length; + indentSb.Length -= oneTab.Length; } sb.Append(indentSb).Append(tokens[i]).Append("\n"); @@ -754,6 +818,18 @@ public override void SerializeAsXml(XmlWriter xmlWriter) xmlWriter.WriteStartElement(nameof(this.SqlQuery)); xmlWriter.WriteCData(this.SqlQuery); xmlWriter.WriteEndElement(); + if (this.InputData != null) + { + xmlWriter.WriteStartElement("InputData"); + xmlWriter.WriteCData(this.InputData); + xmlWriter.WriteEndElement(); + } + if (this.Results != null) + { + xmlWriter.WriteStartElement("Results"); + xmlWriter.WriteCData(this.Results); + xmlWriter.WriteEndElement(); + } if (this.ErrorMessage != null) { xmlWriter.WriteStartElement("ErrorMessage"); diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/LinqTranslationBaselineTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Linq/LinqTranslationBaselineTests.cs similarity index 96% rename from Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/LinqTranslationBaselineTests.cs rename to Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Linq/LinqTranslationBaselineTests.cs index 4c8d6c423f..f13a92da82 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/LinqTranslationBaselineTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Linq/LinqTranslationBaselineTests.cs @@ -17,7 +17,6 @@ namespace Microsoft.Azure.Cosmos.Services.Management.Tests.LinqProviderTests using BaselineTest; using System.Linq.Dynamic; using System.Text; - using Microsoft.Azure.Documents; using Microsoft.Azure.Cosmos.SDK.EmulatorTests; using System.Threading.Tasks; @@ -292,6 +291,38 @@ public void TestTypeCheckFunctions() this.ExecuteTestSuite(inputs); } + [TestMethod] + public void TestRegexMatchFunction() + { + // Similar to the type checking function, RegexMatch are not supported client side. + // Therefore this method is verified with baseline only. + List data = new List(); + IOrderedQueryable query = testContainer.GetItemLinqQueryable(allowSynchronousQueryExecution: true); + Func> getQuery = useQuery => useQuery ? query : data.AsQueryable(); + + List inputs = new List + { + new LinqTestInput("RegexMatch with 1 argument", b => getQuery(b).Where(doc => doc.StringField.RegexMatch("abcd"))), + new LinqTestInput("RegexMatch with 2 argument", b => getQuery(b).Where(doc => doc.StringField.RegexMatch("abcd", "i"))), + new LinqTestInput("RegexMatch with 1st argument member expression", b => getQuery(b).Where(doc => doc.StringField.RegexMatch(doc.StringField2))), + new LinqTestInput("RegexMatch with ToString", b => getQuery(b).Where(doc => doc.StringField.RegexMatch(doc.IntField.ToString()))), + new LinqTestInput("RegexMatch with StringUpper", b => getQuery(b).Where(doc => doc.StringField.RegexMatch(doc.StringField2.ToUpper()))), + new LinqTestInput("RegexMatch with StringLower", b => getQuery(b).Where(doc => doc.StringField.RegexMatch(doc.StringField2.ToLower()))), + new LinqTestInput("RegexMatch with StringConcat", b => getQuery(b).Where(doc => doc.StringField.RegexMatch(string.Concat(doc.StringField, "str")))), + + new LinqTestInput("RegexMatch with string composition", b => getQuery(b).Where(doc => doc.IntField.ToString().RegexMatch(doc.StringField))), + new LinqTestInput("RegexMatch with string composition 2", b => getQuery(b).Where(doc => doc.IntField.ToString().RegexMatch(doc.StringField, doc.StringField2.ToString()))), + + new LinqTestInput("RegexMatch with conditional", b => getQuery(b).Where(doc => doc.StringField.RegexMatch("abc") && doc.StringField2.RegexMatch("def"))), + new LinqTestInput("RegexMatch with conditional 2", b => getQuery(b).Where(doc => doc.StringField.RegexMatch("abc") || doc.StringField2.RegexMatch("def"))), + new LinqTestInput("RegexMatch with conditional 3", b => getQuery(b).Where(doc => doc.StringField.RegexMatch("abc")).Where(doc => doc.StringField2.RegexMatch("abc"))), + new LinqTestInput("RegexMatch with conditional 4", b => getQuery(b).Where(doc => doc.StringField.RegexMatch("abc")).Where(doc => !doc.StringField2.RegexMatch("abc"))), + + new LinqTestInput("RegexMatch with 2nd argument invalid string options", b => getQuery(b).Where(doc => doc.StringField.RegexMatch("abcd", "this should error out on the back end"))), + }; + this.ExecuteTestSuite(inputs); + } + [TestMethod] public void TestMemberInitializer() { @@ -622,7 +653,7 @@ public void TestMemberAccess() List testData = new List(); IOrderedQueryable constantQuery = testContainer.GetItemLinqQueryable(allowSynchronousQueryExecution: true); Func> getQuery = useQuery => useQuery ? constantQuery : testData.AsQueryable(); - + List inputs = new List { // This test case will use the legacy delegate compilation expression evaluator @@ -683,7 +714,7 @@ private Func> CreateDataTestStringFunctions() StringField = sb.ToString(), Id = Guid.NewGuid().ToString(), Pk = "Test", - + // For ToString tests ArrayField = new int[] {}, Point = new Point(0, 0) @@ -805,9 +836,9 @@ public void TestStringFunctions() new LinqTestInput("ToUpper", b => getQuery(b).Select(doc => doc.StringField.ToUpper())) }; this.ExecuteTestSuite(inputs); - } + } - [TestMethod] + [TestMethod] public void TestArrayFunctions() { const int Records = 100; diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/LinqTranslationWithCustomSerializerBaseline.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/LinqTranslationWithCustomSerializerBaseline.cs new file mode 100644 index 0000000000..3266809926 --- /dev/null +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/LinqTranslationWithCustomSerializerBaseline.cs @@ -0,0 +1,407 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +//----------------------------------------------------------------------- +namespace Microsoft.Azure.Cosmos.Services.Management.Tests.LinqProviderTests +{ + using System; + using System.Collections.Generic; + using System.IO; + using System.Linq; + using System.Linq.Dynamic; + using System.Runtime.Serialization; + using System.Text.Json; + using System.Text.Json.Serialization; + using System.Threading.Tasks; + using BaselineTest; + using global::Azure.Core.Serialization; + using Microsoft.Azure.Cosmos.SDK.EmulatorTests; + using Microsoft.VisualStudio.TestTools.UnitTesting; + using Newtonsoft.Json; + using Newtonsoft.Json.Linq; + + [SDK.EmulatorTests.TestClass] + public class LinqTranslationWithCustomSerializerBaseline : BaselineTests + { + private static CosmosClient CosmosClient; + private static Database TestDb; + private static Container TestContainer; + + private const int RecordCount = 3; + private const int MaxValue = 500; + private const int MaxStringLength = 100; + private const int PropertyCount = 4; + + [ClassInitialize] + public async static Task Initialize(TestContext textContext) + { + CosmosClient = TestCommon.CreateCosmosClient((cosmosClientBuilder) + => cosmosClientBuilder.WithCustomSerializer(new SystemTextJsonSerializer(new JsonSerializerOptions()))); + + string dbName = $"{nameof(LinqTranslationBaselineTests)}-{Guid.NewGuid():N}"; + TestDb = await CosmosClient.CreateDatabaseAsync(dbName); + } + + [ClassCleanup] + public async static Task Cleanup() + { + if (TestDb != null) + { + await TestDb.DeleteStreamAsync(); + } + } + + [TestInitialize] + public async Task TestInitialize() + { + TestContainer = await TestDb.CreateContainerAsync(new ContainerProperties(id: Guid.NewGuid().ToString(), partitionKeyPath: "/Pk")); + } + + [TestCleanup] + public async Task TestCleanup() + { + await TestContainer.DeleteContainerStreamAsync(); + } + + public override LinqTestOutput ExecuteTest(LinqTestInput input) + { + return LinqTestsCommon.ExecuteTest(input, serializeResultsInBaseline: true); + } + + [TestMethod] + public void TestMemberInitializerDotNet() + { + Func> getQueryCamelCase; + Func> getQueryDefault; + (getQueryCamelCase, getQueryDefault) = this.InsertDataAndGetQueryables(); + + string insertedData = this.GetInsertedData().Result; + + List inputs = new List(); + foreach (bool useCamelCaseSerializer in new bool[] { true, false }) + { + Func> getQuery = useCamelCaseSerializer ? getQueryCamelCase : getQueryDefault; + + List camelCaseSettingInputs = new List + { + // TODO (10/13/23): extend this and other tests cases as more LINQ features are added (GROUP BY, etc.) + new LinqTestInput("Filter w/ constant value, camelcase = " + useCamelCaseSerializer, b => getQuery(b).Where(doc => doc.NumericField == 1), skipVerification : true, inputData: insertedData), + new LinqTestInput("Filter w/ DataObject initializer with constant value, camelcase = " + useCamelCaseSerializer, b => getQuery(b).Where(doc => doc == new DataObjectDotNet() { NumericField = 1, StringField = "1" }), skipVerification : true, inputData: insertedData), + new LinqTestInput("Select w/ DataObject initializer, camelcase = " + useCamelCaseSerializer, b => getQuery(b).Select(doc => new DataObjectDotNet() { NumericField = 1, StringField = "1" }), skipVerification : true, inputData: insertedData), + new LinqTestInput("Deeper than top level reference, camelcase = " + useCamelCaseSerializer, b => getQuery(b).Select(doc => doc.NumericField > 1 ? new DataObjectDotNet() { NumericField = 1, StringField = "1" } : new DataObjectDotNet() { NumericField = 1, StringField = "1" }), skipVerification : true, inputData: insertedData), + + // Negative test case: serializing only field name using custom serializer not currently supported + new LinqTestInput("Filter w/ DataObject initializer with member initialization, camelcase = " + useCamelCaseSerializer, b => getQuery(b).Where(doc => doc == new DataObjectDotNet() { NumericField = doc.NumericField, StringField = doc.StringField }).Select(b => "A"), skipVerification : true, inputData: insertedData) + }; + + inputs.AddRange(camelCaseSettingInputs); + } + + this.ExecuteTestSuite(inputs); + } + + [TestMethod] + public void TestMemberInitializerNewtonsoft() + { + Func> getQueryCamelCase; + Func> getQueryDefault; + (getQueryCamelCase, getQueryDefault) = this.InsertDataAndGetQueryables(); + + string insertedData = this.GetInsertedData().Result; + + List inputs = new List(); + foreach (bool useCamelCaseSerializer in new bool[] { true, false }) + { + Func> getQuery = useCamelCaseSerializer ? getQueryCamelCase : getQueryDefault; + + List camelCaseSettingInputs = new List + { + new LinqTestInput("Filter w/ constant value, camelcase = " + useCamelCaseSerializer, b => getQuery(b).Where(doc => doc.NumericField == 1), skipVerification : true, inputData: insertedData), + new LinqTestInput("Filter w/ DataObject initializer with constant value, camelcase = " + useCamelCaseSerializer, b => getQuery(b).Where(doc => doc == new DataObjectNewtonsoft() { NumericField = 1, StringField = "1" }), skipVerification : true, inputData: insertedData), + new LinqTestInput("Select w/ DataObject initializer, camelcase = " + useCamelCaseSerializer, b => getQuery(b).Select(doc => new DataObjectNewtonsoft() { NumericField = 1, StringField = "1" }), skipVerification : true, inputData: insertedData), + new LinqTestInput("Deeper than top level reference, camelcase = " + useCamelCaseSerializer, b => getQuery(b).Select(doc => doc.NumericField > 1 ? new DataObjectNewtonsoft() { NumericField = 1, StringField = "1" } : new DataObjectNewtonsoft() { NumericField = 1, StringField = "1" }), skipVerification : true, inputData: insertedData), + + // Negative test case: serializing only field name using custom serializer not currently supported + new LinqTestInput("Filter w/ DataObject initializer with member initialization, camelcase = " + useCamelCaseSerializer, b => getQuery(b).Where(doc => doc == new DataObjectNewtonsoft() { NumericField = doc.NumericField, StringField = doc.StringField }).Select(b => "A"), skipVerification : true, inputData: insertedData) + }; + + inputs.AddRange(camelCaseSettingInputs); + } + + this.ExecuteTestSuite(inputs); + } + + [TestMethod] + public void TestMemberInitializerDataMember() + { + Func> getQueryCamelCase; + Func> getQueryDefault; + (getQueryCamelCase, getQueryDefault) = this.InsertDataAndGetQueryables(); + + string insertedData = this.GetInsertedData().Result; + + List inputs = new List(); + foreach (bool useCamelCaseSerializer in new bool[] { true, false }) + { + Func> getQuery = useCamelCaseSerializer ? getQueryCamelCase : getQueryDefault; + + List camelCaseSettingInputs = new List + { + new LinqTestInput("Filter w/ constant value, camelcase = " + useCamelCaseSerializer, b => getQuery(b).Where(doc => doc.NumericField == 1), skipVerification : true, inputData: insertedData), + new LinqTestInput("Filter w/ DataObject initializer with constant value, camelcase = " + useCamelCaseSerializer, b => getQuery(b).Where(doc => doc == new DataObjectDataMember() { NumericField = 1, StringField = "1" }), skipVerification : true, inputData: insertedData), + new LinqTestInput("Select w/ DataObject initializer, camelcase = " + useCamelCaseSerializer, b => getQuery(b).Select(doc => new DataObjectDataMember() { NumericField = 1, StringField = "1" }), skipVerification : true, inputData: insertedData), + new LinqTestInput("Deeper than top level reference, camelcase = " + useCamelCaseSerializer, b => getQuery(b).Select(doc => doc.NumericField > 1 ? new DataObjectDataMember() { NumericField = 1, StringField = "1" } : new DataObjectDataMember() { NumericField = 1, StringField = "1" }), skipVerification : true, inputData: insertedData), + + // Negative test case: serializing only field name using custom serializer not currently supported + new LinqTestInput("Filter w/ DataObject initializer with member initialization, camelcase = " + useCamelCaseSerializer, b => getQuery(b).Where(doc => doc == new DataObjectDataMember() { NumericField = doc.NumericField, StringField = doc.StringField }).Select(b => "A"), skipVerification : true, inputData: insertedData) + }; + + inputs.AddRange(camelCaseSettingInputs); + } + + this.ExecuteTestSuite(inputs); + } + + [TestMethod] + public void TestMemberInitializerMultiSerializer() + { + Func> getQueryCamelCase; + Func> getQueryDefault; + (getQueryCamelCase, getQueryDefault) = this.InsertDataAndGetQueryables(); + + string insertedData = this.GetInsertedData().Result; + + List inputs = new List(); + foreach (bool useCamelCaseSerializer in new bool[] { true, false }) + { + Func> getQuery = useCamelCaseSerializer ? getQueryCamelCase : getQueryDefault; + + List camelCaseSettingInputs = new List + { + new LinqTestInput("Filter w/ constant value, camelcase = " + useCamelCaseSerializer, b => getQuery(b).Where(doc => doc.NumericField == 1), skipVerification : true, inputData: insertedData), + new LinqTestInput("Filter w/ DataObject initializer with constant value, camelcase = " + useCamelCaseSerializer, b => getQuery(b).Where(doc => doc == new DataObjectMultiSerializer() { NumericField = 1, StringField = "1" }), skipVerification : true, inputData: insertedData), + new LinqTestInput("Select w/ DataObject initializer, camelcase = " + useCamelCaseSerializer, b => getQuery(b).Select(doc => new DataObjectMultiSerializer() { NumericField = 1, StringField = "1" }), skipVerification : true, inputData: insertedData), + new LinqTestInput("Deeper than top level reference, camelcase = " + useCamelCaseSerializer, b => getQuery(b).Select(doc => doc.NumericField > 1 ? new DataObjectMultiSerializer() { NumericField = 1, StringField = "1" } : new DataObjectMultiSerializer() { NumericField = 1, StringField = "1" }), skipVerification : true, inputData: insertedData), + + // Negative test case: serializing only field name using custom serializer not currently supported + new LinqTestInput("Filter w/ DataObject initializer with member initialization, camelcase = " + useCamelCaseSerializer, b => getQuery(b).Where(doc => doc == new DataObjectMultiSerializer() { NumericField = doc.NumericField, StringField = doc.StringField }).Select(b => "A"), skipVerification : true, inputData: insertedData) + }; + + inputs.AddRange(camelCaseSettingInputs); + } + + this.ExecuteTestSuite(inputs); + } + + private (Func>, Func>) InsertDataAndGetQueryables() where T : LinqTestObject + { + static T createDataObj(int index, bool camelCase) + { + T obj = (T)Activator.CreateInstance(typeof(T), new object[] + { + index, index.ToString(), $"{index}-{camelCase}", "Test" + }); + return obj; + } + + Func> getQueryCamelCase = LinqTestsCommon.GenerateSerializationTestCosmosData(createDataObj, RecordCount, TestContainer, camelCaseSerialization: true); + Func> getQueryDefault = LinqTestsCommon.GenerateSerializationTestCosmosData(createDataObj, RecordCount, TestContainer, camelCaseSerialization: false); + + return (getQueryCamelCase, getQueryDefault); + } + + private async Task GetInsertedData() + { + List insertedDataList = new List(); + using (FeedIterator feedIterator = TestContainer.GetItemQueryStreamIterator("SELECT * FROM c")) + { + while (feedIterator.HasMoreResults) + { + using (ResponseMessage response = await feedIterator.ReadNextAsync()) + { + response.EnsureSuccessStatusCode(); + using (StreamReader streamReader = new StreamReader(response.Content)) + using (JsonTextReader jsonTextReader = new JsonTextReader(streamReader)) + { + // manual parsing of response object to preserve property names + JObject queryResponseObject = await JObject.LoadAsync(jsonTextReader); + IEnumerable info = queryResponseObject["Documents"].AsEnumerable(); + + foreach (JToken docToken in info) + { + string documentString = "{"; + for (int index = 0; index < PropertyCount; index++) + { + documentString += index == 0 ? String.Empty : ", "; + documentString += docToken.ElementAt(index).ToString(); + } + documentString += "}"; + insertedDataList.Add(documentString); + } + } + } + } + } + + string insertedData = JsonConvert.SerializeObject(insertedDataList.Select(item => item), new JsonSerializerSettings { Formatting = Newtonsoft.Json.Formatting.Indented }); + return insertedData; + } + + private class SystemTextJsonSerializer : CosmosSerializer + { + private readonly JsonObjectSerializer systemTextJsonSerializer; + + public SystemTextJsonSerializer(JsonSerializerOptions jsonSerializerOptions) + { + this.systemTextJsonSerializer = new JsonObjectSerializer(jsonSerializerOptions); + } + + public override T FromStream(Stream stream) + { + if (stream == null) + throw new ArgumentNullException(nameof(stream)); + + using (stream) + { + if (stream.CanSeek && stream.Length == 0) + { + return default; + } + + if (typeof(Stream).IsAssignableFrom(typeof(T))) + { + return (T)(object)stream; + } + + return (T)this.systemTextJsonSerializer.Deserialize(stream, typeof(T), default); + } + } + + public override Stream ToStream(T input) + { + MemoryStream streamPayload = new MemoryStream(); + this.systemTextJsonSerializer.Serialize(streamPayload, input, typeof(T), default); + streamPayload.Position = 0; + return streamPayload; + } + } + + private class DataObjectDotNet : LinqTestObject + { + [JsonPropertyName("numberValueDotNet")] + public double NumericField { get; set; } + + [JsonPropertyName("stringValueDotNet")] + public string StringField { get; set; } + + public string id { get; set; } + + public string Pk { get; set; } + + public DataObjectDotNet() { } + + public DataObjectDotNet(double numericField, string stringField, string id, string pk) + { + this.NumericField = numericField; + this.StringField = stringField; + this.id = id; + this.Pk = pk; + } + + public override string ToString() + { + return $"{{NumericField:{this.NumericField},StringField:{this.StringField},id:{this.id},Pk:{this.Pk}}}"; + } + } + + private class DataObjectNewtonsoft : LinqTestObject + { + [Newtonsoft.Json.JsonProperty(PropertyName = "NumberValueNewtonsoft")] + public double NumericField { get; set; } + + [Newtonsoft.Json.JsonProperty(PropertyName = "StringValueNewtonsoft")] + public string StringField { get; set; } + + public string id { get; set; } + + public string Pk { get; set; } + + public DataObjectNewtonsoft() { } + + public DataObjectNewtonsoft(double numericField, string stringField, string id, string pk) + { + this.NumericField = numericField; + this.StringField = stringField; + this.id = id; + this.Pk = pk; + } + + public override string ToString() + { + return $"{{NumericField:{this.NumericField},StringField:{this.StringField},id:{this.id},Pk:{this.Pk}}}"; + } + } + + [DataContract] + private class DataObjectDataMember : LinqTestObject + { + [DataMember(Name = "NumericFieldDataMember")] + public double NumericField { get; set; } + + [DataMember(Name = "StringFieldDataMember")] + public string StringField { get; set; } + + [DataMember(Name = "id")] + public string id { get; set; } + + [DataMember(Name = "Pk")] + public string Pk { get; set; } + + public DataObjectDataMember() { } + + public DataObjectDataMember(double numericField, string stringField, string id, string pk) + { + this.NumericField = numericField; + this.StringField = stringField; + this.id = id; + this.Pk = pk; + } + + public override string ToString() + { + return $"{{NumericField:{this.NumericField},StringField:{this.StringField},id:{this.id},Pk:{this.Pk}}}"; + } + } + + private class DataObjectMultiSerializer : LinqTestObject + { + [Newtonsoft.Json.JsonProperty(PropertyName = "NumberValueNewtonsoft")] + [JsonPropertyName("numberValueDotNet")] + public double NumericField { get; set; } + + [Newtonsoft.Json.JsonProperty(PropertyName = "StringValueNewtonsoft")] + [JsonPropertyName("stringValueDotNet")] + public string StringField { get; set; } + + public string id { get; set; } + + public string Pk { get; set; } + + public DataObjectMultiSerializer() { } + + public DataObjectMultiSerializer(double numericField, string stringField, string id, string pk) + { + this.NumericField = numericField; + this.StringField = stringField; + this.id = id; + this.Pk = pk; + } + + public override string ToString() + { + return $"{{NumericField:{this.NumericField},StringField:{this.StringField},id:{this.id},Pk:{this.Pk}}}"; + } + } + } +} diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Microsoft.Azure.Cosmos.EmulatorTests.csproj b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Microsoft.Azure.Cosmos.EmulatorTests.csproj index cb59dfb820..7ff30b3cee 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Microsoft.Azure.Cosmos.EmulatorTests.csproj +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Microsoft.Azure.Cosmos.EmulatorTests.csproj @@ -19,6 +19,7 @@ + @@ -37,6 +38,10 @@ + + + + @@ -201,6 +206,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest @@ -247,7 +255,19 @@ PreserveNewest - PreserveNewest + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest PreserveNewest diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Query/PopulateIndexMetricsTest.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Query/PopulateIndexMetricsTest.cs index 29f1944643..084e7738a5 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Query/PopulateIndexMetricsTest.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Query/PopulateIndexMetricsTest.cs @@ -35,14 +35,6 @@ static async Task ImplementationAsync(Container container, IReadOnlyList 12"); - // Build the expected string - Assert.IsTrue(IndexUtilizationInfo.TryCreateFromDelimitedBase64String("eyJVdGlsaXplZFNpbmdsZUluZGV4ZXMiOlt7IkZpbHRlckV4cHJlc3Npb24iOiIoUk9PVC5uYW1lID0gXCJBQkNcIikiLCJJbmRleFNwZWMiOiJcL25hbWVcLz8iLCJGaWx0ZXJQcmVjaXNlU2V0Ijp0cnVlLCJJbmRleFByZWNpc2VTZXQiOnRydWUsIkluZGV4SW1wYWN0U2NvcmUiOiJIaWdoIn0seyJGaWx0ZXJFeHByZXNzaW9uIjoiKFJPT1QuYWdlID4gMTIpIiwiSW5kZXhTcGVjIjoiXC9hZ2VcLz8iLCJGaWx0ZXJQcmVjaXNlU2V0Ijp0cnVlLCJJbmRleFByZWNpc2VTZXQiOnRydWUsIkluZGV4SW1wYWN0U2NvcmUiOiJIaWdoIn1dLCJQb3RlbnRpYWxTaW5nbGVJbmRleGVzIjpbXSwiVXRpbGl6ZWRDb21wb3NpdGVJbmRleGVzIjpbXSwiUG90ZW50aWFsQ29tcG9zaXRlSW5kZXhlcyI6W3siSW5kZXhTcGVjcyI6WyJcL25hbWUgQVNDIiwiXC9hZ2UgQVNDIl0sIkluZGV4UHJlY2lzZVNldCI6ZmFsc2UsIkluZGV4SW1wYWN0U2NvcmUiOiJIaWdoIn1dfQ==", - out IndexUtilizationInfo parsedInfo)); - StringBuilder stringBuilder = new StringBuilder(); - IndexMetricWriter indexMetricWriter = new IndexMetricWriter(stringBuilder); - indexMetricWriter.WriteIndexMetrics(parsedInfo); - string expectedIndexMetricsString = stringBuilder.ToString(); - // Test using GetItemQueryIterator QueryRequestOptions requestOptions = new QueryRequestOptions() { PopulateIndexMetrics = true }; @@ -56,7 +48,6 @@ static async Task ImplementationAsync(Container container, IReadOnlyList 1); Assert.IsNotNull(page.Headers.Get(HttpConstants.HttpHeaders.IndexUtilization), "Expected index utilization headers for query"); Assert.IsNotNull(page.IndexMetrics, "Expected index metrics response for query"); - Assert.AreEqual(expectedIndexMetricsString, page.IndexMetrics); } // Test using Stream API @@ -73,7 +64,6 @@ static async Task ImplementationAsync(Container container, IReadOnlyList 1); Assert.IsNotNull(response.Headers.Get(HttpConstants.HttpHeaders.IndexUtilization), "Expected index utilization headers for query"); - Assert.AreEqual(expectedIndexMetricsString, response.IndexMetrics); } } } diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/QueryPerfTest/ContentSerializationPerformanceTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/QueryPerfTest/ContentSerializationPerformanceTests.cs index 759e63b345..8ff5660c6f 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/QueryPerfTest/ContentSerializationPerformanceTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/QueryPerfTest/ContentSerializationPerformanceTests.cs @@ -33,15 +33,15 @@ public ContentSerializationPerformanceTests() this.queryStatisticsDatumVisitor = new(); this.endpoint = Utils.ConfigurationManager.AppSettings["GatewayEndpoint"]; this.authKey = Utils.ConfigurationManager.AppSettings["MasterKey"]; - this.cosmosDatabaseId = Utils.ConfigurationManager.AppSettings["ContentSerializationPerformanceTests.CosmosDatabaseId"]; - this.containerId = Utils.ConfigurationManager.AppSettings["ContentSerializationPerformanceTests.ContainerId"]; - this.contentSerialization = Utils.ConfigurationManager.AppSettings["ContentSerializationPerformanceTests.ContentSerialization"]; - this.query = Utils.ConfigurationManager.AppSettings["ContentSerializationPerformanceTests.Query"]; - this.numberOfIterations = int.Parse(Utils.ConfigurationManager.AppSettings["ContentSerializationPerformanceTests.NumberOfIterations"]); - this.warmupIterations = int.Parse(Utils.ConfigurationManager.AppSettings["ContentSerializationPerformanceTests.WarmupIterations"]); - this.MaxConcurrency = int.Parse(Utils.ConfigurationManager.AppSettings["ContentSerializationPerformanceTests.MaxConcurrency"]); - this.MaxItemCount = int.Parse(Utils.ConfigurationManager.AppSettings["ContentSerializationPerformanceTests.MaxItemCount"]); - this.useStronglyTypedIterator = bool.Parse(Utils.ConfigurationManager.AppSettings["ContentSerializationPerformanceTests.UseStronglyTypedIterator"]); + this.cosmosDatabaseId = Utils.ConfigurationManager.AppSettings["QueryPerformanceTests.CosmosDatabaseId"]; + this.containerId = Utils.ConfigurationManager.AppSettings["QueryPerformanceTests.ContainerId"]; + this.contentSerialization = Utils.ConfigurationManager.AppSettings["QueryPerformanceTests.ContentSerialization"]; + this.query = Utils.ConfigurationManager.AppSettings["QueryPerformanceTests.Query"]; + this.numberOfIterations = int.Parse(Utils.ConfigurationManager.AppSettings["QueryPerformanceTests.NumberOfIterations"]); + this.warmupIterations = int.Parse(Utils.ConfigurationManager.AppSettings["QueryPerformanceTests.WarmupIterations"]); + this.MaxConcurrency = int.Parse(Utils.ConfigurationManager.AppSettings["QueryPerformanceTests.MaxConcurrency"]); + this.MaxItemCount = int.Parse(Utils.ConfigurationManager.AppSettings["QueryPerformanceTests.MaxItemCount"]); + this.useStronglyTypedIterator = bool.Parse(Utils.ConfigurationManager.AppSettings["QueryPerformanceTests.UseStronglyTypedIterator"]); } [TestMethod] diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/QueryPerfTest/MetricsAccumulator.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/QueryPerfTest/MetricsAccumulator.cs index 56fc16b683..a7e6032001 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/QueryPerfTest/MetricsAccumulator.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/QueryPerfTest/MetricsAccumulator.cs @@ -53,18 +53,16 @@ public void ReadFromTrace(FeedResponse Response, QueryStatisticsDatumVisit { if (storeResponse.StoreResult.StatusCode == StatusCodes.Ok) { - backendAndClientMetrics.Add(Tuple.Create(retrieveCosmosElementTraces[k], backendMetrics[j], transitMetrics[i])); + backendAndClientMetrics.Add(Tuple.Create(retrieveCosmosElementTraces[k], backendMetrics[j], node)); j++; k++; } else { //We add null values to the tuple since status codes other than Ok will not have data for 'Query Metrics' and 'Get Cosmos Element Response' - backendAndClientMetrics.Add(Tuple.Create(null, null, transitMetrics[i])); + backendAndClientMetrics.Add(Tuple.Create(null, null, node)); } } - - i++; } Debug.Assert(i == transitMetrics.Count, "All 'transit metrics' must be grouped."); @@ -76,7 +74,7 @@ public void ReadFromTrace(FeedResponse Response, QueryStatisticsDatumVisit { if (metrics.Item2 != null) { - Debug.Assert(metrics.Item1 == null, "'Get Cosmos Element Response' is null"); + Debug.Assert(metrics.Item1 != null, "'Get Cosmos Element Response' is null"); queryStatisticsDatumVisitor.AddGetCosmosElementResponseTime(metrics.Item1.Duration.TotalMilliseconds); foreach (KeyValuePair kvp in metrics.Item2.Data) { diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/QueryPerfTest/OptimisticDirectExecutionPerformanceTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/QueryPerfTest/OptimisticDirectExecutionPerformanceTests.cs new file mode 100644 index 0000000000..756357e611 --- /dev/null +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/QueryPerfTest/OptimisticDirectExecutionPerformanceTests.cs @@ -0,0 +1,469 @@ +namespace Microsoft.Azure.Cosmos.SDK.EmulatorTests +{ + using System; + using System.Collections.Generic; + using System.IO; + using System.Linq; + using System.Text; + using System.Threading.Tasks; + using Microsoft.Azure.Cosmos; + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class OptimisticDirectExecutionPerformanceTests + { + private Container Container; + private const string RawDataFileName = "OptimisticDirectExecutionPerformanceTestsRawData.csv"; + private const string AggregateDataFileName = "OptimisticDirectExecutionPerformanceTestsAggregatedData.csv"; + private const string PrintQueryMetrics = "QueryMetrics"; + private static readonly string RawDataPath = Path.GetFullPath(RawDataFileName); + private static readonly string AggregateDataPath = Path.GetFullPath(AggregateDataFileName); + private static readonly string Endpoint = Utils.ConfigurationManager.AppSettings["GatewayEndpoint"]; + private static readonly string AuthKey = Utils.ConfigurationManager.AppSettings["MasterKey"]; + private static readonly string CosmosDatabaseId = Utils.ConfigurationManager.AppSettings["QueryPerformanceTests.CosmosDatabaseId"]; + private static readonly string ContainerId = Utils.ConfigurationManager.AppSettings["QueryPerformanceTests.ContainerId"]; + private static readonly PartitionKey PartitionKeyValue = new PartitionKey("Andersen"); + private static readonly int NumberOfIterations = int.Parse(Utils.ConfigurationManager.AppSettings["QueryPerformanceTests.NumberOfIterations"]); + private static readonly int WarmupIterations = int.Parse(Utils.ConfigurationManager.AppSettings["QueryPerformanceTests.WarmupIterations"]); + + [TestInitialize] + public async Task InitializeTest() + { + CosmosClientOptions clientOptions = new CosmosClientOptions() + { + ConnectionMode = ConnectionMode.Direct, + }; + + CosmosClient cosmosClient = new CosmosClient(Endpoint, AuthKey, clientOptions); + Database database = await cosmosClient.CreateDatabaseAsync(CosmosDatabaseId); + this.Container = await database.CreateContainerAsync(ContainerId, partitionKeyPath: "/name"); + await this.AddItemsToContainerAsync(this.Container); + + if (File.Exists(RawDataPath)) + { + File.Delete(RawDataPath); + } + + if (File.Exists(AggregateDataPath)) + { + File.Delete(AggregateDataPath); + } + } + + [TestCleanup] + public async Task CleanupAsync() + { + if (this.Container != null) + { + await this.Container.Database.DeleteAsync(); + this.Container = null; + } + } + + private async Task AddItemsToContainerAsync(Container container) + { + int totalItems = 5000; + string[] cityOptions = new string[] { "Seattle", "Chicago", "NYC", "SF" }; + int numberOfRecipeints = cityOptions.Length; + List recipientList = new List(numberOfRecipeints); + + for (int j = 0; j < numberOfRecipeints; j++) + { + RecipientList recipient = new RecipientList() + { + Name = "John", + City = cityOptions[j], + }; + + recipientList.Add(recipient); + } + + // Create a family object for the Andersen family + foreach (int i in Enumerable.Range(0, totalItems)) + { + States andersenFamily = new States + { + Id = i.ToString(), + Name = i < (totalItems/2) ? "Andersen" : "Smith", + City = cityOptions[i%cityOptions.Length], + PostalCode = (i * 10).ToString(), + Region = "Northwest", + UserDefinedID = i % 10, + RecipientList = recipientList + }; + + ItemResponse andersenFamilyResponse = await container.CreateItemAsync(andersenFamily, new PartitionKey(andersenFamily.Name)); + Console.WriteLine("Created item in database with id: {0} Operation consumed {1} RUs.\n", andersenFamilyResponse.Resource.Id, andersenFamilyResponse.RequestCharge); + } + } + + //Set Ode perf tests to ignore so that they dont run on every loop build. + //Ignore flag can be removed when checking for Ode performance. + [Ignore] + [TestMethod] + [Owner("akotalwar")] + public async Task RunAsync() + { + string highPrepTimeSumQuery = CreateHighPrepTimeSumQuery(); + string highPrepTimeConditionalQuery = CreateHighPrepTimeConditionalQuery(); + List> globalCustomOdeStatisticsList = new List>(); + + List odeTestCases = new List() + { + //Simple Query + CreateInput("SELECT * FROM c", PartitionKeyValue, false, -1, 2500), + CreateInput("SELECT * FROM c", PartitionKeyValue, true, -1, 2500), + + //TOP + CreateInput("SELECT TOP 1000 c.id FROM c", PartitionKeyValue, false, -1, 1000), + CreateInput("SELECT TOP 1000 c.id FROM c", PartitionKeyValue, true, -1, 1000), + + //Filter + CreateInput("SELECT c.id FROM c WHERE c.city IN ('Seattle', 'NYC')", PartitionKeyValue, false, -1, 1250), + CreateInput("SELECT c.id FROM c WHERE c.city IN ('Seattle', 'NYC')", PartitionKeyValue, true, -1, 1250), + + //DISTINCT + Filter + CreateInput("SELECT DISTINCT c.userDefinedId FROM c WHERE c.userDefinedId BETWEEN 0 AND 5 OFFSET 1 LIMIT 3", PartitionKeyValue, false, -1, 3), + CreateInput("SELECT DISTINCT c.userDefinedId FROM c WHERE c.userDefinedId BETWEEN 0 AND 5 OFFSET 1 LIMIT 3", PartitionKeyValue, true, -1, 3), + + CreateInput("SELECT DISTINCT c.city FROM c WHERE STARTSWITH(c.city, 'S')", PartitionKeyValue, false, -1, 2), + CreateInput("SELECT DISTINCT c.city FROM c WHERE STARTSWITH(c.city, 'S')", PartitionKeyValue, true, -1, 2), + + //JOIN + CreateInput("SELECT root.id " + + "FROM root " + + "JOIN root.id a " + + "JOIN root.id b " + + "JOIN root.id c " + + "WHERE root.id = '1' OR a.id in (1,2,3,4,5,6,7,8,9,10) " + + "OR b.id in (1,2,3,4,5,6,7,8,9,10) " + + "OR c.id in (1,2,3,4,5,6,7,8,9,10)", PartitionKeyValue, false, -1, 1), + CreateInput("SELECT root.id " + + "FROM root " + + "JOIN root.id a " + + "JOIN root.id b " + + "JOIN root.id c " + + "WHERE root.id = '1' OR a.id in (1,2,3,4,5,6,7,8,9,10) " + + "OR b.id in (1,2,3,4,5,6,7,8,9,10) " + + "OR c.id in (1,2,3,4,5,6,7,8,9,10)", PartitionKeyValue, true, -1, 1), + + //High Prep Time + CreateInput(highPrepTimeSumQuery, PartitionKeyValue, false, -1, 2500), + CreateInput(highPrepTimeSumQuery, PartitionKeyValue, true, -1, 2500), + + CreateInput(highPrepTimeConditionalQuery, PartitionKeyValue, false, -1, 1750), + CreateInput(highPrepTimeConditionalQuery, PartitionKeyValue, true, -1, 1750), + + //Order By + CreateInput("SELECT * FROM c ORDER BY c.userDefinedId DESC", PartitionKeyValue, false, -1, 2500), + CreateInput("SELECT * FROM c ORDER BY c.userDefinedId DESC", PartitionKeyValue, true, -1, 2500), + + CreateInput("SELECT c.id FROM c ORDER BY c.postalcode DESC", PartitionKeyValue, false, -1, 2500), + CreateInput("SELECT c.id FROM c ORDER BY c.postalcode DESC", PartitionKeyValue, true, -1, 2500), + + //Order By + TOP + CreateInput("SELECT TOP 5 c.id FROM c ORDER BY c.userDefinedId", PartitionKeyValue, false, -1, 5), + CreateInput("SELECT TOP 5 c.id FROM c ORDER BY c.userDefinedId", PartitionKeyValue, true, -1, 5), + + //Order By + DISTINCT + CreateInput("SELECT DISTINCT c.id FROM c ORDER BY c.city DESC", PartitionKeyValue, false, -1, 2500), + CreateInput("SELECT DISTINCT c.id FROM c ORDER BY c.city DESC", PartitionKeyValue, true, -1, 2500), + + //Order By + DISTINCT + Filter + CreateInput("SELECT DISTINCT c.userDefinedId FROM c WHERE c.userDefinedId > 5 ORDER BY c.userDefinedId", PartitionKeyValue, false, -1, 4), + CreateInput("SELECT DISTINCT c.userDefinedId FROM c WHERE c.userDefinedId > 5 ORDER BY c.userDefinedId", PartitionKeyValue, true, -1, 4), + + CreateInput("SELECT DISTINCT c.userDefinedId FROM c WHERE c.userDefinedId BETWEEN 0 AND 5 ORDER BY c.id DESC", PartitionKeyValue, false, -1, 6), + CreateInput("SELECT DISTINCT c.userDefinedId FROM c WHERE c.userDefinedId BETWEEN 0 AND 5 ORDER BY c.id DESC", PartitionKeyValue, true, -1, 6), + + //Group By + CreateInput("SELECT c.postalcode FROM c GROUP BY c.postalcode", PartitionKeyValue, false, -1, 2500), + CreateInput("SELECT c.postalcode FROM c GROUP BY c.postalcode", PartitionKeyValue, true, -1, 2500), + + CreateInput("SELECT Count(1) AS count, Sum(ARRAY_LENGTH(c.recipientList)) AS sum FROM c WHERE c.city IN ('Seattle', 'SF') GROUP BY c.city", PartitionKeyValue, false, -1, 2), + CreateInput("SELECT Count(1) AS count, Sum(ARRAY_LENGTH(c.recipientList)) AS sum FROM c WHERE c.city IN ('Seattle', 'SF') GROUP BY c.city", PartitionKeyValue, true, -1, 2), + + CreateInput("SELECT c.city, AVG(ARRAY_LENGTH(c.recipientList)) FROM c GROUP BY c.city", PartitionKeyValue, false, -1, 4), + CreateInput("SELECT c.city, AVG(ARRAY_LENGTH(c.recipientList)) FROM c GROUP BY c.city", PartitionKeyValue, true, -1, 4), + + //Group By + OFFSET + CreateInput("SELECT c.id FROM c GROUP BY c.id OFFSET 5 LIMIT 3", PartitionKeyValue, false, -1, 3), + CreateInput("SELECT c.id FROM c GROUP BY c.id OFFSET 5 LIMIT 3", PartitionKeyValue, true, -1, 3), + + //Group By + TOP + CreateInput("SELECT TOP 25 c.id FROM c GROUP BY c.id", PartitionKeyValue, false, -1, 25), + CreateInput("SELECT TOP 25 c.id FROM c GROUP BY c.id", PartitionKeyValue, true, -1, 25), + + //Group By + DISTINCT + CreateInput("SELECT DISTINCT c.id FROM c GROUP BY c.id", PartitionKeyValue, false, -1, 2500), + CreateInput("SELECT DISTINCT c.id FROM c GROUP BY c.id", PartitionKeyValue, true, -1, 2500), + + CreateInput("SELECT DISTINCT c.postalcode FROM c GROUP BY c.postalcode", PartitionKeyValue, false, -1, 2500), + CreateInput("SELECT DISTINCT c.postalcode FROM c GROUP BY c.postalcode", PartitionKeyValue, true, -1, 2500), + }; + + foreach (DirectExecutionTestCase testCase in odeTestCases) + { + globalCustomOdeStatisticsList.AddRange(await this.RunQueryAsync(testCase)); + } + + using (StreamWriter writer = new StreamWriter(new FileStream(RawDataPath, FileMode.Append, FileAccess.Write))) + { + SerializeODEQueryMetrics(writer, globalCustomOdeStatisticsList, NumberOfIterations, rawData: true); + } + + using (StreamWriter writer = new StreamWriter(new FileStream(AggregateDataPath, FileMode.Append, FileAccess.Write))) + { + SerializeODEQueryMetrics(writer, globalCustomOdeStatisticsList, NumberOfIterations, rawData: false); + } + } + + private async Task>> RunQueryAsync(DirectExecutionTestCase queryInput) + { + List> odeQueryStatisticsList = new List>(); + QueryRequestOptions requestOptions = new QueryRequestOptions() + { + MaxItemCount = queryInput.PageSizeOption, + EnableOptimisticDirectExecution = queryInput.EnableOptimisticDirectExecution, + PartitionKey = queryInput.PartitionKey, + }; + + for (int i = 0; i < NumberOfIterations + WarmupIterations; i++) + { + bool isWarmUpIteration = i < WarmupIterations; + using (FeedIterator iterator = this.Container.GetItemQueryIterator( + queryText: queryInput.Query, + requestOptions: requestOptions)) + { + if (isWarmUpIteration) + { + while (iterator.HasMoreResults) + { + await iterator.ReadNextAsync(); + } + } + else + { + odeQueryStatisticsList.Add(await this.GetIteratorStatistics(iterator, queryInput)); + } + } + } + + return odeQueryStatisticsList; + } + + private async Task> GetIteratorStatistics(FeedIterator feedIterator, DirectExecutionTestCase queryInput) + { + MetricsAccumulator metricsAccumulator = new MetricsAccumulator(); + Guid correlatedActivityId = Guid.NewGuid(); + FeedResponse response; + int totalDocumentCount = 0; + string query; + bool enableOde; + List odeQueryStatisticsList = new List(); + + while (feedIterator.HasMoreResults) + { + QueryStatisticsDatumVisitor queryStatisticsDatumVisitor = new QueryStatisticsDatumVisitor(); + System.Diagnostics.Stopwatch totalTime = new System.Diagnostics.Stopwatch(); + System.Diagnostics.Stopwatch traceTime = new System.Diagnostics.Stopwatch(); + + totalTime.Start(); + response = await feedIterator.ReadNextAsync(); + traceTime.Start(); + if (response.RequestCharge != 0) + { + metricsAccumulator.ReadFromTrace(response, queryStatisticsDatumVisitor); + } + + traceTime.Stop(); + totalTime.Stop(); + + query = queryInput.Query; + enableOde = queryInput.EnableOptimisticDirectExecution; + queryStatisticsDatumVisitor.AddEndToEndTime(totalTime.ElapsedMilliseconds - traceTime.ElapsedMilliseconds); + queryStatisticsDatumVisitor.PopulateMetrics(); + + QueryStatisticsMetrics queryStatistics = queryStatisticsDatumVisitor.QueryMetricsList[0]; + queryStatistics.RUCharge = response.RequestCharge; + queryStatistics.CorrelatedActivityId = correlatedActivityId; + + // Each roundtrip is a new item in the list + odeQueryStatisticsList.Add(new OdeQueryStatistics + { + Query = query, + EnableOde = enableOde, + QueryStatisticsMetrics = queryStatistics + }); + + totalDocumentCount += response.Count; + } + + Assert.AreEqual(queryInput.ExpectedResultCount, totalDocumentCount); + + return odeQueryStatisticsList; + } + + private static string CreateHighPrepTimeSumQuery() + { + int exprCount = 9999; + StringBuilder sb = new StringBuilder(); + sb.Append("SELECT r.id FROM root r WHERE "); + for (int i = 0; i < exprCount; i++) + { + sb.Append(i == 0 ? "1" : "+1"); + } + + return sb.Append(" = " + exprCount + " ORDER BY r.id ASC").ToString(); + } + + private static string CreateHighPrepTimeConditionalQuery() + { + int exprCount = 999; + StringBuilder sb = new StringBuilder(); + string[] cityOptions = new string[] { "Seattle", "Chicago", "NYC", "SF" }; + + sb.Append("SELECT * FROM root r WHERE "); + for (int nIdx = 0; nIdx < exprCount; nIdx++) + { + if (nIdx > 0) + { + sb.Append(" OR "); + } + + sb.Append($"r.userDefinedId > {nIdx} AND r.city = '{cityOptions[nIdx % cityOptions.Length]}'"); + } + + return sb.ToString(); + } + + private static void SerializeODEQueryMetrics(TextWriter textWriter, List> customOdeStatisticsList, int numberOfIterations, bool rawData) + { + if (rawData) + { + SerializeODERawDataQueryMetrics(textWriter, customOdeStatisticsList); + } + else + { + SerializeODEProcessedDataQueryMetrics(textWriter, customOdeStatisticsList, numberOfIterations); + } + } + + private static void SerializeODERawDataQueryMetrics(TextWriter textWriter, List> globalOdeQueryStatisticsList) + { + textWriter.WriteLine(); + textWriter.WriteLine(PrintQueryMetrics); + textWriter.Write("\"{0}\",\"{1}\",\"{2}\",\"{3}\",\"{4}\",\"{5}\",\"{6}\"", "Query", "ODE", "RUCharge", "BackendTime", "TransitTime", "ClientTime", "EndToEndTime"); + textWriter.WriteLine(); + + foreach (List queryStatisticsList in globalOdeQueryStatisticsList) + { + double totalClientTime = 0; + double totalBackendTime = 0; + double totalEndToEndTime = 0; + double totalTransitTime = 0; + double totalRU = 0; + string query = ""; + bool ode = false; + + foreach (OdeQueryStatistics queryStatistics in queryStatisticsList) + { + QueryStatisticsMetrics metrics = queryStatistics.QueryStatisticsMetrics; + double transitTime = metrics.Created + metrics.ChannelAcquisitionStarted + metrics.Pipelined + metrics.Received + metrics.Completed; + double backendTime = metrics.TotalQueryExecutionTime; + + totalClientTime += metrics.EndToEndTime - (backendTime + transitTime); + totalBackendTime += backendTime; + totalEndToEndTime += metrics.EndToEndTime; + totalTransitTime += transitTime; + totalRU += metrics.RUCharge; + query = queryStatistics.Query; + ode = queryStatistics.EnableOde; + } + + textWriter.WriteLine($"{query},{ode},{totalRU},{totalBackendTime},{totalTransitTime},{totalClientTime},{totalEndToEndTime}"); + } + } + + private static void SerializeODEProcessedDataQueryMetrics(TextWriter textWriter, List> globalOdeQueryStatisticsList, int numberOfIterations) + { + textWriter.WriteLine(); + textWriter.WriteLine(PrintQueryMetrics); + textWriter.Write("\"{0}\",\"{1}\",\"{2}\",\"{3}\"", "Query", "ODE", "RUCharge", "EndToEndTime"); + textWriter.WriteLine(); + + string prevQuery = globalOdeQueryStatisticsList[0][0].Query; + bool prevOde = globalOdeQueryStatisticsList[0][0].EnableOde; + double totalEndToEndTime = 0; + double totalRU = 0; + + foreach (List odeQueryStatisticsList in globalOdeQueryStatisticsList) + { + if (odeQueryStatisticsList[0].Query == prevQuery && odeQueryStatisticsList[0].EnableOde == prevOde) + { + foreach (OdeQueryStatistics odeQueryStatistics in odeQueryStatisticsList) + { + QueryStatisticsMetrics metrics = odeQueryStatistics.QueryStatisticsMetrics; + totalEndToEndTime += metrics.EndToEndTime; + totalRU += metrics.RUCharge; + } + } + else + { + textWriter.WriteLine($"{prevQuery},{prevOde},{totalRU / numberOfIterations},{totalEndToEndTime / numberOfIterations}"); + + foreach (OdeQueryStatistics odeQueryStatistics in odeQueryStatisticsList) + { + QueryStatisticsMetrics metrics = odeQueryStatistics.QueryStatisticsMetrics; + totalEndToEndTime = metrics.EndToEndTime; + totalRU = metrics.RUCharge; + prevQuery = odeQueryStatistics.Query; + prevOde = odeQueryStatistics.EnableOde; + } + } + } + + textWriter.WriteLine($"{prevQuery},{prevOde},{totalRU / numberOfIterations},{totalEndToEndTime / numberOfIterations}"); + } + + private class OdeQueryStatistics + { + public string Query { get; set; } + public bool EnableOde { get; set; } + public QueryStatisticsMetrics QueryStatisticsMetrics { get; set; } + } + + private static DirectExecutionTestCase CreateInput( + string query, + PartitionKey? partitionKey, + bool enableOptimisticDirectExecution, + int pageSizeOption, + int expectedResultCount) + { + return new DirectExecutionTestCase(query, partitionKey, enableOptimisticDirectExecution, pageSizeOption, expectedResultCount); + } + + private readonly struct DirectExecutionTestCase + { + public string Query { get; } + public PartitionKey? PartitionKey { get; } + public bool EnableOptimisticDirectExecution { get; } + public int PageSizeOption { get; } + public int ExpectedResultCount { get; } + + public DirectExecutionTestCase( + string query, + PartitionKey? partitionKey, + bool enableOptimisticDirectExecution, + int pageSizeOption, + int expectedResultCount) + { + this.Query = query; + this.PartitionKey = partitionKey; + this.EnableOptimisticDirectExecution = enableOptimisticDirectExecution; + this.PageSizeOption = pageSizeOption; + this.ExpectedResultCount = expectedResultCount; + } + } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/QueryPerfTest/QueryStatisticsDatumVisitor.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/QueryPerfTest/QueryStatisticsDatumVisitor.cs index 200150875b..c100146bdb 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/QueryPerfTest/QueryStatisticsDatumVisitor.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/QueryPerfTest/QueryStatisticsDatumVisitor.cs @@ -41,13 +41,13 @@ public void AddGetCosmosElementResponseTime(double time) public void Visit(QueryMetricsTraceDatum queryMetricsTraceDatum) { - this.queryMetrics.RetrievedDocumentCount = queryMetricsTraceDatum.QueryMetrics.BackendMetrics.RetrievedDocumentCount; - this.queryMetrics.RetrievedDocumentSize = queryMetricsTraceDatum.QueryMetrics.BackendMetrics.RetrievedDocumentSize; - this.queryMetrics.OutputDocumentCount = queryMetricsTraceDatum.QueryMetrics.BackendMetrics.OutputDocumentCount; - this.queryMetrics.OutputDocumentSize = queryMetricsTraceDatum.QueryMetrics.BackendMetrics.OutputDocumentSize; - this.queryMetrics.TotalQueryExecutionTime = queryMetricsTraceDatum.QueryMetrics.BackendMetrics.TotalTime.TotalMilliseconds; - this.queryMetrics.DocumentLoadTime = queryMetricsTraceDatum.QueryMetrics.BackendMetrics.DocumentLoadTime.TotalMilliseconds; - this.queryMetrics.DocumentWriteTime = queryMetricsTraceDatum.QueryMetrics.BackendMetrics.DocumentWriteTime.TotalMilliseconds; + this.queryMetrics.RetrievedDocumentCount = queryMetricsTraceDatum.QueryMetrics.ServerSideMetrics.RetrievedDocumentCount; + this.queryMetrics.RetrievedDocumentSize = queryMetricsTraceDatum.QueryMetrics.ServerSideMetrics.RetrievedDocumentSize; + this.queryMetrics.OutputDocumentCount = queryMetricsTraceDatum.QueryMetrics.ServerSideMetrics.OutputDocumentCount; + this.queryMetrics.OutputDocumentSize = queryMetricsTraceDatum.QueryMetrics.ServerSideMetrics.OutputDocumentSize; + this.queryMetrics.TotalQueryExecutionTime = queryMetricsTraceDatum.QueryMetrics.ServerSideMetrics.TotalTime.TotalMilliseconds; + this.queryMetrics.DocumentLoadTime = queryMetricsTraceDatum.QueryMetrics.ServerSideMetrics.DocumentLoadTime.TotalMilliseconds; + this.queryMetrics.DocumentWriteTime = queryMetricsTraceDatum.QueryMetrics.ServerSideMetrics.DocumentWriteTime.TotalMilliseconds; } public void Visit(ClientSideRequestStatisticsTraceDatum clientSideRequestStatisticsTraceDatum) diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/QueryPerfTest/QueryStatisticsMetrics.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/QueryPerfTest/QueryStatisticsMetrics.cs index 70ed146f4c..d72193fc43 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/QueryPerfTest/QueryStatisticsMetrics.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/QueryPerfTest/QueryStatisticsMetrics.cs @@ -1,7 +1,11 @@ namespace Microsoft.Azure.Cosmos.SDK.EmulatorTests { + using System; + internal class QueryStatisticsMetrics { + public Guid CorrelatedActivityId { get; set; } + public double EndToEndTime { get; set; } public double PocoTime { get; set; } @@ -32,6 +36,8 @@ internal class QueryStatisticsMetrics public double Received { get; set; } + public double RUCharge { get; set; } + public double Completed { get; set; } public double BadRequestCreated { get; set; } diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/QueryTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/QueryTests.cs index afc25ec771..762bbbd945 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/QueryTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/QueryTests.cs @@ -1870,11 +1870,11 @@ public async Task TestQueryMetricsNonZero() QueryMetrics queryMetrics = QueryMetrics.CreateFromIEnumerable(feedResonse.QueryMetrics.Values); - Assert.IsTrue(queryMetrics.BackendMetrics.RetrievedDocumentCount > 0); - Assert.IsTrue(queryMetrics.BackendMetrics.RetrievedDocumentSize > 0); - Assert.IsTrue(queryMetrics.BackendMetrics.OutputDocumentCount > 0); - Assert.IsTrue(queryMetrics.BackendMetrics.OutputDocumentSize > 0); - Assert.IsTrue(queryMetrics.BackendMetrics.IndexHitRatio > 0); + Assert.IsTrue(queryMetrics.ServerSideMetrics.RetrievedDocumentCount > 0); + Assert.IsTrue(queryMetrics.ServerSideMetrics.RetrievedDocumentSize > 0); + Assert.IsTrue(queryMetrics.ServerSideMetrics.OutputDocumentCount > 0); + Assert.IsTrue(queryMetrics.ServerSideMetrics.OutputDocumentSize > 0); + Assert.IsTrue(queryMetrics.ServerSideMetrics.IndexHitRatio > 0); await client.DeleteDatabaseAsync(database); } @@ -1960,7 +1960,7 @@ private void TestForceQueryScanHeaders(Database database, bool partitionedCollec query, feedOptions).AsDocumentQuery().ExecuteNextAsync().Result; queryMetrics = result.QueryMetrics.Values.Aggregate((curr, acc) => curr + acc); - Assert.AreEqual(TimeSpan.Zero, queryMetrics.BackendMetrics.IndexLookupTime); + Assert.AreEqual(TimeSpan.Zero, queryMetrics.ServerSideMetrics.IndexLookupTime); // Without ForceQueryScan feedOptions = new FeedOptions() @@ -1976,7 +1976,7 @@ private void TestForceQueryScanHeaders(Database database, bool partitionedCollec query, feedOptions).AsDocumentQuery().ExecuteNextAsync().Result; queryMetrics = result.QueryMetrics.Values.Aggregate((curr, acc) => curr + acc); - Assert.AreNotEqual(TimeSpan.Zero, queryMetrics.BackendMetrics.IndexLookupTime); + Assert.AreNotEqual(TimeSpan.Zero, queryMetrics.ServerSideMetrics.IndexLookupTime); } private void TestFeedOptionInput( @@ -2292,7 +2292,7 @@ private async Task ValidateQueryMetricsHeadersOverContinuations( QueryMetrics queryMetrics = new QueryMetrics( responseQueryMetrics, - IndexUtilizationInfo.CreateFromString(indexUtilization, true), + IndexUtilizationInfo.CreateFromString(indexUtilization), ClientSideMetrics.Empty); this.ValidateQueryMetrics(queryMetrics); @@ -2315,19 +2315,19 @@ private void ValidateQueryMetrics(QueryMetrics metrics) Assert.AreEqual(0, metrics.ClientSideMetrics.Retries); //We are not checking VMExecutionTime, since that is not a public property //Assert.IsTrue(metrics.QueryEngineTimes.VMExecutionTime.TotalMilliseconds > 0, "Expected VMExecutionTimeInMs to be > 0, metrics = {0}", metrics); - Assert.IsTrue(metrics.BackendMetrics.QueryPreparationTimes.QueryCompilationTime.TotalMilliseconds > 0, "Expected CompileTimeInMs to be > 0, metrics = {0}", metrics); + Assert.IsTrue(metrics.ServerSideMetrics.QueryPreparationTimes.QueryCompilationTime.TotalMilliseconds > 0, "Expected CompileTimeInMs to be > 0, metrics = {0}", metrics); //We are not checking DocumentLoadTime and RetrievedDocumentCount, since some queries don't return any documents (especially in the last continuation). //Assert.IsTrue(metrics.QueryEngineTimes.DocumentLoadTime.TotalMilliseconds > 0, "Expected DocumentLoadTimeInMs to be > 0, metrics = {0}", metrics); //Assert.IsTrue(metrics.RetrievedDocumentCount > 0, "Expected RetrievedDocumentCount to be > 0, metrics = {0}", metrics); - Assert.IsTrue(metrics.BackendMetrics.TotalTime.TotalMilliseconds > 0, "Expected TotalExecutionTimeInMs to be > 0, metrics = {0}", metrics); + Assert.IsTrue(metrics.ServerSideMetrics.TotalTime.TotalMilliseconds > 0, "Expected TotalExecutionTimeInMs to be > 0, metrics = {0}", metrics); //Assert.IsTrue(metrics.QueryEngineTimes.WriteOutputTime.TotalMilliseconds > 0, "Expected WriteOutputTimeInMs to be > 0, metrics = {0}", metrics); //Assert.IsTrue(metrics.RetrievedDocumentSize > 0, "Expected RetrievedDocumentSize to be > 0, metrics = {0}", metrics); - Assert.IsTrue(metrics.BackendMetrics.IndexLookupTime.TotalMilliseconds > 0, "Expected IndexLookupTimeInMs to be > 0, metrics = {0}", metrics); - Assert.IsTrue(metrics.BackendMetrics.QueryPreparationTimes.LogicalPlanBuildTime.TotalMilliseconds > 0, "Expected LogicalPlanBuildTimeInMs to be > 0, metrics = {0}", metrics); + Assert.IsTrue(metrics.ServerSideMetrics.IndexLookupTime.TotalMilliseconds > 0, "Expected IndexLookupTimeInMs to be > 0, metrics = {0}", metrics); + Assert.IsTrue(metrics.ServerSideMetrics.QueryPreparationTimes.LogicalPlanBuildTime.TotalMilliseconds > 0, "Expected LogicalPlanBuildTimeInMs to be > 0, metrics = {0}", metrics); //Assert.AreEqual(metrics.QueryEngineTimes.VMExecutionTime - metrics.QueryEngineTimes.IndexLookupTime - metrics.QueryEngineTimes.DocumentLoadTime - metrics.QueryEngineTimes.WriteOutputTime, // metrics.QueryEngineTimes.RuntimeExecutionTimes.TotalTime); - Assert.IsTrue(metrics.BackendMetrics.RuntimeExecutionTimes.QueryEngineExecutionTime >= metrics.BackendMetrics.RuntimeExecutionTimes.SystemFunctionExecutionTime + metrics.BackendMetrics.RuntimeExecutionTimes.UserDefinedFunctionExecutionTime, - "Expected Query VM Execution Time to be > {0}, metrics = {1}", metrics.BackendMetrics.RuntimeExecutionTimes.SystemFunctionExecutionTime + metrics.BackendMetrics.RuntimeExecutionTimes.UserDefinedFunctionExecutionTime, metrics); + Assert.IsTrue(metrics.ServerSideMetrics.RuntimeExecutionTimes.QueryEngineExecutionTime >= metrics.ServerSideMetrics.RuntimeExecutionTimes.SystemFunctionExecutionTime + metrics.ServerSideMetrics.RuntimeExecutionTimes.UserDefinedFunctionExecutionTime, + "Expected Query VM Execution Time to be > {0}, metrics = {1}", metrics.ServerSideMetrics.RuntimeExecutionTimes.SystemFunctionExecutionTime + metrics.ServerSideMetrics.RuntimeExecutionTimes.UserDefinedFunctionExecutionTime, metrics); //Assert.IsTrue(metrics.QueryEngineTimes.VMExecutionTime >= metrics.QueryEngineTimes.RuntimeExecutionTimes.TotalTime, // "Expected Query VM Execution Time to be > {0}, metrics = {1}", metrics.QueryEngineTimes.RuntimeExecutionTimes.TotalTime, metrics); } diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/SynchronizationContextTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/SynchronizationContextTests.cs index a8ae6ce1a4..a51a77f14f 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/SynchronizationContextTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/SynchronizationContextTests.cs @@ -6,9 +6,15 @@ namespace Microsoft.Azure.Cosmos.SDK.EmulatorTests { using System; using System.Linq; + using System.Net; + using System.Net.Http; + using System.Text; using System.Threading; + using System.Threading.Tasks; using Microsoft.Azure.Cosmos.Linq; using Microsoft.VisualStudio.TestTools.UnitTesting; + using Newtonsoft.Json; + using Microsoft.Azure.Documents; [TestClass] public class SynchronizationContextTests @@ -19,10 +25,29 @@ public class SynchronizationContextTests [Timeout(30000)] public void VerifySynchronizationContextDoesNotLock(bool withClientTelemetry) { - if (withClientTelemetry) + HttpClientHandlerHelper httpHandler = new HttpClientHandlerHelper { - Util.EnableClientTelemetryEnvironmentVariables(); - } + RequestCallBack = (request, cancellation) => + { + if (request.RequestUri.AbsoluteUri.Contains(Paths.ClientConfigPathSegment)) + { + HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK); + AccountClientConfiguration clientConfigProperties = new AccountClientConfiguration + { + ClientTelemetryConfiguration = new ClientTelemetryConfiguration + { + IsEnabled = withClientTelemetry, + Endpoint = withClientTelemetry? "http://dummy.telemetry.endpoint/" : null + } + }; + string payload = JsonConvert.SerializeObject(clientConfigProperties); + result.Content = new StringContent(payload, Encoding.UTF8, "application/json"); + return Task.FromResult(result); + } + + return null; + } + }; string databaseId = Guid.NewGuid().ToString(); SynchronizationContext prevContext = SynchronizationContext.Current; @@ -32,7 +57,13 @@ public void VerifySynchronizationContextDoesNotLock(bool withClientTelemetry) SynchronizationContext.SetSynchronizationContext(syncContext); syncContext.Post(_ => { - using (CosmosClient client = TestCommon.CreateCosmosClient()) + using (CosmosClient client = TestCommon.CreateCosmosClient( + customizeClientBuilder: (builder) => builder + .WithClientTelemetryOptions(new CosmosClientTelemetryOptions () + { + DisableSendingMetricsToService = !withClientTelemetry + }) + .WithHttpClientFactory(() => new HttpClient(httpHandler)))) { Cosmos.Database database = client.CreateDatabaseAsync(databaseId).GetAwaiter().GetResult(); database = client.CreateDatabaseIfNotExistsAsync(databaseId).GetAwaiter().GetResult(); @@ -124,7 +155,7 @@ public void VerifySynchronizationContextDoesNotLock(bool withClientTelemetry) double cost = container.GetItemLinqQueryable( allowSynchronousQueryExecution: true).Select(x => x.cost).Sum(); - + ItemResponse deleteResponse = container.DeleteItemAsync(partitionKey: new Cosmos.PartitionKey(testItem.pk), id: testItem.id).ConfigureAwait(false).GetAwaiter().GetResult(); Assert.IsNotNull(deleteResponse); } @@ -138,11 +169,6 @@ public void VerifySynchronizationContextDoesNotLock(bool withClientTelemetry) { client.GetDatabase(databaseId).DeleteAsync().GetAwaiter().GetResult(); } - - if (withClientTelemetry) - { - Util.DisableClientTelemetryEnvironmentVariables(); - } } } diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Tracing/AssertActivity.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Tracing/AssertActivity.cs index 75153d3b88..2bcd002b79 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Tracing/AssertActivity.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Tracing/AssertActivity.cs @@ -8,8 +8,9 @@ namespace Microsoft.Azure.Cosmos.Tracing using System.Collections.Generic; using System.Diagnostics; using System.Linq; - using global::Azure; + using System.Net; using Microsoft.Azure.Cosmos.Telemetry; + using Microsoft.Azure.Cosmos.Telemetry.Diagnostics; using Microsoft.Azure.Cosmos.Tests; using Microsoft.VisualStudio.TestTools.UnitTesting; using Newtonsoft.Json; @@ -32,35 +33,35 @@ public static void IsValidOperationActivity(Activity activity) } IList expectedTags = new List - { - "az.namespace", - "az.schema_url", - "kind", - "db.system", - "db.name", - "db.operation", - "net.peer.name", - "db.cosmosdb.client_id", - "db.cosmosdb.machine_id", - "user_agent.original", - "db.cosmosdb.connection_mode", - "db.cosmosdb.operation_type", - "db.cosmosdb.container", - "db.cosmosdb.request_content_length_bytes", - "db.cosmosdb.response_content_length_bytes", - "db.cosmosdb.status_code", - "db.cosmosdb.sub_status_code", - "db.cosmosdb.request_charge", - "db.cosmosdb.regions_contacted", - "db.cosmosdb.retry_count", - "db.cosmosdb.item_count", - "db.cosmosdb.request_diagnostics", - "exception.type", - "exception.message", - "exception.stacktrace", - "db.cosmosdb.activity_id", - "db.cosmosdb.correlated_activity_id" - }; + { + "az.namespace", + "az.schema_url", + "kind", + "db.system", + "db.name", + "db.operation", + "net.peer.name", + "db.cosmosdb.client_id", + "db.cosmosdb.machine_id", + "user_agent.original", + "db.cosmosdb.connection_mode", + "db.cosmosdb.operation_type", + "db.cosmosdb.container", + "db.cosmosdb.request_content_length_bytes", + "db.cosmosdb.response_content_length_bytes", + "db.cosmosdb.status_code", + "db.cosmosdb.sub_status_code", + "db.cosmosdb.request_charge", + "db.cosmosdb.regions_contacted", + "db.cosmosdb.retry_count", + "db.cosmosdb.item_count", + "db.cosmosdb.request_diagnostics", + "exception.type", + "exception.message", + "exception.stacktrace", + "db.cosmosdb.activity_id", + "db.cosmosdb.correlated_activity_id" + }; foreach (KeyValuePair actualTag in activity.Tags) { @@ -68,6 +69,13 @@ public static void IsValidOperationActivity(Activity activity) AssertActivity.AssertDatabaseAndContainerName(activity.OperationName, actualTag); } + + HttpStatusCode statusCode = (HttpStatusCode)Convert.ToInt32(activity.GetTagItem("db.cosmosdb.status_code")); + int subStatusCode = Convert.ToInt32(activity.GetTagItem("db.cosmosdb.sub_status_code")); + if (!DiagnosticsFilterHelper.IsSuccessfulResponse(statusCode, subStatusCode)) + { + Assert.AreEqual(ActivityStatusCode.Error, activity.Status); + } } } @@ -75,7 +83,9 @@ public static void AreEqualAcrossListeners() { Assert.AreEqual( JsonConvert.SerializeObject(CustomListener.CollectedOperationActivities.OrderBy(x => x.Id)), - JsonConvert.SerializeObject(CustomOtelExporter.CollectedActivities.OrderBy(x => x.Id))); + JsonConvert.SerializeObject(CustomOtelExporter.CollectedActivities + .Where(activity => activity.Source.Name == $"{OpenTelemetryAttributeKeys.DiagnosticNamespace}.Operation") + .OrderBy(x => x.Id))); } private static void AssertDatabaseAndContainerName(string name, KeyValuePair tag) diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Tracing/CustomListener.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Tracing/CustomListener.cs index cae05fa94d..6d612c29c7 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Tracing/CustomListener.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Tracing/CustomListener.cs @@ -26,7 +26,8 @@ internal class CustomListener : { private readonly Func sourceNameFilter; private readonly string eventName; - + private readonly bool suppressAllEvents; + private ConcurrentBag subscriptions = new(); private ConcurrentBag Scopes { get; } = new(); @@ -36,21 +37,22 @@ internal class CustomListener : private static List EventSources { set; get; } = new(); - public CustomListener(string name, string eventName) - : this(n => Regex.Match(n, name).Success, eventName) + public CustomListener(string name, string eventName, bool suppressAllEvents = false) + : this(n => Regex.Match(n, name).Success, eventName, suppressAllEvents) { } - public CustomListener(Func filter, string eventName) + public CustomListener(Func filter, string eventName, bool suppressAllEvents = false) { this.sourceNameFilter = filter; this.eventName = eventName; + this.suppressAllEvents = suppressAllEvents; foreach (EventSource eventSource in EventSources) { this.OnEventSourceCreated(eventSource); } - + DiagnosticListener.AllListeners.Subscribe(this); } @@ -149,7 +151,15 @@ public void OnNext(DiagnosticListener value) { lock (this.Scopes) { - this.subscriptions?.Add(value.Subscribe(this)); + IDisposable subscriber = value.Subscribe(this, isEnabled: (name) => + { + if (this.suppressAllEvents) + { + return false; + } + return true; + }); + this.subscriptions?.Add(subscriber); } } } @@ -159,7 +169,12 @@ public void OnNext(DiagnosticListener value) /// protected override void OnEventSourceCreated(EventSource eventSource) { - if(this.eventName == null) + if (this.eventName == null) + { + EventSources.Add(eventSource); + } + + if (this.eventName == null) { EventSources.Add(eventSource); } diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Tracing/CustomOtelExporter.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Tracing/CustomOtelExporter.cs index eb46d83e48..a115a64084 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Tracing/CustomOtelExporter.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Tracing/CustomOtelExporter.cs @@ -35,7 +35,8 @@ public override ExportResult Export(in Batch batch) foreach (Activity activity in batch) { - if (string.Equals(activity.Source.Name, $"{OpenTelemetryAttributeKeys.DiagnosticNamespace}.Operation", StringComparison.OrdinalIgnoreCase)) + if (string.Equals(activity.Source.Name, $"{OpenTelemetryAttributeKeys.DiagnosticNamespace}.Operation", StringComparison.OrdinalIgnoreCase) + || string.Equals(activity.Source.Name, $"{OpenTelemetryAttributeKeys.DiagnosticNamespace}.Request", StringComparison.OrdinalIgnoreCase)) { AssertActivity.IsValidOperationActivity(activity); diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Tracing/EndToEndTraceWriterBaselineTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Tracing/EndToEndTraceWriterBaselineTests.cs index 6abd4f8ad9..6cd8905b07 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Tracing/EndToEndTraceWriterBaselineTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Tracing/EndToEndTraceWriterBaselineTests.cs @@ -25,7 +25,7 @@ namespace Microsoft.Azure.Cosmos.EmulatorTests.Tracing using Microsoft.VisualStudio.TestTools.UnitTesting; using Newtonsoft.Json.Linq; using static Microsoft.Azure.Cosmos.SDK.EmulatorTests.TransportClientHelper; - + [VisualStudio.TestTools.UnitTesting.TestClass] [TestCategory("UpdateContract")] public sealed class EndToEndTraceWriterBaselineTests : BaselineTests @@ -47,28 +47,48 @@ public sealed class EndToEndTraceWriterBaselineTests : BaselineTests builder + .WithClientTelemetryOptions(new CosmosClientTelemetryOptions() + { + DisableDistributedTracing = false, + CosmosThresholdOptions = new CosmosThresholdOptions() + { + PointOperationLatencyThreshold = TimeSpan.Zero, + NonPointOperationLatencyThreshold = TimeSpan.Zero + } + })); + bulkClient = TestCommon.CreateCosmosClient(builder => builder .WithBulkExecution(true) - .WithDistributedTracingOptions(new DistributedTracingOptions() - { - LatencyThresholdForDiagnosticEvent = TimeSpan.FromMilliseconds(0) - })); - + .WithClientTelemetryOptions(new CosmosClientTelemetryOptions() + { + DisableDistributedTracing = false, + CosmosThresholdOptions = new CosmosThresholdOptions() + { + PointOperationLatencyThreshold = TimeSpan.Zero, + NonPointOperationLatencyThreshold = TimeSpan.Zero + } + })); + // Set a small retry count to reduce test time miscCosmosClient = TestCommon.CreateCosmosClient(builder => builder .AddCustomHandlers(requestHandler) - .WithDistributedTracingOptions(new DistributedTracingOptions() - { - LatencyThresholdForDiagnosticEvent = TimeSpan.FromMilliseconds(0) - })); + .WithClientTelemetryOptions(new CosmosClientTelemetryOptions() + { + DisableDistributedTracing = false, + CosmosThresholdOptions = new CosmosThresholdOptions() + { + PointOperationLatencyThreshold = TimeSpan.Zero, + NonPointOperationLatencyThreshold = TimeSpan.Zero + } + })); EndToEndTraceWriterBaselineTests.database = await client.CreateDatabaseAsync( "databaseName", @@ -682,7 +702,10 @@ public async Task ValidateInvalidCredentialsTraceAsync() // It is not baseline test hence disable distributed tracing for this test CosmosClientOptions clientOptions = new CosmosClientOptions() { - IsDistributedTracingEnabled = false + CosmosClientTelemetryOptions = new CosmosClientTelemetryOptions() + { + DisableDistributedTracing = true + } }; using (CosmosClient client = new CosmosClient( @@ -1015,9 +1038,14 @@ public async Task PointOperationsExceptionsAsync() Guid exceptionActivityId = Guid.NewGuid(); using CosmosClient throttleClient = TestCommon.CreateCosmosClient(builder => builder - .WithDistributedTracingOptions(new DistributedTracingOptions() + .WithClientTelemetryOptions(new CosmosClientTelemetryOptions() { - LatencyThresholdForDiagnosticEvent = TimeSpan.FromMilliseconds(0) + DisableDistributedTracing = false, + CosmosThresholdOptions = new CosmosThresholdOptions() + { + PointOperationLatencyThreshold = TimeSpan.Zero, + NonPointOperationLatencyThreshold = TimeSpan.Zero + } }) .WithThrottlingRetryOptions( maxRetryWaitTimeOnThrottledRequests: TimeSpan.FromSeconds(1), @@ -1303,9 +1331,14 @@ public async Task BulkOperationsAsync() maxRetryWaitTimeOnThrottledRequests: TimeSpan.FromSeconds(1), maxRetryAttemptsOnThrottledRequests: 3) .WithBulkExecution(true) - .WithDistributedTracingOptions(new DistributedTracingOptions() + .WithClientTelemetryOptions(new CosmosClientTelemetryOptions() { - LatencyThresholdForDiagnosticEvent = TimeSpan.FromMilliseconds(0) + DisableDistributedTracing = false, + CosmosThresholdOptions = new CosmosThresholdOptions() + { + PointOperationLatencyThreshold = TimeSpan.Zero, + NonPointOperationLatencyThreshold = TimeSpan.Zero + } }) .WithTransportClientHandlerFactory(transportClient => new TransportClientWrapper( transportClient, diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/TriggersTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/TriggersTests.cs index 82d76427d5..b21feb3e68 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/TriggersTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/TriggersTests.cs @@ -106,7 +106,9 @@ public async Task CRUDTest() } [TestMethod] - public async Task ValidatePreTriggerTest() + [DataRow(TriggerOperation.Create)] + [DataRow(TriggerOperation.Upsert)] + public async Task ValidatePreTriggerTest(TriggerOperation triggerOperation) { string triggerId = "SetJobNumber"; @@ -124,7 +126,7 @@ public async Task ValidatePreTriggerTest() { Id = triggerId, TriggerType = TriggerType.Pre, - TriggerOperation = TriggerOperation.Create, + TriggerOperation = triggerOperation, Body = @"function setJobNumber() { var context = getContext(); var request = context.getRequest(); @@ -150,15 +152,27 @@ public async Task ValidatePreTriggerTest() Job value = new Job() { Id = Guid.NewGuid(), InvestigationKey = "investigation~1" }; - // this should create the document successfully with jobnumber of 1 - Job createdItem = await this.container.CreateItemAsync(item: value, partitionKey: null, requestOptions: new ItemRequestOptions + Job item = null; + if (triggerOperation == TriggerOperation.Create) { - PreTriggers = new List { triggerId } - }); - - Assert.AreEqual(value.Id, createdItem.Id); - Assert.AreEqual(value.InvestigationKey, createdItem.InvestigationKey); - Assert.AreEqual(1, createdItem.JobNumber); + // this should create the document successfully with jobnumber of 1 + item = await this.container.CreateItemAsync(item: value, partitionKey: null, requestOptions: new ItemRequestOptions + { + PreTriggers = new List { triggerId } + }); + } + else if(triggerOperation == TriggerOperation.Upsert) + { + // this should create the document successfully with jobnumber of 1 + item = await this.container.UpsertItemAsync(item: value, partitionKey: null, requestOptions: new ItemRequestOptions + { + PreTriggers = new List { triggerId } + }); + } + + Assert.AreEqual(value.Id, item.Id); + Assert.AreEqual(value.InvestigationKey, item.InvestigationKey); + Assert.AreEqual(1, item.JobNumber); List result = this.container.GetItemLinqQueryable(allowSynchronousQueryExecution: true).Where(x => x.InvestigationKey == "investigation~1").ToList(); Assert.IsNotNull(result); @@ -171,15 +185,27 @@ public async Task ValidatePreTriggerTest() value.Id = Guid.NewGuid(); - // this should create the document successfully with jobnumber of 2 - Job createdItem2 = await this.container.CreateItemAsync(item: value, partitionKey: null, requestOptions: new ItemRequestOptions + Job item2 = null; + if (triggerOperation == TriggerOperation.Create) { - PreTriggers = new List { "SetJobNumber" } - }); + // this should create the document successfully with jobnumber of 2 + item2 = await this.container.CreateItemAsync(item: value, partitionKey: null, requestOptions: new ItemRequestOptions + { + PreTriggers = new List { "SetJobNumber" } + }); + } + else if (triggerOperation == TriggerOperation.Upsert) + { + // this should create the document successfully with jobnumber of 1 + item2 = await this.container.UpsertItemAsync(item: value, partitionKey: null, requestOptions: new ItemRequestOptions + { + PreTriggers = new List { "SetJobNumber" } + }); + } - Assert.AreEqual(value.Id, createdItem2.Id); - Assert.AreEqual(value.InvestigationKey, createdItem2.InvestigationKey); - Assert.AreEqual(2, createdItem2.JobNumber); + Assert.AreEqual(value.Id, item2.Id); + Assert.AreEqual(value.InvestigationKey, item2.InvestigationKey); + Assert.AreEqual(2, item2.JobNumber); result = this.container.GetItemLinqQueryable(allowSynchronousQueryExecution: true).Where(x => x.InvestigationKey == "investigation~1").ToList(); Assert.IsNotNull(result); diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Utils/HttpHandlerHelper.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Utils/HttpHandlerHelper.cs index cedef0658a..aead33feef 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Utils/HttpHandlerHelper.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Utils/HttpHandlerHelper.cs @@ -19,6 +19,8 @@ public HttpClientHandlerHelper() : base(new HttpClientHandler()) public Func> ResponseIntercepter { get; set; } + public Action ExceptionIntercepter { get; set; } + protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { HttpResponseMessage httpResponse = null; @@ -39,7 +41,21 @@ protected override async Task SendAsync(HttpRequestMessage } } - httpResponse = await base.SendAsync(request, cancellationToken); + try + { + httpResponse = await base.SendAsync(request, cancellationToken); + } + catch (Exception ex) { + + if (this.ExceptionIntercepter == null) + { + throw; + } + this.ExceptionIntercepter.Invoke(request, ex); + + throw; // Anyway throw this exception + } + if (this.ResponseIntercepter != null) { httpResponse = await this.ResponseIntercepter(httpResponse); diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Utils/TestCommon.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Utils/TestCommon.cs index 8cfa5be33b..c43a1aaf79 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Utils/TestCommon.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Utils/TestCommon.cs @@ -164,8 +164,7 @@ internal static DocumentClient CreateClient(bool useGateway, Protocol protocol = RetryOptions retryOptions = null, ApiType apiType = ApiType.None, EventHandler recievedResponseEventHandler = null, - bool useMultipleWriteLocations = false, - bool enableClientTelemetry = false) + bool useMultipleWriteLocations = false) { string authKey = ConfigurationManager.AppSettings["MasterKey"]; diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Utils/TransportClientHelper.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Utils/TransportClientHelper.cs index f34135b695..ebeebad7ae 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Utils/TransportClientHelper.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Utils/TransportClientHelper.cs @@ -83,9 +83,14 @@ internal static Container GetContainerWithIntercepter( if (enableDistributingTracing) { - builder.WithDistributedTracingOptions(new DistributedTracingOptions() + builder.WithClientTelemetryOptions(new CosmosClientTelemetryOptions() { - LatencyThresholdForDiagnosticEvent = TimeSpan.FromMilliseconds(.0001) + DisableDistributedTracing = false, + CosmosThresholdOptions = new CosmosThresholdOptions() + { + PointOperationLatencyThreshold = TimeSpan.Zero, + NonPointOperationLatencyThreshold = TimeSpan.Zero + } }); } diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Utils/Util.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Utils/Util.cs index 366cc68811..ea360ea285 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Utils/Util.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Utils/Util.cs @@ -522,20 +522,6 @@ internal static void LogRequestOptions(RequestOptions options, bool shouldLogOff options.OfferThroughput); } - internal static void EnableClientTelemetryEnvironmentVariables() - { - Environment.SetEnvironmentVariable(ClientTelemetryOptions.EnvPropsClientTelemetryEnabled, "true"); - Environment.SetEnvironmentVariable(ClientTelemetryOptions.EnvPropsClientTelemetrySchedulingInSeconds, "1"); - Environment.SetEnvironmentVariable(ClientTelemetryOptions.EnvPropsClientTelemetryEndpoint, "http://dummy.telemetry.endpoint/"); - } - - internal static void DisableClientTelemetryEnvironmentVariables() - { - Environment.SetEnvironmentVariable(ClientTelemetryOptions.EnvPropsClientTelemetryEnabled, null); - Environment.SetEnvironmentVariable(ClientTelemetryOptions.EnvPropsClientTelemetrySchedulingInSeconds, null); - Environment.SetEnvironmentVariable(ClientTelemetryOptions.EnvPropsClientTelemetryEndpoint, null); - } - private static TracerProvider OTelTracerProvider; private static CustomListener TestListener; diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/settings.json b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/settings.json index 51ecc8a707..611ba8c677 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/settings.json +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/settings.json @@ -11,14 +11,14 @@ "MasterKey": "C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==", "ServerStalenessIntervalInSeconds": "5", "MasterStalenessIntervalInSeconds": "1", - "ContentSerializationPerformanceTests.CosmosDatabaseId": "db", - "ContentSerializationPerformanceTests.ContainerId": "container", - "ContentSerializationPerformanceTests.ContentSerialization": "JsonText", - "ContentSerializationPerformanceTests.Query": "SELECT TOP 1 c.region FROM c", - "ContentSerializationPerformanceTests.MaxConcurrency": "-1", - "ContentSerializationPerformanceTests.MaxItemCount": "-1", - "ContentSerializationPerformanceTests.NumberOfIterations": "1", - "ContentSerializationPerformanceTests.WarmupIterations": "0", - "ContentSerializationPerformanceTests.UseStronglyTypedIterator": "true" + "QueryPerformanceTests.CosmosDatabaseId": "db", + "QueryPerformanceTests.ContainerId": "container", + "QueryPerformanceTests.ContentSerialization": "JsonText", + "QueryPerformanceTests.Query": "SELECT TOP 1 c.region FROM c", + "QueryPerformanceTests.MaxConcurrency": "-1", + "QueryPerformanceTests.MaxItemCount": "-1", + "QueryPerformanceTests.NumberOfIterations": "1", + "QueryPerformanceTests.WarmupIterations": "0", + "QueryPerformanceTests.UseStronglyTypedIterator": "true" } } \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Performance.Tests/Contracts/BenchmarkResults.json b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Performance.Tests/Contracts/BenchmarkResults.json index a06dabf09c..8e45a72922 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Performance.Tests/Contracts/BenchmarkResults.json +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Performance.Tests/Contracts/BenchmarkResults.json @@ -39,7 +39,7 @@ "MockedItemBenchmark.ReadItemNotExists;[Type=OfT]": 43489.25, "MockedItemBenchmark.ReadItemNotExists;[Type=OfTCustom]": 43490, "MockedItemBenchmark.ReadItemNotExists;[Type=OfTWithClientTelemetryEnabled]": 43489.25, - "MockedItemBenchmark.ReadItemNotExists;[Type=OfTWithDiagnosticsToString]": 58054, + "MockedItemBenchmark.ReadItemNotExists;[Type=OfTWithDiagnosticsToString]": 64764.75, "MockedItemBenchmark.ReadItemNotExists;[Type=Stream]": 39044, "MockedItemBenchmark.UpdateItem;[Type=OfT]": 36591, "MockedItemBenchmark.UpdateItem;[Type=OfTCustom]": 36594.25, diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Performance.Tests/Mocks/HttpHandlerHelper.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Performance.Tests/Mocks/HttpHandlerHelper.cs new file mode 100644 index 0000000000..65fb15e012 --- /dev/null +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Performance.Tests/Mocks/HttpHandlerHelper.cs @@ -0,0 +1,67 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Performance.Tests +{ + using System; + using System.Net.Http; + using System.Threading; + using System.Threading.Tasks; + + public class HttpClientHandlerHelper : DelegatingHandler + { + public HttpClientHandlerHelper() : base(new HttpClientHandler()) + { + } + + public Func> RequestCallBack { get; set; } + + public Func> ResponseIntercepter { get; set; } + + public Action ExceptionIntercepter { get; set; } + + protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) + { + HttpResponseMessage httpResponse = null; + if (this.RequestCallBack != null) + { + Task response = this.RequestCallBack(request, cancellationToken); + if(response != null) + { + httpResponse = await response; + if (httpResponse != null) + { + if (this.ResponseIntercepter != null) + { + httpResponse = await this.ResponseIntercepter(httpResponse); + } + return httpResponse; + } + } + } + + try + { + httpResponse = await base.SendAsync(request, cancellationToken); + } + catch (Exception ex) { + + if (this.ExceptionIntercepter == null) + { + throw; + } + this.ExceptionIntercepter.Invoke(request, ex); + + throw; // Anyway throw this exception + } + + if (this.ResponseIntercepter != null) + { + httpResponse = await this.ResponseIntercepter(httpResponse); + } + + return httpResponse; + } + } +} diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Performance.Tests/Mocks/MockDocumentClient.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Performance.Tests/Mocks/MockDocumentClient.cs index 2baee14bd8..7d268407de 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Performance.Tests/Mocks/MockDocumentClient.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Performance.Tests/Mocks/MockDocumentClient.cs @@ -6,7 +6,6 @@ namespace Microsoft.Azure.Cosmos.Performance.Tests { using System; using System.Globalization; - using System.Text; using System.Threading; using System.Threading.Tasks; using Microsoft.Azure.Cosmos; @@ -19,11 +18,13 @@ namespace Microsoft.Azure.Cosmos.Performance.Tests using Moq; using System.Collections.ObjectModel; using System.Collections.Generic; - using Microsoft.CodeAnalysis.CSharp.Syntax; - using System.IO; using Microsoft.Azure.Cosmos.Tracing; using Microsoft.Azure.Cosmos.Query.Core.QueryPlan; using Newtonsoft.Json; + using Microsoft.Azure.Cosmos.Telemetry; + using System.Net.Http; + using System.Net; + using System.Text; internal class MockDocumentClient : DocumentClient, ICosmosAuthorizationTokenProvider { @@ -47,9 +48,59 @@ public static CosmosClient CreateMockCosmosClient( bool? isClientTelemetryEnabled = null, Action < CosmosClientBuilder> customizeClientBuilder = null) { - MockDocumentClient documentClient = new MockDocumentClient(); + ConnectionPolicy policy = new ConnectionPolicy(); + + if (isClientTelemetryEnabled.HasValue) + { + policy = new ConnectionPolicy + { + CosmosClientTelemetryOptions = new CosmosClientTelemetryOptions + { + DisableSendingMetricsToService = !isClientTelemetryEnabled.Value + } + }; + } + + MockDocumentClient documentClient = new MockDocumentClient(policy); CosmosClientBuilder cosmosClientBuilder = new CosmosClientBuilder("http://localhost", Convert.ToBase64String(Guid.NewGuid().ToByteArray())); cosmosClientBuilder.WithConnectionModeDirect(); + + Uri telemetryServiceEndpoint = new Uri("https://dummy.endpoint.com/"); + + if (isClientTelemetryEnabled.HasValue) + { + // mock external calls + HttpClientHandlerHelper httpHandler = new HttpClientHandlerHelper + { + RequestCallBack = (request, cancellation) => + { + if (request.RequestUri.AbsoluteUri.Equals(telemetryServiceEndpoint.AbsoluteUri)) + { + return Task.FromResult(new HttpResponseMessage(HttpStatusCode.NoContent)); // In Emulator test, send hardcoded response status code as there is no real communication happens with client telemetry service + } + else if (request.RequestUri.AbsoluteUri.Contains(Paths.ClientConfigPathSegment)) + { + HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK); + AccountClientConfiguration clientConfigProperties = new AccountClientConfiguration + { + ClientTelemetryConfiguration = new ClientTelemetryConfiguration + { + IsEnabled = isClientTelemetryEnabled.Value, + Endpoint = isClientTelemetryEnabled.Value?telemetryServiceEndpoint.AbsoluteUri: null + } + }; + string payload = JsonConvert.SerializeObject(clientConfigProperties); + result.Content = new StringContent(payload, Encoding.UTF8, "application/json"); + return Task.FromResult(result); + } + + return null; + } + }; + + cosmosClientBuilder.WithHttpClientFactory(() => new HttpClient(httpHandler)); + } + customizeClientBuilder?.Invoke(cosmosClientBuilder); if (useCustomSerializer) @@ -61,11 +112,6 @@ public static CosmosClient CreateMockCosmosClient( }); } - if (isClientTelemetryEnabled.HasValue && isClientTelemetryEnabled.Value) - { - cosmosClientBuilder.WithTelemetryEnabled(); - } - documentClient.dummyHeaderNames = new string[100]; for (int i = 0; i < documentClient.dummyHeaderNames.Length; i++) { @@ -79,8 +125,8 @@ public static CosmosClient CreateMockCosmosClient( return cosmosClientBuilder.Build(documentClient); } - public MockDocumentClient() - : base(new Uri("http://localhost"), null) + public MockDocumentClient(ConnectionPolicy policy = null) + : base(new Uri("http://localhost"), connectionPolicy: policy) { this.authKeyHashFunction = new StringHMACSHA256Hash(MockDocumentClient.GenerateRandomKey()); @@ -212,6 +258,13 @@ private void Init() this.globalEndpointManager = new Mock(this, new ConnectionPolicy()); + this.telemetryToServiceHelper = TelemetryToServiceHelper.CreateAndInitializeClientConfigAndTelemetryJob("perf-test-client", + this.ConnectionPolicy, + new Mock().Object, + new Mock().Object, + this.ServiceEndpoint, + this.GlobalEndpointManager, + default); this.InitStoreModels(); } diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Performance.Tests/Query/Metrics/Performance.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Performance.Tests/Query/Metrics/Performance.cs index 6d5db62d6d..40484e792c 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Performance.Tests/Query/Metrics/Performance.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Performance.Tests/Query/Metrics/Performance.cs @@ -37,7 +37,7 @@ public void TestParse() ValueStopwatch stopwatch = ValueStopwatch.StartNew(); for (int i = 0; i < 100000; i++) { - BackendMetricsParser.TryParse(delimitedString, out BackendMetrics backendMetrics); + ServerSideMetricsParser.TryParse(delimitedString, out ServerSideMetricsInternal serverSideMetrics); } stopwatch.Stop(); Console.WriteLine(stopwatch.ElapsedMilliseconds); diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/BaselineTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/BaselineTests.cs index 6e2162ee2f..419a29229b 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/BaselineTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/BaselineTests.cs @@ -135,8 +135,8 @@ public void ExecuteTestSuite(IEnumerable inputs, [CallerMemberName] stri Assert.IsTrue( matched, - $@" Baseline File {baselinePath}, - Output File {outputPath}, + $@" Baseline File {Path.GetFullPath(baselinePath)}, + Output File {Path.GetFullPath(outputPath)}, Expected: {baselineTextSuffix}, Actual: {outputTextSuffix}"); } diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/TestBaseline/ClientDistributionPlanBaselineTests.TestClientDistributionPlanDeserialization.xml b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/TestBaseline/ClientDistributionPlanBaselineTests.TestClientDistributionPlanDeserialization.xml new file mode 100644 index 0000000000..c59b58aef1 --- /dev/null +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/TestBaseline/ClientDistributionPlanBaselineTests.TestClientDistributionPlanDeserialization.xml @@ -0,0 +1,606 @@ + + + + Input Expression + {"clientDistributionPlan": {"Cql": {"Kind": "Input","Name": "root"}}} + + + { + "Cql": { + "Name": "root", + "Kind": 3 + } +} + + + + + Aggregate and ObjectCreate Expressions + {"clientDistributionPlan": {"Cql": {"Kind": "Select","DeclaredVariable": {"Name": "v0","UniqueId": 6},"Expression": {"Kind": "ObjectCreate","ObjectKind": "Object","Properties": [{"Name": "count_a","Expression": {"Kind": "VariableRef","Variable": {"Name": "v0","UniqueId": 6}}}]},"SourceExpression": {"Kind": "Aggregate","Aggregate": {"Kind": "Builtin","OperatorKind": "Sum"},"SourceExpression": {"Kind": "Input","Name": "root"}}}}} + + + { + "Cql": { + "SourceExpression": { + "SourceExpression": { + "Name": "root", + "Kind": 3 + }, + "Aggregate": { + "OperatorKind": 8, + "Kind": 0 + }, + "Kind": 0 + }, + "DeclaredVariable": { + "Name": "v0", + "UniqueId": 6 + }, + "Expression": { + "Properties": [ + { + "Name": "count_a", + "Expression": { + "Variable": { + "Name": "v0", + "UniqueId": 6 + }, + "Kind": 14 + } + } + ], + "ObjectKind": "Object", + "Kind": 7 + }, + "Kind": 6 + } +} + + + + + Select, Aggregate and BinaryOperator Expressions + {"clientDistributionPlan": {"Cql": { "Kind": "Select", "DeclaredVariable": {"Name": "v0","UniqueId": 10 }, "Expression": {"Kind": "ObjectCreate","ObjectKind": "Object","Properties": [ {"Name": "F1","Expression": { "Kind": "ObjectCreate", "ObjectKind": "Object", "Properties": [{ "Name": "FieldA", "Expression": {"Kind": "TupleItemRef","Expression": { "Kind": "VariableRef", "Variable": {"Name": "v0","UniqueId": 10 }},"Index": 0 }},{ "Name": "FieldSum", "Expression": {"Kind": "TupleItemRef","Expression": { "Kind": "VariableRef", "Variable": {"Name": "v0","UniqueId": 10 }},"Index": 1 }},{ "Name": "FieldAvg", "Expression": {"Kind": "Mux","ConditionExpression": { "Kind": "BinaryOperator", "OperatorKind": "Equal", "LeftExpression": {"Kind": "TupleItemRef","Expression": { "Kind": "TupleItemRef", "Expression": {"Kind": "VariableRef","Variable": { "Name": "v0", "UniqueId": 10} }, "Index": 2},"Index": 1 }, "RightExpression": {"Kind": "Literal","Literal": { "Kind": "Number", "Value": 0} }},"LeftExpression": { "Kind": "Literal", "Literal": {"Kind": "Undefined" }},"RightExpression": { "Kind": "BinaryOperator", "OperatorKind": "Divide", "LeftExpression": {"Kind": "TupleItemRef","Expression": { "Kind": "TupleItemRef", "Expression": {"Kind": "VariableRef","Variable": { "Name": "v0", "UniqueId": 10} }, "Index": 2},"Index": 0 }, "RightExpression": {"Kind": "TupleItemRef","Expression": { "Kind": "TupleItemRef", "Expression": {"Kind": "VariableRef","Variable": { "Name": "v0", "UniqueId": 10} }, "Index": 2},"Index": 1 }}}}]}}, {"Name": "F2","Expression": { "Kind": "ObjectCreate", "ObjectKind": "Object", "Properties": [{ "Name": "OtherFieldA", "Expression": {"Kind": "TupleItemRef","Expression": { "Kind": "VariableRef", "Variable": {"Name": "v0","UniqueId": 10 }},"Index": 0 }},{ "Name": "OtherFieldMax", "Expression": {"Kind": "TupleItemRef","Expression": { "Kind": "VariableRef", "Variable": {"Name": "v0","UniqueId": 10 }},"Index": 3 }} ]} }] }, "SourceExpression": {"Kind": "GroupBy","KeyCount": 1,"Aggregates": [ {"Kind": "Builtin","OperatorKind": "Sum" }, {"Kind": "Tuple","Items": [ {"Kind": "Builtin","OperatorKind": "Sum" }, {"Kind": "Builtin","OperatorKind": "Sum" }] }, {"Kind": "Builtin","OperatorKind": "Max" }],"SourceExpression": { "Kind": "Select", "DeclaredVariable": {"Name": "v0","UniqueId": 16 }, "Expression": {"Kind": "TupleCreate","Items": [ {"Kind": "TupleItemRef","Expression": { "Kind": "VariableRef", "Variable": {"Name": "v0","UniqueId": 16 }},"Index": 0 }, {"Kind": "Mux","ConditionExpression": { "Kind": "BinaryOperator", "OperatorKind": "And", "LeftExpression": {"Kind": "BinaryOperator","OperatorKind": "NotEqual","LeftExpression": { "Kind": "TupleItemRef", "Expression": {"Kind": "TupleItemRef","Expression": { "Kind": "VariableRef", "Variable": {"Name": "v0","UniqueId": 16 }},"Index": 1 }, "Index": 1},"RightExpression": { "Kind": "Literal", "Literal": {"Kind": "Number","Value": 0 }} }, "RightExpression": {"Kind": "UnaryOperator","OperatorKind": "Not","Expression": { "Kind": "SystemFunctionCall", "FunctionKind": "Is_Defined", "Arguments": [{ "Kind": "TupleItemRef", "Expression": {"Kind": "TupleItemRef","Expression": { "Kind": "VariableRef", "Variable": {"Name": "v0","UniqueId": 16 }},"Index": 1 }, "Index": 0} ]} }},"LeftExpression": { "Kind": "Literal", "Literal": {"Kind": "Array","Items": [] }},"RightExpression": { "Kind": "TupleItemRef", "Expression": {"Kind": "TupleItemRef","Expression": { "Kind": "VariableRef", "Variable": {"Name": "v0","UniqueId": 16 }},"Index": 1 }, "Index": 0} }, {"Kind": "TupleCreate","Items": [ {"Kind": "Mux","ConditionExpression": { "Kind": "BinaryOperator", "OperatorKind": "And", "LeftExpression": {"Kind": "BinaryOperator","OperatorKind": "NotEqual","LeftExpression": { "Kind": "TupleItemRef", "Expression": {"Kind": "TupleItemRef","Expression": { "Kind": "TupleItemRef", "Expression": {"Kind": "VariableRef","Variable": { "Name": "v0", "UniqueId": 16} }, "Index": 2},"Index": 0 }, "Index": 1},"RightExpression": { "Kind": "Literal", "Literal": {"Kind": "Number","Value": 0 }} }, "RightExpression": {"Kind": "UnaryOperator","OperatorKind": "Not","Expression": { "Kind": "SystemFunctionCall", "FunctionKind": "Is_Defined", "Arguments": [{ "Kind": "TupleItemRef", "Expression": {"Kind": "TupleItemRef","Expression": { "Kind": "TupleItemRef", "Expression": {"Kind": "VariableRef","Variable": { "Name": "v0", "UniqueId": 16} }, "Index": 2},"Index": 0 }, "Index": 0} ]} }},"LeftExpression": { "Kind": "Literal", "Literal": {"Kind": "Array","Items": [] }},"RightExpression": { "Kind": "TupleItemRef", "Expression": {"Kind": "TupleItemRef","Expression": { "Kind": "VariableRef", "Variable": {"Name": "v0","UniqueId": 16 }},"Index": 2 }, "Index": 0} }, {"Kind": "TupleItemRef","Expression": { "Kind": "TupleItemRef", "Expression": {"Kind": "VariableRef","Variable": { "Name": "v0", "UniqueId": 16} }, "Index": 2},"Index": 1 }] }, {"Kind": "Mux","ConditionExpression": { "Kind": "BinaryOperator", "OperatorKind": "And", "LeftExpression": {"Kind": "BinaryOperator","OperatorKind": "NotEqual","LeftExpression": { "Kind": "TupleItemRef", "Expression": {"Kind": "TupleItemRef","Expression": { "Kind": "VariableRef", "Variable": {"Name": "v0","UniqueId": 16 }},"Index": 3 }, "Index": 1},"RightExpression": { "Kind": "Literal", "Literal": {"Kind": "Number","Value": 0 }} }, "RightExpression": {"Kind": "UnaryOperator","OperatorKind": "Not","Expression": { "Kind": "SystemFunctionCall", "FunctionKind": "Is_Defined", "Arguments": [{ "Kind": "TupleItemRef", "Expression": {"Kind": "TupleItemRef","Expression": { "Kind": "VariableRef", "Variable": {"Name": "v0","UniqueId": 16 }},"Index": 3 }, "Index": 0} ]} }},"LeftExpression": { "Kind": "Literal", "Literal": {"Kind": "Array","Items": [] }},"RightExpression": { "Kind": "TupleItemRef", "Expression": {"Kind": "TupleItemRef","Expression": { "Kind": "VariableRef", "Variable": {"Name": "v0","UniqueId": 16}},"Index": 3}, "Index": 0}}]}, "SourceExpression": {"Kind": "Input","Name": "root"}}}}}} + + + { + "Cql": { + "SourceExpression": { + "SourceExpression": { + "SourceExpression": { + "Name": "root", + "Kind": 3 + }, + "DeclaredVariable": { + "Name": "v0", + "UniqueId": 16 + }, + "Expression": { + "Items": [ + { + "Expression": { + "Variable": { + "Name": "v0", + "UniqueId": 16 + }, + "Kind": 14 + }, + "Index": 0, + "Kind": 11 + }, + { + "ConditionExpression": { + "OperatorKind": 1, + "LeftExpression": { + "OperatorKind": 14, + "LeftExpression": { + "Expression": { + "Expression": { + "Variable": { + "Name": "v0", + "UniqueId": 16 + }, + "Kind": 14 + }, + "Index": 1, + "Kind": 11 + }, + "Index": 1, + "Kind": 11 + }, + "RightExpression": { + "Literal": { + "Value": 0, + "Kind": 4 + }, + "Kind": 5 + }, + "Kind": 2 + }, + "RightExpression": { + "OperatorKind": 2, + "Expression": { + "FunctionKind": 55, + "Arguments": [ + { + "Expression": { + "Expression": { + "Variable": { + "Name": "v0", + "UniqueId": 16 + }, + "Kind": 14 + }, + "Index": 1, + "Kind": 11 + }, + "Index": 0, + "Kind": 11 + } + ], + "Kind": 9 + }, + "Kind": 12 + }, + "Kind": 2 + }, + "LeftExpression": { + "Literal": { + "Items": [], + "Kind": 1 + }, + "Kind": 5 + }, + "RightExpression": { + "Expression": { + "Expression": { + "Variable": { + "Name": "v0", + "UniqueId": 16 + }, + "Kind": 14 + }, + "Index": 1, + "Kind": 11 + }, + "Index": 0, + "Kind": 11 + }, + "Kind": 6 + }, + { + "Items": [ + { + "ConditionExpression": { + "OperatorKind": 1, + "LeftExpression": { + "OperatorKind": 14, + "LeftExpression": { + "Expression": { + "Expression": { + "Expression": { + "Variable": { + "Name": "v0", + "UniqueId": 16 + }, + "Kind": 14 + }, + "Index": 2, + "Kind": 11 + }, + "Index": 0, + "Kind": 11 + }, + "Index": 1, + "Kind": 11 + }, + "RightExpression": { + "Literal": { + "Value": 0, + "Kind": 4 + }, + "Kind": 5 + }, + "Kind": 2 + }, + "RightExpression": { + "OperatorKind": 2, + "Expression": { + "FunctionKind": 55, + "Arguments": [ + { + "Expression": { + "Expression": { + "Expression": { + "Variable": { + "Name": "v0", + "UniqueId": 16 + }, + "Kind": 14 + }, + "Index": 2, + "Kind": 11 + }, + "Index": 0, + "Kind": 11 + }, + "Index": 0, + "Kind": 11 + } + ], + "Kind": 9 + }, + "Kind": 12 + }, + "Kind": 2 + }, + "LeftExpression": { + "Literal": { + "Items": [], + "Kind": 1 + }, + "Kind": 5 + }, + "RightExpression": { + "Expression": { + "Expression": { + "Variable": { + "Name": "v0", + "UniqueId": 16 + }, + "Kind": 14 + }, + "Index": 2, + "Kind": 11 + }, + "Index": 0, + "Kind": 11 + }, + "Kind": 6 + }, + { + "Expression": { + "Expression": { + "Variable": { + "Name": "v0", + "UniqueId": 16 + }, + "Kind": 14 + }, + "Index": 2, + "Kind": 11 + }, + "Index": 1, + "Kind": 11 + } + ], + "Kind": 10 + }, + { + "ConditionExpression": { + "OperatorKind": 1, + "LeftExpression": { + "OperatorKind": 14, + "LeftExpression": { + "Expression": { + "Expression": { + "Variable": { + "Name": "v0", + "UniqueId": 16 + }, + "Kind": 14 + }, + "Index": 3, + "Kind": 11 + }, + "Index": 1, + "Kind": 11 + }, + "RightExpression": { + "Literal": { + "Value": 0, + "Kind": 4 + }, + "Kind": 5 + }, + "Kind": 2 + }, + "RightExpression": { + "OperatorKind": 2, + "Expression": { + "FunctionKind": 55, + "Arguments": [ + { + "Expression": { + "Expression": { + "Variable": { + "Name": "v0", + "UniqueId": 16 + }, + "Kind": 14 + }, + "Index": 3, + "Kind": 11 + }, + "Index": 0, + "Kind": 11 + } + ], + "Kind": 9 + }, + "Kind": 12 + }, + "Kind": 2 + }, + "LeftExpression": { + "Literal": { + "Items": [], + "Kind": 1 + }, + "Kind": 5 + }, + "RightExpression": { + "Expression": { + "Expression": { + "Variable": { + "Name": "v0", + "UniqueId": 16 + }, + "Kind": 14 + }, + "Index": 3, + "Kind": 11 + }, + "Index": 0, + "Kind": 11 + }, + "Kind": 6 + } + ], + "Kind": 10 + }, + "Kind": 6 + }, + "KeyCount": 1, + "Aggregates": [ + { + "OperatorKind": 8, + "Kind": 0 + }, + { + "Items": [ + { + "OperatorKind": 8, + "Kind": 0 + }, + { + "OperatorKind": 8, + "Kind": 0 + } + ], + "Kind": 1 + }, + { + "OperatorKind": 6, + "Kind": 0 + } + ], + "Kind": 2 + }, + "DeclaredVariable": { + "Name": "v0", + "UniqueId": 10 + }, + "Expression": { + "Properties": [ + { + "Name": "F1", + "Expression": { + "Properties": [ + { + "Name": "FieldA", + "Expression": { + "Expression": { + "Variable": { + "Name": "v0", + "UniqueId": 10 + }, + "Kind": 14 + }, + "Index": 0, + "Kind": 11 + } + }, + { + "Name": "FieldSum", + "Expression": { + "Expression": { + "Variable": { + "Name": "v0", + "UniqueId": 10 + }, + "Kind": 14 + }, + "Index": 1, + "Kind": 11 + } + }, + { + "Name": "FieldAvg", + "Expression": { + "ConditionExpression": { + "OperatorKind": 6, + "LeftExpression": { + "Expression": { + "Expression": { + "Variable": { + "Name": "v0", + "UniqueId": 10 + }, + "Kind": 14 + }, + "Index": 2, + "Kind": 11 + }, + "Index": 1, + "Kind": 11 + }, + "RightExpression": { + "Literal": { + "Value": 0, + "Kind": 4 + }, + "Kind": 5 + }, + "Kind": 2 + }, + "LeftExpression": { + "Literal": { + "Kind": 0 + }, + "Kind": 5 + }, + "RightExpression": { + "OperatorKind": 5, + "LeftExpression": { + "Expression": { + "Expression": { + "Variable": { + "Name": "v0", + "UniqueId": 10 + }, + "Kind": 14 + }, + "Index": 2, + "Kind": 11 + }, + "Index": 0, + "Kind": 11 + }, + "RightExpression": { + "Expression": { + "Expression": { + "Variable": { + "Name": "v0", + "UniqueId": 10 + }, + "Kind": 14 + }, + "Index": 2, + "Kind": 11 + }, + "Index": 1, + "Kind": 11 + }, + "Kind": 2 + }, + "Kind": 6 + } + } + ], + "ObjectKind": "Object", + "Kind": 7 + } + }, + { + "Name": "F2", + "Expression": { + "Properties": [ + { + "Name": "OtherFieldA", + "Expression": { + "Expression": { + "Variable": { + "Name": "v0", + "UniqueId": 10 + }, + "Kind": 14 + }, + "Index": 0, + "Kind": 11 + } + }, + { + "Name": "OtherFieldMax", + "Expression": { + "Expression": { + "Variable": { + "Name": "v0", + "UniqueId": 10 + }, + "Kind": 14 + }, + "Index": 3, + "Kind": 11 + } + } + ], + "ObjectKind": "Object", + "Kind": 7 + } + } + ], + "ObjectKind": "Object", + "Kind": 7 + }, + "Kind": 6 + } +} + + + + + Select, Sum and VariableRef Expressions + {"clientDistributionPlan": {"Cql": {"Kind": "Select","DeclaredVariable": {"Name": "v0","UniqueId": 6},"Expression": {"Kind": "ObjectCreate","ObjectKind": "Object","Properties": [{"Name": "count_a_plus_five","Expression": {"Kind": "BinaryOperator","OperatorKind": "Add","LeftExpression": {"Kind": "VariableRef","Variable": {"Name": "v0","UniqueId": 6 }}, "RightExpression": { "Kind": "Literal", "Literal": { "Kind": "Number", "Value": 5 }}}}]}, "SourceExpression": { "Kind": "Aggregate", "Aggregate": { "Kind": "Builtin", "OperatorKind": "Sum" }, "SourceExpression": { "Kind": "Input", "Name": "root" }}}}} + + + { + "Cql": { + "SourceExpression": { + "SourceExpression": { + "Name": "root", + "Kind": 3 + }, + "Aggregate": { + "OperatorKind": 8, + "Kind": 0 + }, + "Kind": 0 + }, + "DeclaredVariable": { + "Name": "v0", + "UniqueId": 6 + }, + "Expression": { + "Properties": [ + { + "Name": "count_a_plus_five", + "Expression": { + "OperatorKind": 0, + "LeftExpression": { + "Variable": { + "Name": "v0", + "UniqueId": 6 + }, + "Kind": 14 + }, + "RightExpression": { + "Literal": { + "Value": 5, + "Kind": 4 + }, + "Kind": 5 + }, + "Kind": 2 + } + } + ], + "ObjectKind": "Object", + "Kind": 7 + }, + "Kind": 6 + } +} + + + \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/TestBaseline/PartitionKeyHashBaselineTest.Lists.xml b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/TestBaseline/PartitionKeyHashBaselineTest.Lists.xml new file mode 100644 index 0000000000..3f7faa9f26 --- /dev/null +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/TestBaseline/PartitionKeyHashBaselineTest.Lists.xml @@ -0,0 +1,32 @@ + + + + 1 Path List + ["/path1"] + + + 00-00-00-00-00-00-00-00-00-00-00-00-0A-A1-CC-05 + B6-3D-B6-C4-3A-4F-1B-01-4C-63-B0-C2-E6-28-E8-12 + + + + + 2 Path List + ["/path1","/path2"] + + + 00-00-00-00-00-00-00-00-00-00-00-00-0A-A1-CC-05-00-00-00-00-00-00-00-00-00-00-00-00-C9-1E-F0-78 + B6-3D-B6-C4-3A-4F-1B-01-4C-63-B0-C2-E6-28-E8-12-A6-0C-6C-BE-5A-2D-38-6E-5D-AE-1A-AC-94-21-6B-6C + + + + + 3 Path List + ["/path1","/path2","/path3"] + + + 00-00-00-00-00-00-00-00-00-00-00-00-0A-A1-CC-05-00-00-00-00-00-00-00-00-00-00-00-00-C9-1E-F0-78-00-00-00-00-00-00-00-00-00-00-00-00-9A-B4-68-CD + B6-3D-B6-C4-3A-4F-1B-01-4C-63-B0-C2-E6-28-E8-12-A6-0C-6C-BE-5A-2D-38-6E-5D-AE-1A-AC-94-21-6B-6C-88-A6-18-5D-2D-D5-1C-96-D0-47-75-B7-2E-FA-BE-08 + + + \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/TestBaseline/ScalarExpressionSqlParserBaselineTests.StringLiteral.xml b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/TestBaseline/ScalarExpressionSqlParserBaselineTests.StringLiteral.xml new file mode 100644 index 0000000000..df9e44ceda --- /dev/null +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/TestBaseline/ScalarExpressionSqlParserBaselineTests.StringLiteral.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/TestBaseline/TraceWriterBaselineTests.TraceData.xml b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/TestBaseline/TraceWriterBaselineTests.TraceData.xml index d1dee72a0f..75cd9894de 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/TestBaseline/TraceWriterBaselineTests.TraceData.xml +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/TestBaseline/TraceWriterBaselineTests.TraceData.xml @@ -126,7 +126,7 @@ { QueryMetricsTraceDatum datum = new QueryMetricsTraceDatum( new Lazy(() => new QueryMetrics( - BackendMetricsTests.MockBackendMetrics, + ServerSideMetricsTests.ServerSideMetrics, IndexUtilizationInfoTests.MockIndexUtilizationInfo, ClientSideMetricsTests.MockClientSideMetrics))); rootTrace.AddDatum("Query Metrics", datum); diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Contracts/DotNetPreviewSDKAPI.json b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Contracts/DotNetPreviewSDKAPI.json index 8546a93b2f..dde2d208bc 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Contracts/DotNetPreviewSDKAPI.json +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Contracts/DotNetPreviewSDKAPI.json @@ -352,31 +352,6 @@ }, "NestedTypes": {} }, - "Microsoft.Azure.Cosmos.CosmosClientOptions;System.Object;IsAbstract:False;IsSealed:False;IsInterface:False;IsEnum:False;IsClass:True;IsValueType:False;IsNested:False;IsGenericType:False;IsSerializable:False": { - "Subclasses": {}, - "Members": { - "Boolean get_IsDistributedTracingEnabled()[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]": { - "Type": "Method", - "Attributes": [ - "CompilerGeneratedAttribute" - ], - "MethodInfo": "Boolean get_IsDistributedTracingEnabled();IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" - }, - "Boolean IsDistributedTracingEnabled": { - "Type": "Property", - "Attributes": [], - "MethodInfo": "Boolean IsDistributedTracingEnabled;CanRead:True;CanWrite:True;Boolean get_IsDistributedTracingEnabled();IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;Void set_IsDistributedTracingEnabled(Boolean);IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" - }, - "Void set_IsDistributedTracingEnabled(Boolean)[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]": { - "Type": "Method", - "Attributes": [ - "CompilerGeneratedAttribute" - ], - "MethodInfo": "Void set_IsDistributedTracingEnabled(Boolean);IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" - } - }, - "NestedTypes": {} - }, "Microsoft.Azure.Cosmos.DedicatedGatewayRequestOptions;System.Object;IsAbstract:False;IsSealed:False;IsInterface:False;IsEnum:False;IsClass:True;IsValueType:False;IsNested:False;IsGenericType:False;IsSerializable:False": { "Subclasses": {}, "Members": { @@ -451,17 +426,6 @@ }, "NestedTypes": {} }, - "Microsoft.Azure.Cosmos.Fluent.CosmosClientBuilder;System.Object;IsAbstract:False;IsSealed:False;IsInterface:False;IsEnum:False;IsClass:True;IsValueType:False;IsNested:False;IsGenericType:False;IsSerializable:False": { - "Subclasses": {}, - "Members": { - "Microsoft.Azure.Cosmos.Fluent.CosmosClientBuilder WithDistributedTracing(Boolean)": { - "Type": "Method", - "Attributes": [], - "MethodInfo": "Microsoft.Azure.Cosmos.Fluent.CosmosClientBuilder WithDistributedTracing(Boolean);IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" - } - }, - "NestedTypes": {} - }, "Microsoft.Azure.Cosmos.Linq.CosmosLinqExtensions;System.Object;IsAbstract:True;IsSealed:True;IsInterface:False;IsEnum:False;IsClass:True;IsValueType:False;IsNested:False;IsGenericType:False;IsSerializable:False": { "Subclasses": {}, "Members": { diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Contracts/DotNetSDKAPI.json b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Contracts/DotNetSDKAPI.json index 7fde376d49..8c8d7d6ae1 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Contracts/DotNetSDKAPI.json +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Contracts/DotNetSDKAPI.json @@ -2736,6 +2736,18 @@ "Attributes": [], "MethodInfo": "Microsoft.Azure.Cosmos.ConnectionMode get_ConnectionMode();IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" }, + "Microsoft.Azure.Cosmos.CosmosClientTelemetryOptions CosmosClientTelemetryOptions": { + "Type": "Property", + "Attributes": [], + "MethodInfo": "Microsoft.Azure.Cosmos.CosmosClientTelemetryOptions CosmosClientTelemetryOptions;CanRead:True;CanWrite:True;Microsoft.Azure.Cosmos.CosmosClientTelemetryOptions get_CosmosClientTelemetryOptions();IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;Void set_CosmosClientTelemetryOptions(Microsoft.Azure.Cosmos.CosmosClientTelemetryOptions);IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "Microsoft.Azure.Cosmos.CosmosClientTelemetryOptions get_CosmosClientTelemetryOptions()[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]": { + "Type": "Method", + "Attributes": [ + "CompilerGeneratedAttribute" + ], + "MethodInfo": "Microsoft.Azure.Cosmos.CosmosClientTelemetryOptions get_CosmosClientTelemetryOptions();IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, "Microsoft.Azure.Cosmos.CosmosSerializationOptions get_SerializerOptions()": { "Type": "Method", "Attributes": [], @@ -3007,6 +3019,13 @@ ], "MethodInfo": "Void set_ConsistencyLevel(System.Nullable`1[Microsoft.Azure.Cosmos.ConsistencyLevel]);IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" }, + "Void set_CosmosClientTelemetryOptions(Microsoft.Azure.Cosmos.CosmosClientTelemetryOptions)[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]": { + "Type": "Method", + "Attributes": [ + "CompilerGeneratedAttribute" + ], + "MethodInfo": "Void set_CosmosClientTelemetryOptions(Microsoft.Azure.Cosmos.CosmosClientTelemetryOptions);IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, "Void set_EnableContentResponseOnWrite(System.Nullable`1[System.Boolean])[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]": { "Type": "Method", "Attributes": [ @@ -3116,6 +3135,74 @@ }, "NestedTypes": {} }, + "Microsoft.Azure.Cosmos.CosmosClientTelemetryOptions;System.Object;IsAbstract:False;IsSealed:False;IsInterface:False;IsEnum:False;IsClass:True;IsValueType:False;IsNested:False;IsGenericType:False;IsSerializable:False": { + "Subclasses": {}, + "Members": { + "Boolean DisableDistributedTracing": { + "Type": "Property", + "Attributes": [], + "MethodInfo": "Boolean DisableDistributedTracing;CanRead:True;CanWrite:True;Boolean get_DisableDistributedTracing();IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;Void set_DisableDistributedTracing(Boolean);IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "Boolean DisableSendingMetricsToService": { + "Type": "Property", + "Attributes": [], + "MethodInfo": "Boolean DisableSendingMetricsToService;CanRead:True;CanWrite:True;Boolean get_DisableSendingMetricsToService();IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;Void set_DisableSendingMetricsToService(Boolean);IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "Boolean get_DisableDistributedTracing()[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]": { + "Type": "Method", + "Attributes": [ + "CompilerGeneratedAttribute" + ], + "MethodInfo": "Boolean get_DisableDistributedTracing();IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "Boolean get_DisableSendingMetricsToService()[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]": { + "Type": "Method", + "Attributes": [ + "CompilerGeneratedAttribute" + ], + "MethodInfo": "Boolean get_DisableSendingMetricsToService();IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "Microsoft.Azure.Cosmos.CosmosThresholdOptions CosmosThresholdOptions": { + "Type": "Property", + "Attributes": [], + "MethodInfo": "Microsoft.Azure.Cosmos.CosmosThresholdOptions CosmosThresholdOptions;CanRead:True;CanWrite:True;Microsoft.Azure.Cosmos.CosmosThresholdOptions get_CosmosThresholdOptions();IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;Void set_CosmosThresholdOptions(Microsoft.Azure.Cosmos.CosmosThresholdOptions);IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "Microsoft.Azure.Cosmos.CosmosThresholdOptions get_CosmosThresholdOptions()[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]": { + "Type": "Method", + "Attributes": [ + "CompilerGeneratedAttribute" + ], + "MethodInfo": "Microsoft.Azure.Cosmos.CosmosThresholdOptions get_CosmosThresholdOptions();IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "Void .ctor()": { + "Type": "Constructor", + "Attributes": [], + "MethodInfo": "[Void .ctor(), Void .ctor()]" + }, + "Void set_CosmosThresholdOptions(Microsoft.Azure.Cosmos.CosmosThresholdOptions)[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]": { + "Type": "Method", + "Attributes": [ + "CompilerGeneratedAttribute" + ], + "MethodInfo": "Void set_CosmosThresholdOptions(Microsoft.Azure.Cosmos.CosmosThresholdOptions);IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "Void set_DisableDistributedTracing(Boolean)[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]": { + "Type": "Method", + "Attributes": [ + "CompilerGeneratedAttribute" + ], + "MethodInfo": "Void set_DisableDistributedTracing(Boolean);IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "Void set_DisableSendingMetricsToService(Boolean)[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]": { + "Type": "Method", + "Attributes": [ + "CompilerGeneratedAttribute" + ], + "MethodInfo": "Void set_DisableSendingMetricsToService(Boolean);IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + } + }, + "NestedTypes": {} + }, "Microsoft.Azure.Cosmos.CosmosDiagnostics;System.Object;IsAbstract:True;IsSealed:False;IsInterface:False;IsEnum:False;IsClass:True;IsValueType:False;IsNested:False;IsGenericType:False;IsSerializable:False": { "Subclasses": {}, "Members": { @@ -3124,6 +3211,11 @@ "Attributes": [], "MethodInfo": "Int32 GetFailedRequestCount();IsAbstract:False;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" }, + "Microsoft.Azure.Cosmos.ServerSideCumulativeMetrics GetQueryMetrics()": { + "Type": "Method", + "Attributes": [], + "MethodInfo": "Microsoft.Azure.Cosmos.ServerSideCumulativeMetrics GetQueryMetrics();IsAbstract:False;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, "System.Collections.Generic.IReadOnlyList`1[System.ValueTuple`2[System.String,System.Uri]] GetContactedRegions()": { "Type": "Method", "Attributes": [], @@ -3530,6 +3622,55 @@ }, "NestedTypes": {} }, + "Microsoft.Azure.Cosmos.CosmosThresholdOptions;System.Object;IsAbstract:False;IsSealed:False;IsInterface:False;IsEnum:False;IsClass:True;IsValueType:False;IsNested:False;IsGenericType:False;IsSerializable:False": { + "Subclasses": {}, + "Members": { + "System.TimeSpan get_NonPointOperationLatencyThreshold()[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]": { + "Type": "Method", + "Attributes": [ + "CompilerGeneratedAttribute" + ], + "MethodInfo": "System.TimeSpan get_NonPointOperationLatencyThreshold();IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "System.TimeSpan get_PointOperationLatencyThreshold()[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]": { + "Type": "Method", + "Attributes": [ + "CompilerGeneratedAttribute" + ], + "MethodInfo": "System.TimeSpan get_PointOperationLatencyThreshold();IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "System.TimeSpan NonPointOperationLatencyThreshold": { + "Type": "Property", + "Attributes": [], + "MethodInfo": "System.TimeSpan NonPointOperationLatencyThreshold;CanRead:True;CanWrite:True;System.TimeSpan get_NonPointOperationLatencyThreshold();IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;Void set_NonPointOperationLatencyThreshold(System.TimeSpan);IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "System.TimeSpan PointOperationLatencyThreshold": { + "Type": "Property", + "Attributes": [], + "MethodInfo": "System.TimeSpan PointOperationLatencyThreshold;CanRead:True;CanWrite:True;System.TimeSpan get_PointOperationLatencyThreshold();IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;Void set_PointOperationLatencyThreshold(System.TimeSpan);IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "Void .ctor()": { + "Type": "Constructor", + "Attributes": [], + "MethodInfo": "[Void .ctor(), Void .ctor()]" + }, + "Void set_NonPointOperationLatencyThreshold(System.TimeSpan)[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]": { + "Type": "Method", + "Attributes": [ + "CompilerGeneratedAttribute" + ], + "MethodInfo": "Void set_NonPointOperationLatencyThreshold(System.TimeSpan);IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "Void set_PointOperationLatencyThreshold(System.TimeSpan)[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]": { + "Type": "Method", + "Attributes": [ + "CompilerGeneratedAttribute" + ], + "MethodInfo": "Void set_PointOperationLatencyThreshold(System.TimeSpan);IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + } + }, + "NestedTypes": {} + }, "Microsoft.Azure.Cosmos.Database;System.Object;IsAbstract:True;IsSealed:False;IsInterface:False;IsEnum:False;IsClass:True;IsValueType:False;IsNested:False;IsGenericType:False;IsSerializable:False": { "Subclasses": {}, "Members": { @@ -4413,6 +4554,11 @@ "Attributes": [], "MethodInfo": "Microsoft.Azure.Cosmos.Fluent.CosmosClientBuilder WithBulkExecution(Boolean);IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" }, + "Microsoft.Azure.Cosmos.Fluent.CosmosClientBuilder WithClientTelemetryOptions(Microsoft.Azure.Cosmos.CosmosClientTelemetryOptions)": { + "Type": "Method", + "Attributes": [], + "MethodInfo": "Microsoft.Azure.Cosmos.Fluent.CosmosClientBuilder WithClientTelemetryOptions(Microsoft.Azure.Cosmos.CosmosClientTelemetryOptions);IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, "Microsoft.Azure.Cosmos.Fluent.CosmosClientBuilder WithConnectionModeDirect()": { "Type": "Method", "Attributes": [], @@ -5362,6 +5508,20 @@ ], "MethodInfo": "Boolean IsString(System.Object);IsAbstract:False;IsStatic:True;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" }, + "Boolean RegexMatch(System.Object, System.String, System.String)[System.Runtime.CompilerServices.ExtensionAttribute()]": { + "Type": "Method", + "Attributes": [ + "ExtensionAttribute" + ], + "MethodInfo": "Boolean RegexMatch(System.Object, System.String, System.String);IsAbstract:False;IsStatic:True;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "Boolean RegexMatch(System.Object, System.String)[System.Runtime.CompilerServices.ExtensionAttribute()]": { + "Type": "Method", + "Attributes": [ + "ExtensionAttribute" + ], + "MethodInfo": "Boolean RegexMatch(System.Object, System.String);IsAbstract:False;IsStatic:True;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, "Microsoft.Azure.Cosmos.FeedIterator ToStreamIterator[T](System.Linq.IQueryable`1[T])[System.Runtime.CompilerServices.ExtensionAttribute()]": { "Type": "Method", "Attributes": [ @@ -7785,6 +7945,18 @@ } }, "Members": { + "Microsoft.Azure.Cosmos.CosmosThresholdOptions CosmosThresholdOptions": { + "Type": "Property", + "Attributes": [], + "MethodInfo": "Microsoft.Azure.Cosmos.CosmosThresholdOptions CosmosThresholdOptions;CanRead:True;CanWrite:True;Microsoft.Azure.Cosmos.CosmosThresholdOptions get_CosmosThresholdOptions();IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;Void set_CosmosThresholdOptions(Microsoft.Azure.Cosmos.CosmosThresholdOptions);IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "Microsoft.Azure.Cosmos.CosmosThresholdOptions get_CosmosThresholdOptions()[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]": { + "Type": "Method", + "Attributes": [ + "CompilerGeneratedAttribute" + ], + "MethodInfo": "Microsoft.Azure.Cosmos.CosmosThresholdOptions get_CosmosThresholdOptions();IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, "Microsoft.Azure.Cosmos.RequestOptions ShallowCopy()": { "Type": "Method", "Attributes": [], @@ -7850,6 +8022,13 @@ ], "MethodInfo": "Void set_AddRequestHeaders(System.Action`1[Microsoft.Azure.Cosmos.Headers]);IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" }, + "Void set_CosmosThresholdOptions(Microsoft.Azure.Cosmos.CosmosThresholdOptions)[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]": { + "Type": "Method", + "Attributes": [ + "CompilerGeneratedAttribute" + ], + "MethodInfo": "Void set_CosmosThresholdOptions(Microsoft.Azure.Cosmos.CosmosThresholdOptions);IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, "Void set_IfMatchEtag(System.String)[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]": { "Type": "Method", "Attributes": [ @@ -8620,6 +8799,11 @@ "Type": "Field", "Attributes": [], "MethodInfo": "Microsoft.Azure.Cosmos.Scripts.TriggerOperation Update;IsInitOnly:False;IsStatic:True;" + }, + "Microsoft.Azure.Cosmos.Scripts.TriggerOperation Upsert": { + "Type": "Field", + "Attributes": [], + "MethodInfo": "Microsoft.Azure.Cosmos.Scripts.TriggerOperation Upsert;IsInitOnly:False;IsStatic:True;" } }, "NestedTypes": {} @@ -9029,6 +9213,194 @@ }, "NestedTypes": {} }, + "Microsoft.Azure.Cosmos.ServerSideCumulativeMetrics;System.Object;IsAbstract:True;IsSealed:False;IsInterface:False;IsEnum:False;IsClass:True;IsValueType:False;IsNested:False;IsGenericType:False;IsSerializable:False": { + "Subclasses": {}, + "Members": { + "Microsoft.Azure.Cosmos.ServerSideMetrics CumulativeMetrics": { + "Type": "Property", + "Attributes": [], + "MethodInfo": "Microsoft.Azure.Cosmos.ServerSideMetrics CumulativeMetrics;CanRead:True;CanWrite:False;Microsoft.Azure.Cosmos.ServerSideMetrics get_CumulativeMetrics();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "Microsoft.Azure.Cosmos.ServerSideMetrics get_CumulativeMetrics()": { + "Type": "Method", + "Attributes": [], + "MethodInfo": "Microsoft.Azure.Cosmos.ServerSideMetrics get_CumulativeMetrics();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "System.Collections.Generic.IReadOnlyList`1[Microsoft.Azure.Cosmos.ServerSidePartitionedMetrics] get_PartitionedMetrics()": { + "Type": "Method", + "Attributes": [], + "MethodInfo": "System.Collections.Generic.IReadOnlyList`1[Microsoft.Azure.Cosmos.ServerSidePartitionedMetrics] get_PartitionedMetrics();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "System.Collections.Generic.IReadOnlyList`1[Microsoft.Azure.Cosmos.ServerSidePartitionedMetrics] PartitionedMetrics": { + "Type": "Property", + "Attributes": [], + "MethodInfo": "System.Collections.Generic.IReadOnlyList`1[Microsoft.Azure.Cosmos.ServerSidePartitionedMetrics] PartitionedMetrics;CanRead:True;CanWrite:False;System.Collections.Generic.IReadOnlyList`1[Microsoft.Azure.Cosmos.ServerSidePartitionedMetrics] get_PartitionedMetrics();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + } + }, + "NestedTypes": {} + }, + "Microsoft.Azure.Cosmos.ServerSideMetrics;System.Object;IsAbstract:True;IsSealed:False;IsInterface:False;IsEnum:False;IsClass:True;IsValueType:False;IsNested:False;IsGenericType:False;IsSerializable:False": { + "Subclasses": {}, + "Members": { + "Double get_IndexHitRatio()": { + "Type": "Method", + "Attributes": [], + "MethodInfo": "Double get_IndexHitRatio();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "Double IndexHitRatio": { + "Type": "Property", + "Attributes": [], + "MethodInfo": "Double IndexHitRatio;CanRead:True;CanWrite:False;Double get_IndexHitRatio();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "Int64 get_OutputDocumentCount()": { + "Type": "Method", + "Attributes": [], + "MethodInfo": "Int64 get_OutputDocumentCount();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "Int64 get_OutputDocumentSize()": { + "Type": "Method", + "Attributes": [], + "MethodInfo": "Int64 get_OutputDocumentSize();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "Int64 get_RetrievedDocumentCount()": { + "Type": "Method", + "Attributes": [], + "MethodInfo": "Int64 get_RetrievedDocumentCount();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "Int64 get_RetrievedDocumentSize()": { + "Type": "Method", + "Attributes": [], + "MethodInfo": "Int64 get_RetrievedDocumentSize();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "Int64 OutputDocumentCount": { + "Type": "Property", + "Attributes": [], + "MethodInfo": "Int64 OutputDocumentCount;CanRead:True;CanWrite:False;Int64 get_OutputDocumentCount();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "Int64 OutputDocumentSize": { + "Type": "Property", + "Attributes": [], + "MethodInfo": "Int64 OutputDocumentSize;CanRead:True;CanWrite:False;Int64 get_OutputDocumentSize();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "Int64 RetrievedDocumentCount": { + "Type": "Property", + "Attributes": [], + "MethodInfo": "Int64 RetrievedDocumentCount;CanRead:True;CanWrite:False;Int64 get_RetrievedDocumentCount();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "Int64 RetrievedDocumentSize": { + "Type": "Property", + "Attributes": [], + "MethodInfo": "Int64 RetrievedDocumentSize;CanRead:True;CanWrite:False;Int64 get_RetrievedDocumentSize();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "System.TimeSpan DocumentLoadTime": { + "Type": "Property", + "Attributes": [], + "MethodInfo": "System.TimeSpan DocumentLoadTime;CanRead:True;CanWrite:False;System.TimeSpan get_DocumentLoadTime();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "System.TimeSpan DocumentWriteTime": { + "Type": "Property", + "Attributes": [], + "MethodInfo": "System.TimeSpan DocumentWriteTime;CanRead:True;CanWrite:False;System.TimeSpan get_DocumentWriteTime();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "System.TimeSpan get_DocumentLoadTime()": { + "Type": "Method", + "Attributes": [], + "MethodInfo": "System.TimeSpan get_DocumentLoadTime();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "System.TimeSpan get_DocumentWriteTime()": { + "Type": "Method", + "Attributes": [], + "MethodInfo": "System.TimeSpan get_DocumentWriteTime();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "System.TimeSpan get_IndexLookupTime()": { + "Type": "Method", + "Attributes": [], + "MethodInfo": "System.TimeSpan get_IndexLookupTime();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "System.TimeSpan get_QueryPreparationTime()": { + "Type": "Method", + "Attributes": [], + "MethodInfo": "System.TimeSpan get_QueryPreparationTime();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "System.TimeSpan get_RuntimeExecutionTime()": { + "Type": "Method", + "Attributes": [], + "MethodInfo": "System.TimeSpan get_RuntimeExecutionTime();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "System.TimeSpan get_TotalTime()": { + "Type": "Method", + "Attributes": [], + "MethodInfo": "System.TimeSpan get_TotalTime();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "System.TimeSpan get_VMExecutionTime()": { + "Type": "Method", + "Attributes": [], + "MethodInfo": "System.TimeSpan get_VMExecutionTime();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "System.TimeSpan IndexLookupTime": { + "Type": "Property", + "Attributes": [], + "MethodInfo": "System.TimeSpan IndexLookupTime;CanRead:True;CanWrite:False;System.TimeSpan get_IndexLookupTime();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "System.TimeSpan QueryPreparationTime": { + "Type": "Property", + "Attributes": [], + "MethodInfo": "System.TimeSpan QueryPreparationTime;CanRead:True;CanWrite:False;System.TimeSpan get_QueryPreparationTime();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "System.TimeSpan RuntimeExecutionTime": { + "Type": "Property", + "Attributes": [], + "MethodInfo": "System.TimeSpan RuntimeExecutionTime;CanRead:True;CanWrite:False;System.TimeSpan get_RuntimeExecutionTime();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "System.TimeSpan TotalTime": { + "Type": "Property", + "Attributes": [], + "MethodInfo": "System.TimeSpan TotalTime;CanRead:True;CanWrite:False;System.TimeSpan get_TotalTime();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "System.TimeSpan VMExecutionTime": { + "Type": "Property", + "Attributes": [], + "MethodInfo": "System.TimeSpan VMExecutionTime;CanRead:True;CanWrite:False;System.TimeSpan get_VMExecutionTime();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + } + }, + "NestedTypes": {} + }, + "Microsoft.Azure.Cosmos.ServerSidePartitionedMetrics;System.Object;IsAbstract:True;IsSealed:False;IsInterface:False;IsEnum:False;IsClass:True;IsValueType:False;IsNested:False;IsGenericType:False;IsSerializable:False": { + "Subclasses": {}, + "Members": { + "Microsoft.Azure.Cosmos.ServerSideMetrics get_ServerSideMetrics()": { + "Type": "Method", + "Attributes": [], + "MethodInfo": "Microsoft.Azure.Cosmos.ServerSideMetrics get_ServerSideMetrics();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "Microsoft.Azure.Cosmos.ServerSideMetrics ServerSideMetrics": { + "Type": "Property", + "Attributes": [], + "MethodInfo": "Microsoft.Azure.Cosmos.ServerSideMetrics ServerSideMetrics;CanRead:True;CanWrite:False;Microsoft.Azure.Cosmos.ServerSideMetrics get_ServerSideMetrics();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "System.Nullable`1[System.Int32] get_PartitionKeyRangeId()": { + "Type": "Method", + "Attributes": [], + "MethodInfo": "System.Nullable`1[System.Int32] get_PartitionKeyRangeId();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "System.Nullable`1[System.Int32] PartitionKeyRangeId": { + "Type": "Property", + "Attributes": [], + "MethodInfo": "System.Nullable`1[System.Int32] PartitionKeyRangeId;CanRead:True;CanWrite:False;System.Nullable`1[System.Int32] get_PartitionKeyRangeId();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "System.String FeedRange": { + "Type": "Property", + "Attributes": [], + "MethodInfo": "System.String FeedRange;CanRead:True;CanWrite:False;System.String get_FeedRange();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "System.String get_FeedRange()": { + "Type": "Method", + "Attributes": [], + "MethodInfo": "System.String get_FeedRange();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + } + }, + "NestedTypes": {} + }, "Microsoft.Azure.Cosmos.Spatial.BoundingBox;System.Object;IsAbstract:False;IsSealed:True;IsInterface:False;IsEnum:False;IsClass:True;IsValueType:False;IsNested:False;IsGenericType:False;IsSerializable:False": { "Subclasses": {}, "Members": { diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosClientOptionsUnitTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosClientOptionsUnitTests.cs index 37d89c389a..9390de7f0d 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosClientOptionsUnitTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosClientOptionsUnitTests.cs @@ -7,6 +7,7 @@ namespace Microsoft.Azure.Cosmos.Tests using System; using System.Collections; using System.Collections.Generic; + using System.Collections.ObjectModel; using System.Linq; using System.Net; using System.Net.Http; @@ -99,6 +100,12 @@ public void VerifyCosmosConfigurationPropertiesGetUpdated() Assert.AreNotEqual(Cosmos.ConsistencyLevel.Session, clientOptions.ConsistencyLevel); Assert.IsFalse(policy.EnablePartitionLevelFailover); Assert.IsFalse(clientOptions.EnableAdvancedReplicaSelectionForTcp.HasValue); +#if PREVIEW + Assert.IsFalse(clientOptions.CosmosClientTelemetryOptions.DisableDistributedTracing); +#else + Assert.IsTrue(clientOptions.CosmosClientTelemetryOptions.DisableDistributedTracing); +#endif + Assert.IsTrue(clientOptions.CosmosClientTelemetryOptions.DisableSendingMetricsToService); cosmosClientBuilder.WithApplicationRegion(region) .WithConnectionModeGateway(maxConnections, webProxy) @@ -164,9 +171,14 @@ public void VerifyCosmosConfigurationPropertiesGetUpdated() portReuseMode, enableTcpConnectionEndpointRediscovery) .WithApplicationPreferredRegions(preferredLocations) - .WithDistributedTracingOptions(new DistributedTracingOptions + .WithClientTelemetryOptions(new CosmosClientTelemetryOptions() { - LatencyThresholdForDiagnosticEvent = TimeSpan.FromMilliseconds(100) + DisableDistributedTracing = false, + CosmosThresholdOptions = new CosmosThresholdOptions() + { + PointOperationLatencyThreshold = TimeSpan.FromMilliseconds(100), + NonPointOperationLatencyThreshold = TimeSpan.FromMilliseconds(100) + } }); cosmosClient = cosmosClientBuilder.Build(new MockDocumentClient()); @@ -179,8 +191,9 @@ public void VerifyCosmosConfigurationPropertiesGetUpdated() Assert.AreEqual(portReuseMode, clientOptions.PortReuseMode); Assert.IsTrue(clientOptions.EnableTcpConnectionEndpointRediscovery); CollectionAssert.AreEqual(preferredLocations.ToArray(), clientOptions.ApplicationPreferredRegions.ToArray()); - Assert.AreEqual(TimeSpan.FromMilliseconds(100), clientOptions.DistributedTracingOptions.LatencyThresholdForDiagnosticEvent); - Assert.IsTrue(clientOptions.IsDistributedTracingEnabled); + Assert.AreEqual(TimeSpan.FromMilliseconds(100), clientOptions.CosmosClientTelemetryOptions.CosmosThresholdOptions.PointOperationLatencyThreshold); + Assert.AreEqual(TimeSpan.FromMilliseconds(100), clientOptions.CosmosClientTelemetryOptions.CosmosThresholdOptions.NonPointOperationLatencyThreshold); + Assert.IsFalse(clientOptions.CosmosClientTelemetryOptions.DisableDistributedTracing); //Verify GetConnectionPolicy returns the correct values policy = clientOptions.GetConnectionPolicy(clientId: 0); @@ -544,6 +557,170 @@ public void WithQuorumReadWithEventualConsistencyAccount() Assert.IsTrue(cosmosClientOptions.EnableUpgradeConsistencyToLocalQuorum); } + [TestMethod] + public void VerifyRegionNameFormatConversionForApplicationRegion() + { + CosmosClientOptions cosmosClientOptions = new CosmosClientOptions(); + cosmosClientOptions.ApplicationRegion = "westus2"; + + ConnectionPolicy policy = cosmosClientOptions.GetConnectionPolicy(0); + + // Need to see Regions.WestUS2 in the list, but not "westus2" + bool seenWestUS2 = false; + bool seenNormalized = false; + + foreach (string region in policy.PreferredLocations) + { + if (region == "westus2") + { + seenNormalized = true; + } + + if (region == Regions.WestUS2) + { + seenWestUS2 = true; + } + } + Assert.IsTrue(seenWestUS2); + Assert.IsFalse(seenNormalized); + } + + [TestMethod] + public void VerifyRegionNameFormatConversionBypassForApplicationRegion() + { + CosmosClientOptions cosmosClientOptions = new CosmosClientOptions(); + + // No conversion for expected format. + cosmosClientOptions.ApplicationRegion = Regions.NorthCentralUS; + + ConnectionPolicy policy = cosmosClientOptions.GetConnectionPolicy(0); + + Assert.AreEqual(Regions.NorthCentralUS, policy.PreferredLocations[0]); + + // Ignore unknown values. + cosmosClientOptions.ApplicationRegion = null; + + policy = cosmosClientOptions.GetConnectionPolicy(0); + + Assert.AreEqual(0, policy.PreferredLocations.Count); + + cosmosClientOptions.ApplicationRegion = string.Empty; + policy = cosmosClientOptions.GetConnectionPolicy(0); + + Assert.AreEqual(0, policy.PreferredLocations.Count); + + cosmosClientOptions.ApplicationRegion = "Invalid region"; + Assert.ThrowsException(() => cosmosClientOptions.GetConnectionPolicy(0)); + } + + [TestMethod] + public void VerifyRegionNameFormatConversionForApplicationPreferredRegions() + { + CosmosClientOptions cosmosClientOptions = new CosmosClientOptions(); + cosmosClientOptions.ApplicationPreferredRegions = new List {"westus2", "usdodcentral", Regions.ChinaNorth3}; + + ConnectionPolicy policy = cosmosClientOptions.GetConnectionPolicy(0); + + bool seenUSDodCentral = false; + bool seenWestUS2 = false; + bool seenChinaNorth3 = false; + bool seenNormalizedUSDodCentral = false; + bool seenNormalizedWestUS2 = false; + + foreach (string region in policy.PreferredLocations) + { + if (region == Regions.USDoDCentral) + { + seenUSDodCentral = true; + } + + if (region == Regions.WestUS2) + { + seenWestUS2 = true; + } + + if (region == Regions.ChinaNorth3) + { + seenChinaNorth3 = true; + } + + if (region == "westus2") + { + seenNormalizedWestUS2 = true; + } + + if (region == "usdodcentral") + { + seenNormalizedUSDodCentral = true; + } + } + + Assert.IsTrue(seenChinaNorth3); + Assert.IsTrue(seenWestUS2); + Assert.IsTrue(seenUSDodCentral); + Assert.IsFalse(seenNormalizedUSDodCentral); + Assert.IsFalse(seenNormalizedWestUS2); + } + + [TestMethod] + public void VerifyRegionNameFormatConversionBypassForInvalidApplicationPreferredRegions() + { + CosmosClientOptions cosmosClientOptions = new CosmosClientOptions(); + + // List contains valid and invalid values + cosmosClientOptions.ApplicationPreferredRegions = new List + { + null, + string.Empty, + Regions.JioIndiaCentral, + "westus2", + "Invalid region" + }; + + ConnectionPolicy policy = cosmosClientOptions.GetConnectionPolicy(0); + + bool seenJioIndiaCentral = false; + bool seenWestUS2 = false; + bool seenNormalized = false; + + foreach (string region in policy.PreferredLocations) + { + if (region == Regions.JioIndiaCentral) + { + seenJioIndiaCentral = true; + } + + if (region == Regions.WestUS2) + { + seenWestUS2 = true; + } + + if (region == "westus2") + { + seenNormalized = true; + } + } + + Assert.IsTrue(seenJioIndiaCentral); + Assert.IsTrue(seenWestUS2); + Assert.IsFalse(seenNormalized); + } + + [TestMethod] + public void RegionNameMappingTest() + { + RegionNameMapper mapper = new RegionNameMapper(); + + // Test normalized name + Assert.AreEqual(Regions.WestUS2, mapper.GetCosmosDBRegionName("westus2")); + + // Test with spaces + Assert.AreEqual(Regions.WestUS2, mapper.GetCosmosDBRegionName("west us 2")); + + // Test for case insenstive + Assert.AreEqual(Regions.WestUS2, mapper.GetCosmosDBRegionName("wEsTuS2")); + } + [TestMethod] public void InvalidApplicationNameCatchTest() { diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosClientTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosClientTests.cs index 8d08704eeb..6740001f53 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosClientTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosClientTests.cs @@ -7,7 +7,6 @@ namespace Microsoft.Azure.Cosmos.Tests using System; using System.Collections.Generic; using System.Diagnostics; - using System.Collections.Specialized; using System.Globalization; using System.Linq; using System.Net; @@ -16,7 +15,6 @@ namespace Microsoft.Azure.Cosmos.Tests using System.Threading; using System.Threading.Tasks; using System.Web; - using FluentAssertions; using global::Azure; using global::Azure.Core; using Microsoft.Azure.Cosmos.Core.Trace; @@ -248,11 +246,7 @@ public void ValidateMasterKeyAuthProvider() using (CosmosClient client = new CosmosClient( CosmosClientTests.AccountEndpoint, - masterKeyCredential, - new CosmosClientOptions() - { - EnableClientTelemetry = false, - })) + masterKeyCredential)) { Assert.AreEqual(typeof(AuthorizationTokenProviderMasterKey), client.AuthorizationTokenProvider.GetType()); } @@ -265,11 +259,7 @@ public void ValidateResourceTokenAuthProvider() using (CosmosClient client = new CosmosClient( CosmosClientTests.AccountEndpoint, - resourceToken, - new CosmosClientOptions() - { - EnableClientTelemetry = false, - })) + resourceToken)) { Assert.AreEqual(typeof(AuthorizationTokenProviderResourceToken), client.AuthorizationTokenProvider.GetType()); } @@ -283,11 +273,7 @@ public void ValidateMasterKeyAzureCredentialAuthProvider() AzureKeyCredential masterKeyCredential = new AzureKeyCredential(originalKey); using (CosmosClient client = new CosmosClient( CosmosClientTests.AccountEndpoint, - masterKeyCredential, - new CosmosClientOptions() - { - EnableClientTelemetry = false, - })) + masterKeyCredential)) { Assert.AreEqual(typeof(AzureKeyCredentialAuthorizationTokenProvider), client.AuthorizationTokenProvider.GetType()); @@ -304,11 +290,7 @@ public void ValidateResourceTokenAzureCredentialAuthProvider() AzureKeyCredential resourceTokenCredential = new AzureKeyCredential(resourceToken); using (CosmosClient client = new CosmosClient( CosmosClientTests.AccountEndpoint, - resourceTokenCredential, - new CosmosClientOptions() - { - EnableClientTelemetry = false, - })) + resourceTokenCredential)) { Assert.AreEqual(typeof(AzureKeyCredentialAuthorizationTokenProvider), client.AuthorizationTokenProvider.GetType()); @@ -377,8 +359,7 @@ public async Task ValidateAzureKeyCredentialGatewayModeUpdateAsync() masterKeyCredential, new CosmosClientOptions() { - HttpClientFactory = () => new HttpClient(new HttpHandlerHelper(mockHttpHandler.Object)), - EnableClientTelemetry = false, + HttpClientFactory = () => new HttpClient(new HttpHandlerHelper(mockHttpHandler.Object)) })) { Container container = client.GetContainer(Guid.NewGuid().ToString(), Guid.NewGuid().ToString()); @@ -440,10 +421,7 @@ void TraceHandler(string message) for (int z = 0; z < 100; ++z) { - using CosmosClient cosmos = new(ConnectionString, new CosmosClientOptions - { - EnableClientTelemetry = true - }); + using CosmosClient cosmos = new(ConnectionString); } string assertMsg = String.Empty; diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Diagnostics/DiagnosticHandlerHelperTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Diagnostics/DiagnosticHandlerHelperTests.cs new file mode 100644 index 0000000000..cd0a92ad1b --- /dev/null +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Diagnostics/DiagnosticHandlerHelperTests.cs @@ -0,0 +1,98 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ +namespace Microsoft.Azure.Cosmos.Diagnostics +{ + using System; + using System.Reflection; + using System.Threading.Tasks; + using Microsoft.Azure.Cosmos.Handler; + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class DiagnosticHandlerHelperTests + { + [ClassInitialize] + public static void Initialize(TestContext _) + { + DiagnosticHandlerHelperTests.ResetDiagnosticsHandlerHelper(); + } + + private static void ResetDiagnosticsHandlerHelper() + { + //Stop the job + DiagnosticsHandlerHelper helper = DiagnosticsHandlerHelper.GetInstance(); + MethodInfo iMethod = helper.GetType().GetMethod("StopSystemMonitor", BindingFlags.NonPublic | BindingFlags.Instance); + iMethod.Invoke(helper, new object[] { }); + + //Reset the DiagnosticSystemUsageRecorder with original value + FieldInfo DiagnosticSystemUsageRecorderField = typeof(DiagnosticsHandlerHelper).GetField("DiagnosticSystemUsageRecorder", + BindingFlags.Static | + BindingFlags.NonPublic); + DiagnosticSystemUsageRecorderField.SetValue(null, new Documents.Rntbd.SystemUsageRecorder( + identifier: "diagnostic", + historyLength: 6, + refreshInterval: DiagnosticsHandlerHelper.DiagnosticsRefreshInterval)); + + //Reset the instance with original value + FieldInfo field = typeof(DiagnosticsHandlerHelper).GetField("Instance", + BindingFlags.Static | + BindingFlags.NonPublic); + field.SetValue(null, Activator.CreateInstance(typeof(DiagnosticsHandlerHelper), true)); + + } + + [TestMethod] + public void SingletonTest() + { + DiagnosticsHandlerHelper diagnosticHandlerHelper1 = DiagnosticsHandlerHelper.GetInstance(); + DiagnosticsHandlerHelper diagnosticHandlerHelper2 = DiagnosticsHandlerHelper.GetInstance(); + + Assert.IsNotNull(diagnosticHandlerHelper1); + Assert.IsNotNull(diagnosticHandlerHelper2); + Assert.AreEqual(diagnosticHandlerHelper1, diagnosticHandlerHelper2, "Not Singleton"); + } + + [TestMethod] + public async Task RefreshTestAsync() + { + // Get default instance of DiagnosticsHandlerHelper with client telemetry disabled (default) + DiagnosticsHandlerHelper diagnosticHandlerHelper1 = DiagnosticsHandlerHelper.GetInstance(); + await Task.Delay(10000); // warm up to make sure there is at least one entry in the history + Assert.IsNotNull(diagnosticHandlerHelper1.GetDiagnosticsSystemHistory()); + Assert.IsNull(diagnosticHandlerHelper1.GetClientTelemetrySystemHistory()); + Assert.IsTrue(diagnosticHandlerHelper1.GetDiagnosticsSystemHistory().Values.Count > 0); + int countBeforeRefresh = diagnosticHandlerHelper1.GetDiagnosticsSystemHistory().Values.Count; + + FieldInfo TelemetrySystemUsageRecorderField1 = typeof(DiagnosticsHandlerHelper).GetField("TelemetrySystemUsageRecorder", + BindingFlags.Static | + BindingFlags.NonPublic); + Assert.IsNull(TelemetrySystemUsageRecorderField1.GetValue(null)); + + // Refresh instance of DiagnosticsHandlerHelper with client telemetry enabled + DiagnosticsHandlerHelper.Refresh(isClientTelemetryEnabled: true); + DiagnosticsHandlerHelper diagnosticHandlerHelper2 = DiagnosticsHandlerHelper.GetInstance(); + Assert.IsNotNull(diagnosticHandlerHelper2.GetDiagnosticsSystemHistory()); + int countAfterRefresh = diagnosticHandlerHelper2.GetDiagnosticsSystemHistory().Values.Count; + + Assert.IsTrue(countBeforeRefresh <= countAfterRefresh, "After Refresh count should be greater than or equal to before refresh count"); + Assert.AreNotEqual(diagnosticHandlerHelper1, diagnosticHandlerHelper2); + + await Task.Delay(5000); // warm up to make sure there is at least one entry in the history + Assert.IsNotNull(diagnosticHandlerHelper2.GetClientTelemetrySystemHistory()); + + Assert.IsTrue(diagnosticHandlerHelper2.GetClientTelemetrySystemHistory().Values.Count > 0); + + // Refresh instance of DiagnosticsHandlerHelper with client telemetry disabled + DiagnosticsHandlerHelper.Refresh(isClientTelemetryEnabled: false); + DiagnosticsHandlerHelper diagnosticHandlerHelper3 = DiagnosticsHandlerHelper.GetInstance(); + Assert.IsNotNull(diagnosticHandlerHelper3.GetDiagnosticsSystemHistory()); + Assert.IsNull(diagnosticHandlerHelper3.GetClientTelemetrySystemHistory()); + + FieldInfo TelemetrySystemUsageRecorderField3 = typeof(DiagnosticsHandlerHelper).GetField("TelemetrySystemUsageRecorder", + BindingFlags.Static | + BindingFlags.NonPublic); + Assert.IsNull(TelemetrySystemUsageRecorderField3.GetValue(null)); + } + } +} diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/HandlerTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/HandlerTests.cs index ae5dccd2c8..d3d0e45653 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/HandlerTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/HandlerTests.cs @@ -36,6 +36,7 @@ public void HandlerOrder() { typeof(RequestInvokerHandler), typeof(DiagnosticsHandler), + typeof(TelemetryHandler), typeof(RetryHandler), typeof(RouterHandler) }; @@ -50,29 +51,6 @@ public void HandlerOrder() Assert.IsNull(handler); } - [TestMethod] - public void HandlerOrderIfTelemetryIsEnabled() - { - using CosmosClient client = MockCosmosUtil.CreateMockCosmosClient(enableTelemetry: true); - - Type[] types = new Type[] - { - typeof(RequestInvokerHandler), - typeof(DiagnosticsHandler), - typeof(TelemetryHandler), - typeof(RetryHandler), - typeof(RouterHandler) - }; - - RequestHandler handler = client.RequestHandler; - foreach (Type type in types) - { - Assert.IsTrue(type.Equals(handler.GetType()), $"{type} is not equal to {handler.GetType()}"); - handler = handler.InnerHandler; - } - Assert.IsNull(handler); - } - [TestMethod] public async Task TestPreProcessingHandler() { diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Json/JsonReaderTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Json/JsonReaderTests.cs index 52571f33e9..2f31613d08 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Json/JsonReaderTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Json/JsonReaderTests.cs @@ -2281,9 +2281,9 @@ public void SimpleObjectTest() List elements = new List { - new byte[] { (byte)JsonBinaryEncoding.TypeMarker.UserString2ByteLengthMin, 0 }, + new byte[] { (byte)JsonBinaryEncoding.TypeMarker.UserString1ByteLengthMin }, new byte[] { JsonBinaryEncoding.TypeMarker.LiteralIntMin + 10 }, - new byte[] { (byte)JsonBinaryEncoding.TypeMarker.UserString2ByteLengthMin, 1 }, + new byte[] { (byte)(JsonBinaryEncoding.TypeMarker.UserString1ByteLengthMin + 1) }, new byte[] { (byte)(JsonBinaryEncoding.TypeMarker.EncodedStringLengthMin + "example glossary".Length), 101, 120, 97, 109, 112, 108, 101, 32, 103, 108, 111, 115, 115, 97, 114, 121 } }; byte[] elementsBytes = elements.SelectMany(x => x).ToArray(); @@ -2405,25 +2405,25 @@ public void AllPrimitivesObjectTest() new byte[] { (byte)(JsonBinaryEncoding.TypeMarker.SystemString1ByteLengthMin + 12) }, new byte[] { (byte)(JsonBinaryEncoding.TypeMarker.EncodedStringLengthMin + "7029d079-4016-4436-b7da-36c0bae54ff6".Length), 55, 48, 50, 57, 100, 48, 55, 57, 45, 52, 48, 49, 54, 45, 52, 52, 51, 54, 45, 98, 55, 100, 97, 45, 51, 54, 99, 48, 98, 97, 101, 53, 52, 102, 102, 54 }, - new byte[] { (byte)JsonBinaryEncoding.TypeMarker.UserString2ByteLengthMin, 0 }, + new byte[] { (byte)JsonBinaryEncoding.TypeMarker.UserString1ByteLengthMin }, new byte[] { JsonBinaryEncoding.TypeMarker.NumberDouble, 0x98, 0x8B, 0x30, 0xE3, 0xCB, 0x45, 0xC8, 0x3F }, - new byte[] { (byte)JsonBinaryEncoding.TypeMarker.UserString2ByteLengthMin, 1 }, + new byte[] { (byte)(JsonBinaryEncoding.TypeMarker.UserString1ByteLengthMin + 1) }, new byte[] { JsonBinaryEncoding.TypeMarker.NumberInt32, 0x19, 0xDF, 0xB6, 0xB0 }, - new byte[] { (byte)JsonBinaryEncoding.TypeMarker.UserString2ByteLengthMin, 2 }, + new byte[] { (byte)(JsonBinaryEncoding.TypeMarker.UserString1ByteLengthMin + 2) }, new byte[] { (byte)(JsonBinaryEncoding.TypeMarker.EncodedStringLengthMin + "XCPCFXPHHF".Length), 88, 67, 80, 67, 70, 88, 80, 72, 72, 70 }, - new byte[] { (byte)JsonBinaryEncoding.TypeMarker.UserString2ByteLengthMin, 3 }, + new byte[] { (byte)(JsonBinaryEncoding.TypeMarker.UserString1ByteLengthMin + 3) }, new byte[] { JsonBinaryEncoding.TypeMarker.True }, - new byte[] { (byte)JsonBinaryEncoding.TypeMarker.UserString2ByteLengthMin, 4 }, + new byte[] { (byte)(JsonBinaryEncoding.TypeMarker.UserString1ByteLengthMin + 4) }, new byte[] { JsonBinaryEncoding.TypeMarker.Null }, - new byte[] { (byte)JsonBinaryEncoding.TypeMarker.UserString2ByteLengthMin, 5 }, + new byte[] { (byte)(JsonBinaryEncoding.TypeMarker.UserString1ByteLengthMin + 5) }, new byte[] { (byte)(JsonBinaryEncoding.TypeMarker.EncodedStringLengthMin + "2526-07-11T18:18:16.4520716".Length), 50, 53, 50, 54, 45, 48, 55, 45, 49, 49, 84, 49, 56, 58, 49, 56, 58, 49, 54, 46, 52, 53, 50, 48, 55, 49, 54 }, - new byte[] { (byte)JsonBinaryEncoding.TypeMarker.UserString2ByteLengthMin, 6 } + new byte[] { (byte)(JsonBinaryEncoding.TypeMarker.UserString1ByteLengthMin + 6) } }; List innerObjectElements = new List @@ -2447,7 +2447,7 @@ public void AllPrimitivesObjectTest() elements.Add(new byte[] { JsonBinaryEncoding.TypeMarker.Object1ByteLength, (byte)innerObjectElementsBytes.Length }); elements.Add(innerObjectElementsBytes); - elements.Add(new byte[] { (byte)JsonBinaryEncoding.TypeMarker.UserString2ByteLengthMin, 7 }); + elements.Add(new byte[] { (byte)(JsonBinaryEncoding.TypeMarker.UserString1ByteLengthMin + 7) }); elements.Add(new byte[] { JsonBinaryEncoding.TypeMarker.String1ByteLength, (byte)"tiger diamond newbrunswick snowleopard chocolate dog snowleopard turtle cat sapphire peach sapphire vancouver white chocolate horse diamond lion superlongcolourname ruby".Length, 116, 105, 103, 101, 114, 32, 100, 105, 97, 109, 111, 110, 100, 32, 110, 101, 119, 98, 114, 117, 110, 115, 119, 105, 99, 107, 32, 115, 110, 111, 119, 108, 101, 111, 112, 97, 114, 100, 32, 99, 104, 111, 99, 111, 108, 97, 116, 101, 32, 100, 111, 103, 32, 115, 110, 111, 119, 108, 101, 111, 112, 97, 114, 100, 32, 116, 117, 114, 116, 108, 101, 32, 99, 97, 116, 32, 115, 97, 112, 112, 104, 105, 114, 101, 32, 112, 101, 97, 99, 104, 32, 115, 97, 112, 112, 104, 105, 114, 101, 32, 118, 97, 110, 99, 111, 117, 118, 101, 114, 32, 119, 104, 105, 116, 101, 32, 99, 104, 111, 99, 111, 108, 97, 116, 101, 32, 104, 111, 114, 115, 101, 32, 100, 105, 97, 109, 111, 110, 100, 32, 108, 105, 111, 110, 32, 115, 117, 112, 101, 114, 108, 111, 110, 103, 99, 111, 108, 111, 117, 114, 110, 97, 109, 101, 32, 114, 117, 98, 121 }); byte[] elementsBytes = elements.SelectMany(x => x).ToArray(); diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Json/JsonWriterTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Json/JsonWriterTests.cs index b44cb49b1f..0997b4dfd2 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Json/JsonWriterTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Json/JsonWriterTests.cs @@ -2353,9 +2353,9 @@ public void SimpleObjectTest() List elements = new List { - new byte[] { (byte)JsonBinaryEncoding.TypeMarker.UserString2ByteLengthMin, 0 }, + new byte[] { (byte)JsonBinaryEncoding.TypeMarker.UserString1ByteLengthMin }, new byte[] { JsonBinaryEncoding.TypeMarker.LiteralIntMin + 10 }, - new byte[] { (byte)JsonBinaryEncoding.TypeMarker.UserString2ByteLengthMin, 1 }, + new byte[] { (byte)(JsonBinaryEncoding.TypeMarker.UserString1ByteLengthMin + 1) }, new byte[] { (byte)(JsonBinaryEncoding.TypeMarker.EncodedStringLengthMin + "example glossary".Length), 101, 120, 97, 109, 112, 108, 101, 32, 103, 108, 111, 115, 115, 97, 114, 121 } }; byte[] elementsBytes = elements.SelectMany(x => x).ToArray(); @@ -2484,25 +2484,25 @@ public void AllPrimitivesObjectTest() new byte[] { (byte)(JsonBinaryEncoding.TypeMarker.SystemString1ByteLengthMin + 12) }, new byte[] { JsonBinaryEncoding.TypeMarker.LowercaseGuidString, 0x07, 0x92, 0x0D, 0x97, 0x04, 0x61, 0x44, 0x63, 0x7B, 0xAD, 0x63, 0x0C, 0xAB, 0x5E, 0xF4, 0x6F }, - new byte[] { (byte)JsonBinaryEncoding.TypeMarker.UserString2ByteLengthMin, 0 }, + new byte[] { (byte)JsonBinaryEncoding.TypeMarker.UserString1ByteLengthMin }, new byte[] { JsonBinaryEncoding.TypeMarker.NumberDouble, 0x98, 0x8B, 0x30, 0xE3, 0xCB, 0x45, 0xC8, 0x3F }, - new byte[] { (byte)JsonBinaryEncoding.TypeMarker.UserString2ByteLengthMin, 1 }, + new byte[] { (byte)(JsonBinaryEncoding.TypeMarker.UserString1ByteLengthMin + 1) }, new byte[] { JsonBinaryEncoding.TypeMarker.NumberInt32, 0x19, 0xDF, 0xB6, 0xB0 }, - new byte[] { (byte)JsonBinaryEncoding.TypeMarker.UserString2ByteLengthMin, 2 }, + new byte[] { (byte)(JsonBinaryEncoding.TypeMarker.UserString1ByteLengthMin + 2) }, new byte[] { (byte)(JsonBinaryEncoding.TypeMarker.EncodedStringLengthMin + "XCPCFXPHHF".Length), 88, 67, 80, 67, 70, 88, 80, 72, 72, 70 }, - new byte[] { (byte)JsonBinaryEncoding.TypeMarker.UserString2ByteLengthMin, 3 }, + new byte[] { (byte)(JsonBinaryEncoding.TypeMarker.UserString1ByteLengthMin + 3) }, new byte[] { JsonBinaryEncoding.TypeMarker.True }, - new byte[] { (byte)JsonBinaryEncoding.TypeMarker.UserString2ByteLengthMin, 4 }, + new byte[] { (byte)(JsonBinaryEncoding.TypeMarker.UserString1ByteLengthMin + 4) }, new byte[] { JsonBinaryEncoding.TypeMarker.Null }, - new byte[] { (byte)JsonBinaryEncoding.TypeMarker.UserString2ByteLengthMin, 5 }, + new byte[] { (byte)(JsonBinaryEncoding.TypeMarker.UserString1ByteLengthMin + 5) }, new byte[] { JsonBinaryEncoding.TypeMarker.CompressedDateTimeString, 0x1B, 0x63, 0x73, 0x1C, 0xC8, 0x22, 0x2E, 0xB9, 0x92, 0x2B, 0xD7, 0x65, 0x13, 0x28, 0x07 }, - new byte[] { (byte)JsonBinaryEncoding.TypeMarker.UserString2ByteLengthMin, 6 } + new byte[] { (byte)(JsonBinaryEncoding.TypeMarker.UserString1ByteLengthMin + 6) } }; List innerObjectElements = new List @@ -2526,7 +2526,7 @@ public void AllPrimitivesObjectTest() elements.Add(new byte[] { JsonBinaryEncoding.TypeMarker.Object1ByteLength, (byte)innerObjectElementsBytes.Length }); elements.Add(innerObjectElementsBytes); - elements.Add(new byte[] { (byte)JsonBinaryEncoding.TypeMarker.UserString2ByteLengthMin, 7 }); + elements.Add(new byte[] { (byte)(JsonBinaryEncoding.TypeMarker.UserString1ByteLengthMin + 7) }); elements.Add(new byte[] { JsonBinaryEncoding.TypeMarker.Packed7BitStringLength1, (byte)"tiger diamond newbrunswick snowleopard chocolate dog snowleopard turtle cat sapphire peach sapphire vancouver white chocolate horse diamond lion superlongcolourname ruby".Length, 0xF4, 0xF4, 0xB9, 0x2C, 0x07, 0x91, 0xD3, 0xE1, 0xF6, 0xDB, 0x4D, 0x06, 0xB9, 0xCB, 0x77, 0xB1, 0xBC, 0xEE, 0x9E, 0xDF, 0xD3, 0xE3, 0x35, 0x68, 0xEE, 0x7E, 0xDF, 0xD9, 0xE5, 0x37, 0x3C, 0x2C, 0x27, 0x83, 0xC6, 0xE8, 0xF7, 0xF8, 0xCD, 0x0E, 0xD3, 0xCB, 0x20, 0xF2, 0xFB, 0x0C, 0x9A, 0xBB, 0xDF, 0x77, 0x76, 0xF9, 0x0D, 0x0F, 0xCB, 0xC9, 0x20, 0x7A, 0x5D, 0x4E, 0x67, 0x97, 0x41, 0xE3, 0x30, 0x1D, 0x34, 0x0F, 0xC3, 0xE1, 0xE8, 0xB4, 0xBC, 0x0C, 0x82, 0x97, 0xC3, 0x63, 0x34, 0x68, 0x1E, 0x86, 0xC3, 0xD1, 0x69, 0x79, 0x19, 0x64, 0x0F, 0xBB, 0xC7, 0xEF, 0xBA, 0xBD, 0x2C, 0x07, 0xDD, 0xD1, 0x69, 0x7A, 0x19, 0x34, 0x46, 0xBF, 0xC7, 0x6F, 0x76, 0x98, 0x5E, 0x06, 0xA1, 0xDF, 0xF2, 0x79, 0x19, 0x44, 0x4E, 0x87, 0xDB, 0x6F, 0x37, 0x19, 0xC4, 0x4E, 0xBF, 0xDD, 0xA0, 0x79, 0x1D, 0x5E, 0x96, 0xB3, 0xDF, 0xEE, 0xF3, 0xF8, 0xCD, 0x7E, 0xD7, 0xE5, 0xEE, 0x70, 0xBB, 0x0C, 0x92, 0xD7, 0xC5, 0x79 }); byte[] elementsBytes = elements.SelectMany(x => x).ToArray(); diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Microsoft.Azure.Cosmos.Tests.csproj b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Microsoft.Azure.Cosmos.Tests.csproj index c867b0f003..e1dbbe8030 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Microsoft.Azure.Cosmos.Tests.csproj +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Microsoft.Azure.Cosmos.Tests.csproj @@ -78,9 +78,15 @@ + + PreserveNewest + PreserveNewest + + PreserveNewest + PreserveNewest @@ -114,6 +120,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Pagination/InMemoryContainer.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Pagination/InMemoryContainer.cs index f2201d3cc4..5c6e8961e7 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Pagination/InMemoryContainer.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Pagination/InMemoryContainer.cs @@ -31,6 +31,7 @@ namespace Microsoft.Azure.Cosmos.Tests.Pagination using Microsoft.Azure.Cosmos.Tracing; using Microsoft.Azure.Documents; using ResourceIdentifier = Cosmos.Pagination.ResourceIdentifier; + using UInt128 = UInt128; // Collection useful for mocking requests and repartitioning (splits / merge). internal class InMemoryContainer : IMonadicDocumentContainer @@ -280,8 +281,8 @@ static Task> CreateNotFoundException(CosmosElement partitionKey requestCharge: 42))); } - PartitionKeyHash partitionKeyHash = GetHashFromPartitionKey( - partitionKey, + PartitionKeyHash partitionKeyHash = GetHashFromPartitionKeys( + new List { partitionKey }, this.partitionKeyDefinition); if (!this.partitionedRecords.TryGetValue(partitionKeyHash, out Records records)) @@ -797,9 +798,20 @@ public Task MonadicSplitAsync( } // Split the range space - PartitionKeyHashRanges partitionKeyHashRanges = PartitionKeyHashRangeSplitterAndMerger.SplitRange( - parentRange, - rangeCount: 2); + PartitionKeyHashRanges partitionKeyHashRanges; + if (this.partitionKeyDefinition.Kind == PartitionKind.MultiHash && + this.partitionKeyDefinition.Paths.Count > 1) + { + //For MultiHash, to help with testing we will split using the median partition key among documents. + PartitionKeyHash midPoint = this.ComputeMedianSplitPointAmongDocumentsInPKRange(parentRange); + partitionKeyHashRanges = PartitionKeyHashRangeSplitterAndMerger.SplitRange(parentRange, midPoint); + } + else + { + partitionKeyHashRanges = PartitionKeyHashRangeSplitterAndMerger.SplitRange( + parentRange, + rangeCount: 2); + } // Update the partition routing map int maxPartitionKeyRangeId = this.partitionKeyRangeIdToHashRange.Keys.Max(); @@ -1084,16 +1096,16 @@ private static PartitionKeyHash GetHashFromPayload( CosmosObject payload, PartitionKeyDefinition partitionKeyDefinition) { - CosmosElement partitionKey = GetPartitionKeyFromPayload(payload, partitionKeyDefinition); - return GetHashFromPartitionKey(partitionKey, partitionKeyDefinition); + IList partitionKey = GetPartitionKeysFromPayload(payload, partitionKeyDefinition); + return GetHashFromPartitionKeys(partitionKey, partitionKeyDefinition); } private static PartitionKeyHash GetHashFromObjectModel( Cosmos.PartitionKey payload, PartitionKeyDefinition partitionKeyDefinition) { - CosmosElement partitionKey = GetPartitionKeyFromObjectModel(payload); - return GetHashFromPartitionKey(partitionKey, partitionKeyDefinition); + IList partitionKeys = GetPartitionKeysFromObjectModel(payload); + return GetHashFromPartitionKeys(partitionKeys, partitionKeyDefinition); } private static CosmosElement GetPartitionKeyFromPayload(CosmosObject payload, PartitionKeyDefinition partitionKeyDefinition) @@ -1131,23 +1143,56 @@ private static CosmosElement GetPartitionKeyFromPayload(CosmosObject payload, Pa return partitionKey; } - private static CosmosElement GetPartitionKeyFromObjectModel(Cosmos.PartitionKey payload) + private static IList GetPartitionKeysFromPayload(CosmosObject payload, PartitionKeyDefinition partitionKeyDefinition) { - CosmosArray partitionKeyPayload = CosmosArray.Parse(payload.ToJsonString()); - if (partitionKeyPayload.Count != 1) + // Restrict the partition key definition for now to keep things simple + if (partitionKeyDefinition.Kind != PartitionKind.MultiHash && partitionKeyDefinition.Kind != PartitionKind.Hash) { - throw new ArgumentOutOfRangeException("Can only support a single partition key path."); + throw new ArgumentOutOfRangeException("Can only support Hash/MultiHash partitioning"); + } + + if (partitionKeyDefinition.Version != Documents.PartitionKeyDefinitionVersion.V2) + { + throw new ArgumentOutOfRangeException("Can only support hash v2"); + } + + IList cosmosElements = new List(); + foreach (string partitionKeyPath in partitionKeyDefinition.Paths) + { + IEnumerable tokens = partitionKeyPath.Split("/").Skip(1); + CosmosElement partitionKey = payload; + foreach (string token in tokens) + { + if (partitionKey != default) + { + if (!payload.TryGetValue(token, out partitionKey)) + { + partitionKey = default; + } + } + } + cosmosElements.Add(partitionKey); } + return cosmosElements; + } - return partitionKeyPayload[0]; + private static IList GetPartitionKeysFromObjectModel(Cosmos.PartitionKey payload) + { + CosmosArray partitionKeyPayload = CosmosArray.Parse(payload.ToJsonString()); + List cosmosElemementPayload = new List(); + foreach (CosmosElement element in partitionKeyPayload) + { + cosmosElemementPayload.Add(element); + } + return cosmosElemementPayload; } - private static PartitionKeyHash GetHashFromPartitionKey(CosmosElement partitionKey, PartitionKeyDefinition partitionKeyDefinition) + private static PartitionKeyHash GetHashFromPartitionKeys(IList partitionKeys, PartitionKeyDefinition partitionKeyDefinition) { // Restrict the partition key definition for now to keep things simple - if (partitionKeyDefinition.Kind != PartitionKind.Hash) + if (partitionKeyDefinition.Kind != PartitionKind.MultiHash && partitionKeyDefinition.Kind != PartitionKind.Hash) { - throw new ArgumentOutOfRangeException("Can only support hash partitioning"); + throw new ArgumentOutOfRangeException("Can only support Hash/MultiHash partitioning"); } if (partitionKeyDefinition.Version != Documents.PartitionKeyDefinitionVersion.V2) @@ -1155,21 +1200,41 @@ private static PartitionKeyHash GetHashFromPartitionKey(CosmosElement partitionK throw new ArgumentOutOfRangeException("Can only support hash v2"); } - if (partitionKeyDefinition.Paths.Count != 1) + IList partitionKeyHashValues = new List(); + + foreach (CosmosElement partitionKey in partitionKeys) { - throw new ArgumentOutOfRangeException("Can only support a single partition key path."); + if (partitionKey is CosmosArray cosmosArray) + { + foreach (CosmosElement element in cosmosArray) + { + PartitionKeyHash elementHash = element switch + { + null => PartitionKeyHash.V2.HashUndefined(), + CosmosString stringPartitionKey => PartitionKeyHash.V2.Hash(stringPartitionKey.Value), + CosmosNumber numberPartitionKey => PartitionKeyHash.V2.Hash(Number64.ToDouble(numberPartitionKey.Value)), + CosmosBoolean cosmosBoolean => PartitionKeyHash.V2.Hash(cosmosBoolean.Value), + CosmosNull _ => PartitionKeyHash.V2.HashNull(), + _ => throw new ArgumentOutOfRangeException(), + }; + partitionKeyHashValues.Add(elementHash.HashValues[0]); + } + continue; + } + + PartitionKeyHash partitionKeyHash = partitionKey switch + { + null => PartitionKeyHash.V2.HashUndefined(), + CosmosString stringPartitionKey => PartitionKeyHash.V2.Hash(stringPartitionKey.Value), + CosmosNumber numberPartitionKey => PartitionKeyHash.V2.Hash(Number64.ToDouble(numberPartitionKey.Value)), + CosmosBoolean cosmosBoolean => PartitionKeyHash.V2.Hash(cosmosBoolean.Value), + CosmosNull _ => PartitionKeyHash.V2.HashNull(), + _ => throw new ArgumentOutOfRangeException(), + }; + partitionKeyHashValues.Add(partitionKeyHash.HashValues[0]); } - PartitionKeyHash partitionKeyHash = partitionKey switch - { - null => PartitionKeyHash.V2.HashUndefined(), - CosmosString stringPartitionKey => PartitionKeyHash.V2.Hash(stringPartitionKey.Value), - CosmosNumber numberPartitionKey => PartitionKeyHash.V2.Hash(Number64.ToDouble(numberPartitionKey.Value)), - CosmosBoolean cosmosBoolean => PartitionKeyHash.V2.Hash(cosmosBoolean.Value), - CosmosNull _ => PartitionKeyHash.V2.HashNull(), - _ => throw new ArgumentOutOfRangeException(), - }; - return partitionKeyHash; + return new PartitionKeyHash(partitionKeyHashValues.ToArray()); } private static CosmosObject ConvertRecordToCosmosElement(Record record) @@ -1196,9 +1261,16 @@ private static bool IsRecordWithinFeedRange( { if (feedRange is FeedRangePartitionKey feedRangePartitionKey) { - CosmosElement partitionKey = GetPartitionKeyFromObjectModel(feedRangePartitionKey.PartitionKey); - CosmosElement partitionKeyFromRecord = GetPartitionKeyFromPayload(record.Payload, partitionKeyDefinition); - return partitionKey.Equals(partitionKeyFromRecord); + IList partitionKey = GetPartitionKeysFromObjectModel(feedRangePartitionKey.PartitionKey); + IList partitionKeyFromRecord = GetPartitionKeysFromPayload(record.Payload, partitionKeyDefinition); + if (partitionKeyDefinition.Kind == PartitionKind.MultiHash) + { + PartitionKeyHash partitionKeyHash = GetHashFromPartitionKeys(partitionKey, partitionKeyDefinition); + PartitionKeyHash partitionKeyFromRecordHash = GetHashFromPartitionKeys(partitionKeyFromRecord, partitionKeyDefinition); + + return partitionKeyHash.Equals(partitionKeyFromRecordHash) || partitionKeyFromRecordHash.Value.StartsWith(partitionKeyHash.Value); + } + return partitionKey.SequenceEqual(partitionKeyFromRecord); } else if (feedRange is FeedRangeEpk feedRangeEpk) { @@ -1301,6 +1373,32 @@ private static FeedRangeEpk HashRangeToFeedRangeEpk(PartitionKeyHashRange hashRa isMaxInclusive: false)); } + private PartitionKeyHash ComputeMedianSplitPointAmongDocumentsInPKRange(PartitionKeyHashRange hashRange) + { + if (!this.partitionedRecords.TryGetValue(hashRange, out Records parentRecords)) + { + throw new InvalidOperationException("failed to find the range."); + } + + List partitionKeyHashes = new List(); + foreach (Record record in parentRecords) + { + PartitionKeyHash partitionKeyHash = GetHashFromPayload(record.Payload, this.partitionKeyDefinition); + partitionKeyHashes.Add(partitionKeyHash); + } + + partitionKeyHashes.Sort(); + PartitionKeyHash medianPkHash = partitionKeyHashes[partitionKeyHashes.Count / 2]; + + // For MultiHash Collection, split at top level to ensure documents for top level key exist across partitions + // after split + if (medianPkHash.HashValues.Count > 1) + { + return new PartitionKeyHash(medianPkHash.HashValues[0]); + } + + return medianPkHash; + } public Task> MonadicGetResourceIdentifierAsync(ITrace trace, CancellationToken cancellationToken) { return Task.FromResult(TryCatch.FromResult("AYIMAMmFOw8YAAAAAAAAAA==")); @@ -1516,4 +1614,4 @@ public SqlScalarExpression Visit(CosmosUndefined cosmosUndefined) } } } -} +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/ClientDistributionPlanBaselineTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/ClientDistributionPlanBaselineTests.cs new file mode 100644 index 0000000000..845f71d25e --- /dev/null +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/ClientDistributionPlanBaselineTests.cs @@ -0,0 +1,100 @@ +namespace Microsoft.Azure.Cosmos.Tests.Query +{ + using System.Collections.Generic; + using System.Xml; + using Microsoft.Azure.Cosmos.Query.Core.ClientDistributionPlan; + using Microsoft.Azure.Cosmos.Query.Core.ClientDistributionPlan.Cql; + using Microsoft.Azure.Cosmos.Test.BaselineTest; + using Microsoft.VisualStudio.TestTools.UnitTesting; + using Newtonsoft.Json; + using Newtonsoft.Json.Linq; + + [TestClass] + public class ClientDistributionPlanBaselineTests : BaselineTests + { + [TestMethod] + [Owner("akotalwar")] + public void TestClientDistributionPlanDeserialization() + { + List testVariations = new List + { + CreateInput( + description: @"Input Expression", + clientPlanJson: "{\"clientDistributionPlan\": {\"Cql\": {\"Kind\": \"Input\",\"Name\": \"root\"}}}"), + + CreateInput( + description: @"Aggregate and ObjectCreate Expressions", + clientPlanJson: "{\"clientDistributionPlan\": {\"Cql\": {\"Kind\": \"Select\",\"DeclaredVariable\": {\"Name\": \"v0\",\"UniqueId\": 6},\"Expression\": {\"Kind\": \"ObjectCreate\",\"ObjectKind\": \"Object\",\"Properties\": [{\"Name\": \"count_a\",\"Expression\": {\"Kind\": \"VariableRef\",\"Variable\": {\"Name\": \"v0\",\"UniqueId\": 6}}}]},\"SourceExpression\": {\"Kind\": \"Aggregate\",\"Aggregate\": {\"Kind\": \"Builtin\",\"OperatorKind\": \"Sum\"},\"SourceExpression\": {\"Kind\": \"Input\",\"Name\": \"root\"}}}}}"), + + CreateInput( + description: @"Select, Aggregate and BinaryOperator Expressions", + clientPlanJson: "{\"clientDistributionPlan\": {\"Cql\": { \"Kind\": \"Select\", \"DeclaredVariable\": {\"Name\": \"v0\",\"UniqueId\": 10 }, \"Expression\": {\"Kind\": \"ObjectCreate\",\"ObjectKind\": \"Object\",\"Properties\": [ {\"Name\": \"F1\",\"Expression\": { \"Kind\": \"ObjectCreate\", \"ObjectKind\": \"Object\", \"Properties\": [{ \"Name\": \"FieldA\", \"Expression\": {\"Kind\": \"TupleItemRef\",\"Expression\": { \"Kind\": \"VariableRef\", \"Variable\": {\"Name\": \"v0\",\"UniqueId\": 10 }},\"Index\": 0 }},{ \"Name\": \"FieldSum\", \"Expression\": {\"Kind\": \"TupleItemRef\",\"Expression\": { \"Kind\": \"VariableRef\", \"Variable\": {\"Name\": \"v0\",\"UniqueId\": 10 }},\"Index\": 1 }},{ \"Name\": \"FieldAvg\", \"Expression\": {\"Kind\": \"Mux\",\"ConditionExpression\": { \"Kind\": \"BinaryOperator\", \"OperatorKind\": \"Equal\", \"LeftExpression\": {\"Kind\": \"TupleItemRef\",\"Expression\": { \"Kind\": \"TupleItemRef\", \"Expression\": {\"Kind\": \"VariableRef\",\"Variable\": { \"Name\": \"v0\", \"UniqueId\": 10} }, \"Index\": 2},\"Index\": 1 }, \"RightExpression\": {\"Kind\": \"Literal\",\"Literal\": { \"Kind\": \"Number\", \"Value\": 0} }},\"LeftExpression\": { \"Kind\": \"Literal\", \"Literal\": {\"Kind\": \"Undefined\" }},\"RightExpression\": { \"Kind\": \"BinaryOperator\", \"OperatorKind\": \"Divide\", \"LeftExpression\": {\"Kind\": \"TupleItemRef\",\"Expression\": { \"Kind\": \"TupleItemRef\", \"Expression\": {\"Kind\": \"VariableRef\",\"Variable\": { \"Name\": \"v0\", \"UniqueId\": 10} }, \"Index\": 2},\"Index\": 0 }, \"RightExpression\": {\"Kind\": \"TupleItemRef\",\"Expression\": { \"Kind\": \"TupleItemRef\", \"Expression\": {\"Kind\": \"VariableRef\",\"Variable\": { \"Name\": \"v0\", \"UniqueId\": 10} }, \"Index\": 2},\"Index\": 1 }}}}]}}, {\"Name\": \"F2\",\"Expression\": { \"Kind\": \"ObjectCreate\", \"ObjectKind\": \"Object\", \"Properties\": [{ \"Name\": \"OtherFieldA\", \"Expression\": {\"Kind\": \"TupleItemRef\",\"Expression\": { \"Kind\": \"VariableRef\", \"Variable\": {\"Name\": \"v0\",\"UniqueId\": 10 }},\"Index\": 0 }},{ \"Name\": \"OtherFieldMax\", \"Expression\": {\"Kind\": \"TupleItemRef\",\"Expression\": { \"Kind\": \"VariableRef\", \"Variable\": {\"Name\": \"v0\",\"UniqueId\": 10 }},\"Index\": 3 }} ]} }] }, \"SourceExpression\": {\"Kind\": \"GroupBy\",\"KeyCount\": 1,\"Aggregates\": [ {\"Kind\": \"Builtin\",\"OperatorKind\": \"Sum\" }, {\"Kind\": \"Tuple\",\"Items\": [ {\"Kind\": \"Builtin\",\"OperatorKind\": \"Sum\" }, {\"Kind\": \"Builtin\",\"OperatorKind\": \"Sum\" }] }, {\"Kind\": \"Builtin\",\"OperatorKind\": \"Max\" }],\"SourceExpression\": { \"Kind\": \"Select\", \"DeclaredVariable\": {\"Name\": \"v0\",\"UniqueId\": 16 }, \"Expression\": {\"Kind\": \"TupleCreate\",\"Items\": [ {\"Kind\": \"TupleItemRef\",\"Expression\": { \"Kind\": \"VariableRef\", \"Variable\": {\"Name\": \"v0\",\"UniqueId\": 16 }},\"Index\": 0 }, {\"Kind\": \"Mux\",\"ConditionExpression\": { \"Kind\": \"BinaryOperator\", \"OperatorKind\": \"And\", \"LeftExpression\": {\"Kind\": \"BinaryOperator\",\"OperatorKind\": \"NotEqual\",\"LeftExpression\": { \"Kind\": \"TupleItemRef\", \"Expression\": {\"Kind\": \"TupleItemRef\",\"Expression\": { \"Kind\": \"VariableRef\", \"Variable\": {\"Name\": \"v0\",\"UniqueId\": 16 }},\"Index\": 1 }, \"Index\": 1},\"RightExpression\": { \"Kind\": \"Literal\", \"Literal\": {\"Kind\": \"Number\",\"Value\": 0 }} }, \"RightExpression\": {\"Kind\": \"UnaryOperator\",\"OperatorKind\": \"Not\",\"Expression\": { \"Kind\": \"SystemFunctionCall\", \"FunctionKind\": \"Is_Defined\", \"Arguments\": [{ \"Kind\": \"TupleItemRef\", \"Expression\": {\"Kind\": \"TupleItemRef\",\"Expression\": { \"Kind\": \"VariableRef\", \"Variable\": {\"Name\": \"v0\",\"UniqueId\": 16 }},\"Index\": 1 }, \"Index\": 0} ]} }},\"LeftExpression\": { \"Kind\": \"Literal\", \"Literal\": {\"Kind\": \"Array\",\"Items\": [] }},\"RightExpression\": { \"Kind\": \"TupleItemRef\", \"Expression\": {\"Kind\": \"TupleItemRef\",\"Expression\": { \"Kind\": \"VariableRef\", \"Variable\": {\"Name\": \"v0\",\"UniqueId\": 16 }},\"Index\": 1 }, \"Index\": 0} }, {\"Kind\": \"TupleCreate\",\"Items\": [ {\"Kind\": \"Mux\",\"ConditionExpression\": { \"Kind\": \"BinaryOperator\", \"OperatorKind\": \"And\", \"LeftExpression\": {\"Kind\": \"BinaryOperator\",\"OperatorKind\": \"NotEqual\",\"LeftExpression\": { \"Kind\": \"TupleItemRef\", \"Expression\": {\"Kind\": \"TupleItemRef\",\"Expression\": { \"Kind\": \"TupleItemRef\", \"Expression\": {\"Kind\": \"VariableRef\",\"Variable\": { \"Name\": \"v0\", \"UniqueId\": 16} }, \"Index\": 2},\"Index\": 0 }, \"Index\": 1},\"RightExpression\": { \"Kind\": \"Literal\", \"Literal\": {\"Kind\": \"Number\",\"Value\": 0 }} }, \"RightExpression\": {\"Kind\": \"UnaryOperator\",\"OperatorKind\": \"Not\",\"Expression\": { \"Kind\": \"SystemFunctionCall\", \"FunctionKind\": \"Is_Defined\", \"Arguments\": [{ \"Kind\": \"TupleItemRef\", \"Expression\": {\"Kind\": \"TupleItemRef\",\"Expression\": { \"Kind\": \"TupleItemRef\", \"Expression\": {\"Kind\": \"VariableRef\",\"Variable\": { \"Name\": \"v0\", \"UniqueId\": 16} }, \"Index\": 2},\"Index\": 0 }, \"Index\": 0} ]} }},\"LeftExpression\": { \"Kind\": \"Literal\", \"Literal\": {\"Kind\": \"Array\",\"Items\": [] }},\"RightExpression\": { \"Kind\": \"TupleItemRef\", \"Expression\": {\"Kind\": \"TupleItemRef\",\"Expression\": { \"Kind\": \"VariableRef\", \"Variable\": {\"Name\": \"v0\",\"UniqueId\": 16 }},\"Index\": 2 }, \"Index\": 0} }, {\"Kind\": \"TupleItemRef\",\"Expression\": { \"Kind\": \"TupleItemRef\", \"Expression\": {\"Kind\": \"VariableRef\",\"Variable\": { \"Name\": \"v0\", \"UniqueId\": 16} }, \"Index\": 2},\"Index\": 1 }] }, {\"Kind\": \"Mux\",\"ConditionExpression\": { \"Kind\": \"BinaryOperator\", \"OperatorKind\": \"And\", \"LeftExpression\": {\"Kind\": \"BinaryOperator\",\"OperatorKind\": \"NotEqual\",\"LeftExpression\": { \"Kind\": \"TupleItemRef\", \"Expression\": {\"Kind\": \"TupleItemRef\",\"Expression\": { \"Kind\": \"VariableRef\", \"Variable\": {\"Name\": \"v0\",\"UniqueId\": 16 }},\"Index\": 3 }, \"Index\": 1},\"RightExpression\": { \"Kind\": \"Literal\", \"Literal\": {\"Kind\": \"Number\",\"Value\": 0 }} }, \"RightExpression\": {\"Kind\": \"UnaryOperator\",\"OperatorKind\": \"Not\",\"Expression\": { \"Kind\": \"SystemFunctionCall\", \"FunctionKind\": \"Is_Defined\", \"Arguments\": [{ \"Kind\": \"TupleItemRef\", \"Expression\": {\"Kind\": \"TupleItemRef\",\"Expression\": { \"Kind\": \"VariableRef\", \"Variable\": {\"Name\": \"v0\",\"UniqueId\": 16 }},\"Index\": 3 }, \"Index\": 0} ]} }},\"LeftExpression\": { \"Kind\": \"Literal\", \"Literal\": {\"Kind\": \"Array\",\"Items\": [] }},\"RightExpression\": { \"Kind\": \"TupleItemRef\", \"Expression\": {\"Kind\": \"TupleItemRef\",\"Expression\": { \"Kind\": \"VariableRef\", \"Variable\": {\"Name\": \"v0\",\"UniqueId\": 16}},\"Index\": 3}, \"Index\": 0}}]}, \"SourceExpression\": {\"Kind\": \"Input\",\"Name\": \"root\"}}}}}}"), + + CreateInput( + description: @"Select, Sum and VariableRef Expressions", + clientPlanJson: "{\"clientDistributionPlan\": {\"Cql\": {\"Kind\": \"Select\",\"DeclaredVariable\": {\"Name\": \"v0\",\"UniqueId\": 6},\"Expression\": {\"Kind\": \"ObjectCreate\",\"ObjectKind\": \"Object\",\"Properties\": [{\"Name\": \"count_a_plus_five\",\"Expression\": {\"Kind\": \"BinaryOperator\",\"OperatorKind\": \"Add\",\"LeftExpression\": {\"Kind\": \"VariableRef\",\"Variable\": {\"Name\": \"v0\",\"UniqueId\": 6 }}, \"RightExpression\": { \"Kind\": \"Literal\", \"Literal\": { \"Kind\": \"Number\", \"Value\": 5 }}}}]}, \"SourceExpression\": { \"Kind\": \"Aggregate\", \"Aggregate\": { \"Kind\": \"Builtin\", \"OperatorKind\": \"Sum\" }, \"SourceExpression\": { \"Kind\": \"Input\", \"Name\": \"root\" }}}}}"), + }; + + this.ExecuteTestSuite(testVariations); + } + + + private static ClientDistributionPlanTestInput CreateInput( + string description, + string clientPlanJson) + { + return new ClientDistributionPlanTestInput(description, clientPlanJson); + } + + public override ClientDistributionPlanTestOutput ExecuteTest(ClientDistributionPlanTestInput input) + { + JsonSerializerSettings settings = new JsonSerializerSettings + { + Formatting = Newtonsoft.Json.Formatting.Indented + }; + + ClientDistributionPlan distributionPlan = ClientDistributionPlanDeserializer.DeserializeClientDistributionPlan(input.ClientPlanJson); + string serializedDistributionPlan = JsonConvert.SerializeObject(distributionPlan, settings); + + return new ClientDistributionPlanTestOutput(serializedDistributionPlan); + } + + public sealed class ClientDistributionPlanTestOutput : BaselineTestOutput + { + public ClientDistributionPlanTestOutput(string serializedclientPlanJson) + { + this.SerializedclientPlanJson = serializedclientPlanJson; + } + + public string SerializedclientPlanJson { get; } + + public override void SerializeAsXml(XmlWriter xmlWriter) + { + JObject jObject = JObject.Parse(this.SerializedclientPlanJson); + string jsonString = jObject.ToString(); + xmlWriter.WriteStartElement("SerializedClientPlanJson"); + xmlWriter.WriteString(jsonString); + xmlWriter.WriteEndElement(); + } + } + + public sealed class ClientDistributionPlanTestInput : BaselineTestInput + { + internal string ClientPlanJson { get; set; } + + internal ClientDistributionPlanTestInput( + string description, + string clientPlanJson) + : base(description) + { + this.ClientPlanJson = clientPlanJson; + } + + public override void SerializeAsXml(XmlWriter xmlWriter) + { + xmlWriter.WriteElementString("Description", this.Description); + xmlWriter.WriteElementString("ClientDistributionPlanJson", this.ClientPlanJson); + } + } + } +} diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Metrics/ClientSideMetricsTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Metrics/ClientSideMetricsTests.cs index 4a446bb933..90f9fec8ad 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Metrics/ClientSideMetricsTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Metrics/ClientSideMetricsTests.cs @@ -21,11 +21,11 @@ public class ClientSideMetricsTests [TestMethod] public void TestAccumulator() { - ClientSideMetrics.Accumulator accumulator = new ClientSideMetrics.Accumulator(); - accumulator = accumulator.Accumulate(MockClientSideMetrics); - accumulator = accumulator.Accumulate(MockClientSideMetrics); + ClientSideMetricsAccumulator accumulator = new ClientSideMetricsAccumulator(); + accumulator.Accumulate(MockClientSideMetrics); + accumulator.Accumulate(MockClientSideMetrics); - ClientSideMetrics doubleMetrics = ClientSideMetrics.Accumulator.ToClientSideMetrics(accumulator); + ClientSideMetrics doubleMetrics = accumulator.GetClientSideMetrics(); Assert.AreEqual(2 * MockClientSideMetrics.Retries, doubleMetrics.Retries); Assert.AreEqual(2 * MockClientSideMetrics.RequestCharge, doubleMetrics.RequestCharge); Assert.AreEqual(2 * MockClientSideMetrics.FetchExecutionRanges.Count(), doubleMetrics.FetchExecutionRanges.Count()); diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Metrics/IndexUtilizationInfoTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Metrics/IndexUtilizationInfoTests.cs index 13702de3b5..b3bce119dd 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Metrics/IndexUtilizationInfoTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Metrics/IndexUtilizationInfoTests.cs @@ -8,7 +8,6 @@ namespace Microsoft.Azure.Cosmos.Tests.Query.Metrics using VisualStudio.TestTools.UnitTesting; using Microsoft.Azure.Cosmos.Query.Core.Metrics; using System.Collections.Generic; - using System.Text; [TestClass] public class IndexUtilizationInfoTests @@ -35,11 +34,11 @@ public class IndexUtilizationInfoTests [TestMethod] public void TestAccumulator() { - IndexUtilizationInfo.Accumulator accumulator = new IndexUtilizationInfo.Accumulator(); - accumulator = accumulator.Accumulate(MockIndexUtilizationInfo); - accumulator = accumulator.Accumulate(MockIndexUtilizationInfo); + IndexUtilizationInfoAccumulator accumulator = new IndexUtilizationInfoAccumulator(); + accumulator.Accumulate(MockIndexUtilizationInfo); + accumulator.Accumulate(MockIndexUtilizationInfo); - IndexUtilizationInfo doubleInfo = IndexUtilizationInfo.Accumulator.ToIndexUtilizationInfo(accumulator); + IndexUtilizationInfo doubleInfo = accumulator.GetIndexUtilizationInfo(); Assert.AreEqual(2 * MockIndexUtilizationInfo.PotentialSingleIndexes.Count, doubleInfo.PotentialSingleIndexes.Count); Assert.AreEqual(2 * MockIndexUtilizationInfo.UtilizedSingleIndexes.Count, doubleInfo.UtilizedSingleIndexes.Count); Assert.AreEqual(2 * MockIndexUtilizationInfo.PotentialCompositeIndexes.Count, doubleInfo.PotentialCompositeIndexes.Count); @@ -98,9 +97,7 @@ private static void TestParses(bool isBase64Encoded) } else { - Assert.IsTrue(IndexUtilizationInfo.TryCreateFromDelimitedString(testString, - out IndexUtilizationInfo parsedInfo)); - Assert.IsNotNull(parsedInfo); + Assert.IsTrue(IndexMetricsInfo.TryCreateFromString(testString, out _)); } } } diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Metrics/QueryMetricsTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Metrics/QueryMetricsTests.cs index d655de097a..17f73616c2 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Metrics/QueryMetricsTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Metrics/QueryMetricsTests.cs @@ -12,21 +12,21 @@ namespace Microsoft.Azure.Cosmos.Tests.Query.Metrics public class QueryMetricsTests { private static readonly QueryMetrics MockQueryMetrics = new QueryMetrics( - BackendMetricsTests.MockBackendMetrics, + ServerSideMetricsTests.ServerSideMetrics, IndexUtilizationInfoTests.MockIndexUtilizationInfo, ClientSideMetricsTests.MockClientSideMetrics); [TestMethod] public void TestAccumulator() { - QueryMetrics.Accumulator accumulator = new QueryMetrics.Accumulator(); - accumulator = accumulator.Accumulate(MockQueryMetrics); - accumulator = accumulator.Accumulate(MockQueryMetrics); + QueryMetricsAccumulator accumulator = new QueryMetricsAccumulator(); + accumulator.Accumulate(MockQueryMetrics); + accumulator.Accumulate(MockQueryMetrics); - QueryMetrics doubleQueryMetrics = QueryMetrics.Accumulator.ToQueryMetrics(accumulator); + QueryMetrics doubleQueryMetrics = accumulator.GetQueryMetrics(); // Spot check - Assert.AreEqual(2 * BackendMetricsTests.MockBackendMetrics.IndexLookupTime, doubleQueryMetrics.BackendMetrics.IndexLookupTime); + Assert.AreEqual(2 * ServerSideMetricsTests.ServerSideMetrics.IndexLookupTime, doubleQueryMetrics.ServerSideMetrics.IndexLookupTime); Assert.AreEqual(2 * IndexUtilizationInfoTests.MockIndexUtilizationInfo.PotentialSingleIndexes.Count, doubleQueryMetrics.IndexUtilizationInfo.PotentialSingleIndexes.Count); Assert.AreEqual(2 * ClientSideMetricsTests.MockClientSideMetrics.RequestCharge, doubleQueryMetrics.ClientSideMetrics.RequestCharge); } @@ -37,7 +37,7 @@ public void TestAddition() QueryMetrics doubleQueryMetrics = MockQueryMetrics + MockQueryMetrics; // Spot check - Assert.AreEqual(2 * BackendMetricsTests.MockBackendMetrics.IndexLookupTime, doubleQueryMetrics.BackendMetrics.IndexLookupTime); + Assert.AreEqual(2 * ServerSideMetricsTests.ServerSideMetrics.IndexLookupTime, doubleQueryMetrics.ServerSideMetrics.IndexLookupTime); Assert.AreEqual(2 * IndexUtilizationInfoTests.MockIndexUtilizationInfo.PotentialSingleIndexes.Count, doubleQueryMetrics.IndexUtilizationInfo.PotentialSingleIndexes.Count); Assert.AreEqual(2 * ClientSideMetricsTests.MockClientSideMetrics.RequestCharge, doubleQueryMetrics.ClientSideMetrics.RequestCharge); } @@ -48,7 +48,7 @@ public void TestCreateFromEnumerable() QueryMetrics tripleQueryMetrics = QueryMetrics.CreateFromIEnumerable(new List() { MockQueryMetrics, MockQueryMetrics, MockQueryMetrics }); // Spot check - Assert.AreEqual(3 * BackendMetricsTests.MockBackendMetrics.IndexLookupTime, tripleQueryMetrics.BackendMetrics.IndexLookupTime); + Assert.AreEqual(3 * ServerSideMetricsTests.ServerSideMetrics.IndexLookupTime, tripleQueryMetrics.ServerSideMetrics.IndexLookupTime); Assert.AreEqual(3 * IndexUtilizationInfoTests.MockIndexUtilizationInfo.PotentialSingleIndexes.Count, tripleQueryMetrics.IndexUtilizationInfo.PotentialSingleIndexes.Count); Assert.AreEqual(3 * ClientSideMetricsTests.MockClientSideMetrics.RequestCharge, tripleQueryMetrics.ClientSideMetrics.RequestCharge); } diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Metrics/BackendMetricsTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Metrics/ServerSideMetricsTests.cs similarity index 78% rename from Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Metrics/BackendMetricsTests.cs rename to Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Metrics/ServerSideMetricsTests.cs index 221057790d..4c6e382ebf 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Metrics/BackendMetricsTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Metrics/ServerSideMetricsTests.cs @@ -7,11 +7,10 @@ namespace Microsoft.Azure.Cosmos.Tests.Query.Metrics using System; using VisualStudio.TestTools.UnitTesting; using Microsoft.Azure.Cosmos.Query.Core.Metrics; - using System.Diagnostics; using System.Collections.Generic; [TestClass] - public class BackendMetricsTests + public class ServerSideMetricsTests { private static readonly TimeSpan totalExecutionTime = TimeSpan.FromTicks((long)(TimeSpan.TicksPerMillisecond * 33.67)); private static readonly TimeSpan queryCompileTime = TimeSpan.FromTicks((long)(TimeSpan.TicksPerMillisecond * 0.06)); @@ -32,14 +31,14 @@ public class BackendMetricsTests private static readonly string delimitedString = $"totalExecutionTimeInMs={totalExecutionTime.TotalMilliseconds};queryCompileTimeInMs={queryCompileTime.TotalMilliseconds};queryLogicalPlanBuildTimeInMs={logicalPlanBuildTime.TotalMilliseconds};queryPhysicalPlanBuildTimeInMs={physicalPlanBuildTime.TotalMilliseconds};queryOptimizationTimeInMs={queryOptimizationTime.TotalMilliseconds};VMExecutionTimeInMs={vmExecutionTime.TotalMilliseconds};indexLookupTimeInMs={indexLookupTime.TotalMilliseconds};documentLoadTimeInMs={documentLoadTime.TotalMilliseconds};systemFunctionExecuteTimeInMs={systemFunctionExecuteTime.TotalMilliseconds};userFunctionExecuteTimeInMs={userFunctionExecuteTime.TotalMilliseconds};retrievedDocumentCount={retrievedDocumentCount};retrievedDocumentSize={retrievedDocumentSize};outputDocumentCount={outputDocumentCount};outputDocumentSize={outputDocumentSize};writeOutputTimeInMs={documentWriteTime.TotalMilliseconds};indexUtilizationRatio={indexHitRatio}"; - internal static readonly BackendMetrics MockBackendMetrics = new BackendMetrics( + internal static readonly ServerSideMetricsInternal ServerSideMetrics = new ServerSideMetricsInternal( retrievedDocumentCount, retrievedDocumentSize, outputDocumentCount, outputDocumentSize, indexHitRatio, totalExecutionTime, - new QueryPreparationTimes( + new QueryPreparationTimesInternal( queryCompileTime, logicalPlanBuildTime, physicalPlanBuildTime, @@ -47,7 +46,7 @@ public class BackendMetricsTests indexLookupTime, documentLoadTime, vmExecutionTime, - new RuntimeExecutionTimes( + new RuntimeExecutionTimesInternal( totalExecutionTime - systemFunctionExecuteTime - userFunctionExecuteTime, systemFunctionExecuteTime, userFunctionExecuteTime), @@ -57,13 +56,13 @@ public class BackendMetricsTests [TestMethod] public void TestParse() { - BackendMetricsTests.ValidateParse(delimitedString, MockBackendMetrics); + ServerSideMetricsTests.ValidateParse(delimitedString, ServerSideMetrics); } [TestMethod] public void TestParseEmptyString() { - BackendMetricsTests.ValidateParse(string.Empty, BackendMetrics.Empty); + ServerSideMetricsTests.ValidateParse(string.Empty, ServerSideMetricsInternal.Empty); } [TestMethod] @@ -72,14 +71,14 @@ public void TestParseStringWithMissingFields() TimeSpan totalExecutionTime = TimeSpan.FromTicks((long)(TimeSpan.TicksPerMillisecond * 33.67)); string delimitedString = $"totalExecutionTimeInMs={totalExecutionTime.TotalMilliseconds}"; - BackendMetrics expected = new BackendMetrics( + ServerSideMetricsInternal expected = new ServerSideMetricsInternal( default(long), default(long), default(long), default(long), default(double), totalExecutionTime, - new QueryPreparationTimes( + new QueryPreparationTimesInternal( default(TimeSpan), default(TimeSpan), default(TimeSpan), @@ -87,27 +86,27 @@ public void TestParseStringWithMissingFields() default(TimeSpan), default(TimeSpan), default(TimeSpan), - new RuntimeExecutionTimes( + new RuntimeExecutionTimesInternal( default(TimeSpan), default(TimeSpan), default(TimeSpan)), default(TimeSpan)); - BackendMetricsTests.ValidateParse(delimitedString, expected); + ServerSideMetricsTests.ValidateParse(delimitedString, expected); } [TestMethod] public void TestParseStringWithTrailingUnknownField() { string delimitedString = $"thisIsNotAKnownField=asdf"; - BackendMetrics expected = new BackendMetrics( + ServerSideMetricsInternal expected = new ServerSideMetricsInternal( default(long), default(long), default(long), default(long), default(double), default(TimeSpan), - new QueryPreparationTimes( + new QueryPreparationTimesInternal( default(TimeSpan), default(TimeSpan), default(TimeSpan), @@ -115,13 +114,13 @@ public void TestParseStringWithTrailingUnknownField() default(TimeSpan), default(TimeSpan), default(TimeSpan), - new RuntimeExecutionTimes( + new RuntimeExecutionTimesInternal( default(TimeSpan), default(TimeSpan), default(TimeSpan)), default(TimeSpan)); - BackendMetricsTests.ValidateParse(delimitedString, expected); + ServerSideMetricsTests.ValidateParse(delimitedString, expected); } [TestMethod] @@ -129,7 +128,7 @@ public void TestParseStringWithTrailingUnknownField() [DataRow("totalExecutionTimeInMs=33.6+totalExecutionTimeInMs=33.6", DisplayName = "Wrong Delimiter")] public void TestNegativeCases(string delimitedString) { - Assert.IsFalse(BackendMetricsParser.TryParse(delimitedString, out BackendMetrics backendMetrics)); + Assert.IsFalse(ServerSideMetricsParser.TryParse(delimitedString, out ServerSideMetricsInternal serverSideMetrics)); } [TestMethod] @@ -137,14 +136,14 @@ public void TestParseStringWithUnknownField() { TimeSpan totalExecutionTime = TimeSpan.FromTicks((long)(TimeSpan.TicksPerMillisecond * 33.67)); string delimitedString = $"totalExecutionTimeInMs={totalExecutionTime.TotalMilliseconds};thisIsNotAKnownField={totalExecutionTime.TotalMilliseconds};totalExecutionTimeInMs={totalExecutionTime.TotalMilliseconds}"; - BackendMetrics expected = new BackendMetrics( + ServerSideMetricsInternal expected = new ServerSideMetricsInternal( default(long), default(long), default(long), default(long), default(double), totalExecutionTime, - new QueryPreparationTimes( + new QueryPreparationTimesInternal( default(TimeSpan), default(TimeSpan), default(TimeSpan), @@ -152,31 +151,34 @@ public void TestParseStringWithUnknownField() default(TimeSpan), default(TimeSpan), default(TimeSpan), - new RuntimeExecutionTimes( + new RuntimeExecutionTimesInternal( default(TimeSpan), default(TimeSpan), default(TimeSpan)), default(TimeSpan)); - BackendMetricsTests.ValidateParse(delimitedString, expected); + ServerSideMetricsTests.ValidateParse(delimitedString, expected); } [TestMethod] public void TestAccumulator() { - BackendMetrics.Accumulator accumulator = new BackendMetrics.Accumulator(); - accumulator = accumulator.Accumulate(MockBackendMetrics); - accumulator = accumulator.Accumulate(MockBackendMetrics); + ServerSideMetricsInternalAccumulator accumulator = new ServerSideMetricsInternalAccumulator(); + accumulator.Accumulate(ServerSideMetrics); + accumulator.Accumulate(ServerSideMetrics); + ServerSideMetricsInternal serverSideMetricsFromAddition = accumulator.GetServerSideMetrics(); - BackendMetrics backendMetricsFromAddition = BackendMetrics.Accumulator.ToBackendMetrics(accumulator); - BackendMetrics expected = new BackendMetrics( + List metricsList = new List { ServerSideMetrics, ServerSideMetrics }; + ServerSideMetricsInternal serverSideMetricsFromCreate = ServerSideMetricsInternal.Create(metricsList); + + ServerSideMetricsInternal expected = new ServerSideMetricsInternal( retrievedDocumentCount * 2, retrievedDocumentSize * 2, outputDocumentCount * 2, outputDocumentSize * 2, indexHitRatio, totalExecutionTime * 2, - new QueryPreparationTimes( + new QueryPreparationTimesInternal( queryCompileTime * 2, logicalPlanBuildTime * 2, physicalPlanBuildTime * 2, @@ -184,22 +186,22 @@ public void TestAccumulator() indexLookupTime * 2, documentLoadTime * 2, vmExecutionTime * 2, - new RuntimeExecutionTimes( + new RuntimeExecutionTimesInternal( (totalExecutionTime - systemFunctionExecuteTime - userFunctionExecuteTime) * 2, systemFunctionExecuteTime * 2, userFunctionExecuteTime * 2), documentWriteTime * 2); - BackendMetricsTests.ValidateBackendMetricsEquals(expected, backendMetricsFromAddition); + ServerSideMetricsTests.ValidateServerSideMetricsEquals(expected, serverSideMetricsFromAddition); + ServerSideMetricsTests.ValidateServerSideMetricsEquals(expected, serverSideMetricsFromCreate); } - - private static void ValidateParse(string delimitedString, BackendMetrics expected) + private static void ValidateParse(string delimitedString, ServerSideMetricsInternal expected) { - Assert.IsTrue(BackendMetricsParser.TryParse(delimitedString, out BackendMetrics actual)); - BackendMetricsTests.ValidateBackendMetricsEquals(expected, actual); + Assert.IsTrue(ServerSideMetricsParser.TryParse(delimitedString, out ServerSideMetricsInternal actual)); + ServerSideMetricsTests.ValidateServerSideMetricsEquals(expected, actual); } - private static void ValidateBackendMetricsEquals(BackendMetrics expected, BackendMetrics actual) + private static void ValidateServerSideMetricsEquals(ServerSideMetricsInternal expected, ServerSideMetricsInternal actual) { Assert.AreEqual(expected.DocumentLoadTime, actual.DocumentLoadTime); Assert.AreEqual(expected.DocumentWriteTime, actual.DocumentWriteTime); diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/OptimisticDirectExecutionQueryBaselineTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/OptimisticDirectExecutionQueryBaselineTests.cs index 81c765adc4..9076506e64 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/OptimisticDirectExecutionQueryBaselineTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/OptimisticDirectExecutionQueryBaselineTests.cs @@ -19,6 +19,7 @@ using Microsoft.Azure.Cosmos.Query.Core.Pipeline; using Microsoft.Azure.Cosmos.Query.Core.Pipeline.CrossPartition.OrderBy; using Microsoft.Azure.Cosmos.Query.Core.Pipeline.CrossPartition.Parallel; + using Microsoft.Azure.Cosmos.Query.Core.Pipeline.OptimisticDirectExecutionQuery; using Microsoft.Azure.Cosmos.Query.Core.Pipeline.Pagination; using Microsoft.Azure.Cosmos.Query.Core.QueryClient; using Microsoft.Azure.Cosmos.Query.Core.QueryPlan; @@ -94,6 +95,7 @@ public void PositiveOptimisticDirectExecutionOutput() partitionKeyPath: @"/pk", partitionKeyValue: null), }; + this.ExecuteTestSuite(testVariations); } @@ -190,6 +192,49 @@ public async Task TestPipelineForBackendDocumentsOnSinglePartitionAsync() Assert.AreEqual(100, documentCountInSinglePartition); } + [TestMethod] + public async Task TestOdeTokenWithSpecializedPipeline() + { + int numItems = 100; + ParallelContinuationToken parallelContinuationToken = new ParallelContinuationToken( + token: Guid.NewGuid().ToString(), + range: new Documents.Routing.Range("A", "B", true, false)); + + OptimisticDirectExecutionContinuationToken optimisticDirectExecutionContinuationToken = new OptimisticDirectExecutionContinuationToken(parallelContinuationToken); + CosmosElement cosmosElementContinuationToken = OptimisticDirectExecutionContinuationToken.ToCosmosElement(optimisticDirectExecutionContinuationToken); + + OptimisticDirectExecutionTestInput input = CreateInput( + description: @"Single Partition Key and Value Field", + query: "SELECT VALUE COUNT(1) FROM c", + expectedOptimisticDirectExecution: false, + partitionKeyPath: @"/pk", + partitionKeyValue: "a", + continuationToken: cosmosElementContinuationToken); + + DocumentContainer documentContainer = await CreateDocumentContainerAsync(numItems, multiPartition: false); + QueryRequestOptions queryRequestOptions = GetQueryRequestOptions(enableOptimisticDirectExecution: input.ExpectedOptimisticDirectExecution); + (CosmosQueryExecutionContextFactory.InputParameters inputParameters, CosmosQueryContextCore cosmosQueryContextCore) = CreateInputParamsAndQueryContext(input, queryRequestOptions); + IQueryPipelineStage queryPipelineStage = CosmosQueryExecutionContextFactory.Create( + documentContainer, + cosmosQueryContextCore, + inputParameters, + NoOpTrace.Singleton); + + string expectedErrorMessage = "The continuation token supplied requires the Optimistic Direct Execution flag to be enabled in QueryRequestOptions for the query execution to resume. "; + + while (await queryPipelineStage.MoveNextAsync(NoOpTrace.Singleton)) + { + if (queryPipelineStage.Current.Failed) + { + Assert.IsTrue(queryPipelineStage.Current.InnerMostException.ToString().Contains(expectedErrorMessage)); + return; + } + + Assert.IsFalse(true); + break; + } + } + [TestMethod] public async Task TestQueriesWhichNeverRequireDistribution() { @@ -335,11 +380,11 @@ public async Task TestPipelineForContinuationTokenOnSinglePartitionAsync() { int numItems = 100; OptimisticDirectExecutionTestInput input = CreateInput( - description: @"Single Partition Key and Value Field", + description: @"Single Partition Key and Value Field", query: "SELECT * FROM c", - expectedOptimisticDirectExecution: true, - partitionKeyPath: @"/pk", - partitionKeyValue: "a"); + expectedOptimisticDirectExecution: true, + partitionKeyPath: @"/pk", + partitionKeyValue: "a"); int result = await this.GetPipelineAndDrainAsync( input, @@ -350,6 +395,63 @@ public async Task TestPipelineForContinuationTokenOnSinglePartitionAsync() Assert.AreEqual(numItems, result); } + // test checks that the Ode code path ensures that a query is valid before sending it to the backend + // these queries with previous ODE implementation would have succeeded. However, with the new query validity check, they should all throw an exception + [TestMethod] + public async Task TestQueryValidityCheckWithODEAsync() + { + const string UnsupportedSelectStarInGroupBy = "'SELECT *' is not allowed with GROUP BY"; + const string UnsupportedCompositeAggregate = "Compositions of aggregates and other expressions are not allowed."; + const string UnsupportedNestedAggregateExpression = "Cannot perform an aggregate function on an expression containing an aggregate or a subquery."; + const string UnsupportedSelectLisWithAggregateOrGroupByExpression = "invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause"; + + List<(string Query, string ExpectedMessage)> testVariations = new List<(string Query, string ExpectedMessage)> + { + ("SELECT COUNT (1) + 5 FROM c", UnsupportedCompositeAggregate), + ("SELECT MIN(c.price) + 10 FROM c", UnsupportedCompositeAggregate), + ("SELECT MAX(c.price) - 4 FROM c", UnsupportedCompositeAggregate), + ("SELECT SUM (c.price) + 20 FROM c",UnsupportedCompositeAggregate), + ("SELECT AVG(c.price) * 50 FROM c", UnsupportedCompositeAggregate), + ("SELECT * from c GROUP BY c.name", UnsupportedSelectStarInGroupBy), + ("SELECT SUM(c.sales) AS totalSales, AVG(SUM(c.salesAmount)) AS averageTotalSales\n\n\nFROM c", UnsupportedNestedAggregateExpression), + ("SELECT c.category, c.price, COUNT(c) FROM c GROUP BY c.category\r\n", UnsupportedSelectLisWithAggregateOrGroupByExpression) + }; + + List<(string, string)> testVariationsWithCaseSensitivity = new List<(string, string)>(); + foreach ((string Query, string ExpectedMessage) testCase in testVariations) + { + testVariationsWithCaseSensitivity.Add((testCase.Query, testCase.ExpectedMessage)); + testVariationsWithCaseSensitivity.Add((testCase.Query.ToLower(), testCase.ExpectedMessage)); + testVariationsWithCaseSensitivity.Add((testCase.Query.ToUpper(), testCase.ExpectedMessage)); + } + + foreach ((string Query, string ExpectedMessage) testCase in testVariationsWithCaseSensitivity) + { + OptimisticDirectExecutionTestInput input = CreateInput( + description: @"Unsupported queries in CosmosDB that were previously supported by Ode pipeline and returning wrong results", + query: testCase.Query, + expectedOptimisticDirectExecution: true, + partitionKeyPath: @"/pk", + partitionKeyValue: "a"); + + try + { + int result = await this.GetPipelineAndDrainAsync( + input, + numItems: 100, + isMultiPartition: false, + expectedContinuationTokenCount: 0, + requiresDist: true); + Assert.Fail("Invalid query being executed did not result in an exception"); + } + catch (Exception ex) + { + Assert.IsTrue(ex.InnerException.Message.Contains(testCase.ExpectedMessage)); + continue; + } + } + } + // test to check if pipeline handles a 410 exception properly and returns all the documents. [TestMethod] public async Task TestPipelineForGoneExceptionOnSingleAndMultiplePartitionAsync() @@ -526,7 +628,7 @@ private async Task GetPipelineAndDrainAsync(OptimisticDirectExecutionTestIn return documents.Count; } - internal static PartitionedQueryExecutionInfo GetPartitionedQueryExecutionInfo(string querySpecJsonString, PartitionKeyDefinition pkDefinition) + internal static TryCatch TryGetPartitionedQueryExecutionInfo(string querySpecJsonString, PartitionKeyDefinition pkDefinition) { TryCatch tryGetQueryPlan = QueryPartitionProviderTestInstance.Object.TryGetPartitionedQueryExecutionInfo( querySpecJsonString: querySpecJsonString, @@ -539,7 +641,7 @@ internal static PartitionedQueryExecutionInfo GetPartitionedQueryExecutionInfo(s useSystemPrefix: false, geospatialType: Cosmos.GeospatialType.Geography); - return tryGetQueryPlan.Result; + return tryGetQueryPlan; } private static async Task GetOdePipelineAsync(OptimisticDirectExecutionTestInput input, DocumentContainer documentContainer, QueryRequestOptions queryRequestOptions) @@ -687,7 +789,6 @@ public override OptimisticDirectExecutionTestOutput ExecuteTest(OptimisticDirect using StreamReader streamReader = new(serializerCore.ToStreamSqlQuerySpec(new SqlQuerySpec(input.Query), Documents.ResourceType.Document)); string sqlQuerySpecJsonString = streamReader.ReadToEnd(); - PartitionedQueryExecutionInfo partitionedQueryExecutionInfo = GetPartitionedQueryExecutionInfo(sqlQuerySpecJsonString, input.PartitionKeyDefinition); CosmosQueryExecutionContextFactory.InputParameters inputParameters = new CosmosQueryExecutionContextFactory.InputParameters( sqlQuerySpec: new SqlQuerySpec(input.Query), initialUserContinuationToken: input.ContinuationToken, @@ -696,8 +797,8 @@ public override OptimisticDirectExecutionTestOutput ExecuteTest(OptimisticDirect maxItemCount: queryRequestOptions.MaxItemCount, maxBufferedItemCount: queryRequestOptions.MaxBufferedItemCount, partitionKey: input.PartitionKeyValue, - properties: queryRequestOptions.Properties, - partitionedQueryExecutionInfo: partitionedQueryExecutionInfo, + properties: new Dictionary() { { "x-ms-query-partitionkey-definition", input.PartitionKeyDefinition } }, + partitionedQueryExecutionInfo: null, executionEnvironment: null, returnResultsInDeterministicOrder: null, forcePassthrough: false, @@ -959,9 +1060,16 @@ public override Task ForceRefreshCollectionCacheAsync(string collectionLink, Can public override Task GetCachedContainerQueryPropertiesAsync(string containerLink, Cosmos.PartitionKey? partitionKey, ITrace trace, CancellationToken cancellationToken) { - return Task.FromResult(new ContainerQueryProperties( + return Task.FromResult(new ContainerQueryProperties( "test", - WFConstants.BackendHeaders.EffectivePartitionKeyString, + new List> + { + new Range( + PartitionKeyInternal.MinimumInclusiveEffectivePartitionKey, + PartitionKeyInternal.MaximumExclusiveEffectivePartitionKey, + true, + true) + }, new PartitionKeyDefinition(), Cosmos.GeospatialType.Geometry)); } @@ -971,17 +1079,7 @@ public override Task> GetTargetPartitionKeyRangeByFeedRa throw new NotImplementedException(); } - public override Task> GetTargetPartitionKeyRangesAsync(string resourceLink, string collectionResourceId, List> providedRanges, bool forceRefresh, ITrace trace) - { - return Task.FromResult(new List{new PartitionKeyRange() - { - MinInclusive = PartitionKeyInternal.MinimumInclusiveEffectivePartitionKey, - MaxExclusive = PartitionKeyInternal.MaximumExclusiveEffectivePartitionKey - } - }); - } - - public override Task> GetTargetPartitionKeyRangesByEpkStringAsync(string resourceLink, string collectionResourceId, string effectivePartitionKeyString, bool forceRefresh, ITrace trace) + public override Task> GetTargetPartitionKeyRangesAsync(string resourceLink, string collectionResourceId, IReadOnlyList> providedRanges, bool forceRefresh, ITrace trace) { return Task.FromResult(new List{new PartitionKeyRange() { @@ -1002,7 +1100,8 @@ public override async Task> TryGetPartit using StreamReader streamReader = new(serializerCore.ToStreamSqlQuerySpec(sqlQuerySpec, Documents.ResourceType.Document)); string sqlQuerySpecJsonString = streamReader.ReadToEnd(); - PartitionedQueryExecutionInfo partitionedQueryExecutionInfo = OptimisticDirectExecutionQueryBaselineTests.GetPartitionedQueryExecutionInfo(sqlQuerySpecJsonString, partitionKeyDefinition); + TryCatch queryPlan = OptimisticDirectExecutionQueryBaselineTests.TryGetPartitionedQueryExecutionInfo(sqlQuerySpecJsonString, partitionKeyDefinition); + PartitionedQueryExecutionInfo partitionedQueryExecutionInfo = queryPlan.Succeeded ? queryPlan.Result : throw queryPlan.Exception; return TryCatch.FromResult(partitionedQueryExecutionInfo); } } diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Parser/ScalarExpressionSqlParserBaselineTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Parser/ScalarExpressionSqlParserBaselineTests.cs index 43377f0074..10f6fe3ee0 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Parser/ScalarExpressionSqlParserBaselineTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Parser/ScalarExpressionSqlParserBaselineTests.cs @@ -520,6 +520,30 @@ public void OrderOfOperation() this.ExecuteTestSuite(inputs); } + [TestMethod] + public void StringLiteral() + { + List inputs = new List() + { + // Single quoted string literals do not allow ' even when it's escaped. + // Parser currently fails with Antlr4.Runtime.NoViableAltException + CreateInput( + description: @"Single quoted string literals with escape seqence", + scalarExpression: @"['\""DoubleQuote', '\\ReverseSolidus', '\/solidus', '\bBackspace', '\fSeparatorFeed', '\nLineFeed', '\rCarriageReturn', '\tTab', '\u1234']"), + CreateInput( + description: @"Double quoted string literals with escape seqence", + scalarExpression: @"[""'SingleQuote"", ""\""DoubleQuote"", ""\\ReverseSolidus"", ""\/solidus"", ""\bBackspace"", ""\fSeparatorFeed"", ""\nLineFeed"", ""\rCarriageReturn"", ""\tTab"", ""\u1234""]"), + CreateInput( + description: @"Single quoted string literals special cases", + scalarExpression: @"['\""', '\""\""', '\\', '\\\\', '\/', '\/\/', '\b', '\b\b', '\f', '\f\f', '\n', '\n\n', '\r', '\r\r', '\t', '\t\t', '\u1234', '\u1234\u1234']"), + CreateInput( + description: @"Double quoted string literals special cases", + scalarExpression: @"[""\"""", ""\""\"""", ""\\"", ""\\\\"", ""\/"", ""\/\/"", ""\b"", ""\b\b"", ""\f"", ""\f\f"", ""\n"", ""\n\n"", ""\r"", ""\r\r"", ""\t"", ""\t\t"", ""\u1234"", ""\u1234\u1234""]"), + }; + + this.ExecuteTestSuite(inputs); + } + public static SqlParserBaselineTestInput CreateInput(string description, string scalarExpression) { return new SqlParserBaselineTestInput(description, $"SELECT VALUE {scalarExpression}"); diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/SplitPartitionQueryTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/SplitPartitionQueryTests.cs new file mode 100644 index 0000000000..4dd4ed1bd8 --- /dev/null +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/SplitPartitionQueryTests.cs @@ -0,0 +1,77 @@ +namespace Microsoft.Azure.Cosmos.Tests.Query +{ + using System; + using System.Threading.Tasks; + using Microsoft.Azure.Cosmos.Pagination; + using Microsoft.VisualStudio.TestTools.UnitTesting; + using Microsoft.Azure.Documents; + using Microsoft.Azure.Cosmos.Tests.Pagination; + using Microsoft.Azure.Cosmos.CosmosElements; + using Microsoft.Azure.Cosmos.Query.Core.Monads; + using Microsoft.Azure.Cosmos.Tracing; + using Microsoft.Azure.Cosmos.Query.Core.Pipeline.Pagination; + + [TestClass] + public class SplitPartitionQueryTests + { + [TestMethod] + public async Task PrefixPartitionKeyQueryOnSplitParitionTest() + { + int numItems = 500; + IDocumentContainer documentContainer = await CreateSplitDocumentContainerAsync(numItems); + + string query = "SELECT * FROM c"; + for(int i = 0; i < 5; i++) + { + Cosmos.PartitionKey partitionKey = new PartitionKeyBuilder() + .Add(i.ToString()) + .Build(); + + QueryPage queryPage = await documentContainer.QueryAsync( + sqlQuerySpec: new Cosmos.Query.Core.SqlQuerySpec(query), + feedRangeState: new FeedRangeState(new FeedRangePartitionKey(partitionKey), state: null), + queryPaginationOptions: new QueryPaginationOptions(pageSizeHint: int.MaxValue), + trace: NoOpTrace.Singleton, + cancellationToken: default); + + Assert.AreEqual(numItems / 5, queryPage.Documents.Count); + } + } + + private static async Task CreateSplitDocumentContainerAsync(int numItems) + { + PartitionKeyDefinition partitionKeyDefinition = new PartitionKeyDefinition() + { + Paths = new System.Collections.ObjectModel.Collection() + { + "/id", + "/value1", + "/value2" + }, + Kind = PartitionKind.MultiHash, + Version = PartitionKeyDefinitionVersion.V2, + }; + + IMonadicDocumentContainer monadicDocumentContainer = new InMemoryContainer(partitionKeyDefinition); + DocumentContainer documentContainer = new DocumentContainer(monadicDocumentContainer); + + for (int i = 0; i < numItems; i++) + { + // Insert an item + CosmosObject item = CosmosObject.Parse($"{{\"id\" : \"{i%5}\", \"value1\" : \"{Guid.NewGuid()}\", \"value2\" : \"{i}\" }}"); + while (true) + { + TryCatch monadicCreateRecord = await documentContainer.MonadicCreateItemAsync(item, cancellationToken: default); + if (monadicCreateRecord.Succeeded) + { + break; + } + } + } + + await documentContainer.SplitAsync(FeedRangeEpk.FullRange, cancellationToken: default); + + return documentContainer; + } + } +} diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Routing/PartitionKeyHashBaselineTest.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Routing/PartitionKeyHashBaselineTest.cs index 4fb7b5b53f..f60d0849ca 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Routing/PartitionKeyHashBaselineTest.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Routing/PartitionKeyHashBaselineTest.cs @@ -6,6 +6,7 @@ namespace Microsoft.Azure.Cosmos.Tests.Routing { using System; using System.Collections.Generic; + using System.Linq; using System.Numerics; using System.Xml; using Microsoft.Azure.Cosmos.CosmosElements; @@ -126,6 +127,37 @@ public void Numbers() this.ExecuteTestSuite(inputs); } + [TestMethod] + public void Lists() + { + List inputs = new List() + { + new Input( + description: "1 Path List", + partitionKeyValue: CosmosArray.Create(new List() + { + CosmosString.Create("/path1") + })), + new Input( + description: "2 Path List", + partitionKeyValue: CosmosArray.Create(new List() + { + CosmosString.Create("/path1"), + CosmosString.Create("/path2") + })), + new Input( + description: "3 Path List", + partitionKeyValue: CosmosArray.Create(new List() + { + CosmosString.Create("/path1"), + CosmosString.Create("/path2"), + CosmosString.Create("/path3") + })), + }; + + this.ExecuteTestSuite(inputs); + } + public override Output ExecuteTest(Input input) { CosmosElement value = input.PartitionKeyValue; @@ -159,7 +191,38 @@ public override Output ExecuteTest(Input input) partitionKeyHashV1 = PartitionKeyHash.V1.Hash(Number64.ToDouble(cosmosNumber.Value)); partitionKeyHashV2 = PartitionKeyHash.V2.Hash(Number64.ToDouble(cosmosNumber.Value)); break; + case CosmosArray cosmosArray: + IList partitionKeyHashValuesV1 = new List(); + IList partitionKeyHashValuesV2 = new List(); + foreach (CosmosElement element in cosmosArray) + { + PartitionKeyHash elementHashV1 = element switch + { + null => PartitionKeyHash.V2.HashUndefined(), + CosmosString stringPartitionKey => PartitionKeyHash.V1.Hash(stringPartitionKey.Value), + CosmosNumber numberPartitionKey => PartitionKeyHash.V1.Hash(Number64.ToDouble(numberPartitionKey.Value)), + CosmosBoolean cosmosBoolean => PartitionKeyHash.V1.Hash(cosmosBoolean.Value), + CosmosNull _ => PartitionKeyHash.V1.HashNull(), + _ => throw new ArgumentOutOfRangeException(), + }; + partitionKeyHashValuesV1.Add(elementHashV1.HashValues[0]); + + PartitionKeyHash elementHashV2 = element switch + { + null => PartitionKeyHash.V2.HashUndefined(), + CosmosString stringPartitionKey => PartitionKeyHash.V2.Hash(stringPartitionKey.Value), + CosmosNumber numberPartitionKey => PartitionKeyHash.V2.Hash(Number64.ToDouble(numberPartitionKey.Value)), + CosmosBoolean cosmosBoolean => PartitionKeyHash.V2.Hash(cosmosBoolean.Value), + CosmosNull _ => PartitionKeyHash.V2.HashNull(), + _ => throw new ArgumentOutOfRangeException(), + }; + partitionKeyHashValuesV2.Add(elementHashV2.HashValues[0]); + } + + partitionKeyHashV1 = new PartitionKeyHash(partitionKeyHashValuesV1.ToArray()); + partitionKeyHashV2 = new PartitionKeyHash(partitionKeyHashValuesV2.ToArray()); + break; default: throw new ArgumentOutOfRangeException($"Unknown {nameof(CosmosElement)} type: {value.GetType()}."); } diff --git a/Microsoft.Azure.Cosmos/src/Routing/PartitionKeyHashRangeSplitterAndMerger.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Routing/PartitionKeyHashRangeSplitterAndMerger.cs similarity index 73% rename from Microsoft.Azure.Cosmos/src/Routing/PartitionKeyHashRangeSplitterAndMerger.cs rename to Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Routing/PartitionKeyHashRangeSplitterAndMerger.cs index 54b72ae3a2..af005b1515 100644 --- a/Microsoft.Azure.Cosmos/src/Routing/PartitionKeyHashRangeSplitterAndMerger.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Routing/PartitionKeyHashRangeSplitterAndMerger.cs @@ -39,8 +39,8 @@ public static SplitOutcome TrySplitRange(PartitionKeyHashRange partitionKeyHashR return SplitOutcome.NumRangesNeedsToBeGreaterThanZero; } - UInt128 actualEnd = partitionKeyHashRange.EndExclusive.HasValue ? partitionKeyHashRange.EndExclusive.Value.Value : UInt128.MaxValue; - UInt128 actualStart = partitionKeyHashRange.StartInclusive.HasValue ? partitionKeyHashRange.StartInclusive.Value.Value : UInt128.MinValue; + UInt128 actualEnd = partitionKeyHashRange.EndExclusive.HasValue ? partitionKeyHashRange.EndExclusive.Value.HashValues[0] : UInt128.MaxValue; + UInt128 actualStart = partitionKeyHashRange.StartInclusive.HasValue ? partitionKeyHashRange.StartInclusive.Value.HashValues[0] : UInt128.MinValue; UInt128 rangeLength = actualEnd - actualStart; if (rangeLength < rangeCount) { @@ -67,7 +67,7 @@ public static SplitOutcome TrySplitRange(PartitionKeyHashRange partitionKeyHashR for (int i = 1; i < rangeCount - 1; i++) { PartitionKeyHash start = new PartitionKeyHash(actualStart + (childRangeLength * i)); - PartitionKeyHash end = new PartitionKeyHash(start.Value + childRangeLength); + PartitionKeyHash end = new PartitionKeyHash(start.HashValues[0] + childRangeLength); childRanges.Add(new PartitionKeyHashRange(start, end)); } @@ -82,6 +82,39 @@ public static SplitOutcome TrySplitRange(PartitionKeyHashRange partitionKeyHashR return SplitOutcome.Success; } + public static PartitionKeyHashRanges SplitRange(PartitionKeyHashRange partitionKeyHashRange, PartitionKeyHash explicitSplitPoint) + { + SplitOutcome splitOutcome = PartitionKeyHashRangeSplitterAndMerger.TrySplitRange( + partitionKeyHashRange, + explicitSplitPoint, + out PartitionKeyHashRanges splitRanges); + + return splitOutcome switch + { + SplitOutcome.Success => splitRanges, + _ => throw new RangeSplitException($"Splitting range failed because {splitOutcome}"), + }; + } + + public static SplitOutcome TrySplitRange(PartitionKeyHashRange partitionKeyHashRange, PartitionKeyHash explicitSplitPoint, out PartitionKeyHashRanges splitRanges) + { + if (explicitSplitPoint < (partitionKeyHashRange.StartInclusive != null ? partitionKeyHashRange.StartInclusive : PartitionKeyHash.None) || + explicitSplitPoint > partitionKeyHashRange.EndExclusive) + { + splitRanges = default; + return SplitOutcome.RangeNotWideEnough; + } + + IList childRanges = new List + { + new PartitionKeyHashRange(partitionKeyHashRange.StartInclusive, explicitSplitPoint), + new PartitionKeyHashRange(explicitSplitPoint, partitionKeyHashRange.EndExclusive) + }; + + splitRanges = PartitionKeyHashRanges.Create(childRanges); + return SplitOutcome.Success; + } + public static PartitionKeyHashRange MergeRanges(PartitionKeyHashRanges partitionedSortedEffectiveRanges) { if (partitionedSortedEffectiveRanges == null) @@ -111,7 +144,13 @@ private sealed class V2 : PartitionKeyHashRangeSplitterAndMerger public override PartitionKeyHashRange FullRange => PartitionKeyHashRangeSplitterAndMerger.V2.fullRange; } - + private sealed class RangeSplitException : Exception + { + public RangeSplitException(string message) + : base(message) + { + } + } public enum SplitOutcome { Success, @@ -119,4 +158,4 @@ public enum SplitOutcome RangeNotWideEnough, } } -} +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/SettingsContractTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/SettingsContractTests.cs index 2e8df92318..4cf045cd7b 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/SettingsContractTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/SettingsContractTests.cs @@ -69,7 +69,7 @@ public void OperationKindMatchesDirect() [TestMethod] public void TriggerOperationMatchesDirect() { - this.AssertEnums(); + this.AssertEnumsContains(); } [TestMethod] @@ -1147,5 +1147,16 @@ private void AssertEnums() where TFirstEnum : struct, I Assert.AreEqual(Convert.ToInt32(documentssVersion), Convert.ToInt32(cosmosVersion)); } } + + private void AssertEnumsContains() where TFirstEnum : struct, IConvertible where TSecondEnum : struct, IConvertible + { + string[] allCosmosEntries = Enum.GetNames(typeof(TFirstEnum)); + string[] allDocumentsEntries = Enum.GetNames(typeof(TSecondEnum)); + + foreach(string entry in allDocumentsEntries) + { + Assert.IsTrue(allCosmosEntries.Contains(entry)); + } + } } } diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Telemetry/ClientTelemetryTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Telemetry/ClientTelemetryTests.cs index 9308d22806..6005ec3045 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Telemetry/ClientTelemetryTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Telemetry/ClientTelemetryTests.cs @@ -26,13 +26,6 @@ namespace Microsoft.Azure.Cosmos.Tests.Telemetry [TestClass] public class ClientTelemetryTests { - [TestCleanup] - public void Cleanup() - { - Environment.SetEnvironmentVariable(ClientTelemetryOptions.EnvPropsClientTelemetryEnabled, null); - Environment.SetEnvironmentVariable(ClientTelemetryOptions.EnvPropsClientTelemetryEndpoint, null); - } - [TestMethod] public void CheckMetricsAggregationLogic() { @@ -126,7 +119,6 @@ public void CheckJsonSerializerContractWithPreferredRegions() [DataRow(150, 0, 0)] // When only operation info is there in payload public async Task CheckIfPayloadIsDividedCorrectlyAsync(int expectedOperationInfoSize, int expectedCacheRefreshInfoSize, int expectedRequestInfoSize) { - Environment.SetEnvironmentVariable(ClientTelemetryOptions.EnvPropsClientTelemetryEndpoint, "http://dummy.telemetry.endpoint/"); ClientTelemetryOptions.PayloadSizeThreshold = 1024 * 15; //15 Kb string data = File.ReadAllText("Telemetry/ClientTelemetryPayloadWithoutMetrics.json", Encoding.UTF8); @@ -245,7 +237,8 @@ await processor.ProcessAndSendAsync( clientTelemetryProperties, operationInfoSnapshot, cacheRefreshInfoSnapshot, - requestInfoList, + requestInfoList, + "http://dummy.telemetry.endpoint/", new CancellationTokenSource(ClientTelemetryOptions.ClientTelemetryProcessorTimeOut).Token); Assert.AreEqual(expectedOperationInfoSize, actualOperationInfoSize, "Operation Info is not correct"); @@ -256,8 +249,6 @@ await processor.ProcessAndSendAsync( [TestMethod] public async Task ClientTelmetryProcessor_should_timeout() { - Environment.SetEnvironmentVariable(ClientTelemetryOptions.EnvPropsClientTelemetryEndpoint, "http://dummy.telemetry.endpoint/"); - string data = File.ReadAllText("Telemetry/ClientTelemetryPayloadWithoutMetrics.json", Encoding.UTF8); ClientTelemetryProperties clientTelemetryProperties = JsonConvert.DeserializeObject(data); @@ -344,6 +335,7 @@ await processor.ProcessAndSendAsync(clientTelemetryProperties, operationInfoSnapshot, cacheRefreshInfoSnapshot, default, + "http://dummy.telemetry.endpoint/", cts.Token); }); @@ -352,13 +344,5 @@ await Assert.ThrowsExceptionAsync(() => ClientTeleme processingTask: processorTask, timeout: TimeSpan.FromTicks(1))); } - - [TestMethod] - [ExpectedException(typeof(FormatException))] - public void CheckMisconfiguredTelemetry_should_fail() - { - Environment.SetEnvironmentVariable(ClientTelemetryOptions.EnvPropsClientTelemetryEnabled, "non-boolean"); - using CosmosClient client = MockCosmosUtil.CreateMockCosmosClient(); - } } } diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Telemetry/DiagnosticsFilterHelperTest.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Telemetry/DiagnosticsFilterHelperTest.cs index e345394265..62517239e3 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Telemetry/DiagnosticsFilterHelperTest.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Telemetry/DiagnosticsFilterHelperTest.cs @@ -14,7 +14,6 @@ namespace Microsoft.Azure.Cosmos.Tests.Telemetry using Documents; using VisualStudio.TestTools.UnitTesting; - [TestClass] public class DiagnosticsFilterHelperTest { @@ -33,9 +32,9 @@ public void CheckReturnFalseOnSuccessAndLowerLatencyThanConfiguredConfig() { Assert.IsTrue(this.rootTrace.Duration > TimeSpan.Zero); - DistributedTracingOptions distributedTracingOptions = new DistributedTracingOptions + CosmosThresholdOptions distributedTracingOptions = new CosmosThresholdOptions { - LatencyThresholdForDiagnosticEvent = this.rootTrace.Duration.Add(TimeSpan.FromSeconds(1)) + PointOperationLatencyThreshold = this.rootTrace.Duration.Add(TimeSpan.FromSeconds(1)) }; OpenTelemetryAttributes response = new OpenTelemetryAttributes @@ -48,7 +47,7 @@ public void CheckReturnFalseOnSuccessAndLowerLatencyThanConfiguredConfig() DiagnosticsFilterHelper .IsLatencyThresholdCrossed(distributedTracingOptions, OperationType.Read, response), $" Response time is {response.Diagnostics.GetClientElapsedTime().Milliseconds}ms " + - $"and Configured threshold value is {distributedTracingOptions.LatencyThresholdForDiagnosticEvent.Value.Milliseconds}ms " + + $"and Configured threshold value is {distributedTracingOptions.PointOperationLatencyThreshold.Milliseconds}ms " + $"and Is response Success : {response.StatusCode.IsSuccess()}" ); } @@ -56,13 +55,6 @@ public void CheckReturnFalseOnSuccessAndLowerLatencyThanConfiguredConfig() public void CheckReturnTrueOnFailedStatusCode() { Assert.IsTrue(this.rootTrace.Duration > TimeSpan.Zero); - - - DistributedTracingOptions distributedTracingOptions = new DistributedTracingOptions - { - LatencyThresholdForDiagnosticEvent = this.rootTrace.Duration.Add(TimeSpan.FromSeconds(1)) - }; - OpenTelemetryAttributes response = new OpenTelemetryAttributes { StatusCode = HttpStatusCode.BadRequest, @@ -71,11 +63,29 @@ public void CheckReturnTrueOnFailedStatusCode() Assert.IsTrue( !DiagnosticsFilterHelper - .IsSuccessfulResponse(response), + .IsSuccessfulResponse(response.StatusCode, response.SubStatusCode), $" Response time is {response.Diagnostics.GetClientElapsedTime().Milliseconds}ms " + - $"and Configured threshold value is {distributedTracingOptions.LatencyThresholdForDiagnosticEvent.Value.Milliseconds}ms " + $"and Is response Success : {response.StatusCode.IsSuccess()}"); + } + + [TestMethod] + public void CheckedDefaultThresholdBasedOnOperationType() + { + Assert.IsTrue(this.rootTrace.Duration > TimeSpan.Zero); + + CosmosThresholdOptions config = new CosmosThresholdOptions(); + Array values = Enum.GetValues(typeof(OperationType)); + + foreach(OperationType operationType in values) + { + TimeSpan defaultThreshold = DiagnosticsFilterHelper.DefaultThreshold(operationType, config); + + if(DiagnosticsFilterHelper.IsPointOperation(operationType)) + Assert.AreEqual(defaultThreshold, config.PointOperationLatencyThreshold); + else + Assert.AreEqual(defaultThreshold, config.NonPointOperationLatencyThreshold); + } } } diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Telemetry/OpenTelemetryRecorderTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Telemetry/OpenTelemetryRecorderTests.cs index 2095999f6c..601045cba5 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Telemetry/OpenTelemetryRecorderTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Telemetry/OpenTelemetryRecorderTests.cs @@ -6,12 +6,18 @@ namespace Microsoft.Azure.Cosmos.Tests.Telemetry { using System; using System.Collections.Generic; + using System.Collections.ObjectModel; using System.Linq; + using System.Net; using System.Reflection; + using System.Threading; + using System.Threading.Tasks; using Cosmos.Telemetry; using Microsoft.Azure.Cosmos.Diagnostics; + using Microsoft.Azure.Cosmos.Scripts; using Microsoft.Azure.Cosmos.Tracing; using Microsoft.VisualStudio.TestTools.UnitTesting; + using Moq; [TestClass] public class OpenTelemetryRecorderTests @@ -43,6 +49,201 @@ public void CheckExceptionsCompatibility() } } + /// + /// This test verifies whether OpenTelemetryResponse can be initialized using a specific type of response available in the SDK. + /// If any new response is added to the SDK in the future, it must be configured in either of the following dictionaries. + /// + [TestMethod] + public async Task CheckResponseCompatibility() + { + // This list contains all the response types which are not compatible with Open Telemetry Response + IReadOnlyList excludedResponses = new List() + { + "MediaResponse", // Part of dead code + "DocumentFeedResponse`1",// Part of dead code + "CosmosQuotaResponse",// Part of dead code + "StoredProcedureResponse`1" // Not supported as of now + }; + + // This dictionary contains a Key-Value pair where the Key represents the Response Type compatible with Open Telemetry Response, and the corresponding Value is a mocked instance. + // Essentially, at some point in the code, we send an instance of the response to Open Telemetry to retrieve relevant information. + IDictionary responseInstances = new Dictionary() + { + { "PartitionKeyRangeBatchResponse", await OpenTelemetryRecorderTests.GetPartitionKeyRangeBatchResponse() }, + { "TransactionalBatchResponse", await OpenTelemetryRecorderTests.GetTransactionalBatchResponse() }, + { "QueryResponse", new Mock().Object }, + { "QueryResponse`1", OpenTelemetryRecorderTests.GetQueryResponseWithGenerics()}, + { "ReadFeedResponse`1", ReadFeedResponse.CreateResponse (new ResponseMessage(HttpStatusCode.OK),MockCosmosUtil.Serializer)}, + { "ClientEncryptionKeyResponse", new Mock().Object}, + { "ContainerResponse", new Mock().Object }, + { "ItemResponse`1", new Mock>().Object }, + { "DatabaseResponse", new Mock().Object }, + { "PermissionResponse", new Mock().Object }, + { "ThroughputResponse", new Mock().Object }, + { "UserResponse", new Mock().Object }, + { "ChangeFeedEstimatorFeedResponse", ChangefeedResponseFunc}, + { "ChangeFeedEstimatorEmptyFeedResponse", ChangeFeedEstimatorEmptyFeedResponseFunc }, + { "StoredProcedureExecuteResponse`1",new Mock>().Object }, + { "StoredProcedureResponse", new Mock().Object }, + { "TriggerResponse", new Mock().Object }, + { "UserDefinedFunctionResponse", new Mock().Object } + }; + + Assembly asm = OpenTelemetryRecorderTests.GetAssemblyLocally(DllName); + + // Get all types (including internal) defined in the assembly + IEnumerable actualClasses = asm + .GetTypes() + .Where(type => + (type.Name.EndsWith("Response") || type.Name.EndsWith("Response`1")) && // Ending with Response and Response + !type.Name.Contains("OpenTelemetryResponse") && // Excluding OpenTelemetryResponse because we are testing this class + !type.IsAbstract && // Excluding abstract classes + !type.IsInterface && // Excluding interfaces + !excludedResponses.Contains(type.Name)); // Excluding all the types defined in excludedResponses list + + foreach (Type className in actualClasses) + { + Assert.IsTrue(responseInstances.TryGetValue(className.Name, out object instance), $" New Response type found i.e.{className.Name}"); + + if (instance is TransactionalBatchResponse transactionInstance) + { + _ = new OpenTelemetryResponse(transactionInstance); + } + else if (instance is ResponseMessage responseMessageInstance) + { + _ = new OpenTelemetryResponse(responseMessageInstance); + } + else if (instance is FeedResponse feedResponseInstance) + { + _ = new OpenTelemetryResponse(feedResponseInstance); + } + else if (instance is Response responseInstance) + { + _ = new OpenTelemetryResponse(responseInstance); + } + else if (instance is Response encrypResponse) + { + _ = new OpenTelemetryResponse(encrypResponse); + } + else if (instance is Response containerPropertiesResponse) + { + _ = new OpenTelemetryResponse(containerPropertiesResponse); + } + else if (instance is Response databasePropertiesResponse) + { + _ = new OpenTelemetryResponse(databasePropertiesResponse); + } + else if (instance is Response permissionPropertiesResponse) + { + _ = new OpenTelemetryResponse(permissionPropertiesResponse); + } + else if (instance is Response throughputPropertiesResponse) + { + _ = new OpenTelemetryResponse(throughputPropertiesResponse); + } + else if (instance is Response userPropertiesResponse) + { + _ = new OpenTelemetryResponse(userPropertiesResponse); + } + else if (instance is Func> fucntion) + { + _ = new OpenTelemetryResponse(fucntion(className)); + } + else if (instance is Response storedProcedureResponse) + { + _ = new OpenTelemetryResponse(storedProcedureResponse); + } + else if (instance is Response triggerResponse) + { + _ = new OpenTelemetryResponse(triggerResponse); + } + else if (instance is Response userDefinedFunctionResponse) + { + _ = new OpenTelemetryResponse(userDefinedFunctionResponse); + } + else if (instance is Response> storedProcedureExecuteResponse) + { + _ = new OpenTelemetryResponse>(storedProcedureExecuteResponse); + } + else + { + Assert.Fail("Opentelemetry does not support this response type " + className.Name); + } + } + } + + private static readonly Func> ChangefeedResponseFunc = (Type type) => + { + ConstructorInfo constructorInfo = type + .GetConstructor(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(ITrace), typeof(ReadOnlyCollection), typeof(double) }, null); + if (constructorInfo != null) + { + return (FeedResponse)constructorInfo.Invoke( + new object[] { + NoOpTrace.Singleton, new List().AsReadOnly(), 10 }); + } + + return null; + }; + + private static readonly Func> ChangeFeedEstimatorEmptyFeedResponseFunc = (Type type) => + { + ConstructorInfo constructorInfo = type + .GetConstructor(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(ITrace) }, null); + if (constructorInfo != null) + { + return (FeedResponse)constructorInfo.Invoke( + new object[] { + NoOpTrace.Singleton}); + } + + return null; + }; + + private static QueryResponse GetQueryResponseWithGenerics() + { + return QueryResponse.CreateResponse( + QueryResponse.CreateFailure( + new CosmosQueryResponseMessageHeaders(null, null, Documents.ResourceType.Document, "col"), HttpStatusCode.OK, new RequestMessage(), null, NoOpTrace.Singleton), + MockCosmosUtil.Serializer); + } + + private static async Task GetTransactionalBatchResponse(ItemBatchOperation[] arrayOperations = null) + { + if(arrayOperations == null) + { + arrayOperations = new ItemBatchOperation[1]; + arrayOperations[0] = new ItemBatchOperation(Documents.OperationType.Read, 0, new PartitionKey("0")); + } + + SinglePartitionKeyServerBatchRequest batchRequest = await SinglePartitionKeyServerBatchRequest.CreateAsync( + partitionKey: null, + operations: new ArraySegment(arrayOperations), + serializerCore: MockCosmosUtil.Serializer, + trace: NoOpTrace.Singleton, + cancellationToken: default); + + return await TransactionalBatchResponse.FromResponseMessageAsync( + new ResponseMessage(HttpStatusCode.OK) { Content = new System.IO.MemoryStream() }, + batchRequest, + MockCosmosUtil.Serializer, + true, + NoOpTrace.Singleton, + CancellationToken.None); + } + + private static async Task GetPartitionKeyRangeBatchResponse() + { + ItemBatchOperation[] arrayOperations = new ItemBatchOperation[1]; + + arrayOperations[0] = new ItemBatchOperation(Documents.OperationType.Read, 0, new PartitionKey("0")); + PartitionKeyRangeBatchResponse partitionKeyRangeBatchResponse = new PartitionKeyRangeBatchResponse( + arrayOperations.Length, + await OpenTelemetryRecorderTests.GetTransactionalBatchResponse(arrayOperations), + MockCosmosUtil.Serializer); + + return partitionKeyRangeBatchResponse; + } [TestMethod] public void MarkFailedTest() diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Tracing/TraceWriterBaselineTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Tracing/TraceWriterBaselineTests.cs index fe3dc7054f..2d69341182 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Tracing/TraceWriterBaselineTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Tracing/TraceWriterBaselineTests.cs @@ -41,7 +41,7 @@ namespace Microsoft.Azure.Cosmos.Tests.Tracing public sealed class TraceWriterBaselineTests : BaselineTests { private static readonly Lazy MockQueryMetrics = new Lazy(() => new QueryMetrics( - BackendMetricsTests.MockBackendMetrics, + ServerSideMetricsTests.ServerSideMetrics, IndexUtilizationInfoTests.MockIndexUtilizationInfo, ClientSideMetricsTests.MockClientSideMetrics)); @@ -316,7 +316,7 @@ public void TraceData() { QueryMetricsTraceDatum datum = new QueryMetricsTraceDatum( new Lazy(() => new QueryMetrics( - BackendMetricsTests.MockBackendMetrics, + ServerSideMetricsTests.ServerSideMetrics, IndexUtilizationInfoTests.MockIndexUtilizationInfo, ClientSideMetricsTests.MockClientSideMetrics))); rootTrace.AddDatum("Query Metrics", datum); diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Utils/MockCosmosUtil.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Utils/MockCosmosUtil.cs index 8ea04f99a5..77ba6981cb 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Utils/MockCosmosUtil.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Utils/MockCosmosUtil.cs @@ -34,16 +34,18 @@ public static CosmosClient CreateMockCosmosClient( Cosmos.ConsistencyLevel? accountConsistencyLevel = null, bool enableTelemetry = false) { - DocumentClient documentClient = accountConsistencyLevel.HasValue ? new MockDocumentClient(accountConsistencyLevel.Value) : new MockDocumentClient(); - CosmosClientBuilder cosmosClientBuilder = new CosmosClientBuilder("http://localhost", MockCosmosUtil.RandomInvalidCorrectlyFormatedAuthKey); - customizeClientBuilder?.Invoke(cosmosClientBuilder); - if(enableTelemetry) + ConnectionPolicy policy = new ConnectionPolicy { - documentClient.clientTelemetry = new Mock().Object; - - cosmosClientBuilder.WithTelemetryEnabled(); - } + CosmosClientTelemetryOptions = new CosmosClientTelemetryOptions + { + DisableSendingMetricsToService = !enableTelemetry + } + }; + DocumentClient documentClient = accountConsistencyLevel.HasValue ? new MockDocumentClient(accountConsistencyLevel.Value, policy) : new MockDocumentClient(policy); + CosmosClientBuilder cosmosClientBuilder = new CosmosClientBuilder("http://localhost", MockCosmosUtil.RandomInvalidCorrectlyFormatedAuthKey); + + customizeClientBuilder?.Invoke(cosmosClientBuilder); return cosmosClientBuilder.Build(documentClient); } diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Utils/MockDocumentClient.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Utils/MockDocumentClient.cs index 12d776fb38..b0c29eb016 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Utils/MockDocumentClient.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Utils/MockDocumentClient.cs @@ -15,6 +15,7 @@ namespace Microsoft.Azure.Cosmos.Tests using Microsoft.Azure.Cosmos.Common; using Microsoft.Azure.Cosmos.Query.Core.QueryPlan; using Microsoft.Azure.Cosmos.Routing; + using Microsoft.Azure.Cosmos.Telemetry; using Microsoft.Azure.Cosmos.Tracing; using Microsoft.Azure.Documents; using Microsoft.Azure.Documents.Collections; @@ -27,14 +28,14 @@ internal class MockDocumentClient : DocumentClient, IAuthorizationTokenProvider, Mock partitionKeyRangeCache; private readonly Cosmos.ConsistencyLevel accountConsistencyLevel; - public MockDocumentClient() - : base(new Uri("http://localhost"), MockCosmosUtil.RandomInvalidCorrectlyFormatedAuthKey) + public MockDocumentClient(ConnectionPolicy connectionPolicy = null) + : base(new Uri("http://localhost"), MockCosmosUtil.RandomInvalidCorrectlyFormatedAuthKey, connectionPolicy) { this.Init(); } - public MockDocumentClient(Cosmos.ConsistencyLevel accountConsistencyLevel) - : base(new Uri("http://localhost"), null) + public MockDocumentClient(Cosmos.ConsistencyLevel accountConsistencyLevel, ConnectionPolicy connectionPolicy = null) + : base(new Uri("http://localhost"), connectionPolicy) { this.accountConsistencyLevel = accountConsistencyLevel; this.Init(); @@ -261,6 +262,14 @@ private void Init() this.MockGlobalEndpointManager.Setup(gep => gep.ResolveServiceEndpoint(It.IsAny())).Returns(new Uri("http://localhost")); this.MockGlobalEndpointManager.Setup(gep => gep.InitializeAccountPropertiesAndStartBackgroundRefresh(It.IsAny())); SessionContainer sessionContainer = new SessionContainer(this.ServiceEndpoint.Host); + + this.telemetryToServiceHelper = TelemetryToServiceHelper.CreateAndInitializeClientConfigAndTelemetryJob("test-client", + this.ConnectionPolicy, + new Mock().Object, + new Mock().Object, + this.ServiceEndpoint, + this.GlobalEndpointManager, + default); this.sessionContainer = sessionContainer; } diff --git a/azure-pipelines-nightly.yml b/azure-pipelines-nightly.yml index 04a53968aa..f0f7f3faea 100644 --- a/azure-pipelines-nightly.yml +++ b/azure-pipelines-nightly.yml @@ -16,10 +16,13 @@ variables: VmImage: windows-latest # https://docs.microsoft.com/en-us/azure/devops/pipelines/agents/hosted?view=azure-devops BuildConfiguration: Release Packaging.EnableSBOMSigning: true + Codeql.Enabled: true stages: - stage: displayName: Generate nightly GA + variables: + Codeql.BuildIdentifier: ga jobs: - template: templates/nuget-pack.yml parameters: @@ -32,6 +35,8 @@ stages: CleanupFolder: true - stage: displayName: Generate nightly preview + variables: + Codeql.BuildIdentifier: preview jobs: - template: templates/nuget-pack.yml parameters: @@ -41,4 +46,4 @@ stages: ReleasePackage: true OutputPath: '$(Build.ArtifactStagingDirectory)/bin/AnyCPU/$(BuildConfiguration)/Microsoft.Azure.Cosmos' BlobVersion: 'nightly-preview' - CleanupFolder: true \ No newline at end of file + CleanupFolder: true diff --git a/azure-pipelines-official.yml b/azure-pipelines-official.yml index 510bf5f6f8..2410dfb61f 100644 --- a/azure-pipelines-official.yml +++ b/azure-pipelines-official.yml @@ -7,6 +7,7 @@ variables: VmImage: windows-latest # https://docs.microsoft.com/en-us/azure/devops/pipelines/agents/hosted?view=azure-devops BuildConfiguration: Release Packaging.EnableSBOMSigning: true + OS: 'Windows' stages: - stage: @@ -22,6 +23,38 @@ stages: BuildConfiguration: $(BuildConfiguration) Arguments: $(ReleaseArguments) VmImage: $(VmImage) + + - job: + displayName: TelemetryToService $(BuildConfiguration) + timeoutInMinutes: 120 + condition: and(succeeded(), eq('$(OS)', 'Windows')) + pool: + vmImage: windows-2019 + + steps: + - checkout: self # self represents the repo where the initial Pipelines YAML file was found + clean: true # if true, execute `execute git clean -ffdx && git reset --hard HEAD` before fetching + + # Add this Command to Include the .NET 6 SDK + - task: UseDotNet@2 + displayName: Use .NET 6.0 + inputs: + packageType: 'sdk' + version: '6.x' + + - task: DotNetCoreCLI@2 + displayName: Integration Test With Client Telemetry Service + condition: succeeded() + inputs: + command: test + projects: 'Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/*.csproj' + arguments: --filter "TestCategory=ClientTelemetryRelease" --verbosity normal --configuration $(BuildConfiguration) /p:OS=$(OS) + nugetConfigPath: NuGet.config + publishTestResults: true + testRunTitle: Microsoft.Azure.Cosmos.EmulatorTests + env: + COSMOSDB_ACCOUNT_CONNECTION_STRING: $(COSMOSDB_ACCOUNT_CONNECTION_STRING) # Real Account Connection String used by Integration Tests while running as part of release pipeline + CLIENT_TELEMETRY_SERVICE_ENDPOINT: $(CLIENT_TELEMETRY_SERVICE_ENDPOINT) # Client telemetry service url returned by configured account client config API - stage: displayName: Publish diff --git a/changelog.md b/changelog.md index ab733a4137..8b08e37210 100644 --- a/changelog.md +++ b/changelog.md @@ -1,6 +1,6 @@ ## Recommended version -The **minimum recommended version is [3.33.0](#3.33.0) when using Direct mode and [3.35.1](#3.35.1) for Gateway mode**. +The **minimum recommended version is [3.35.4](#3.35.4)**. Make sure that your applications, when using the .NET V3 SDK, are using at least the version described here to have all the critical fixes. @@ -13,6 +13,46 @@ Preview features are treated as a separate branch and will not be included in th The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +### [3.36.0](https://www.nuget.org/packages/Microsoft.Azure.Cosmos/3.36.0) - 2023-10-17 + +#### Fixed +- [4039](https://github.com/Azure/azure-cosmos-dotnet-v3/pull/4039) GatewayAddressCache: Fixes Unobserved Exception During Background Address Refresh (#4039) +- [4098](https://github.com/Azure/azure-cosmos-dotnet-v3/pull/4098) Distributed Tracing: Fixes dependency failure on appinsights (#4098) +- [4097](https://github.com/Azure/azure-cosmos-dotnet-v3/pull/4097) Distributed Tracing: Fixes SDK responses compatibility with opentelemetry response (#4097) +- [4111](https://github.com/Azure/azure-cosmos-dotnet-v3/pull/4111) Distributed Tracing: Fixes traceid null exception issue (#4111) + +#### Added +- [4009](https://github.com/Azure/azure-cosmos-dotnet-v3/pull/4009) Query: Adds ODE continuation token support for non-ODE pipelines (#4009) +- [4078](https://github.com/Azure/azure-cosmos-dotnet-v3/pull/4078) Query: Adds LINQ RegexMatch Extension method (#4078) +- [4001](https://github.com/Azure/azure-cosmos-dotnet-v3/pull/4001) Query: Adds public backend metrics property to Diagnostics (#4001) +- [4016](https://github.com/Azure/azure-cosmos-dotnet-v3/pull/4016) CosmosClientOptions: Adds support for multiple formats of Azure region names (#4016) +- [4056](https://github.com/Azure/azure-cosmos-dotnet-v3/pull/4056) Client Telemetry: Adds new public APIs (#4056) +> Note: Refer this [3983](https://github.com/Azure/azure-cosmos-dotnet-v3/issues/3983) for API signature and default values. +- [4119](https://github.com/Azure/azure-cosmos-dotnet-v3/pull/4119) TriggerOperation: Adds Upsert Operation Support(#4119) + +### [3.356.0-preview](https://www.nuget.org/packages/Microsoft.Azure.Cosmos/3.36.0-preview) - 2023-10-17 + +#### Added + - [4056](https://github.com/Azure/azure-cosmos-dotnet-v3/pull/4056) Client Telemetry: Adds new public APIs (#4056). WARNING: This is breaking change for preview SDK + > Note: `isDistributedTracingEnabled` is removed from `CosmosClientOptions` and `withDistributedTracing()` is removed from `CosmosClientBuilder`. + > Refer this [3983](https://github.com/Azure/azure-cosmos-dotnet-v3/issues/3983) for new API signature and default values + +### [3.35.4-preview](https://www.nuget.org/packages/Microsoft.Azure.Cosmos/3.35.4-preview) - 2023-09-15 +### [3.35.4](https://www.nuget.org/packages/Microsoft.Azure.Cosmos/3.35.4) - 2023-09-15 + +#### Fixed +- [3934](https://github.com/Azure/azure-cosmos-dotnet-v3/pull/3934) Subpartitioning: Fixes bug for queries on subpartitioned containers with split physical partitions + +### [3.35.3-preview](https://www.nuget.org/packages/Microsoft.Azure.Cosmos/3.35.3-preview) - 2023-08-10 +### [3.35.3](https://www.nuget.org/packages/Microsoft.Azure.Cosmos/3.35.3) - 2023-08-10 + + +#### Fixed +- [4030](https://github.com/Azure/azure-cosmos-dotnet-v3/pull/4030) Upgrade Resiliency: Fixes Race Condition by Calling Dispose Too Early + +#### Added +- [4019](https://github.com/Azure/azure-cosmos-dotnet-v3/pull/4019) Upgrade Resiliency: Disables Replica Validation Feature By Default in Preview (The feature was previously enabled by default in the [`3.35.2-preview`](https://www.nuget.org/packages/Microsoft.Azure.Cosmos/3.35.2-preview) release) + ### [3.35.2-preview](https://www.nuget.org/packages/Microsoft.Azure.Cosmos/3.35.2-preview) - 2023-07-17 #### Fixed @@ -44,6 +84,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [3836](https://github.com/Azure/azure-cosmos-dotnet-v3/pull/3836) Integrated cache: Adds BypassIntegratedCache to DedicatedGatewayRequestOptions - [3909](https://github.com/Azure/azure-cosmos-dotnet-v3/pull/3909) Query: Adds EnableOptimisticDirectExecution in QueryRequestOptions enabled by default +Recommendation for customers regarding Optimistic Direct Execution: + +Starting Version 3.35.0, the Preview SDK enables the ODE feature by default. This can potentially cause a new type of continuation token to be generated. Such a token is not recognized by the older SDKs by design and this could result in a Malformed Continuation Token Exception. +If you have a scenario where tokens generated from the newer SDKs are used by an older SDK, we recommend a 2 step approach to upgrade: + +- Upgrade to the new SDK and disable ODE, both together as part of a single deployment. Wait for all nodes to upgrade. + - In order to disable ODE, set EnableOptimisticDirectExecution to false in the QueryRequestOptions. +- Enable ODE as part of second deployment for all nodes. + ### [3.35.0](https://www.nuget.org/packages/Microsoft.Azure.Cosmos/3.35.0) - 2023-06-19 #### Fixed @@ -191,7 +240,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [#3433](https://github.com/Azure/azure-cosmos-dotnet-v3/pull/3433) CosmosOperationCanceledException: Adds serializable functionality - [#3419](https://github.com/Azure/azure-cosmos-dotnet-v3/pull/3419) Documentation: Removes mention of obsolete disableAutomaticIdGeneration - [#3404](https://github.com/Azure/azure-cosmos-dotnet-v3/pull/3404) Patch: Adds public to `PatchOperation` class for testing -- [#3400](https://github.com/Azure/azure-cosmos-dotnet-v3/pull/3400) Query: Adds new system strings in JsonBinaryEncoding, replacing 1-byte user strings - [#3380](https://github.com/Azure/azure-cosmos-dotnet-v3/pull/3380) Query: Adds aggressive prefetching for `GROUP BY` and `COUNT(DISTINCT)` ### [3.30.1](https://www.nuget.org/packages/Microsoft.Azure.Cosmos/3.30.1) - 2022-09-01 diff --git a/docs/LocalQuorum.md b/docs/LocalQuorum.md index 5ca45e9055..a971955006 100644 --- a/docs/LocalQuorum.md +++ b/docs/LocalQuorum.md @@ -37,23 +37,23 @@ upgradeConsistencyProperty.SetValue(clientOptions, true); CosmosClient cosmosClient = new CosmosClient(..., clientOptions); ``` -#### Per request upgrade consistency to Bounded -> ###### Please note that Bounded here is only used as HINT for SDK to do quorum reads +#### Per request upgrade consistency to Strong +> ###### Please note that Strong here is only used as HINT for SDK to do quorum reads > ###### It will not impact CosmosDB account or write consistency levels ```C# ItemRequestOptions requestOption = new ItemRequestOptions(); -requestOption.ConsistencyLevel = ConsistencyLevel.Bounded; +requestOption.ConsistencyLevel = ConsistencyLevel.Strong; T item = await container.ReadItemAsync(docId, new PartitionKey(docPartitionKey), requestOption); ``` ```C# QueryRequestOptions requestOption = new QueryRequestOptions(); -requestOption.ConsistencyLevel = ConsistencyLevel.Bounded; +requestOption.ConsistencyLevel = ConsistencyLevel.Strong; await container.GetItemQueryIterator(queryText, continuationToken, requestOption); ``` -> #### Please use Bounded only for per request options as pattern +> #### Please use Strong only for per request options as pattern > #### Single master account possibly Strong == Bounded (**TBD**) \ No newline at end of file diff --git a/templates/build-test.yml b/templates/build-test.yml index 3a016080e1..8d22aeb758 100644 --- a/templates/build-test.yml +++ b/templates/build-test.yml @@ -5,9 +5,9 @@ parameters: Arguments: '' VmImage: '' # https://docs.microsoft.com/en-us/azure/devops/pipelines/agents/hosted?view=azure-devops OS: 'Windows' - EmulatorPipeline1Arguments: ' --filter "TestCategory!=Quarantine & TestCategory!=Functional & (TestCategory=Query|TestCategory=ReadFeed|TestCategory=Batch|TestCategory=ChangeFeed)" --verbosity normal ' - EmulatorPipeline2Arguments: ' --filter "TestCategory!=Quarantine & TestCategory!=Functional & TestCategory!=Query & TestCategory!=ReadFeed & TestCategory!=Batch & TestCategory!=ChangeFeed" --verbosity normal ' - EmulatorPipeline1CategoryListName: ' Query, ChangeFeed, ReadFeed, Batch ' # Divided in 2 categories to run them in parallel and reduce the PR feedback time + EmulatorPipeline1Arguments: ' --filter "TestCategory!=Quarantine & TestCategory!=Functional & TestCategory!=ClientTelemetryRelease & (TestCategory=ClientTelemetryEmulator|TestCategory=Query|TestCategory=ReadFeed|TestCategory=Batch|TestCategory=ChangeFeed)" --verbosity normal ' + EmulatorPipeline2Arguments: ' --filter "TestCategory!=Quarantine & TestCategory!=Functional & TestCategory!=ClientTelemetryRelease & TestCategory!=ClientTelemetryEmulator & TestCategory!=Query & TestCategory!=ReadFeed & TestCategory!=Batch & TestCategory!=ChangeFeed" --verbosity normal ' + EmulatorPipeline1CategoryListName: ' Client Telemetry, Query, ChangeFeed, ReadFeed, Batch ' # Divided in 2 categories to run them in parallel and reduce the PR feedback time EmulatorPipeline2CategoryListName: ' Others ' jobs: