From 94e811f848bbed1ededd422bd1efce9305721632 Mon Sep 17 00:00:00 2001 From: Debdatta Kunda <87335885+kundadebdatta@users.noreply.github.com> Date: Fri, 24 Mar 2023 07:04:44 -0700 Subject: [PATCH] [Internal] Msdata/Direct: Refactors msdata/direct branch with latest v3 master and Cosmos.Direct v3.30.4 (#3776) * [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. * Code changes to sync up msdata direct. * Removing direct dependency from documents.test. --------- 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> --- Directory.Build.props | 6 +- .../contracts/API_3.32.1-preview.txt | 1531 +++++++++++++++++ .../contracts/API_3.32.1.txt | 1478 ++++++++++++++++ .../contracts/API_3.32.2-preview.txt | 1531 +++++++++++++++++ .../contracts/API_3.32.2.txt | 1478 ++++++++++++++++ .../DocumentServiceLeaseManagerCosmos.cs | 48 +- Microsoft.Azure.Cosmos/src/CosmosClient.cs | 5 +- .../src/Handler/RequestInvokerHandler.cs | 29 + .../src/Handler/TelemetryHandler.cs | 5 +- .../src/Linq/CosmosLinqExtensions.cs | 2 +- .../src/Linq/ExpressionToSQL.cs | 47 +- .../src/PartitionKeyBuilder.cs | 7 +- .../src/Query/Core/Parser/CstToAstVisitor.cs | 20 + .../src/Query/Core/Parser/IsqlListener.cs | 24 + .../src/Query/Core/Parser/IsqlVisitor.cs | 14 + .../src/Query/Core/Parser/sql.g4 | 6 + .../src/Query/Core/Parser/sqlBaseListener.cs | 28 + .../src/Query/Core/Parser/sqlBaseVisitor.cs | 22 + .../src/Query/Core/Parser/sqlLexer.cs | 978 +++++------ .../src/Query/Core/Parser/sqlParser.cs | 579 ++++--- .../CosmosQueryExecutionContextFactory.cs | 16 +- .../src/Query/v3Query/QueryIterator.cs | 6 +- .../src/RMResources.Designer.cs | 232 +++ Microsoft.Azure.Cosmos/src/RMResources.resx | 94 +- .../src/ReadManyQueryHelper.cs | 8 +- .../Resource/Container/ContainerCore.Items.cs | 13 +- .../src/Resource/Database/Database.cs | 7 +- .../src/Resource/Database/DatabaseCore.cs | 8 +- .../Resource/Settings/ContainerProperties.cs | 26 +- .../src/Routing/AsyncCacheNonBlocking.cs | 6 +- .../src/Routing/GatewayAddressCache.cs | 61 +- .../src/Routing/GlobalAddressResolver.cs | 25 +- .../Serializer/CosmosLinqSerializerOptions.cs | 9 - .../SqlObjects/SqlFirstScalarExpression.cs | 40 + .../src/SqlObjects/SqlLastScalarExpression.cs | 40 + .../Visitors/SqlObjectEqualityVisitor.cs | 30 + .../SqlObjects/Visitors/SqlObjectHasher.cs | 16 + .../Visitors/SqlObjectObfuscator.cs | 12 +- .../Visitors/SqlObjectTextSerializer.cs | 16 + .../SqlObjects/Visitors/SqlObjectVisitor.cs | 2 + .../SqlObjectVisitor{TArg,TOutput}.cs | 2 + .../Visitors/SqlObjectVisitor{TResult}.cs | 2 + .../Visitors/SqlScalarExpressionVisitor.cs | 2 + ...qlScalarExpressionVisitor{TArg,TOutput}.cs | 2 + .../SqlScalarExpressionVisitor{TResult}.cs | 2 + .../src/Telemetry/ClientTelemetry.cs | 213 +-- .../src/Telemetry/ClientTelemetryHelper.cs | 92 +- .../src/Telemetry/ClientTelemetryOptions.cs | 42 +- .../Telemetry/ClientTelemetryPayloadWriter.cs | 161 ++ .../src/Telemetry/ClientTelemetryProcessor.cs | 142 ++ .../Models/ClientTelemetryProperties.cs | 77 + .../src/Telemetry/Models/RequestInfo.cs | 66 + .../ClientSideRequestStatisticsTraceDatum.cs | 1 + .../Tracing/TraceData/SummaryDiagnostics.cs | 24 +- .../Tracing/TraceWriter.TraceJsonWriter.cs | 4 +- .../Tracing/TraceWriter.TraceTextWriter.cs | 1 + .../src/ValidationHelpers.cs | 9 +- .../src/direct/BytesDeserializer.cs | 21 +- .../src/direct/BytesSerializer.cs | 2 + Microsoft.Azure.Cosmos/src/direct/Channel.cs | 3 +- .../src/direct/ChannelProperties.cs | 8 +- .../src/direct/CloneableStream.cs | 36 +- .../src/direct/Connection.cs | 12 +- .../src/direct/Constants.cs | 58 +- .../src/direct/CpuMonitor.cs | 82 +- .../src/direct/CustomTypeExtensions.cs | 294 ++-- .../src/direct/DefaultTrace.cs | 3 +- .../DictionaryNameValueCollectionFactory.cs | 49 - .../src/direct/Dispatcher.cs | 67 +- .../src/direct/DocumentServiceRequest.cs | 4 + .../src/direct/GoneAndRetryWithRetryPolicy.cs | 35 +- .../src/direct/HttpConstants.cs | Bin 110202 -> 114490 bytes .../src/direct/HttpException.cs | 6 + .../src/direct/HttpTransportClient.cs | 9 + .../src/direct/IAddressResolver.cs | 4 - .../src/direct/InAccountRestoreParameters.cs | 16 +- .../src/direct/LoadBalancingChannel.cs | 4 +- .../src/direct/LocationNames.cs | 3 +- .../NameValueCollectionWrapperFactory.cs | 49 - .../src/direct/OperationType.cs | 11 +- .../PartitionKeyInternalJsonConverter.cs | 3 +- Microsoft.Azure.Cosmos/src/direct/Paths.cs | 33 +- .../src/direct/PathsHelper.cs | 20 + .../src/direct/PerfCounters.cs | 170 +- .../src/direct/PriorityLevel.cs | 7 +- .../src/direct/RegionProximityUtil.cs | 6 +- .../src/direct/RequestNameValueCollection.cs | 389 ++++- .../src/direct/RequestOptions.cs | 2 +- .../src/direct/RntbdConstants.cs | 357 +--- .../src/direct/RntbdStreamReader.cs | 24 +- .../src/direct/SDKSupportedCapabilities.cs | 1 + .../src/direct/SnapshotContent.cs | 13 + .../src/direct/StatusCodes.cs | 17 +- .../src/direct/StoreClientFactory.cs | 6 +- .../src/direct/StoreReader.cs | 10 +- .../StoreResponseNameValueCollection.cs | 285 ++- .../direct/SupportedSerializationFormats.cs | 29 + .../src/direct/SystemSynchronizationScope.cs | 158 ++ .../src/direct/TransportAddressUri.cs | 6 + .../src/direct/TransportSerialization.cs | 281 ++- .../src/direct/WFConstants.cs | Bin 22452 -> 24166 bytes .../rntbd2/HeadersTransportSerialization.cs | 756 ++++++++ .../rntbd2/HeadersTransportSerialization.tt | 341 ++++ .../src/direct/rntbd2/TransportClient.cs | 11 +- ...iterBaselineTests.BatchOperationsAsync.xml | 2 +- ...riterBaselineTests.BulkOperationsAsync.xml | 64 +- ...aceWriterBaselineTests.ChangeFeedAsync.xml | 368 +--- ...eWriterBaselineTests.MiscellanousAsync.xml | 4 +- ...neTests.PointOperationsExceptionsAsync.xml | 12 +- ...EndTraceWriterBaselineTests.QueryAsync.xml | 14 +- ...TraceWriterBaselineTests.ReadFeedAsync.xml | 8 +- ...TraceWriterBaselineTests.ReadManyAsync.xml | 4 +- ...selineTests.StreamPointOperationsAsync.xml | 8 +- ...aselineTests.TypedPointOperationsAsync.xml | 8 +- ...BaselineTests.TestLiteralSerialization.xml | 2 +- ...rializerBaseline.TestMemberInitializer.xml | 48 - .../ClientTelemetryTests.cs | 92 +- .../CosmosContainerTests.cs | 4 +- .../CosmosMultiHashTest.cs | 429 +++-- .../CosmosReadManyItemsTests.cs | 70 +- ...reateFromPartitionKeyAsyncEmulatorTests.cs | 344 ++++ .../LinqTestsCommon.cs | 4 +- .../LinqTranslationBaselineTests.cs | 2 +- ...TranslationWithCustomSerializerBaseline.cs | 159 -- ...icrosoft.Azure.Cosmos.EmulatorTests.csproj | 4 - .../Query/BypassQueryParsingTests.cs | 64 + .../OptimisticDirectExecutionQueryTests.cs | 286 ++- .../EndToEndTraceWriterBaselineTests.cs | 45 - ...teSubquerySqlParserBaselineTests.First.xml | 92 + ...ateSubquerySqlParserBaselineTests.Last.xml | 92 + ...ExpressionSqlParserBaselineTests.First.xml | 47 + ...rExpressionSqlParserBaselineTests.Last.xml | 47 + ...raceWriterBaselineTests.ScenariosAsync.xml | 6 +- ...TraceWriterBaselineTests.Serialization.xml | 14 +- .../TraceWriterBaselineTests.TraceData.xml | 14 +- .../DocumentServiceLeaseManagerCosmosTests.cs | 195 +++ .../ClientTelemetryTests.cs | 57 +- .../Contracts/ContractTests.cs | 6 +- .../Contracts/DotNetPreviewSDKAPI.json | 63 - .../Contracts/DotNetSDKAPI.json | 63 + .../GatewayAddressCacheTests.cs | 38 +- .../HandlerTests.cs | 148 ++ .../Microsoft.Azure.Cosmos.Tests.csproj | 37 +- .../AggregateProjectionDector.cs | 12 + .../AggregateProjectionTransformer.cs | 12 + .../ScalarExpressionEvaluator.cs | 20 + .../Query/OfflineEngine/SqlInterpreter.cs | 10 + ...AggregateSubquerySqlParserBaselineTests.cs | 99 +- .../ScalarExpressionSqlParserBaselineTests.cs | 64 + .../ClientTelemetryPayloadWithoutMetrics.json | 135 ++ .../Telemetry/ClientTelemetryTests.cs | 258 +++ .../Tracing/TraceTests.cs | 2 + .../ValidationHelpersTests.cs | 98 +- changelog.md | 13 + templates/static-tools.yml | 38 +- 155 files changed, 13524 insertions(+), 3249 deletions(-) create mode 100644 Microsoft.Azure.Cosmos/contracts/API_3.32.1-preview.txt create mode 100644 Microsoft.Azure.Cosmos/contracts/API_3.32.1.txt create mode 100644 Microsoft.Azure.Cosmos/contracts/API_3.32.2-preview.txt create mode 100644 Microsoft.Azure.Cosmos/contracts/API_3.32.2.txt create mode 100644 Microsoft.Azure.Cosmos/src/SqlObjects/SqlFirstScalarExpression.cs create mode 100644 Microsoft.Azure.Cosmos/src/SqlObjects/SqlLastScalarExpression.cs create mode 100644 Microsoft.Azure.Cosmos/src/Telemetry/ClientTelemetryPayloadWriter.cs create mode 100644 Microsoft.Azure.Cosmos/src/Telemetry/ClientTelemetryProcessor.cs create mode 100644 Microsoft.Azure.Cosmos/src/Telemetry/Models/RequestInfo.cs delete mode 100644 Microsoft.Azure.Cosmos/src/direct/DictionaryNameValueCollectionFactory.cs delete mode 100644 Microsoft.Azure.Cosmos/src/direct/NameValueCollectionWrapperFactory.cs create mode 100644 Microsoft.Azure.Cosmos/src/direct/SupportedSerializationFormats.cs create mode 100644 Microsoft.Azure.Cosmos/src/direct/SystemSynchronizationScope.cs create mode 100644 Microsoft.Azure.Cosmos/src/direct/rntbd2/HeadersTransportSerialization.cs create mode 100644 Microsoft.Azure.Cosmos/src/direct/rntbd2/HeadersTransportSerialization.tt delete mode 100644 Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/BaselineTest/TestBaseline/LinqTranslationWithCustomSerializerBaseline.TestMemberInitializer.xml create mode 100644 Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/FeedRangeCreateFromPartitionKeyAsyncEmulatorTests.cs delete mode 100644 Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/LinqTranslationWithCustomSerializerBaseline.cs create mode 100644 Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Query/BypassQueryParsingTests.cs create mode 100644 Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/TestBaseline/AggregateSubquerySqlParserBaselineTests.First.xml create mode 100644 Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/TestBaseline/AggregateSubquerySqlParserBaselineTests.Last.xml create mode 100644 Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/TestBaseline/ScalarExpressionSqlParserBaselineTests.First.xml create mode 100644 Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/TestBaseline/ScalarExpressionSqlParserBaselineTests.Last.xml create mode 100644 Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Telemetry/ClientTelemetryPayloadWithoutMetrics.json create mode 100644 Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Telemetry/ClientTelemetryTests.cs diff --git a/Directory.Build.props b/Directory.Build.props index a4a5b0a087..39004a08ab 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,9 +1,9 @@ - 3.32.0 - 3.32.0 + 3.32.2 + 3.32.2 preview - 3.30.2 + 3.30.4 2.0.1 2.0.1 preview diff --git a/Microsoft.Azure.Cosmos/contracts/API_3.32.1-preview.txt b/Microsoft.Azure.Cosmos/contracts/API_3.32.1-preview.txt new file mode 100644 index 0000000000..69b7a4b83e --- /dev/null +++ b/Microsoft.Azure.Cosmos/contracts/API_3.32.1-preview.txt @@ -0,0 +1,1531 @@ +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 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 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 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 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 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, + 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 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 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 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 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 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 IsDefined(this object obj); + public static bool IsNull(this object obj); + public static bool IsPrimitive(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.32.1.txt b/Microsoft.Azure.Cosmos/contracts/API_3.32.1.txt new file mode 100644 index 0000000000..5218206b0e --- /dev/null +++ b/Microsoft.Azure.Cosmos/contracts/API_3.32.1.txt @@ -0,0 +1,1478 @@ +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 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, 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 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 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 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 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, + 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 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 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 IsDefined(this object obj); + public static bool IsNull(this object obj); + public static bool IsPrimitive(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.32.2-preview.txt b/Microsoft.Azure.Cosmos/contracts/API_3.32.2-preview.txt new file mode 100644 index 0000000000..69b7a4b83e --- /dev/null +++ b/Microsoft.Azure.Cosmos/contracts/API_3.32.2-preview.txt @@ -0,0 +1,1531 @@ +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 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 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 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 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 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, + 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 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 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 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 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 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 IsDefined(this object obj); + public static bool IsNull(this object obj); + public static bool IsPrimitive(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.32.2.txt b/Microsoft.Azure.Cosmos/contracts/API_3.32.2.txt new file mode 100644 index 0000000000..5218206b0e --- /dev/null +++ b/Microsoft.Azure.Cosmos/contracts/API_3.32.2.txt @@ -0,0 +1,1478 @@ +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 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, 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 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 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 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 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, + 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 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 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 IsDefined(this object obj); + public static bool IsNull(this object obj); + public static bool IsPrimitive(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/src/ChangeFeedProcessor/LeaseManagement/DocumentServiceLeaseManagerCosmos.cs b/Microsoft.Azure.Cosmos/src/ChangeFeedProcessor/LeaseManagement/DocumentServiceLeaseManagerCosmos.cs index 260bff3161..d5a75abb47 100644 --- a/Microsoft.Azure.Cosmos/src/ChangeFeedProcessor/LeaseManagement/DocumentServiceLeaseManagerCosmos.cs +++ b/Microsoft.Azure.Cosmos/src/ChangeFeedProcessor/LeaseManagement/DocumentServiceLeaseManagerCosmos.cs @@ -190,7 +190,17 @@ await this.leaseUpdater.UpdateLeaseAsync( if (serverLease.Owner != lease.Owner) { DefaultTrace.TraceInformation("Lease with token {0} no need to release lease. The lease was already taken by another host '{1}'.", lease.CurrentLeaseToken, serverLease.Owner); - throw new LeaseLostException(lease); + throw new LeaseLostException( + lease, + CosmosExceptionFactory.Create( + statusCode: HttpStatusCode.PreconditionFailed, + message: $"{lease.CurrentLeaseToken} lease token was taken over by owner '{serverLease.Owner}'", + headers: new Headers(), + stackTrace: default, + trace: NoOpTrace.Singleton, + error: default, + innerException: default), + isGone: false); } serverLease.Owner = null; return serverLease; @@ -232,7 +242,17 @@ public override async Task RenewAsync(DocumentServiceLease if (serverLease.Owner != lease.Owner) { DefaultTrace.TraceInformation("Lease with token {0} was taken over by owner '{1}'", lease.CurrentLeaseToken, serverLease.Owner); - throw new LeaseLostException(lease); + throw new LeaseLostException( + lease, + CosmosExceptionFactory.Create( + statusCode: HttpStatusCode.PreconditionFailed, + message: $"{lease.CurrentLeaseToken} lease token was taken over by owner '{serverLease.Owner}'", + headers: new Headers(), + stackTrace: default, + trace: NoOpTrace.Singleton, + error: default, + innerException: default), + isGone: false); } return serverLease; }).ConfigureAwait(false); @@ -245,7 +265,17 @@ public override async Task UpdatePropertiesAsync(DocumentS if (lease.Owner != this.options.HostName) { DefaultTrace.TraceInformation("Lease with token '{0}' was taken over by owner '{1}' before lease properties update", lease.CurrentLeaseToken, lease.Owner); - throw new LeaseLostException(lease); + throw new LeaseLostException( + lease, + CosmosExceptionFactory.Create( + statusCode: HttpStatusCode.PreconditionFailed, + message: $"{lease.CurrentLeaseToken} lease token was taken over by owner '{lease.Owner}'", + headers: new Headers(), + stackTrace: default, + trace: NoOpTrace.Singleton, + error: default, + innerException: default), + isGone: false); } return await this.leaseUpdater.UpdateLeaseAsync( @@ -257,7 +287,17 @@ public override async Task UpdatePropertiesAsync(DocumentS if (serverLease.Owner != lease.Owner) { DefaultTrace.TraceInformation("Lease with token '{0}' was taken over by owner '{1}'", lease.CurrentLeaseToken, serverLease.Owner); - throw new LeaseLostException(lease); + throw new LeaseLostException( + lease, + CosmosExceptionFactory.Create( + statusCode: HttpStatusCode.PreconditionFailed, + message: $"{lease.CurrentLeaseToken} lease token was taken over by owner '{serverLease.Owner}'", + headers: new Headers(), + stackTrace: default, + trace: NoOpTrace.Singleton, + error: default, + innerException: default), + isGone: false); } serverLease.Properties = lease.Properties; return serverLease; diff --git a/Microsoft.Azure.Cosmos/src/CosmosClient.cs b/Microsoft.Azure.Cosmos/src/CosmosClient.cs index e5ca2d8b53..d4fe7dcb9b 100644 --- a/Microsoft.Azure.Cosmos/src/CosmosClient.cs +++ b/Microsoft.Azure.Cosmos/src/CosmosClient.cs @@ -115,11 +115,8 @@ public class CosmosClient : IDisposable static CosmosClient() { -#if PREVIEW HttpConstants.Versions.CurrentVersion = HttpConstants.Versions.v2020_07_15; -#else - HttpConstants.Versions.CurrentVersion = HttpConstants.Versions.v2018_12_31; -#endif + HttpConstants.Versions.CurrentVersionUTF8 = Encoding.UTF8.GetBytes(HttpConstants.Versions.CurrentVersion); ServiceInteropWrapper.AssembliesExist = new Lazy(() => diff --git a/Microsoft.Azure.Cosmos/src/Handler/RequestInvokerHandler.cs b/Microsoft.Azure.Cosmos/src/Handler/RequestInvokerHandler.cs index 96b889832e..bb322f19b1 100644 --- a/Microsoft.Azure.Cosmos/src/Handler/RequestInvokerHandler.cs +++ b/Microsoft.Azure.Cosmos/src/Handler/RequestInvokerHandler.cs @@ -161,6 +161,14 @@ public virtual async Task SendAsync( if (feedRange != null) { + if (!request.OperationType.IsPointOperation()) + { + feedRange = await RequestInvokerHandler.ResolveFeedRangeBasedOnPrefixContainerAsync( + feedRange: feedRange, + cosmosContainerCore: cosmosContainerCore, + cancellationToken: cancellationToken); + } + if (feedRange is FeedRangePartitionKey feedRangePartitionKey) { if (cosmosContainerCore == null && object.ReferenceEquals(feedRangePartitionKey.PartitionKey, Cosmos.PartitionKey.None)) @@ -480,5 +488,26 @@ private static bool IsClientNoResponseSet(CosmosClientOptions clientOptions, Ope && clientOptions.EnableContentResponseOnWrite.HasValue && RequestInvokerHandler.IsItemNoRepsonseSet(clientOptions.EnableContentResponseOnWrite.Value, operationType); } + + internal static async Task ResolveFeedRangeBasedOnPrefixContainerAsync( + FeedRange feedRange, + ContainerInternal cosmosContainerCore, + CancellationToken cancellationToken) + { + if (feedRange is FeedRangePartitionKey feedRangePartitionKey) + { + PartitionKeyDefinition partitionKeyDefinition = await cosmosContainerCore + .GetPartitionKeyDefinitionAsync(cancellationToken) + .ConfigureAwait(false); + + if (partitionKeyDefinition != null && partitionKeyDefinition.Kind == PartitionKind.MultiHash + && feedRangePartitionKey.PartitionKey.InternalKey?.Components?.Count < partitionKeyDefinition.Paths?.Count) + { + feedRange = new FeedRangeEpk(feedRangePartitionKey.PartitionKey.InternalKey.GetEPKRangeForPrefixPartitionKey(partitionKeyDefinition)); + } + } + + return feedRange; + } } } diff --git a/Microsoft.Azure.Cosmos/src/Handler/TelemetryHandler.cs b/Microsoft.Azure.Cosmos/src/Handler/TelemetryHandler.cs index 449a981d0d..9d7e504eba 100644 --- a/Microsoft.Azure.Cosmos/src/Handler/TelemetryHandler.cs +++ b/Microsoft.Azure.Cosmos/src/Handler/TelemetryHandler.cs @@ -40,11 +40,12 @@ public override async Task SendAsync( resourceType: request.ResourceType, consistencyLevel: request.Headers?[Documents.HttpConstants.HttpHeaders.ConsistencyLevel], requestCharge: response.Headers.RequestCharge, - subStatusCode: response.Headers.SubStatusCode); + subStatusCode: response.Headers.SubStatusCode, + trace: response.Trace); } catch (Exception ex) { - DefaultTrace.TraceError("Error while collecting telemetry information : " + ex.Message); + DefaultTrace.TraceError("Error while collecting telemetry information : {0}", ex); } } return response; diff --git a/Microsoft.Azure.Cosmos/src/Linq/CosmosLinqExtensions.cs b/Microsoft.Azure.Cosmos/src/Linq/CosmosLinqExtensions.cs index baddf0fe31..dc86de0cb6 100644 --- a/Microsoft.Azure.Cosmos/src/Linq/CosmosLinqExtensions.cs +++ b/Microsoft.Azure.Cosmos/src/Linq/CosmosLinqExtensions.cs @@ -186,7 +186,7 @@ public static FeedIterator ToFeedIterator(this IQueryable query) /// /// linqQueryable = this.Container.GetItemLinqQueryable(); - /// using (FeedIterator setIterator = linqQueryable.Where(item => (item.taskNum < 100)).ToFeedIterator() + /// using (FeedIterator setIterator = linqQueryable.Where(item => (item.taskNum < 100)).ToStreamIterator()) /// ]]> /// /// diff --git a/Microsoft.Azure.Cosmos/src/Linq/ExpressionToSQL.cs b/Microsoft.Azure.Cosmos/src/Linq/ExpressionToSQL.cs index 1dcd249ccf..112f86be39 100644 --- a/Microsoft.Azure.Cosmos/src/Linq/ExpressionToSQL.cs +++ b/Microsoft.Azure.Cosmos/src/Linq/ExpressionToSQL.cs @@ -10,7 +10,6 @@ namespace Microsoft.Azure.Cosmos.Linq using System.Collections.ObjectModel; using System.Diagnostics; using System.Globalization; - using System.IO; using System.Linq; using System.Linq.Expressions; using System.Reflection; @@ -111,10 +110,10 @@ public static SqlQuery TranslateQuery( /// /// Expression to translate. /// Context for translation. - private static Collection Translate(Expression inputExpression, TranslationContext context) + private static Collection Translate(Expression inputExpression, TranslationContext context) { - Debug.Assert(context != null, "Translation Context should not be null"); - + Debug.Assert(context != null, "Translation Context should not be null"); + if (inputExpression == null) { throw new ArgumentNullException("inputExpression"); @@ -552,7 +551,7 @@ private static SqlScalarExpression ApplyCustomConverters(Expression left, SqlLit else if (memberType == typeof(DateTime)) { SqlStringLiteral serializedDateTime = (SqlStringLiteral)right.Literal; - value = DateTime.Parse(serializedDateTime.Value, provider: null, DateTimeStyles.RoundtripKind); + value = DateTime.Parse(serializedDateTime.Value, provider: null, DateTimeStyles.RoundtripKind); } if (value != default(object)) @@ -712,23 +711,7 @@ public static SqlScalarExpression VisitConstant(ConstantExpression inputExpressi return SqlArrayCreateScalarExpression.Create(arrayItems.ToImmutableArray()); } - - if (context.linqSerializerOptions?.CustomCosmosSerializer != null) - { - StringWriter writer = new StringWriter(CultureInfo.InvariantCulture); - - // Use the user serializer for the parameter values so custom conversions are correctly handled - using (Stream stream = context.linqSerializerOptions.CustomCosmosSerializer.ToStream(inputExpression.Value)) - { - using (StreamReader streamReader = new StreamReader(stream)) - { - string propertyValue = streamReader.ReadToEnd(); - writer.Write(propertyValue); - return CosmosElement.Parse(writer.ToString()).Accept(CosmosElementToSqlScalarExpressionVisitor.Singleton); - } - } - } - + return CosmosElement.Parse(JsonConvert.SerializeObject(inputExpression.Value)).Accept(CosmosElementToSqlScalarExpressionVisitor.Singleton); } @@ -757,21 +740,21 @@ private static SqlScalarExpression VisitParameter(ParameterExpression inputExpre private static SqlScalarExpression VisitMemberAccess(MemberExpression inputExpression, TranslationContext context) { SqlScalarExpression memberExpression = ExpressionToSql.VisitScalarExpression(inputExpression.Expression, context); - string memberName = inputExpression.Member.GetMemberName(context.linqSerializerOptions); + string memberName = inputExpression.Member.GetMemberName(context.linqSerializerOptions); // if expression is nullable if (inputExpression.Expression.Type.IsNullable()) { - MemberNames memberNames = context.memberNames; - + MemberNames memberNames = context.memberNames; + // ignore .Value - if (memberName == memberNames.Value) + if (memberName == memberNames.Value) { return memberExpression; } // convert .HasValue to IS_DEFINED expression - if (memberName == memberNames.HasValue) + if (memberName == memberNames.HasValue) { return SqlFunctionCallScalarExpression.CreateBuiltin("IS_DEFINED", memberExpression); } @@ -2028,11 +2011,11 @@ public SqlScalarExpression Visit(CosmosString cosmosString) { return SqlLiteralScalarExpression.Create(SqlStringLiteral.Create(cosmosString.Value)); } - - public SqlScalarExpression Visit(CosmosUndefined cosmosUndefined) - { - return SqlLiteralScalarExpression.Create(SqlUndefinedLiteral.Create()); - } + + public SqlScalarExpression Visit(CosmosUndefined cosmosUndefined) + { + return SqlLiteralScalarExpression.Create(SqlUndefinedLiteral.Create()); + } } private enum SubqueryKind { diff --git a/Microsoft.Azure.Cosmos/src/PartitionKeyBuilder.cs b/Microsoft.Azure.Cosmos/src/PartitionKeyBuilder.cs index 6154921a86..e9b0e70a7d 100644 --- a/Microsoft.Azure.Cosmos/src/PartitionKeyBuilder.cs +++ b/Microsoft.Azure.Cosmos/src/PartitionKeyBuilder.cs @@ -11,12 +11,7 @@ namespace Microsoft.Azure.Cosmos /// /// Represents a partition key value list in the Azure Cosmos DB service. /// -#if PREVIEW - public -#else - internal -#endif - sealed class PartitionKeyBuilder + public sealed class PartitionKeyBuilder { private readonly List partitionKeyValues; diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Parser/CstToAstVisitor.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Parser/CstToAstVisitor.cs index 448b8f4ca6..8ba6c4fc45 100644 --- a/Microsoft.Azure.Cosmos/src/Query/Core/Parser/CstToAstVisitor.cs +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Parser/CstToAstVisitor.cs @@ -568,6 +568,16 @@ public override SqlObject VisitExistsScalarExpression([NotNull] sqlParser.Exists return SqlExistsScalarExpression.Create(subquery); } + public override SqlObject VisitFirstScalarExpression([NotNull] sqlParser.FirstScalarExpressionContext context) + { + Contract.Requires(context != null); + // K_FIRST '(' sql_query ')' + Contract.Requires(context.ChildCount == 4); + + SqlQuery subquery = (SqlQuery)this.Visit(context.children[2]); + return SqlFirstScalarExpression.Create(subquery); + } + public override SqlObject VisitFunctionCallScalarExpression([NotNull] sqlParser.FunctionCallScalarExpressionContext context) { Contract.Requires(context != null); @@ -627,6 +637,16 @@ public override SqlObject VisitIn_scalar_expression([NotNull] sqlParser.In_scala return SqlInScalarExpression.Create(needle, not, searchList.ToImmutableArray()); } + public override SqlObject VisitLastScalarExpression([NotNull] sqlParser.LastScalarExpressionContext context) + { + Contract.Requires(context != null); + // K_LAST '(' sql_query ')' + Contract.Requires(context.ChildCount == 4); + + SqlQuery subquery = (SqlQuery)this.Visit(context.children[2]); + return SqlLastScalarExpression.Create(subquery); + } + public override SqlObject VisitLike_scalar_expression([NotNull] sqlParser.Like_scalar_expressionContext context) { Contract.Requires(context != null); diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Parser/IsqlListener.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Parser/IsqlListener.cs index 24a4a0694a..9cde50fb6b 100644 --- a/Microsoft.Azure.Cosmos/src/Query/Core/Parser/IsqlListener.cs +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Parser/IsqlListener.cs @@ -562,6 +562,18 @@ internal interface IsqlListener : IParseTreeListener { /// The parse tree. void ExitObjectCreateScalarExpression([NotNull] sqlParser.ObjectCreateScalarExpressionContext context); /// + /// Enter a parse tree produced by the FirstScalarExpression + /// labeled alternative in . + /// + /// The parse tree. + void EnterFirstScalarExpression([NotNull] sqlParser.FirstScalarExpressionContext context); + /// + /// Exit a parse tree produced by the FirstScalarExpression + /// labeled alternative in . + /// + /// The parse tree. + void ExitFirstScalarExpression([NotNull] sqlParser.FirstScalarExpressionContext context); + /// /// Enter a parse tree produced by the ArrayCreateScalarExpression /// labeled alternative in . /// @@ -670,6 +682,18 @@ internal interface IsqlListener : IParseTreeListener { /// The parse tree. void ExitArrayScalarExpression([NotNull] sqlParser.ArrayScalarExpressionContext context); /// + /// Enter a parse tree produced by the LastScalarExpression + /// labeled alternative in . + /// + /// The parse tree. + void EnterLastScalarExpression([NotNull] sqlParser.LastScalarExpressionContext context); + /// + /// Exit a parse tree produced by the LastScalarExpression + /// labeled alternative in . + /// + /// The parse tree. + void ExitLastScalarExpression([NotNull] sqlParser.LastScalarExpressionContext context); + /// /// Enter a parse tree produced by the PropertyRefScalarExpressionRecursive /// labeled alternative in . /// diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Parser/IsqlVisitor.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Parser/IsqlVisitor.cs index e22a9d4218..b9bea8ca1d 100644 --- a/Microsoft.Azure.Cosmos/src/Query/Core/Parser/IsqlVisitor.cs +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Parser/IsqlVisitor.cs @@ -347,6 +347,13 @@ internal interface IsqlVisitor : IParseTreeVisitor { /// The visitor result. Result VisitObjectCreateScalarExpression([NotNull] sqlParser.ObjectCreateScalarExpressionContext context); /// + /// Visit a parse tree produced by the FirstScalarExpression + /// labeled alternative in . + /// + /// The parse tree. + /// The visitor result. + Result VisitFirstScalarExpression([NotNull] sqlParser.FirstScalarExpressionContext context); + /// /// Visit a parse tree produced by the ArrayCreateScalarExpression /// labeled alternative in . /// @@ -410,6 +417,13 @@ internal interface IsqlVisitor : IParseTreeVisitor { /// The visitor result. Result VisitArrayScalarExpression([NotNull] sqlParser.ArrayScalarExpressionContext context); /// + /// Visit a parse tree produced by the LastScalarExpression + /// labeled alternative in . + /// + /// The parse tree. + /// The visitor result. + Result VisitLastScalarExpression([NotNull] sqlParser.LastScalarExpressionContext context); + /// /// Visit a parse tree produced by the PropertyRefScalarExpressionRecursive /// labeled alternative in . /// diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Parser/sql.g4 b/Microsoft.Azure.Cosmos/src/Query/Core/Parser/sql.g4 index 42ac229557..2b0002a8ab 100644 --- a/Microsoft.Azure.Cosmos/src/Query/Core/Parser/sql.g4 +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Parser/sql.g4 @@ -173,6 +173,8 @@ primary_expression | K_EXISTS '(' sql_query ')' #ExistsScalarExpression | K_ARRAY '(' sql_query ')' #ArrayScalarExpression | K_ALL '(' sql_query ')' #AllScalarExpression + | K_FIRST '(' sql_query ')' #FirstScalarExpression + | K_LAST '(' sql_query ')' #LastScalarExpression | function_call_scalar_expression #FunctionCallScalarExpression ; @@ -191,6 +193,8 @@ object_property : STRING_LITERAL ':' scalar_expression ; identifier : LEX_IDENTIFIER | K_ALL + | K_FIRST + | K_LAST ; /*--------------------------------------------------------------------------------*/ @@ -208,11 +212,13 @@ K_DESC : D E S C; K_DISTINCT : D I S T I N C T; K_ESCAPE: E S C A P E; K_EXISTS : E X I S T S; +K_FIRST : F I R S T; K_FALSE : 'false'; K_FROM : F R O M; K_GROUP : G R O U P; K_IN : I N ; K_JOIN : J O I N; +K_LAST : L A S T; K_LEFT : L E F T; K_LIKE : L I K E; K_LIMIT : L I M I T; diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Parser/sqlBaseListener.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Parser/sqlBaseListener.cs index 18003391b1..62f2873d72 100644 --- a/Microsoft.Azure.Cosmos/src/Query/Core/Parser/sqlBaseListener.cs +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Parser/sqlBaseListener.cs @@ -666,6 +666,20 @@ public virtual void EnterObjectCreateScalarExpression([NotNull] sqlParser.Object /// The parse tree. public virtual void ExitObjectCreateScalarExpression([NotNull] sqlParser.ObjectCreateScalarExpressionContext context) { } /// + /// Enter a parse tree produced by the FirstScalarExpression + /// labeled alternative in . + /// The default implementation does nothing. + /// + /// The parse tree. + public virtual void EnterFirstScalarExpression([NotNull] sqlParser.FirstScalarExpressionContext context) { } + /// + /// Exit a parse tree produced by the FirstScalarExpression + /// labeled alternative in . + /// The default implementation does nothing. + /// + /// The parse tree. + public virtual void ExitFirstScalarExpression([NotNull] sqlParser.FirstScalarExpressionContext context) { } + /// /// Enter a parse tree produced by the ArrayCreateScalarExpression /// labeled alternative in . /// The default implementation does nothing. @@ -792,6 +806,20 @@ public virtual void EnterArrayScalarExpression([NotNull] sqlParser.ArrayScalarEx /// The parse tree. public virtual void ExitArrayScalarExpression([NotNull] sqlParser.ArrayScalarExpressionContext context) { } /// + /// Enter a parse tree produced by the LastScalarExpression + /// labeled alternative in . + /// The default implementation does nothing. + /// + /// The parse tree. + public virtual void EnterLastScalarExpression([NotNull] sqlParser.LastScalarExpressionContext context) { } + /// + /// Exit a parse tree produced by the LastScalarExpression + /// labeled alternative in . + /// The default implementation does nothing. + /// + /// The parse tree. + public virtual void ExitLastScalarExpression([NotNull] sqlParser.LastScalarExpressionContext context) { } + /// /// Enter a parse tree produced by the PropertyRefScalarExpressionRecursive /// labeled alternative in . /// The default implementation does nothing. diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Parser/sqlBaseVisitor.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Parser/sqlBaseVisitor.cs index bb3b86379d..4594f5fc79 100644 --- a/Microsoft.Azure.Cosmos/src/Query/Core/Parser/sqlBaseVisitor.cs +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Parser/sqlBaseVisitor.cs @@ -549,6 +549,17 @@ internal partial class sqlBaseVisitor : AbstractParseTreeVisitor /// The visitor result. public virtual Result VisitObjectCreateScalarExpression([NotNull] sqlParser.ObjectCreateScalarExpressionContext context) { return VisitChildren(context); } /// + /// Visit a parse tree produced by the FirstScalarExpression + /// labeled alternative in . + /// + /// The default implementation returns the result of calling + /// on . + /// + /// + /// The parse tree. + /// The visitor result. + public virtual Result VisitFirstScalarExpression([NotNull] sqlParser.FirstScalarExpressionContext context) { return VisitChildren(context); } + /// /// Visit a parse tree produced by the ArrayCreateScalarExpression /// labeled alternative in . /// @@ -648,6 +659,17 @@ internal partial class sqlBaseVisitor : AbstractParseTreeVisitor /// The visitor result. public virtual Result VisitArrayScalarExpression([NotNull] sqlParser.ArrayScalarExpressionContext context) { return VisitChildren(context); } /// + /// Visit a parse tree produced by the LastScalarExpression + /// labeled alternative in . + /// + /// The default implementation returns the result of calling + /// on . + /// + /// + /// The parse tree. + /// The visitor result. + public virtual Result VisitLastScalarExpression([NotNull] sqlParser.LastScalarExpressionContext context) { return VisitChildren(context); } + /// /// Visit a parse tree produced by the PropertyRefScalarExpressionRecursive /// labeled alternative in . /// diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Parser/sqlLexer.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Parser/sqlLexer.cs index 1d5b7262bd..88888fea5d 100644 --- a/Microsoft.Azure.Cosmos/src/Query/Core/Parser/sqlLexer.cs +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Parser/sqlLexer.cs @@ -37,11 +37,11 @@ public const int T__17=18, T__18=19, T__19=20, T__20=21, T__21=22, T__22=23, T__23=24, T__24=25, T__25=26, T__26=27, K_ALL=28, K_AND=29, K_ARRAY=30, K_AS=31, K_ASC=32, K_BETWEEN=33, K_BY=34, K_DESC=35, K_DISTINCT=36, K_ESCAPE=37, - K_EXISTS=38, K_FALSE=39, K_FROM=40, K_GROUP=41, K_IN=42, K_JOIN=43, K_LEFT=44, - K_LIKE=45, K_LIMIT=46, K_NOT=47, K_NULL=48, K_OFFSET=49, K_OR=50, K_ORDER=51, - K_RIGHT=52, K_SELECT=53, K_TOP=54, K_TRUE=55, K_UDF=56, K_UNDEFINED=57, - K_VALUE=58, K_WHERE=59, WS=60, NUMERIC_LITERAL=61, STRING_LITERAL=62, - LEX_IDENTIFIER=63, PARAMETER=64; + K_EXISTS=38, K_FIRST=39, K_FALSE=40, K_FROM=41, K_GROUP=42, K_IN=43, K_JOIN=44, + K_LAST=45, K_LEFT=46, K_LIKE=47, K_LIMIT=48, K_NOT=49, K_NULL=50, K_OFFSET=51, + K_OR=52, K_ORDER=53, K_RIGHT=54, K_SELECT=55, K_TOP=56, K_TRUE=57, K_UDF=58, + K_UNDEFINED=59, K_VALUE=60, K_WHERE=61, WS=62, NUMERIC_LITERAL=63, STRING_LITERAL=64, + LEX_IDENTIFIER=65, PARAMETER=66; public static string[] channelNames = { "DEFAULT_TOKEN_CHANNEL", "HIDDEN" }; @@ -55,11 +55,11 @@ public const int "T__9", "T__10", "T__11", "T__12", "T__13", "T__14", "T__15", "T__16", "T__17", "T__18", "T__19", "T__20", "T__21", "T__22", "T__23", "T__24", "T__25", "T__26", "K_ALL", "K_AND", "K_ARRAY", "K_AS", "K_ASC", "K_BETWEEN", - "K_BY", "K_DESC", "K_DISTINCT", "K_ESCAPE", "K_EXISTS", "K_FALSE", "K_FROM", - "K_GROUP", "K_IN", "K_JOIN", "K_LEFT", "K_LIKE", "K_LIMIT", "K_NOT", "K_NULL", - "K_OFFSET", "K_OR", "K_ORDER", "K_RIGHT", "K_SELECT", "K_TOP", "K_TRUE", - "K_UDF", "K_UNDEFINED", "K_VALUE", "K_WHERE", "WS", "NUMERIC_LITERAL", - "STRING_LITERAL", "ESC", "UNICODE", "HEX", "SAFECODEPOINTWITHSINGLEQUOTATION", + "K_BY", "K_DESC", "K_DISTINCT", "K_ESCAPE", "K_EXISTS", "K_FIRST", "K_FALSE", + "K_FROM", "K_GROUP", "K_IN", "K_JOIN", "K_LAST", "K_LEFT", "K_LIKE", "K_LIMIT", + "K_NOT", "K_NULL", "K_OFFSET", "K_OR", "K_ORDER", "K_RIGHT", "K_SELECT", + "K_TOP", "K_TRUE", "K_UDF", "K_UNDEFINED", "K_VALUE", "K_WHERE", "WS", + "NUMERIC_LITERAL", "STRING_LITERAL", "ESC", "UNICODE", "HEX", "SAFECODEPOINTWITHSINGLEQUOTATION", "SAFECODEPOINTWITHDOUBLEQUOTATION", "LEX_IDENTIFIER", "PARAMETER", "DIGIT", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" @@ -79,19 +79,20 @@ public sqlLexer(ICharStream input, TextWriter output, TextWriter errorOutput) null, "'*'", "','", "'('", "')'", "'.'", "'['", "']'", "'?'", "':'", "'??'", "'/'", "'%'", "'+'", "'-'", "'<'", "'>'", "'>='", "'<='", "'='", "'!='", "'&'", "'^'", "'|'", "'||'", "'~'", "'{'", "'}'", null, null, null, null, - null, null, null, null, null, null, null, "'false'", null, null, null, - null, null, null, null, null, "'null'", null, null, null, null, null, - null, "'true'", "'udf'", "'undefined'" + null, null, null, null, null, null, null, null, "'false'", null, null, + null, null, null, null, null, null, null, "'null'", null, null, null, + null, null, null, "'true'", "'udf'", "'undefined'" }; private static readonly string[] _SymbolicNames = { null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, "K_ALL", "K_AND", "K_ARRAY", "K_AS", "K_ASC", - "K_BETWEEN", "K_BY", "K_DESC", "K_DISTINCT", "K_ESCAPE", "K_EXISTS", "K_FALSE", - "K_FROM", "K_GROUP", "K_IN", "K_JOIN", "K_LEFT", "K_LIKE", "K_LIMIT", - "K_NOT", "K_NULL", "K_OFFSET", "K_OR", "K_ORDER", "K_RIGHT", "K_SELECT", - "K_TOP", "K_TRUE", "K_UDF", "K_UNDEFINED", "K_VALUE", "K_WHERE", "WS", - "NUMERIC_LITERAL", "STRING_LITERAL", "LEX_IDENTIFIER", "PARAMETER" + "K_BETWEEN", "K_BY", "K_DESC", "K_DISTINCT", "K_ESCAPE", "K_EXISTS", "K_FIRST", + "K_FALSE", "K_FROM", "K_GROUP", "K_IN", "K_JOIN", "K_LAST", "K_LEFT", + "K_LIKE", "K_LIMIT", "K_NOT", "K_NULL", "K_OFFSET", "K_OR", "K_ORDER", + "K_RIGHT", "K_SELECT", "K_TOP", "K_TRUE", "K_UDF", "K_UNDEFINED", "K_VALUE", + "K_WHERE", "WS", "NUMERIC_LITERAL", "STRING_LITERAL", "LEX_IDENTIFIER", + "PARAMETER" }; public static readonly IVocabulary DefaultVocabulary = new Vocabulary(_LiteralNames, _SymbolicNames); @@ -122,7 +123,7 @@ static sqlLexer() { } private static char[] _serializedATN = { '\x3', '\x608B', '\xA72A', '\x8133', '\xB9ED', '\x417C', '\x3BE7', '\x7786', - '\x5964', '\x2', '\x42', '\x24E', '\b', '\x1', '\x4', '\x2', '\t', '\x2', + '\x5964', '\x2', '\x44', '\x25D', '\b', '\x1', '\x4', '\x2', '\t', '\x2', '\x4', '\x3', '\t', '\x3', '\x4', '\x4', '\t', '\x4', '\x4', '\x5', '\t', '\x5', '\x4', '\x6', '\t', '\x6', '\x4', '\a', '\t', '\a', '\x4', '\b', '\t', '\b', '\x4', '\t', '\t', '\t', '\x4', '\n', '\t', '\n', '\x4', '\v', @@ -156,469 +157,482 @@ static sqlLexer() { 'X', '\x4', 'Y', '\t', 'Y', '\x4', 'Z', '\t', 'Z', '\x4', '[', '\t', '[', '\x4', '\\', '\t', '\\', '\x4', ']', '\t', ']', '\x4', '^', '\t', '^', '\x4', '_', '\t', '_', '\x4', '`', '\t', '`', '\x4', '\x61', '\t', '\x61', - '\x3', '\x2', '\x3', '\x2', '\x3', '\x3', '\x3', '\x3', '\x3', '\x4', - '\x3', '\x4', '\x3', '\x5', '\x3', '\x5', '\x3', '\x6', '\x3', '\x6', - '\x3', '\a', '\x3', '\a', '\x3', '\b', '\x3', '\b', '\x3', '\t', '\x3', - '\t', '\x3', '\n', '\x3', '\n', '\x3', '\v', '\x3', '\v', '\x3', '\v', - '\x3', '\f', '\x3', '\f', '\x3', '\r', '\x3', '\r', '\x3', '\xE', '\x3', - '\xE', '\x3', '\xF', '\x3', '\xF', '\x3', '\x10', '\x3', '\x10', '\x3', - '\x11', '\x3', '\x11', '\x3', '\x12', '\x3', '\x12', '\x3', '\x12', '\x3', - '\x13', '\x3', '\x13', '\x3', '\x13', '\x3', '\x14', '\x3', '\x14', '\x3', - '\x15', '\x3', '\x15', '\x3', '\x15', '\x3', '\x16', '\x3', '\x16', '\x3', - '\x17', '\x3', '\x17', '\x3', '\x18', '\x3', '\x18', '\x3', '\x19', '\x3', - '\x19', '\x3', '\x19', '\x3', '\x1A', '\x3', '\x1A', '\x3', '\x1B', '\x3', - '\x1B', '\x3', '\x1C', '\x3', '\x1C', '\x3', '\x1D', '\x3', '\x1D', '\x3', - '\x1D', '\x3', '\x1D', '\x3', '\x1E', '\x3', '\x1E', '\x3', '\x1E', '\x3', - '\x1E', '\x3', '\x1F', '\x3', '\x1F', '\x3', '\x1F', '\x3', '\x1F', '\x3', - '\x1F', '\x3', '\x1F', '\x3', ' ', '\x3', ' ', '\x3', ' ', '\x3', '!', - '\x3', '!', '\x3', '!', '\x3', '!', '\x3', '\"', '\x3', '\"', '\x3', '\"', - '\x3', '\"', '\x3', '\"', '\x3', '\"', '\x3', '\"', '\x3', '\"', '\x3', - '#', '\x3', '#', '\x3', '#', '\x3', '$', '\x3', '$', '\x3', '$', '\x3', - '$', '\x3', '$', '\x3', '%', '\x3', '%', '\x3', '%', '\x3', '%', '\x3', - '%', '\x3', '%', '\x3', '%', '\x3', '%', '\x3', '%', '\x3', '&', '\x3', - '&', '\x3', '&', '\x3', '&', '\x3', '&', '\x3', '&', '\x3', '&', '\x3', - '\'', '\x3', '\'', '\x3', '\'', '\x3', '\'', '\x3', '\'', '\x3', '\'', - '\x3', '\'', '\x3', '(', '\x3', '(', '\x3', '(', '\x3', '(', '\x3', '(', - '\x3', '(', '\x3', ')', '\x3', ')', '\x3', ')', '\x3', ')', '\x3', ')', - '\x3', '*', '\x3', '*', '\x3', '*', '\x3', '*', '\x3', '*', '\x3', '*', - '\x3', '+', '\x3', '+', '\x3', '+', '\x3', ',', '\x3', ',', '\x3', ',', - '\x3', ',', '\x3', ',', '\x3', '-', '\x3', '-', '\x3', '-', '\x3', '-', - '\x3', '-', '\x3', '.', '\x3', '.', '\x3', '.', '\x3', '.', '\x3', '.', - '\x3', '/', '\x3', '/', '\x3', '/', '\x3', '/', '\x3', '/', '\x3', '/', - '\x3', '\x30', '\x3', '\x30', '\x3', '\x30', '\x3', '\x30', '\x3', '\x31', - '\x3', '\x31', '\x3', '\x31', '\x3', '\x31', '\x3', '\x31', '\x3', '\x32', - '\x3', '\x32', '\x3', '\x32', '\x3', '\x32', '\x3', '\x32', '\x3', '\x32', - '\x3', '\x32', '\x3', '\x33', '\x3', '\x33', '\x3', '\x33', '\x3', '\x34', - '\x3', '\x34', '\x3', '\x34', '\x3', '\x34', '\x3', '\x34', '\x3', '\x34', - '\x3', '\x35', '\x3', '\x35', '\x3', '\x35', '\x3', '\x35', '\x3', '\x35', - '\x3', '\x35', '\x3', '\x36', '\x3', '\x36', '\x3', '\x36', '\x3', '\x36', - '\x3', '\x36', '\x3', '\x36', '\x3', '\x36', '\x3', '\x37', '\x3', '\x37', - '\x3', '\x37', '\x3', '\x37', '\x3', '\x38', '\x3', '\x38', '\x3', '\x38', - '\x3', '\x38', '\x3', '\x38', '\x3', '\x39', '\x3', '\x39', '\x3', '\x39', - '\x3', '\x39', '\x3', ':', '\x3', ':', '\x3', ':', '\x3', ':', '\x3', - ':', '\x3', ':', '\x3', ':', '\x3', ':', '\x3', ':', '\x3', ':', '\x3', - ';', '\x3', ';', '\x3', ';', '\x3', ';', '\x3', ';', '\x3', ';', '\x3', - '<', '\x3', '<', '\x3', '<', '\x3', '<', '\x3', '<', '\x3', '<', '\x3', - '=', '\x6', '=', '\x1AE', '\n', '=', '\r', '=', '\xE', '=', '\x1AF', '\x3', - '=', '\x3', '=', '\x3', '>', '\x5', '>', '\x1B5', '\n', '>', '\x3', '>', - '\x6', '>', '\x1B8', '\n', '>', '\r', '>', '\xE', '>', '\x1B9', '\x3', - '>', '\x3', '>', '\a', '>', '\x1BE', '\n', '>', '\f', '>', '\xE', '>', - '\x1C1', '\v', '>', '\x5', '>', '\x1C3', '\n', '>', '\x3', '>', '\x3', - '>', '\x5', '>', '\x1C7', '\n', '>', '\x3', '>', '\x6', '>', '\x1CA', - '\n', '>', '\r', '>', '\xE', '>', '\x1CB', '\x5', '>', '\x1CE', '\n', - '>', '\x3', '>', '\x5', '>', '\x1D1', '\n', '>', '\x3', '>', '\x3', '>', - '\x6', '>', '\x1D5', '\n', '>', '\r', '>', '\xE', '>', '\x1D6', '\x3', - '>', '\x3', '>', '\x5', '>', '\x1DB', '\n', '>', '\x3', '>', '\x6', '>', - '\x1DE', '\n', '>', '\r', '>', '\xE', '>', '\x1DF', '\x5', '>', '\x1E2', - '\n', '>', '\x5', '>', '\x1E4', '\n', '>', '\x3', '?', '\x3', '?', '\x3', - '?', '\a', '?', '\x1E9', '\n', '?', '\f', '?', '\xE', '?', '\x1EC', '\v', - '?', '\x3', '?', '\x3', '?', '\x3', '?', '\x3', '?', '\a', '?', '\x1F2', - '\n', '?', '\f', '?', '\xE', '?', '\x1F5', '\v', '?', '\x3', '?', '\x5', - '?', '\x1F8', '\n', '?', '\x3', '@', '\x3', '@', '\x3', '@', '\x5', '@', - '\x1FD', '\n', '@', '\x3', '\x41', '\x3', '\x41', '\x3', '\x41', '\x3', - '\x41', '\x3', '\x41', '\x3', '\x41', '\x3', '\x42', '\x3', '\x42', '\x3', - '\x43', '\x3', '\x43', '\x3', '\x44', '\x3', '\x44', '\x3', '\x45', '\x3', - '\x45', '\x3', '\x45', '\x3', '\x45', '\a', '\x45', '\x20F', '\n', '\x45', - '\f', '\x45', '\xE', '\x45', '\x212', '\v', '\x45', '\x5', '\x45', '\x214', - '\n', '\x45', '\x3', '\x46', '\x3', '\x46', '\x3', '\x46', '\x3', 'G', - '\x3', 'G', '\x3', 'H', '\x3', 'H', '\x3', 'I', '\x3', 'I', '\x3', 'J', - '\x3', 'J', '\x3', 'K', '\x3', 'K', '\x3', 'L', '\x3', 'L', '\x3', 'M', - '\x3', 'M', '\x3', 'N', '\x3', 'N', '\x3', 'O', '\x3', 'O', '\x3', 'P', - '\x3', 'P', '\x3', 'Q', '\x3', 'Q', '\x3', 'R', '\x3', 'R', '\x3', 'S', - '\x3', 'S', '\x3', 'T', '\x3', 'T', '\x3', 'U', '\x3', 'U', '\x3', 'V', - '\x3', 'V', '\x3', 'W', '\x3', 'W', '\x3', 'X', '\x3', 'X', '\x3', 'Y', - '\x3', 'Y', '\x3', 'Z', '\x3', 'Z', '\x3', '[', '\x3', '[', '\x3', '\\', - '\x3', '\\', '\x3', ']', '\x3', ']', '\x3', '^', '\x3', '^', '\x3', '_', - '\x3', '_', '\x3', '`', '\x3', '`', '\x3', '\x61', '\x3', '\x61', '\x2', - '\x2', '\x62', '\x3', '\x3', '\x5', '\x4', '\a', '\x5', '\t', '\x6', '\v', - '\a', '\r', '\b', '\xF', '\t', '\x11', '\n', '\x13', '\v', '\x15', '\f', - '\x17', '\r', '\x19', '\xE', '\x1B', '\xF', '\x1D', '\x10', '\x1F', '\x11', - '!', '\x12', '#', '\x13', '%', '\x14', '\'', '\x15', ')', '\x16', '+', - '\x17', '-', '\x18', '/', '\x19', '\x31', '\x1A', '\x33', '\x1B', '\x35', - '\x1C', '\x37', '\x1D', '\x39', '\x1E', ';', '\x1F', '=', ' ', '?', '!', - '\x41', '\"', '\x43', '#', '\x45', '$', 'G', '%', 'I', '&', 'K', '\'', - 'M', '(', 'O', ')', 'Q', '*', 'S', '+', 'U', ',', 'W', '-', 'Y', '.', - '[', '/', ']', '\x30', '_', '\x31', '\x61', '\x32', '\x63', '\x33', '\x65', - '\x34', 'g', '\x35', 'i', '\x36', 'k', '\x37', 'm', '\x38', 'o', '\x39', - 'q', ':', 's', ';', 'u', '<', 'w', '=', 'y', '>', '{', '?', '}', '@', - '\x7F', '\x2', '\x81', '\x2', '\x83', '\x2', '\x85', '\x2', '\x87', '\x2', - '\x89', '\x41', '\x8B', '\x42', '\x8D', '\x2', '\x8F', '\x2', '\x91', - '\x2', '\x93', '\x2', '\x95', '\x2', '\x97', '\x2', '\x99', '\x2', '\x9B', - '\x2', '\x9D', '\x2', '\x9F', '\x2', '\xA1', '\x2', '\xA3', '\x2', '\xA5', - '\x2', '\xA7', '\x2', '\xA9', '\x2', '\xAB', '\x2', '\xAD', '\x2', '\xAF', - '\x2', '\xB1', '\x2', '\xB3', '\x2', '\xB5', '\x2', '\xB7', '\x2', '\xB9', - '\x2', '\xBB', '\x2', '\xBD', '\x2', '\xBF', '\x2', '\xC1', '\x2', '\x3', - '\x2', '$', '\x5', '\x2', '\v', '\f', '\xF', '\xF', '\"', '\"', '\x4', - '\x2', '-', '-', '/', '/', '\n', '\x2', '$', '$', '\x31', '\x31', '^', - '^', '\x64', '\x64', 'h', 'h', 'p', 'p', 't', 't', 'v', 'v', '\x5', '\x2', - '\x32', ';', '\x43', 'H', '\x63', 'h', '\x5', '\x2', '\x2', '!', ')', - ')', '^', '^', '\x5', '\x2', '\x2', '!', '$', '$', '^', '^', '\x5', '\x2', - '\x43', '\\', '\x61', '\x61', '\x63', '|', '\x3', '\x2', '\x32', ';', - '\x4', '\x2', '\x43', '\x43', '\x63', '\x63', '\x4', '\x2', '\x44', '\x44', - '\x64', '\x64', '\x4', '\x2', '\x45', '\x45', '\x65', '\x65', '\x4', '\x2', - '\x46', '\x46', '\x66', '\x66', '\x4', '\x2', 'G', 'G', 'g', 'g', '\x4', - '\x2', 'H', 'H', 'h', 'h', '\x4', '\x2', 'I', 'I', 'i', 'i', '\x4', '\x2', - 'J', 'J', 'j', 'j', '\x4', '\x2', 'K', 'K', 'k', 'k', '\x4', '\x2', 'L', - 'L', 'l', 'l', '\x4', '\x2', 'M', 'M', 'm', 'm', '\x4', '\x2', 'N', 'N', - 'n', 'n', '\x4', '\x2', 'O', 'O', 'o', 'o', '\x4', '\x2', 'P', 'P', 'p', - 'p', '\x4', '\x2', 'Q', 'Q', 'q', 'q', '\x4', '\x2', 'R', 'R', 'r', 'r', - '\x4', '\x2', 'S', 'S', 's', 's', '\x4', '\x2', 'T', 'T', 't', 't', '\x4', - '\x2', 'U', 'U', 'u', 'u', '\x4', '\x2', 'V', 'V', 'v', 'v', '\x4', '\x2', - 'W', 'W', 'w', 'w', '\x4', '\x2', 'X', 'X', 'x', 'x', '\x4', '\x2', 'Y', - 'Y', 'y', 'y', '\x4', '\x2', 'Z', 'Z', 'z', 'z', '\x4', '\x2', '[', '[', - '{', '{', '\x4', '\x2', '\\', '\\', '|', '|', '\x2', '\x244', '\x2', '\x3', - '\x3', '\x2', '\x2', '\x2', '\x2', '\x5', '\x3', '\x2', '\x2', '\x2', - '\x2', '\a', '\x3', '\x2', '\x2', '\x2', '\x2', '\t', '\x3', '\x2', '\x2', - '\x2', '\x2', '\v', '\x3', '\x2', '\x2', '\x2', '\x2', '\r', '\x3', '\x2', - '\x2', '\x2', '\x2', '\xF', '\x3', '\x2', '\x2', '\x2', '\x2', '\x11', - '\x3', '\x2', '\x2', '\x2', '\x2', '\x13', '\x3', '\x2', '\x2', '\x2', - '\x2', '\x15', '\x3', '\x2', '\x2', '\x2', '\x2', '\x17', '\x3', '\x2', - '\x2', '\x2', '\x2', '\x19', '\x3', '\x2', '\x2', '\x2', '\x2', '\x1B', - '\x3', '\x2', '\x2', '\x2', '\x2', '\x1D', '\x3', '\x2', '\x2', '\x2', - '\x2', '\x1F', '\x3', '\x2', '\x2', '\x2', '\x2', '!', '\x3', '\x2', '\x2', - '\x2', '\x2', '#', '\x3', '\x2', '\x2', '\x2', '\x2', '%', '\x3', '\x2', - '\x2', '\x2', '\x2', '\'', '\x3', '\x2', '\x2', '\x2', '\x2', ')', '\x3', - '\x2', '\x2', '\x2', '\x2', '+', '\x3', '\x2', '\x2', '\x2', '\x2', '-', - '\x3', '\x2', '\x2', '\x2', '\x2', '/', '\x3', '\x2', '\x2', '\x2', '\x2', - '\x31', '\x3', '\x2', '\x2', '\x2', '\x2', '\x33', '\x3', '\x2', '\x2', - '\x2', '\x2', '\x35', '\x3', '\x2', '\x2', '\x2', '\x2', '\x37', '\x3', - '\x2', '\x2', '\x2', '\x2', '\x39', '\x3', '\x2', '\x2', '\x2', '\x2', - ';', '\x3', '\x2', '\x2', '\x2', '\x2', '=', '\x3', '\x2', '\x2', '\x2', - '\x2', '?', '\x3', '\x2', '\x2', '\x2', '\x2', '\x41', '\x3', '\x2', '\x2', - '\x2', '\x2', '\x43', '\x3', '\x2', '\x2', '\x2', '\x2', '\x45', '\x3', - '\x2', '\x2', '\x2', '\x2', 'G', '\x3', '\x2', '\x2', '\x2', '\x2', 'I', - '\x3', '\x2', '\x2', '\x2', '\x2', 'K', '\x3', '\x2', '\x2', '\x2', '\x2', - 'M', '\x3', '\x2', '\x2', '\x2', '\x2', 'O', '\x3', '\x2', '\x2', '\x2', - '\x2', 'Q', '\x3', '\x2', '\x2', '\x2', '\x2', 'S', '\x3', '\x2', '\x2', - '\x2', '\x2', 'U', '\x3', '\x2', '\x2', '\x2', '\x2', 'W', '\x3', '\x2', - '\x2', '\x2', '\x2', 'Y', '\x3', '\x2', '\x2', '\x2', '\x2', '[', '\x3', - '\x2', '\x2', '\x2', '\x2', ']', '\x3', '\x2', '\x2', '\x2', '\x2', '_', - '\x3', '\x2', '\x2', '\x2', '\x2', '\x61', '\x3', '\x2', '\x2', '\x2', - '\x2', '\x63', '\x3', '\x2', '\x2', '\x2', '\x2', '\x65', '\x3', '\x2', - '\x2', '\x2', '\x2', 'g', '\x3', '\x2', '\x2', '\x2', '\x2', 'i', '\x3', - '\x2', '\x2', '\x2', '\x2', 'k', '\x3', '\x2', '\x2', '\x2', '\x2', 'm', - '\x3', '\x2', '\x2', '\x2', '\x2', 'o', '\x3', '\x2', '\x2', '\x2', '\x2', - 'q', '\x3', '\x2', '\x2', '\x2', '\x2', 's', '\x3', '\x2', '\x2', '\x2', - '\x2', 'u', '\x3', '\x2', '\x2', '\x2', '\x2', 'w', '\x3', '\x2', '\x2', - '\x2', '\x2', 'y', '\x3', '\x2', '\x2', '\x2', '\x2', '{', '\x3', '\x2', - '\x2', '\x2', '\x2', '}', '\x3', '\x2', '\x2', '\x2', '\x2', '\x89', '\x3', - '\x2', '\x2', '\x2', '\x2', '\x8B', '\x3', '\x2', '\x2', '\x2', '\x3', - '\xC3', '\x3', '\x2', '\x2', '\x2', '\x5', '\xC5', '\x3', '\x2', '\x2', - '\x2', '\a', '\xC7', '\x3', '\x2', '\x2', '\x2', '\t', '\xC9', '\x3', - '\x2', '\x2', '\x2', '\v', '\xCB', '\x3', '\x2', '\x2', '\x2', '\r', '\xCD', - '\x3', '\x2', '\x2', '\x2', '\xF', '\xCF', '\x3', '\x2', '\x2', '\x2', - '\x11', '\xD1', '\x3', '\x2', '\x2', '\x2', '\x13', '\xD3', '\x3', '\x2', - '\x2', '\x2', '\x15', '\xD5', '\x3', '\x2', '\x2', '\x2', '\x17', '\xD8', - '\x3', '\x2', '\x2', '\x2', '\x19', '\xDA', '\x3', '\x2', '\x2', '\x2', - '\x1B', '\xDC', '\x3', '\x2', '\x2', '\x2', '\x1D', '\xDE', '\x3', '\x2', - '\x2', '\x2', '\x1F', '\xE0', '\x3', '\x2', '\x2', '\x2', '!', '\xE2', - '\x3', '\x2', '\x2', '\x2', '#', '\xE4', '\x3', '\x2', '\x2', '\x2', '%', - '\xE7', '\x3', '\x2', '\x2', '\x2', '\'', '\xEA', '\x3', '\x2', '\x2', - '\x2', ')', '\xEC', '\x3', '\x2', '\x2', '\x2', '+', '\xEF', '\x3', '\x2', - '\x2', '\x2', '-', '\xF1', '\x3', '\x2', '\x2', '\x2', '/', '\xF3', '\x3', - '\x2', '\x2', '\x2', '\x31', '\xF5', '\x3', '\x2', '\x2', '\x2', '\x33', - '\xF8', '\x3', '\x2', '\x2', '\x2', '\x35', '\xFA', '\x3', '\x2', '\x2', - '\x2', '\x37', '\xFC', '\x3', '\x2', '\x2', '\x2', '\x39', '\xFE', '\x3', - '\x2', '\x2', '\x2', ';', '\x102', '\x3', '\x2', '\x2', '\x2', '=', '\x106', - '\x3', '\x2', '\x2', '\x2', '?', '\x10C', '\x3', '\x2', '\x2', '\x2', - '\x41', '\x10F', '\x3', '\x2', '\x2', '\x2', '\x43', '\x113', '\x3', '\x2', - '\x2', '\x2', '\x45', '\x11B', '\x3', '\x2', '\x2', '\x2', 'G', '\x11E', - '\x3', '\x2', '\x2', '\x2', 'I', '\x123', '\x3', '\x2', '\x2', '\x2', - 'K', '\x12C', '\x3', '\x2', '\x2', '\x2', 'M', '\x133', '\x3', '\x2', - '\x2', '\x2', 'O', '\x13A', '\x3', '\x2', '\x2', '\x2', 'Q', '\x140', - '\x3', '\x2', '\x2', '\x2', 'S', '\x145', '\x3', '\x2', '\x2', '\x2', - 'U', '\x14B', '\x3', '\x2', '\x2', '\x2', 'W', '\x14E', '\x3', '\x2', - '\x2', '\x2', 'Y', '\x153', '\x3', '\x2', '\x2', '\x2', '[', '\x158', - '\x3', '\x2', '\x2', '\x2', ']', '\x15D', '\x3', '\x2', '\x2', '\x2', - '_', '\x163', '\x3', '\x2', '\x2', '\x2', '\x61', '\x167', '\x3', '\x2', - '\x2', '\x2', '\x63', '\x16C', '\x3', '\x2', '\x2', '\x2', '\x65', '\x173', - '\x3', '\x2', '\x2', '\x2', 'g', '\x176', '\x3', '\x2', '\x2', '\x2', - 'i', '\x17C', '\x3', '\x2', '\x2', '\x2', 'k', '\x182', '\x3', '\x2', - '\x2', '\x2', 'm', '\x189', '\x3', '\x2', '\x2', '\x2', 'o', '\x18D', - '\x3', '\x2', '\x2', '\x2', 'q', '\x192', '\x3', '\x2', '\x2', '\x2', - 's', '\x196', '\x3', '\x2', '\x2', '\x2', 'u', '\x1A0', '\x3', '\x2', - '\x2', '\x2', 'w', '\x1A6', '\x3', '\x2', '\x2', '\x2', 'y', '\x1AD', - '\x3', '\x2', '\x2', '\x2', '{', '\x1E3', '\x3', '\x2', '\x2', '\x2', - '}', '\x1F7', '\x3', '\x2', '\x2', '\x2', '\x7F', '\x1F9', '\x3', '\x2', - '\x2', '\x2', '\x81', '\x1FE', '\x3', '\x2', '\x2', '\x2', '\x83', '\x204', - '\x3', '\x2', '\x2', '\x2', '\x85', '\x206', '\x3', '\x2', '\x2', '\x2', - '\x87', '\x208', '\x3', '\x2', '\x2', '\x2', '\x89', '\x213', '\x3', '\x2', - '\x2', '\x2', '\x8B', '\x215', '\x3', '\x2', '\x2', '\x2', '\x8D', '\x218', - '\x3', '\x2', '\x2', '\x2', '\x8F', '\x21A', '\x3', '\x2', '\x2', '\x2', - '\x91', '\x21C', '\x3', '\x2', '\x2', '\x2', '\x93', '\x21E', '\x3', '\x2', - '\x2', '\x2', '\x95', '\x220', '\x3', '\x2', '\x2', '\x2', '\x97', '\x222', - '\x3', '\x2', '\x2', '\x2', '\x99', '\x224', '\x3', '\x2', '\x2', '\x2', - '\x9B', '\x226', '\x3', '\x2', '\x2', '\x2', '\x9D', '\x228', '\x3', '\x2', - '\x2', '\x2', '\x9F', '\x22A', '\x3', '\x2', '\x2', '\x2', '\xA1', '\x22C', - '\x3', '\x2', '\x2', '\x2', '\xA3', '\x22E', '\x3', '\x2', '\x2', '\x2', - '\xA5', '\x230', '\x3', '\x2', '\x2', '\x2', '\xA7', '\x232', '\x3', '\x2', - '\x2', '\x2', '\xA9', '\x234', '\x3', '\x2', '\x2', '\x2', '\xAB', '\x236', - '\x3', '\x2', '\x2', '\x2', '\xAD', '\x238', '\x3', '\x2', '\x2', '\x2', - '\xAF', '\x23A', '\x3', '\x2', '\x2', '\x2', '\xB1', '\x23C', '\x3', '\x2', - '\x2', '\x2', '\xB3', '\x23E', '\x3', '\x2', '\x2', '\x2', '\xB5', '\x240', - '\x3', '\x2', '\x2', '\x2', '\xB7', '\x242', '\x3', '\x2', '\x2', '\x2', - '\xB9', '\x244', '\x3', '\x2', '\x2', '\x2', '\xBB', '\x246', '\x3', '\x2', - '\x2', '\x2', '\xBD', '\x248', '\x3', '\x2', '\x2', '\x2', '\xBF', '\x24A', - '\x3', '\x2', '\x2', '\x2', '\xC1', '\x24C', '\x3', '\x2', '\x2', '\x2', - '\xC3', '\xC4', '\a', ',', '\x2', '\x2', '\xC4', '\x4', '\x3', '\x2', - '\x2', '\x2', '\xC5', '\xC6', '\a', '.', '\x2', '\x2', '\xC6', '\x6', - '\x3', '\x2', '\x2', '\x2', '\xC7', '\xC8', '\a', '*', '\x2', '\x2', '\xC8', - '\b', '\x3', '\x2', '\x2', '\x2', '\xC9', '\xCA', '\a', '+', '\x2', '\x2', - '\xCA', '\n', '\x3', '\x2', '\x2', '\x2', '\xCB', '\xCC', '\a', '\x30', - '\x2', '\x2', '\xCC', '\f', '\x3', '\x2', '\x2', '\x2', '\xCD', '\xCE', - '\a', ']', '\x2', '\x2', '\xCE', '\xE', '\x3', '\x2', '\x2', '\x2', '\xCF', - '\xD0', '\a', '_', '\x2', '\x2', '\xD0', '\x10', '\x3', '\x2', '\x2', - '\x2', '\xD1', '\xD2', '\a', '\x41', '\x2', '\x2', '\xD2', '\x12', '\x3', - '\x2', '\x2', '\x2', '\xD3', '\xD4', '\a', '<', '\x2', '\x2', '\xD4', - '\x14', '\x3', '\x2', '\x2', '\x2', '\xD5', '\xD6', '\a', '\x41', '\x2', - '\x2', '\xD6', '\xD7', '\a', '\x41', '\x2', '\x2', '\xD7', '\x16', '\x3', - '\x2', '\x2', '\x2', '\xD8', '\xD9', '\a', '\x31', '\x2', '\x2', '\xD9', - '\x18', '\x3', '\x2', '\x2', '\x2', '\xDA', '\xDB', '\a', '\'', '\x2', - '\x2', '\xDB', '\x1A', '\x3', '\x2', '\x2', '\x2', '\xDC', '\xDD', '\a', - '-', '\x2', '\x2', '\xDD', '\x1C', '\x3', '\x2', '\x2', '\x2', '\xDE', - '\xDF', '\a', '/', '\x2', '\x2', '\xDF', '\x1E', '\x3', '\x2', '\x2', - '\x2', '\xE0', '\xE1', '\a', '>', '\x2', '\x2', '\xE1', ' ', '\x3', '\x2', - '\x2', '\x2', '\xE2', '\xE3', '\a', '@', '\x2', '\x2', '\xE3', '\"', '\x3', - '\x2', '\x2', '\x2', '\xE4', '\xE5', '\a', '@', '\x2', '\x2', '\xE5', - '\xE6', '\a', '?', '\x2', '\x2', '\xE6', '$', '\x3', '\x2', '\x2', '\x2', - '\xE7', '\xE8', '\a', '>', '\x2', '\x2', '\xE8', '\xE9', '\a', '?', '\x2', - '\x2', '\xE9', '&', '\x3', '\x2', '\x2', '\x2', '\xEA', '\xEB', '\a', - '?', '\x2', '\x2', '\xEB', '(', '\x3', '\x2', '\x2', '\x2', '\xEC', '\xED', - '\a', '#', '\x2', '\x2', '\xED', '\xEE', '\a', '?', '\x2', '\x2', '\xEE', - '*', '\x3', '\x2', '\x2', '\x2', '\xEF', '\xF0', '\a', '(', '\x2', '\x2', - '\xF0', ',', '\x3', '\x2', '\x2', '\x2', '\xF1', '\xF2', '\a', '`', '\x2', - '\x2', '\xF2', '.', '\x3', '\x2', '\x2', '\x2', '\xF3', '\xF4', '\a', - '~', '\x2', '\x2', '\xF4', '\x30', '\x3', '\x2', '\x2', '\x2', '\xF5', - '\xF6', '\a', '~', '\x2', '\x2', '\xF6', '\xF7', '\a', '~', '\x2', '\x2', - '\xF7', '\x32', '\x3', '\x2', '\x2', '\x2', '\xF8', '\xF9', '\a', '\x80', - '\x2', '\x2', '\xF9', '\x34', '\x3', '\x2', '\x2', '\x2', '\xFA', '\xFB', - '\a', '}', '\x2', '\x2', '\xFB', '\x36', '\x3', '\x2', '\x2', '\x2', '\xFC', - '\xFD', '\a', '\x7F', '\x2', '\x2', '\xFD', '\x38', '\x3', '\x2', '\x2', - '\x2', '\xFE', '\xFF', '\x5', '\x8F', 'H', '\x2', '\xFF', '\x100', '\x5', - '\xA5', 'S', '\x2', '\x100', '\x101', '\x5', '\xA5', 'S', '\x2', '\x101', - ':', '\x3', '\x2', '\x2', '\x2', '\x102', '\x103', '\x5', '\x8F', 'H', - '\x2', '\x103', '\x104', '\x5', '\xA9', 'U', '\x2', '\x104', '\x105', - '\x5', '\x95', 'K', '\x2', '\x105', '<', '\x3', '\x2', '\x2', '\x2', '\x106', - '\x107', '\x5', '\x8F', 'H', '\x2', '\x107', '\x108', '\x5', '\xB1', 'Y', - '\x2', '\x108', '\x109', '\x5', '\xB1', 'Y', '\x2', '\x109', '\x10A', - '\x5', '\x8F', 'H', '\x2', '\x10A', '\x10B', '\x5', '\xBF', '`', '\x2', - '\x10B', '>', '\x3', '\x2', '\x2', '\x2', '\x10C', '\x10D', '\x5', '\x8F', - 'H', '\x2', '\x10D', '\x10E', '\x5', '\xB3', 'Z', '\x2', '\x10E', '@', - '\x3', '\x2', '\x2', '\x2', '\x10F', '\x110', '\x5', '\x8F', 'H', '\x2', - '\x110', '\x111', '\x5', '\xB3', 'Z', '\x2', '\x111', '\x112', '\x5', - '\x93', 'J', '\x2', '\x112', '\x42', '\x3', '\x2', '\x2', '\x2', '\x113', - '\x114', '\x5', '\x91', 'I', '\x2', '\x114', '\x115', '\x5', '\x97', 'L', - '\x2', '\x115', '\x116', '\x5', '\xB5', '[', '\x2', '\x116', '\x117', - '\x5', '\xBB', '^', '\x2', '\x117', '\x118', '\x5', '\x97', 'L', '\x2', - '\x118', '\x119', '\x5', '\x97', 'L', '\x2', '\x119', '\x11A', '\x5', - '\xA9', 'U', '\x2', '\x11A', '\x44', '\x3', '\x2', '\x2', '\x2', '\x11B', - '\x11C', '\x5', '\x91', 'I', '\x2', '\x11C', '\x11D', '\x5', '\xBF', '`', - '\x2', '\x11D', '\x46', '\x3', '\x2', '\x2', '\x2', '\x11E', '\x11F', - '\x5', '\x95', 'K', '\x2', '\x11F', '\x120', '\x5', '\x97', 'L', '\x2', - '\x120', '\x121', '\x5', '\xB3', 'Z', '\x2', '\x121', '\x122', '\x5', - '\x93', 'J', '\x2', '\x122', 'H', '\x3', '\x2', '\x2', '\x2', '\x123', - '\x124', '\x5', '\x95', 'K', '\x2', '\x124', '\x125', '\x5', '\x9F', 'P', - '\x2', '\x125', '\x126', '\x5', '\xB3', 'Z', '\x2', '\x126', '\x127', - '\x5', '\xB5', '[', '\x2', '\x127', '\x128', '\x5', '\x9F', 'P', '\x2', - '\x128', '\x129', '\x5', '\xA9', 'U', '\x2', '\x129', '\x12A', '\x5', - '\x93', 'J', '\x2', '\x12A', '\x12B', '\x5', '\xB5', '[', '\x2', '\x12B', - 'J', '\x3', '\x2', '\x2', '\x2', '\x12C', '\x12D', '\x5', '\x97', 'L', - '\x2', '\x12D', '\x12E', '\x5', '\xB3', 'Z', '\x2', '\x12E', '\x12F', - '\x5', '\x93', 'J', '\x2', '\x12F', '\x130', '\x5', '\x8F', 'H', '\x2', - '\x130', '\x131', '\x5', '\xAD', 'W', '\x2', '\x131', '\x132', '\x5', - '\x97', 'L', '\x2', '\x132', 'L', '\x3', '\x2', '\x2', '\x2', '\x133', - '\x134', '\x5', '\x97', 'L', '\x2', '\x134', '\x135', '\x5', '\xBD', '_', - '\x2', '\x135', '\x136', '\x5', '\x9F', 'P', '\x2', '\x136', '\x137', - '\x5', '\xB3', 'Z', '\x2', '\x137', '\x138', '\x5', '\xB5', '[', '\x2', - '\x138', '\x139', '\x5', '\xB3', 'Z', '\x2', '\x139', 'N', '\x3', '\x2', - '\x2', '\x2', '\x13A', '\x13B', '\a', 'h', '\x2', '\x2', '\x13B', '\x13C', - '\a', '\x63', '\x2', '\x2', '\x13C', '\x13D', '\a', 'n', '\x2', '\x2', - '\x13D', '\x13E', '\a', 'u', '\x2', '\x2', '\x13E', '\x13F', '\a', 'g', - '\x2', '\x2', '\x13F', 'P', '\x3', '\x2', '\x2', '\x2', '\x140', '\x141', - '\x5', '\x99', 'M', '\x2', '\x141', '\x142', '\x5', '\xB1', 'Y', '\x2', - '\x142', '\x143', '\x5', '\xAB', 'V', '\x2', '\x143', '\x144', '\x5', - '\xA7', 'T', '\x2', '\x144', 'R', '\x3', '\x2', '\x2', '\x2', '\x145', - '\x146', '\x5', '\x9B', 'N', '\x2', '\x146', '\x147', '\x5', '\xB1', 'Y', - '\x2', '\x147', '\x148', '\x5', '\xAB', 'V', '\x2', '\x148', '\x149', - '\x5', '\xB7', '\\', '\x2', '\x149', '\x14A', '\x5', '\xAD', 'W', '\x2', - '\x14A', 'T', '\x3', '\x2', '\x2', '\x2', '\x14B', '\x14C', '\x5', '\x9F', - 'P', '\x2', '\x14C', '\x14D', '\x5', '\xA9', 'U', '\x2', '\x14D', 'V', - '\x3', '\x2', '\x2', '\x2', '\x14E', '\x14F', '\x5', '\xA1', 'Q', '\x2', - '\x14F', '\x150', '\x5', '\xAB', 'V', '\x2', '\x150', '\x151', '\x5', - '\x9F', 'P', '\x2', '\x151', '\x152', '\x5', '\xA9', 'U', '\x2', '\x152', - 'X', '\x3', '\x2', '\x2', '\x2', '\x153', '\x154', '\x5', '\xA5', 'S', - '\x2', '\x154', '\x155', '\x5', '\x97', 'L', '\x2', '\x155', '\x156', - '\x5', '\x99', 'M', '\x2', '\x156', '\x157', '\x5', '\xB5', '[', '\x2', - '\x157', 'Z', '\x3', '\x2', '\x2', '\x2', '\x158', '\x159', '\x5', '\xA5', - 'S', '\x2', '\x159', '\x15A', '\x5', '\x9F', 'P', '\x2', '\x15A', '\x15B', - '\x5', '\xA3', 'R', '\x2', '\x15B', '\x15C', '\x5', '\x97', 'L', '\x2', - '\x15C', '\\', '\x3', '\x2', '\x2', '\x2', '\x15D', '\x15E', '\x5', '\xA5', - 'S', '\x2', '\x15E', '\x15F', '\x5', '\x9F', 'P', '\x2', '\x15F', '\x160', - '\x5', '\xA7', 'T', '\x2', '\x160', '\x161', '\x5', '\x9F', 'P', '\x2', - '\x161', '\x162', '\x5', '\xB5', '[', '\x2', '\x162', '^', '\x3', '\x2', - '\x2', '\x2', '\x163', '\x164', '\x5', '\xA9', 'U', '\x2', '\x164', '\x165', - '\x5', '\xAB', 'V', '\x2', '\x165', '\x166', '\x5', '\xB5', '[', '\x2', - '\x166', '`', '\x3', '\x2', '\x2', '\x2', '\x167', '\x168', '\a', 'p', - '\x2', '\x2', '\x168', '\x169', '\a', 'w', '\x2', '\x2', '\x169', '\x16A', - '\a', 'n', '\x2', '\x2', '\x16A', '\x16B', '\a', 'n', '\x2', '\x2', '\x16B', - '\x62', '\x3', '\x2', '\x2', '\x2', '\x16C', '\x16D', '\x5', '\xAB', 'V', - '\x2', '\x16D', '\x16E', '\x5', '\x99', 'M', '\x2', '\x16E', '\x16F', - '\x5', '\x99', 'M', '\x2', '\x16F', '\x170', '\x5', '\xB3', 'Z', '\x2', - '\x170', '\x171', '\x5', '\x97', 'L', '\x2', '\x171', '\x172', '\x5', - '\xB5', '[', '\x2', '\x172', '\x64', '\x3', '\x2', '\x2', '\x2', '\x173', - '\x174', '\x5', '\xAB', 'V', '\x2', '\x174', '\x175', '\x5', '\xB1', 'Y', - '\x2', '\x175', '\x66', '\x3', '\x2', '\x2', '\x2', '\x176', '\x177', - '\x5', '\xAB', 'V', '\x2', '\x177', '\x178', '\x5', '\xB1', 'Y', '\x2', - '\x178', '\x179', '\x5', '\x95', 'K', '\x2', '\x179', '\x17A', '\x5', - '\x97', 'L', '\x2', '\x17A', '\x17B', '\x5', '\xB1', 'Y', '\x2', '\x17B', - 'h', '\x3', '\x2', '\x2', '\x2', '\x17C', '\x17D', '\x5', '\xB1', 'Y', - '\x2', '\x17D', '\x17E', '\x5', '\x9F', 'P', '\x2', '\x17E', '\x17F', - '\x5', '\x9B', 'N', '\x2', '\x17F', '\x180', '\x5', '\x9D', 'O', '\x2', - '\x180', '\x181', '\x5', '\xB5', '[', '\x2', '\x181', 'j', '\x3', '\x2', - '\x2', '\x2', '\x182', '\x183', '\x5', '\xB3', 'Z', '\x2', '\x183', '\x184', - '\x5', '\x97', 'L', '\x2', '\x184', '\x185', '\x5', '\xA5', 'S', '\x2', - '\x185', '\x186', '\x5', '\x97', 'L', '\x2', '\x186', '\x187', '\x5', - '\x93', 'J', '\x2', '\x187', '\x188', '\x5', '\xB5', '[', '\x2', '\x188', - 'l', '\x3', '\x2', '\x2', '\x2', '\x189', '\x18A', '\x5', '\xB5', '[', - '\x2', '\x18A', '\x18B', '\x5', '\xAB', 'V', '\x2', '\x18B', '\x18C', - '\x5', '\xAD', 'W', '\x2', '\x18C', 'n', '\x3', '\x2', '\x2', '\x2', '\x18D', - '\x18E', '\a', 'v', '\x2', '\x2', '\x18E', '\x18F', '\a', 't', '\x2', - '\x2', '\x18F', '\x190', '\a', 'w', '\x2', '\x2', '\x190', '\x191', '\a', - 'g', '\x2', '\x2', '\x191', 'p', '\x3', '\x2', '\x2', '\x2', '\x192', - '\x193', '\a', 'w', '\x2', '\x2', '\x193', '\x194', '\a', '\x66', '\x2', - '\x2', '\x194', '\x195', '\a', 'h', '\x2', '\x2', '\x195', 'r', '\x3', - '\x2', '\x2', '\x2', '\x196', '\x197', '\a', 'w', '\x2', '\x2', '\x197', - '\x198', '\a', 'p', '\x2', '\x2', '\x198', '\x199', '\a', '\x66', '\x2', - '\x2', '\x199', '\x19A', '\a', 'g', '\x2', '\x2', '\x19A', '\x19B', '\a', - 'h', '\x2', '\x2', '\x19B', '\x19C', '\a', 'k', '\x2', '\x2', '\x19C', - '\x19D', '\a', 'p', '\x2', '\x2', '\x19D', '\x19E', '\a', 'g', '\x2', - '\x2', '\x19E', '\x19F', '\a', '\x66', '\x2', '\x2', '\x19F', 't', '\x3', - '\x2', '\x2', '\x2', '\x1A0', '\x1A1', '\x5', '\xB9', ']', '\x2', '\x1A1', - '\x1A2', '\x5', '\x8F', 'H', '\x2', '\x1A2', '\x1A3', '\x5', '\xA5', 'S', - '\x2', '\x1A3', '\x1A4', '\x5', '\xB7', '\\', '\x2', '\x1A4', '\x1A5', - '\x5', '\x97', 'L', '\x2', '\x1A5', 'v', '\x3', '\x2', '\x2', '\x2', '\x1A6', - '\x1A7', '\x5', '\xBB', '^', '\x2', '\x1A7', '\x1A8', '\x5', '\x9D', 'O', - '\x2', '\x1A8', '\x1A9', '\x5', '\x97', 'L', '\x2', '\x1A9', '\x1AA', - '\x5', '\xB1', 'Y', '\x2', '\x1AA', '\x1AB', '\x5', '\x97', 'L', '\x2', - '\x1AB', 'x', '\x3', '\x2', '\x2', '\x2', '\x1AC', '\x1AE', '\t', '\x2', - '\x2', '\x2', '\x1AD', '\x1AC', '\x3', '\x2', '\x2', '\x2', '\x1AE', '\x1AF', - '\x3', '\x2', '\x2', '\x2', '\x1AF', '\x1AD', '\x3', '\x2', '\x2', '\x2', - '\x1AF', '\x1B0', '\x3', '\x2', '\x2', '\x2', '\x1B0', '\x1B1', '\x3', - '\x2', '\x2', '\x2', '\x1B1', '\x1B2', '\b', '=', '\x2', '\x2', '\x1B2', - 'z', '\x3', '\x2', '\x2', '\x2', '\x1B3', '\x1B5', '\t', '\x3', '\x2', - '\x2', '\x1B4', '\x1B3', '\x3', '\x2', '\x2', '\x2', '\x1B4', '\x1B5', - '\x3', '\x2', '\x2', '\x2', '\x1B5', '\x1B7', '\x3', '\x2', '\x2', '\x2', - '\x1B6', '\x1B8', '\x5', '\x8D', 'G', '\x2', '\x1B7', '\x1B6', '\x3', - '\x2', '\x2', '\x2', '\x1B8', '\x1B9', '\x3', '\x2', '\x2', '\x2', '\x1B9', - '\x1B7', '\x3', '\x2', '\x2', '\x2', '\x1B9', '\x1BA', '\x3', '\x2', '\x2', - '\x2', '\x1BA', '\x1C2', '\x3', '\x2', '\x2', '\x2', '\x1BB', '\x1BF', - '\a', '\x30', '\x2', '\x2', '\x1BC', '\x1BE', '\x5', '\x8D', 'G', '\x2', - '\x1BD', '\x1BC', '\x3', '\x2', '\x2', '\x2', '\x1BE', '\x1C1', '\x3', - '\x2', '\x2', '\x2', '\x1BF', '\x1BD', '\x3', '\x2', '\x2', '\x2', '\x1BF', - '\x1C0', '\x3', '\x2', '\x2', '\x2', '\x1C0', '\x1C3', '\x3', '\x2', '\x2', - '\x2', '\x1C1', '\x1BF', '\x3', '\x2', '\x2', '\x2', '\x1C2', '\x1BB', - '\x3', '\x2', '\x2', '\x2', '\x1C2', '\x1C3', '\x3', '\x2', '\x2', '\x2', - '\x1C3', '\x1CD', '\x3', '\x2', '\x2', '\x2', '\x1C4', '\x1C6', '\x5', - '\x97', 'L', '\x2', '\x1C5', '\x1C7', '\t', '\x3', '\x2', '\x2', '\x1C6', - '\x1C5', '\x3', '\x2', '\x2', '\x2', '\x1C6', '\x1C7', '\x3', '\x2', '\x2', - '\x2', '\x1C7', '\x1C9', '\x3', '\x2', '\x2', '\x2', '\x1C8', '\x1CA', - '\x5', '\x8D', 'G', '\x2', '\x1C9', '\x1C8', '\x3', '\x2', '\x2', '\x2', - '\x1CA', '\x1CB', '\x3', '\x2', '\x2', '\x2', '\x1CB', '\x1C9', '\x3', - '\x2', '\x2', '\x2', '\x1CB', '\x1CC', '\x3', '\x2', '\x2', '\x2', '\x1CC', - '\x1CE', '\x3', '\x2', '\x2', '\x2', '\x1CD', '\x1C4', '\x3', '\x2', '\x2', - '\x2', '\x1CD', '\x1CE', '\x3', '\x2', '\x2', '\x2', '\x1CE', '\x1E4', - '\x3', '\x2', '\x2', '\x2', '\x1CF', '\x1D1', '\t', '\x3', '\x2', '\x2', - '\x1D0', '\x1CF', '\x3', '\x2', '\x2', '\x2', '\x1D0', '\x1D1', '\x3', - '\x2', '\x2', '\x2', '\x1D1', '\x1D2', '\x3', '\x2', '\x2', '\x2', '\x1D2', - '\x1D4', '\a', '\x30', '\x2', '\x2', '\x1D3', '\x1D5', '\x5', '\x8D', - 'G', '\x2', '\x1D4', '\x1D3', '\x3', '\x2', '\x2', '\x2', '\x1D5', '\x1D6', - '\x3', '\x2', '\x2', '\x2', '\x1D6', '\x1D4', '\x3', '\x2', '\x2', '\x2', - '\x1D6', '\x1D7', '\x3', '\x2', '\x2', '\x2', '\x1D7', '\x1E1', '\x3', - '\x2', '\x2', '\x2', '\x1D8', '\x1DA', '\x5', '\x97', 'L', '\x2', '\x1D9', - '\x1DB', '\t', '\x3', '\x2', '\x2', '\x1DA', '\x1D9', '\x3', '\x2', '\x2', - '\x2', '\x1DA', '\x1DB', '\x3', '\x2', '\x2', '\x2', '\x1DB', '\x1DD', - '\x3', '\x2', '\x2', '\x2', '\x1DC', '\x1DE', '\x5', '\x8D', 'G', '\x2', - '\x1DD', '\x1DC', '\x3', '\x2', '\x2', '\x2', '\x1DE', '\x1DF', '\x3', - '\x2', '\x2', '\x2', '\x1DF', '\x1DD', '\x3', '\x2', '\x2', '\x2', '\x1DF', - '\x1E0', '\x3', '\x2', '\x2', '\x2', '\x1E0', '\x1E2', '\x3', '\x2', '\x2', - '\x2', '\x1E1', '\x1D8', '\x3', '\x2', '\x2', '\x2', '\x1E1', '\x1E2', - '\x3', '\x2', '\x2', '\x2', '\x1E2', '\x1E4', '\x3', '\x2', '\x2', '\x2', - '\x1E3', '\x1B4', '\x3', '\x2', '\x2', '\x2', '\x1E3', '\x1D0', '\x3', - '\x2', '\x2', '\x2', '\x1E4', '|', '\x3', '\x2', '\x2', '\x2', '\x1E5', - '\x1EA', '\a', '$', '\x2', '\x2', '\x1E6', '\x1E9', '\x5', '\x7F', '@', - '\x2', '\x1E7', '\x1E9', '\x5', '\x87', '\x44', '\x2', '\x1E8', '\x1E6', - '\x3', '\x2', '\x2', '\x2', '\x1E8', '\x1E7', '\x3', '\x2', '\x2', '\x2', - '\x1E9', '\x1EC', '\x3', '\x2', '\x2', '\x2', '\x1EA', '\x1E8', '\x3', - '\x2', '\x2', '\x2', '\x1EA', '\x1EB', '\x3', '\x2', '\x2', '\x2', '\x1EB', - '\x1ED', '\x3', '\x2', '\x2', '\x2', '\x1EC', '\x1EA', '\x3', '\x2', '\x2', - '\x2', '\x1ED', '\x1F8', '\a', '$', '\x2', '\x2', '\x1EE', '\x1F3', '\a', - ')', '\x2', '\x2', '\x1EF', '\x1F2', '\x5', '\x7F', '@', '\x2', '\x1F0', - '\x1F2', '\x5', '\x85', '\x43', '\x2', '\x1F1', '\x1EF', '\x3', '\x2', - '\x2', '\x2', '\x1F1', '\x1F0', '\x3', '\x2', '\x2', '\x2', '\x1F2', '\x1F5', - '\x3', '\x2', '\x2', '\x2', '\x1F3', '\x1F1', '\x3', '\x2', '\x2', '\x2', - '\x1F3', '\x1F4', '\x3', '\x2', '\x2', '\x2', '\x1F4', '\x1F6', '\x3', - '\x2', '\x2', '\x2', '\x1F5', '\x1F3', '\x3', '\x2', '\x2', '\x2', '\x1F6', - '\x1F8', '\a', ')', '\x2', '\x2', '\x1F7', '\x1E5', '\x3', '\x2', '\x2', - '\x2', '\x1F7', '\x1EE', '\x3', '\x2', '\x2', '\x2', '\x1F8', '~', '\x3', - '\x2', '\x2', '\x2', '\x1F9', '\x1FC', '\a', '^', '\x2', '\x2', '\x1FA', - '\x1FD', '\t', '\x4', '\x2', '\x2', '\x1FB', '\x1FD', '\x5', '\x81', '\x41', - '\x2', '\x1FC', '\x1FA', '\x3', '\x2', '\x2', '\x2', '\x1FC', '\x1FB', - '\x3', '\x2', '\x2', '\x2', '\x1FD', '\x80', '\x3', '\x2', '\x2', '\x2', - '\x1FE', '\x1FF', '\a', 'w', '\x2', '\x2', '\x1FF', '\x200', '\x5', '\x83', - '\x42', '\x2', '\x200', '\x201', '\x5', '\x83', '\x42', '\x2', '\x201', - '\x202', '\x5', '\x83', '\x42', '\x2', '\x202', '\x203', '\x5', '\x83', - '\x42', '\x2', '\x203', '\x82', '\x3', '\x2', '\x2', '\x2', '\x204', '\x205', - '\t', '\x5', '\x2', '\x2', '\x205', '\x84', '\x3', '\x2', '\x2', '\x2', - '\x206', '\x207', '\n', '\x6', '\x2', '\x2', '\x207', '\x86', '\x3', '\x2', - '\x2', '\x2', '\x208', '\x209', '\n', '\a', '\x2', '\x2', '\x209', '\x88', - '\x3', '\x2', '\x2', '\x2', '\x20A', '\x214', '\x3', '\x2', '\x2', '\x2', - '\x20B', '\x210', '\t', '\b', '\x2', '\x2', '\x20C', '\x20F', '\t', '\b', - '\x2', '\x2', '\x20D', '\x20F', '\x5', '\x8D', 'G', '\x2', '\x20E', '\x20C', - '\x3', '\x2', '\x2', '\x2', '\x20E', '\x20D', '\x3', '\x2', '\x2', '\x2', - '\x20F', '\x212', '\x3', '\x2', '\x2', '\x2', '\x210', '\x20E', '\x3', - '\x2', '\x2', '\x2', '\x210', '\x211', '\x3', '\x2', '\x2', '\x2', '\x211', - '\x214', '\x3', '\x2', '\x2', '\x2', '\x212', '\x210', '\x3', '\x2', '\x2', - '\x2', '\x213', '\x20A', '\x3', '\x2', '\x2', '\x2', '\x213', '\x20B', - '\x3', '\x2', '\x2', '\x2', '\x214', '\x8A', '\x3', '\x2', '\x2', '\x2', - '\x215', '\x216', '\a', '\x42', '\x2', '\x2', '\x216', '\x217', '\x5', - '\x89', '\x45', '\x2', '\x217', '\x8C', '\x3', '\x2', '\x2', '\x2', '\x218', - '\x219', '\t', '\t', '\x2', '\x2', '\x219', '\x8E', '\x3', '\x2', '\x2', - '\x2', '\x21A', '\x21B', '\t', '\n', '\x2', '\x2', '\x21B', '\x90', '\x3', - '\x2', '\x2', '\x2', '\x21C', '\x21D', '\t', '\v', '\x2', '\x2', '\x21D', - '\x92', '\x3', '\x2', '\x2', '\x2', '\x21E', '\x21F', '\t', '\f', '\x2', - '\x2', '\x21F', '\x94', '\x3', '\x2', '\x2', '\x2', '\x220', '\x221', - '\t', '\r', '\x2', '\x2', '\x221', '\x96', '\x3', '\x2', '\x2', '\x2', - '\x222', '\x223', '\t', '\xE', '\x2', '\x2', '\x223', '\x98', '\x3', '\x2', - '\x2', '\x2', '\x224', '\x225', '\t', '\xF', '\x2', '\x2', '\x225', '\x9A', - '\x3', '\x2', '\x2', '\x2', '\x226', '\x227', '\t', '\x10', '\x2', '\x2', - '\x227', '\x9C', '\x3', '\x2', '\x2', '\x2', '\x228', '\x229', '\t', '\x11', - '\x2', '\x2', '\x229', '\x9E', '\x3', '\x2', '\x2', '\x2', '\x22A', '\x22B', - '\t', '\x12', '\x2', '\x2', '\x22B', '\xA0', '\x3', '\x2', '\x2', '\x2', - '\x22C', '\x22D', '\t', '\x13', '\x2', '\x2', '\x22D', '\xA2', '\x3', - '\x2', '\x2', '\x2', '\x22E', '\x22F', '\t', '\x14', '\x2', '\x2', '\x22F', - '\xA4', '\x3', '\x2', '\x2', '\x2', '\x230', '\x231', '\t', '\x15', '\x2', - '\x2', '\x231', '\xA6', '\x3', '\x2', '\x2', '\x2', '\x232', '\x233', - '\t', '\x16', '\x2', '\x2', '\x233', '\xA8', '\x3', '\x2', '\x2', '\x2', - '\x234', '\x235', '\t', '\x17', '\x2', '\x2', '\x235', '\xAA', '\x3', - '\x2', '\x2', '\x2', '\x236', '\x237', '\t', '\x18', '\x2', '\x2', '\x237', - '\xAC', '\x3', '\x2', '\x2', '\x2', '\x238', '\x239', '\t', '\x19', '\x2', - '\x2', '\x239', '\xAE', '\x3', '\x2', '\x2', '\x2', '\x23A', '\x23B', - '\t', '\x1A', '\x2', '\x2', '\x23B', '\xB0', '\x3', '\x2', '\x2', '\x2', - '\x23C', '\x23D', '\t', '\x1B', '\x2', '\x2', '\x23D', '\xB2', '\x3', - '\x2', '\x2', '\x2', '\x23E', '\x23F', '\t', '\x1C', '\x2', '\x2', '\x23F', - '\xB4', '\x3', '\x2', '\x2', '\x2', '\x240', '\x241', '\t', '\x1D', '\x2', - '\x2', '\x241', '\xB6', '\x3', '\x2', '\x2', '\x2', '\x242', '\x243', - '\t', '\x1E', '\x2', '\x2', '\x243', '\xB8', '\x3', '\x2', '\x2', '\x2', - '\x244', '\x245', '\t', '\x1F', '\x2', '\x2', '\x245', '\xBA', '\x3', - '\x2', '\x2', '\x2', '\x246', '\x247', '\t', ' ', '\x2', '\x2', '\x247', - '\xBC', '\x3', '\x2', '\x2', '\x2', '\x248', '\x249', '\t', '!', '\x2', - '\x2', '\x249', '\xBE', '\x3', '\x2', '\x2', '\x2', '\x24A', '\x24B', - '\t', '\"', '\x2', '\x2', '\x24B', '\xC0', '\x3', '\x2', '\x2', '\x2', - '\x24C', '\x24D', '\t', '#', '\x2', '\x2', '\x24D', '\xC2', '\x3', '\x2', - '\x2', '\x2', '\x1A', '\x2', '\x1AF', '\x1B4', '\x1B9', '\x1BF', '\x1C2', - '\x1C6', '\x1CB', '\x1CD', '\x1D0', '\x1D6', '\x1DA', '\x1DF', '\x1E1', - '\x1E3', '\x1E8', '\x1EA', '\x1F1', '\x1F3', '\x1F7', '\x1FC', '\x20E', - '\x210', '\x213', '\x3', '\b', '\x2', '\x2', + '\x4', '\x62', '\t', '\x62', '\x4', '\x63', '\t', '\x63', '\x3', '\x2', + '\x3', '\x2', '\x3', '\x3', '\x3', '\x3', '\x3', '\x4', '\x3', '\x4', + '\x3', '\x5', '\x3', '\x5', '\x3', '\x6', '\x3', '\x6', '\x3', '\a', '\x3', + '\a', '\x3', '\b', '\x3', '\b', '\x3', '\t', '\x3', '\t', '\x3', '\n', + '\x3', '\n', '\x3', '\v', '\x3', '\v', '\x3', '\v', '\x3', '\f', '\x3', + '\f', '\x3', '\r', '\x3', '\r', '\x3', '\xE', '\x3', '\xE', '\x3', '\xF', + '\x3', '\xF', '\x3', '\x10', '\x3', '\x10', '\x3', '\x11', '\x3', '\x11', + '\x3', '\x12', '\x3', '\x12', '\x3', '\x12', '\x3', '\x13', '\x3', '\x13', + '\x3', '\x13', '\x3', '\x14', '\x3', '\x14', '\x3', '\x15', '\x3', '\x15', + '\x3', '\x15', '\x3', '\x16', '\x3', '\x16', '\x3', '\x17', '\x3', '\x17', + '\x3', '\x18', '\x3', '\x18', '\x3', '\x19', '\x3', '\x19', '\x3', '\x19', + '\x3', '\x1A', '\x3', '\x1A', '\x3', '\x1B', '\x3', '\x1B', '\x3', '\x1C', + '\x3', '\x1C', '\x3', '\x1D', '\x3', '\x1D', '\x3', '\x1D', '\x3', '\x1D', + '\x3', '\x1E', '\x3', '\x1E', '\x3', '\x1E', '\x3', '\x1E', '\x3', '\x1F', + '\x3', '\x1F', '\x3', '\x1F', '\x3', '\x1F', '\x3', '\x1F', '\x3', '\x1F', + '\x3', ' ', '\x3', ' ', '\x3', ' ', '\x3', '!', '\x3', '!', '\x3', '!', + '\x3', '!', '\x3', '\"', '\x3', '\"', '\x3', '\"', '\x3', '\"', '\x3', + '\"', '\x3', '\"', '\x3', '\"', '\x3', '\"', '\x3', '#', '\x3', '#', '\x3', + '#', '\x3', '$', '\x3', '$', '\x3', '$', '\x3', '$', '\x3', '$', '\x3', + '%', '\x3', '%', '\x3', '%', '\x3', '%', '\x3', '%', '\x3', '%', '\x3', + '%', '\x3', '%', '\x3', '%', '\x3', '&', '\x3', '&', '\x3', '&', '\x3', + '&', '\x3', '&', '\x3', '&', '\x3', '&', '\x3', '\'', '\x3', '\'', '\x3', + '\'', '\x3', '\'', '\x3', '\'', '\x3', '\'', '\x3', '\'', '\x3', '(', + '\x3', '(', '\x3', '(', '\x3', '(', '\x3', '(', '\x3', '(', '\x3', ')', + '\x3', ')', '\x3', ')', '\x3', ')', '\x3', ')', '\x3', ')', '\x3', '*', + '\x3', '*', '\x3', '*', '\x3', '*', '\x3', '*', '\x3', '+', '\x3', '+', + '\x3', '+', '\x3', '+', '\x3', '+', '\x3', '+', '\x3', ',', '\x3', ',', + '\x3', ',', '\x3', '-', '\x3', '-', '\x3', '-', '\x3', '-', '\x3', '-', + '\x3', '.', '\x3', '.', '\x3', '.', '\x3', '.', '\x3', '.', '\x3', '/', + '\x3', '/', '\x3', '/', '\x3', '/', '\x3', '/', '\x3', '\x30', '\x3', + '\x30', '\x3', '\x30', '\x3', '\x30', '\x3', '\x30', '\x3', '\x31', '\x3', + '\x31', '\x3', '\x31', '\x3', '\x31', '\x3', '\x31', '\x3', '\x31', '\x3', + '\x32', '\x3', '\x32', '\x3', '\x32', '\x3', '\x32', '\x3', '\x33', '\x3', + '\x33', '\x3', '\x33', '\x3', '\x33', '\x3', '\x33', '\x3', '\x34', '\x3', + '\x34', '\x3', '\x34', '\x3', '\x34', '\x3', '\x34', '\x3', '\x34', '\x3', + '\x34', '\x3', '\x35', '\x3', '\x35', '\x3', '\x35', '\x3', '\x36', '\x3', + '\x36', '\x3', '\x36', '\x3', '\x36', '\x3', '\x36', '\x3', '\x36', '\x3', + '\x37', '\x3', '\x37', '\x3', '\x37', '\x3', '\x37', '\x3', '\x37', '\x3', + '\x37', '\x3', '\x38', '\x3', '\x38', '\x3', '\x38', '\x3', '\x38', '\x3', + '\x38', '\x3', '\x38', '\x3', '\x38', '\x3', '\x39', '\x3', '\x39', '\x3', + '\x39', '\x3', '\x39', '\x3', ':', '\x3', ':', '\x3', ':', '\x3', ':', + '\x3', ':', '\x3', ';', '\x3', ';', '\x3', ';', '\x3', ';', '\x3', '<', + '\x3', '<', '\x3', '<', '\x3', '<', '\x3', '<', '\x3', '<', '\x3', '<', + '\x3', '<', '\x3', '<', '\x3', '<', '\x3', '=', '\x3', '=', '\x3', '=', + '\x3', '=', '\x3', '=', '\x3', '=', '\x3', '>', '\x3', '>', '\x3', '>', + '\x3', '>', '\x3', '>', '\x3', '>', '\x3', '?', '\x6', '?', '\x1BD', '\n', + '?', '\r', '?', '\xE', '?', '\x1BE', '\x3', '?', '\x3', '?', '\x3', '@', + '\x5', '@', '\x1C4', '\n', '@', '\x3', '@', '\x6', '@', '\x1C7', '\n', + '@', '\r', '@', '\xE', '@', '\x1C8', '\x3', '@', '\x3', '@', '\a', '@', + '\x1CD', '\n', '@', '\f', '@', '\xE', '@', '\x1D0', '\v', '@', '\x5', + '@', '\x1D2', '\n', '@', '\x3', '@', '\x3', '@', '\x5', '@', '\x1D6', + '\n', '@', '\x3', '@', '\x6', '@', '\x1D9', '\n', '@', '\r', '@', '\xE', + '@', '\x1DA', '\x5', '@', '\x1DD', '\n', '@', '\x3', '@', '\x5', '@', + '\x1E0', '\n', '@', '\x3', '@', '\x3', '@', '\x6', '@', '\x1E4', '\n', + '@', '\r', '@', '\xE', '@', '\x1E5', '\x3', '@', '\x3', '@', '\x5', '@', + '\x1EA', '\n', '@', '\x3', '@', '\x6', '@', '\x1ED', '\n', '@', '\r', + '@', '\xE', '@', '\x1EE', '\x5', '@', '\x1F1', '\n', '@', '\x5', '@', + '\x1F3', '\n', '@', '\x3', '\x41', '\x3', '\x41', '\x3', '\x41', '\a', + '\x41', '\x1F8', '\n', '\x41', '\f', '\x41', '\xE', '\x41', '\x1FB', '\v', + '\x41', '\x3', '\x41', '\x3', '\x41', '\x3', '\x41', '\x3', '\x41', '\a', + '\x41', '\x201', '\n', '\x41', '\f', '\x41', '\xE', '\x41', '\x204', '\v', + '\x41', '\x3', '\x41', '\x5', '\x41', '\x207', '\n', '\x41', '\x3', '\x42', + '\x3', '\x42', '\x3', '\x42', '\x5', '\x42', '\x20C', '\n', '\x42', '\x3', + '\x43', '\x3', '\x43', '\x3', '\x43', '\x3', '\x43', '\x3', '\x43', '\x3', + '\x43', '\x3', '\x44', '\x3', '\x44', '\x3', '\x45', '\x3', '\x45', '\x3', + '\x46', '\x3', '\x46', '\x3', 'G', '\x3', 'G', '\x3', 'G', '\x3', 'G', + '\a', 'G', '\x21E', '\n', 'G', '\f', 'G', '\xE', 'G', '\x221', '\v', 'G', + '\x5', 'G', '\x223', '\n', 'G', '\x3', 'H', '\x3', 'H', '\x3', 'H', '\x3', + 'I', '\x3', 'I', '\x3', 'J', '\x3', 'J', '\x3', 'K', '\x3', 'K', '\x3', + 'L', '\x3', 'L', '\x3', 'M', '\x3', 'M', '\x3', 'N', '\x3', 'N', '\x3', + 'O', '\x3', 'O', '\x3', 'P', '\x3', 'P', '\x3', 'Q', '\x3', 'Q', '\x3', + 'R', '\x3', 'R', '\x3', 'S', '\x3', 'S', '\x3', 'T', '\x3', 'T', '\x3', + 'U', '\x3', 'U', '\x3', 'V', '\x3', 'V', '\x3', 'W', '\x3', 'W', '\x3', + 'X', '\x3', 'X', '\x3', 'Y', '\x3', 'Y', '\x3', 'Z', '\x3', 'Z', '\x3', + '[', '\x3', '[', '\x3', '\\', '\x3', '\\', '\x3', ']', '\x3', ']', '\x3', + '^', '\x3', '^', '\x3', '_', '\x3', '_', '\x3', '`', '\x3', '`', '\x3', + '\x61', '\x3', '\x61', '\x3', '\x62', '\x3', '\x62', '\x3', '\x63', '\x3', + '\x63', '\x2', '\x2', '\x64', '\x3', '\x3', '\x5', '\x4', '\a', '\x5', + '\t', '\x6', '\v', '\a', '\r', '\b', '\xF', '\t', '\x11', '\n', '\x13', + '\v', '\x15', '\f', '\x17', '\r', '\x19', '\xE', '\x1B', '\xF', '\x1D', + '\x10', '\x1F', '\x11', '!', '\x12', '#', '\x13', '%', '\x14', '\'', '\x15', + ')', '\x16', '+', '\x17', '-', '\x18', '/', '\x19', '\x31', '\x1A', '\x33', + '\x1B', '\x35', '\x1C', '\x37', '\x1D', '\x39', '\x1E', ';', '\x1F', '=', + ' ', '?', '!', '\x41', '\"', '\x43', '#', '\x45', '$', 'G', '%', 'I', + '&', 'K', '\'', 'M', '(', 'O', ')', 'Q', '*', 'S', '+', 'U', ',', 'W', + '-', 'Y', '.', '[', '/', ']', '\x30', '_', '\x31', '\x61', '\x32', '\x63', + '\x33', '\x65', '\x34', 'g', '\x35', 'i', '\x36', 'k', '\x37', 'm', '\x38', + 'o', '\x39', 'q', ':', 's', ';', 'u', '<', 'w', '=', 'y', '>', '{', '?', + '}', '@', '\x7F', '\x41', '\x81', '\x42', '\x83', '\x2', '\x85', '\x2', + '\x87', '\x2', '\x89', '\x2', '\x8B', '\x2', '\x8D', '\x43', '\x8F', '\x44', + '\x91', '\x2', '\x93', '\x2', '\x95', '\x2', '\x97', '\x2', '\x99', '\x2', + '\x9B', '\x2', '\x9D', '\x2', '\x9F', '\x2', '\xA1', '\x2', '\xA3', '\x2', + '\xA5', '\x2', '\xA7', '\x2', '\xA9', '\x2', '\xAB', '\x2', '\xAD', '\x2', + '\xAF', '\x2', '\xB1', '\x2', '\xB3', '\x2', '\xB5', '\x2', '\xB7', '\x2', + '\xB9', '\x2', '\xBB', '\x2', '\xBD', '\x2', '\xBF', '\x2', '\xC1', '\x2', + '\xC3', '\x2', '\xC5', '\x2', '\x3', '\x2', '$', '\x5', '\x2', '\v', '\f', + '\xF', '\xF', '\"', '\"', '\x4', '\x2', '-', '-', '/', '/', '\n', '\x2', + '$', '$', '\x31', '\x31', '^', '^', '\x64', '\x64', 'h', 'h', 'p', 'p', + 't', 't', 'v', 'v', '\x5', '\x2', '\x32', ';', '\x43', 'H', '\x63', 'h', + '\x5', '\x2', '\x2', '!', ')', ')', '^', '^', '\x5', '\x2', '\x2', '!', + '$', '$', '^', '^', '\x5', '\x2', '\x43', '\\', '\x61', '\x61', '\x63', + '|', '\x3', '\x2', '\x32', ';', '\x4', '\x2', '\x43', '\x43', '\x63', + '\x63', '\x4', '\x2', '\x44', '\x44', '\x64', '\x64', '\x4', '\x2', '\x45', + '\x45', '\x65', '\x65', '\x4', '\x2', '\x46', '\x46', '\x66', '\x66', + '\x4', '\x2', 'G', 'G', 'g', 'g', '\x4', '\x2', 'H', 'H', 'h', 'h', '\x4', + '\x2', 'I', 'I', 'i', 'i', '\x4', '\x2', 'J', 'J', 'j', 'j', '\x4', '\x2', + 'K', 'K', 'k', 'k', '\x4', '\x2', 'L', 'L', 'l', 'l', '\x4', '\x2', 'M', + 'M', 'm', 'm', '\x4', '\x2', 'N', 'N', 'n', 'n', '\x4', '\x2', 'O', 'O', + 'o', 'o', '\x4', '\x2', 'P', 'P', 'p', 'p', '\x4', '\x2', 'Q', 'Q', 'q', + 'q', '\x4', '\x2', 'R', 'R', 'r', 'r', '\x4', '\x2', 'S', 'S', 's', 's', + '\x4', '\x2', 'T', 'T', 't', 't', '\x4', '\x2', 'U', 'U', 'u', 'u', '\x4', + '\x2', 'V', 'V', 'v', 'v', '\x4', '\x2', 'W', 'W', 'w', 'w', '\x4', '\x2', + 'X', 'X', 'x', 'x', '\x4', '\x2', 'Y', 'Y', 'y', 'y', '\x4', '\x2', 'Z', + 'Z', 'z', 'z', '\x4', '\x2', '[', '[', '{', '{', '\x4', '\x2', '\\', '\\', + '|', '|', '\x2', '\x253', '\x2', '\x3', '\x3', '\x2', '\x2', '\x2', '\x2', + '\x5', '\x3', '\x2', '\x2', '\x2', '\x2', '\a', '\x3', '\x2', '\x2', '\x2', + '\x2', '\t', '\x3', '\x2', '\x2', '\x2', '\x2', '\v', '\x3', '\x2', '\x2', + '\x2', '\x2', '\r', '\x3', '\x2', '\x2', '\x2', '\x2', '\xF', '\x3', '\x2', + '\x2', '\x2', '\x2', '\x11', '\x3', '\x2', '\x2', '\x2', '\x2', '\x13', + '\x3', '\x2', '\x2', '\x2', '\x2', '\x15', '\x3', '\x2', '\x2', '\x2', + '\x2', '\x17', '\x3', '\x2', '\x2', '\x2', '\x2', '\x19', '\x3', '\x2', + '\x2', '\x2', '\x2', '\x1B', '\x3', '\x2', '\x2', '\x2', '\x2', '\x1D', + '\x3', '\x2', '\x2', '\x2', '\x2', '\x1F', '\x3', '\x2', '\x2', '\x2', + '\x2', '!', '\x3', '\x2', '\x2', '\x2', '\x2', '#', '\x3', '\x2', '\x2', + '\x2', '\x2', '%', '\x3', '\x2', '\x2', '\x2', '\x2', '\'', '\x3', '\x2', + '\x2', '\x2', '\x2', ')', '\x3', '\x2', '\x2', '\x2', '\x2', '+', '\x3', + '\x2', '\x2', '\x2', '\x2', '-', '\x3', '\x2', '\x2', '\x2', '\x2', '/', + '\x3', '\x2', '\x2', '\x2', '\x2', '\x31', '\x3', '\x2', '\x2', '\x2', + '\x2', '\x33', '\x3', '\x2', '\x2', '\x2', '\x2', '\x35', '\x3', '\x2', + '\x2', '\x2', '\x2', '\x37', '\x3', '\x2', '\x2', '\x2', '\x2', '\x39', + '\x3', '\x2', '\x2', '\x2', '\x2', ';', '\x3', '\x2', '\x2', '\x2', '\x2', + '=', '\x3', '\x2', '\x2', '\x2', '\x2', '?', '\x3', '\x2', '\x2', '\x2', + '\x2', '\x41', '\x3', '\x2', '\x2', '\x2', '\x2', '\x43', '\x3', '\x2', + '\x2', '\x2', '\x2', '\x45', '\x3', '\x2', '\x2', '\x2', '\x2', 'G', '\x3', + '\x2', '\x2', '\x2', '\x2', 'I', '\x3', '\x2', '\x2', '\x2', '\x2', 'K', + '\x3', '\x2', '\x2', '\x2', '\x2', 'M', '\x3', '\x2', '\x2', '\x2', '\x2', + 'O', '\x3', '\x2', '\x2', '\x2', '\x2', 'Q', '\x3', '\x2', '\x2', '\x2', + '\x2', 'S', '\x3', '\x2', '\x2', '\x2', '\x2', 'U', '\x3', '\x2', '\x2', + '\x2', '\x2', 'W', '\x3', '\x2', '\x2', '\x2', '\x2', 'Y', '\x3', '\x2', + '\x2', '\x2', '\x2', '[', '\x3', '\x2', '\x2', '\x2', '\x2', ']', '\x3', + '\x2', '\x2', '\x2', '\x2', '_', '\x3', '\x2', '\x2', '\x2', '\x2', '\x61', + '\x3', '\x2', '\x2', '\x2', '\x2', '\x63', '\x3', '\x2', '\x2', '\x2', + '\x2', '\x65', '\x3', '\x2', '\x2', '\x2', '\x2', 'g', '\x3', '\x2', '\x2', + '\x2', '\x2', 'i', '\x3', '\x2', '\x2', '\x2', '\x2', 'k', '\x3', '\x2', + '\x2', '\x2', '\x2', 'm', '\x3', '\x2', '\x2', '\x2', '\x2', 'o', '\x3', + '\x2', '\x2', '\x2', '\x2', 'q', '\x3', '\x2', '\x2', '\x2', '\x2', 's', + '\x3', '\x2', '\x2', '\x2', '\x2', 'u', '\x3', '\x2', '\x2', '\x2', '\x2', + 'w', '\x3', '\x2', '\x2', '\x2', '\x2', 'y', '\x3', '\x2', '\x2', '\x2', + '\x2', '{', '\x3', '\x2', '\x2', '\x2', '\x2', '}', '\x3', '\x2', '\x2', + '\x2', '\x2', '\x7F', '\x3', '\x2', '\x2', '\x2', '\x2', '\x81', '\x3', + '\x2', '\x2', '\x2', '\x2', '\x8D', '\x3', '\x2', '\x2', '\x2', '\x2', + '\x8F', '\x3', '\x2', '\x2', '\x2', '\x3', '\xC7', '\x3', '\x2', '\x2', + '\x2', '\x5', '\xC9', '\x3', '\x2', '\x2', '\x2', '\a', '\xCB', '\x3', + '\x2', '\x2', '\x2', '\t', '\xCD', '\x3', '\x2', '\x2', '\x2', '\v', '\xCF', + '\x3', '\x2', '\x2', '\x2', '\r', '\xD1', '\x3', '\x2', '\x2', '\x2', + '\xF', '\xD3', '\x3', '\x2', '\x2', '\x2', '\x11', '\xD5', '\x3', '\x2', + '\x2', '\x2', '\x13', '\xD7', '\x3', '\x2', '\x2', '\x2', '\x15', '\xD9', + '\x3', '\x2', '\x2', '\x2', '\x17', '\xDC', '\x3', '\x2', '\x2', '\x2', + '\x19', '\xDE', '\x3', '\x2', '\x2', '\x2', '\x1B', '\xE0', '\x3', '\x2', + '\x2', '\x2', '\x1D', '\xE2', '\x3', '\x2', '\x2', '\x2', '\x1F', '\xE4', + '\x3', '\x2', '\x2', '\x2', '!', '\xE6', '\x3', '\x2', '\x2', '\x2', '#', + '\xE8', '\x3', '\x2', '\x2', '\x2', '%', '\xEB', '\x3', '\x2', '\x2', + '\x2', '\'', '\xEE', '\x3', '\x2', '\x2', '\x2', ')', '\xF0', '\x3', '\x2', + '\x2', '\x2', '+', '\xF3', '\x3', '\x2', '\x2', '\x2', '-', '\xF5', '\x3', + '\x2', '\x2', '\x2', '/', '\xF7', '\x3', '\x2', '\x2', '\x2', '\x31', + '\xF9', '\x3', '\x2', '\x2', '\x2', '\x33', '\xFC', '\x3', '\x2', '\x2', + '\x2', '\x35', '\xFE', '\x3', '\x2', '\x2', '\x2', '\x37', '\x100', '\x3', + '\x2', '\x2', '\x2', '\x39', '\x102', '\x3', '\x2', '\x2', '\x2', ';', + '\x106', '\x3', '\x2', '\x2', '\x2', '=', '\x10A', '\x3', '\x2', '\x2', + '\x2', '?', '\x110', '\x3', '\x2', '\x2', '\x2', '\x41', '\x113', '\x3', + '\x2', '\x2', '\x2', '\x43', '\x117', '\x3', '\x2', '\x2', '\x2', '\x45', + '\x11F', '\x3', '\x2', '\x2', '\x2', 'G', '\x122', '\x3', '\x2', '\x2', + '\x2', 'I', '\x127', '\x3', '\x2', '\x2', '\x2', 'K', '\x130', '\x3', + '\x2', '\x2', '\x2', 'M', '\x137', '\x3', '\x2', '\x2', '\x2', 'O', '\x13E', + '\x3', '\x2', '\x2', '\x2', 'Q', '\x144', '\x3', '\x2', '\x2', '\x2', + 'S', '\x14A', '\x3', '\x2', '\x2', '\x2', 'U', '\x14F', '\x3', '\x2', + '\x2', '\x2', 'W', '\x155', '\x3', '\x2', '\x2', '\x2', 'Y', '\x158', + '\x3', '\x2', '\x2', '\x2', '[', '\x15D', '\x3', '\x2', '\x2', '\x2', + ']', '\x162', '\x3', '\x2', '\x2', '\x2', '_', '\x167', '\x3', '\x2', + '\x2', '\x2', '\x61', '\x16C', '\x3', '\x2', '\x2', '\x2', '\x63', '\x172', + '\x3', '\x2', '\x2', '\x2', '\x65', '\x176', '\x3', '\x2', '\x2', '\x2', + 'g', '\x17B', '\x3', '\x2', '\x2', '\x2', 'i', '\x182', '\x3', '\x2', + '\x2', '\x2', 'k', '\x185', '\x3', '\x2', '\x2', '\x2', 'm', '\x18B', + '\x3', '\x2', '\x2', '\x2', 'o', '\x191', '\x3', '\x2', '\x2', '\x2', + 'q', '\x198', '\x3', '\x2', '\x2', '\x2', 's', '\x19C', '\x3', '\x2', + '\x2', '\x2', 'u', '\x1A1', '\x3', '\x2', '\x2', '\x2', 'w', '\x1A5', + '\x3', '\x2', '\x2', '\x2', 'y', '\x1AF', '\x3', '\x2', '\x2', '\x2', + '{', '\x1B5', '\x3', '\x2', '\x2', '\x2', '}', '\x1BC', '\x3', '\x2', + '\x2', '\x2', '\x7F', '\x1F2', '\x3', '\x2', '\x2', '\x2', '\x81', '\x206', + '\x3', '\x2', '\x2', '\x2', '\x83', '\x208', '\x3', '\x2', '\x2', '\x2', + '\x85', '\x20D', '\x3', '\x2', '\x2', '\x2', '\x87', '\x213', '\x3', '\x2', + '\x2', '\x2', '\x89', '\x215', '\x3', '\x2', '\x2', '\x2', '\x8B', '\x217', + '\x3', '\x2', '\x2', '\x2', '\x8D', '\x222', '\x3', '\x2', '\x2', '\x2', + '\x8F', '\x224', '\x3', '\x2', '\x2', '\x2', '\x91', '\x227', '\x3', '\x2', + '\x2', '\x2', '\x93', '\x229', '\x3', '\x2', '\x2', '\x2', '\x95', '\x22B', + '\x3', '\x2', '\x2', '\x2', '\x97', '\x22D', '\x3', '\x2', '\x2', '\x2', + '\x99', '\x22F', '\x3', '\x2', '\x2', '\x2', '\x9B', '\x231', '\x3', '\x2', + '\x2', '\x2', '\x9D', '\x233', '\x3', '\x2', '\x2', '\x2', '\x9F', '\x235', + '\x3', '\x2', '\x2', '\x2', '\xA1', '\x237', '\x3', '\x2', '\x2', '\x2', + '\xA3', '\x239', '\x3', '\x2', '\x2', '\x2', '\xA5', '\x23B', '\x3', '\x2', + '\x2', '\x2', '\xA7', '\x23D', '\x3', '\x2', '\x2', '\x2', '\xA9', '\x23F', + '\x3', '\x2', '\x2', '\x2', '\xAB', '\x241', '\x3', '\x2', '\x2', '\x2', + '\xAD', '\x243', '\x3', '\x2', '\x2', '\x2', '\xAF', '\x245', '\x3', '\x2', + '\x2', '\x2', '\xB1', '\x247', '\x3', '\x2', '\x2', '\x2', '\xB3', '\x249', + '\x3', '\x2', '\x2', '\x2', '\xB5', '\x24B', '\x3', '\x2', '\x2', '\x2', + '\xB7', '\x24D', '\x3', '\x2', '\x2', '\x2', '\xB9', '\x24F', '\x3', '\x2', + '\x2', '\x2', '\xBB', '\x251', '\x3', '\x2', '\x2', '\x2', '\xBD', '\x253', + '\x3', '\x2', '\x2', '\x2', '\xBF', '\x255', '\x3', '\x2', '\x2', '\x2', + '\xC1', '\x257', '\x3', '\x2', '\x2', '\x2', '\xC3', '\x259', '\x3', '\x2', + '\x2', '\x2', '\xC5', '\x25B', '\x3', '\x2', '\x2', '\x2', '\xC7', '\xC8', + '\a', ',', '\x2', '\x2', '\xC8', '\x4', '\x3', '\x2', '\x2', '\x2', '\xC9', + '\xCA', '\a', '.', '\x2', '\x2', '\xCA', '\x6', '\x3', '\x2', '\x2', '\x2', + '\xCB', '\xCC', '\a', '*', '\x2', '\x2', '\xCC', '\b', '\x3', '\x2', '\x2', + '\x2', '\xCD', '\xCE', '\a', '+', '\x2', '\x2', '\xCE', '\n', '\x3', '\x2', + '\x2', '\x2', '\xCF', '\xD0', '\a', '\x30', '\x2', '\x2', '\xD0', '\f', + '\x3', '\x2', '\x2', '\x2', '\xD1', '\xD2', '\a', ']', '\x2', '\x2', '\xD2', + '\xE', '\x3', '\x2', '\x2', '\x2', '\xD3', '\xD4', '\a', '_', '\x2', '\x2', + '\xD4', '\x10', '\x3', '\x2', '\x2', '\x2', '\xD5', '\xD6', '\a', '\x41', + '\x2', '\x2', '\xD6', '\x12', '\x3', '\x2', '\x2', '\x2', '\xD7', '\xD8', + '\a', '<', '\x2', '\x2', '\xD8', '\x14', '\x3', '\x2', '\x2', '\x2', '\xD9', + '\xDA', '\a', '\x41', '\x2', '\x2', '\xDA', '\xDB', '\a', '\x41', '\x2', + '\x2', '\xDB', '\x16', '\x3', '\x2', '\x2', '\x2', '\xDC', '\xDD', '\a', + '\x31', '\x2', '\x2', '\xDD', '\x18', '\x3', '\x2', '\x2', '\x2', '\xDE', + '\xDF', '\a', '\'', '\x2', '\x2', '\xDF', '\x1A', '\x3', '\x2', '\x2', + '\x2', '\xE0', '\xE1', '\a', '-', '\x2', '\x2', '\xE1', '\x1C', '\x3', + '\x2', '\x2', '\x2', '\xE2', '\xE3', '\a', '/', '\x2', '\x2', '\xE3', + '\x1E', '\x3', '\x2', '\x2', '\x2', '\xE4', '\xE5', '\a', '>', '\x2', + '\x2', '\xE5', ' ', '\x3', '\x2', '\x2', '\x2', '\xE6', '\xE7', '\a', + '@', '\x2', '\x2', '\xE7', '\"', '\x3', '\x2', '\x2', '\x2', '\xE8', '\xE9', + '\a', '@', '\x2', '\x2', '\xE9', '\xEA', '\a', '?', '\x2', '\x2', '\xEA', + '$', '\x3', '\x2', '\x2', '\x2', '\xEB', '\xEC', '\a', '>', '\x2', '\x2', + '\xEC', '\xED', '\a', '?', '\x2', '\x2', '\xED', '&', '\x3', '\x2', '\x2', + '\x2', '\xEE', '\xEF', '\a', '?', '\x2', '\x2', '\xEF', '(', '\x3', '\x2', + '\x2', '\x2', '\xF0', '\xF1', '\a', '#', '\x2', '\x2', '\xF1', '\xF2', + '\a', '?', '\x2', '\x2', '\xF2', '*', '\x3', '\x2', '\x2', '\x2', '\xF3', + '\xF4', '\a', '(', '\x2', '\x2', '\xF4', ',', '\x3', '\x2', '\x2', '\x2', + '\xF5', '\xF6', '\a', '`', '\x2', '\x2', '\xF6', '.', '\x3', '\x2', '\x2', + '\x2', '\xF7', '\xF8', '\a', '~', '\x2', '\x2', '\xF8', '\x30', '\x3', + '\x2', '\x2', '\x2', '\xF9', '\xFA', '\a', '~', '\x2', '\x2', '\xFA', + '\xFB', '\a', '~', '\x2', '\x2', '\xFB', '\x32', '\x3', '\x2', '\x2', + '\x2', '\xFC', '\xFD', '\a', '\x80', '\x2', '\x2', '\xFD', '\x34', '\x3', + '\x2', '\x2', '\x2', '\xFE', '\xFF', '\a', '}', '\x2', '\x2', '\xFF', + '\x36', '\x3', '\x2', '\x2', '\x2', '\x100', '\x101', '\a', '\x7F', '\x2', + '\x2', '\x101', '\x38', '\x3', '\x2', '\x2', '\x2', '\x102', '\x103', + '\x5', '\x93', 'J', '\x2', '\x103', '\x104', '\x5', '\xA9', 'U', '\x2', + '\x104', '\x105', '\x5', '\xA9', 'U', '\x2', '\x105', ':', '\x3', '\x2', + '\x2', '\x2', '\x106', '\x107', '\x5', '\x93', 'J', '\x2', '\x107', '\x108', + '\x5', '\xAD', 'W', '\x2', '\x108', '\x109', '\x5', '\x99', 'M', '\x2', + '\x109', '<', '\x3', '\x2', '\x2', '\x2', '\x10A', '\x10B', '\x5', '\x93', + 'J', '\x2', '\x10B', '\x10C', '\x5', '\xB5', '[', '\x2', '\x10C', '\x10D', + '\x5', '\xB5', '[', '\x2', '\x10D', '\x10E', '\x5', '\x93', 'J', '\x2', + '\x10E', '\x10F', '\x5', '\xC3', '\x62', '\x2', '\x10F', '>', '\x3', '\x2', + '\x2', '\x2', '\x110', '\x111', '\x5', '\x93', 'J', '\x2', '\x111', '\x112', + '\x5', '\xB7', '\\', '\x2', '\x112', '@', '\x3', '\x2', '\x2', '\x2', + '\x113', '\x114', '\x5', '\x93', 'J', '\x2', '\x114', '\x115', '\x5', + '\xB7', '\\', '\x2', '\x115', '\x116', '\x5', '\x97', 'L', '\x2', '\x116', + '\x42', '\x3', '\x2', '\x2', '\x2', '\x117', '\x118', '\x5', '\x95', 'K', + '\x2', '\x118', '\x119', '\x5', '\x9B', 'N', '\x2', '\x119', '\x11A', + '\x5', '\xB9', ']', '\x2', '\x11A', '\x11B', '\x5', '\xBF', '`', '\x2', + '\x11B', '\x11C', '\x5', '\x9B', 'N', '\x2', '\x11C', '\x11D', '\x5', + '\x9B', 'N', '\x2', '\x11D', '\x11E', '\x5', '\xAD', 'W', '\x2', '\x11E', + '\x44', '\x3', '\x2', '\x2', '\x2', '\x11F', '\x120', '\x5', '\x95', 'K', + '\x2', '\x120', '\x121', '\x5', '\xC3', '\x62', '\x2', '\x121', '\x46', + '\x3', '\x2', '\x2', '\x2', '\x122', '\x123', '\x5', '\x99', 'M', '\x2', + '\x123', '\x124', '\x5', '\x9B', 'N', '\x2', '\x124', '\x125', '\x5', + '\xB7', '\\', '\x2', '\x125', '\x126', '\x5', '\x97', 'L', '\x2', '\x126', + 'H', '\x3', '\x2', '\x2', '\x2', '\x127', '\x128', '\x5', '\x99', 'M', + '\x2', '\x128', '\x129', '\x5', '\xA3', 'R', '\x2', '\x129', '\x12A', + '\x5', '\xB7', '\\', '\x2', '\x12A', '\x12B', '\x5', '\xB9', ']', '\x2', + '\x12B', '\x12C', '\x5', '\xA3', 'R', '\x2', '\x12C', '\x12D', '\x5', + '\xAD', 'W', '\x2', '\x12D', '\x12E', '\x5', '\x97', 'L', '\x2', '\x12E', + '\x12F', '\x5', '\xB9', ']', '\x2', '\x12F', 'J', '\x3', '\x2', '\x2', + '\x2', '\x130', '\x131', '\x5', '\x9B', 'N', '\x2', '\x131', '\x132', + '\x5', '\xB7', '\\', '\x2', '\x132', '\x133', '\x5', '\x97', 'L', '\x2', + '\x133', '\x134', '\x5', '\x93', 'J', '\x2', '\x134', '\x135', '\x5', + '\xB1', 'Y', '\x2', '\x135', '\x136', '\x5', '\x9B', 'N', '\x2', '\x136', + 'L', '\x3', '\x2', '\x2', '\x2', '\x137', '\x138', '\x5', '\x9B', 'N', + '\x2', '\x138', '\x139', '\x5', '\xC1', '\x61', '\x2', '\x139', '\x13A', + '\x5', '\xA3', 'R', '\x2', '\x13A', '\x13B', '\x5', '\xB7', '\\', '\x2', + '\x13B', '\x13C', '\x5', '\xB9', ']', '\x2', '\x13C', '\x13D', '\x5', + '\xB7', '\\', '\x2', '\x13D', 'N', '\x3', '\x2', '\x2', '\x2', '\x13E', + '\x13F', '\x5', '\x9D', 'O', '\x2', '\x13F', '\x140', '\x5', '\xA3', 'R', + '\x2', '\x140', '\x141', '\x5', '\xB5', '[', '\x2', '\x141', '\x142', + '\x5', '\xB7', '\\', '\x2', '\x142', '\x143', '\x5', '\xB9', ']', '\x2', + '\x143', 'P', '\x3', '\x2', '\x2', '\x2', '\x144', '\x145', '\a', 'h', + '\x2', '\x2', '\x145', '\x146', '\a', '\x63', '\x2', '\x2', '\x146', '\x147', + '\a', 'n', '\x2', '\x2', '\x147', '\x148', '\a', 'u', '\x2', '\x2', '\x148', + '\x149', '\a', 'g', '\x2', '\x2', '\x149', 'R', '\x3', '\x2', '\x2', '\x2', + '\x14A', '\x14B', '\x5', '\x9D', 'O', '\x2', '\x14B', '\x14C', '\x5', + '\xB5', '[', '\x2', '\x14C', '\x14D', '\x5', '\xAF', 'X', '\x2', '\x14D', + '\x14E', '\x5', '\xAB', 'V', '\x2', '\x14E', 'T', '\x3', '\x2', '\x2', + '\x2', '\x14F', '\x150', '\x5', '\x9F', 'P', '\x2', '\x150', '\x151', + '\x5', '\xB5', '[', '\x2', '\x151', '\x152', '\x5', '\xAF', 'X', '\x2', + '\x152', '\x153', '\x5', '\xBB', '^', '\x2', '\x153', '\x154', '\x5', + '\xB1', 'Y', '\x2', '\x154', 'V', '\x3', '\x2', '\x2', '\x2', '\x155', + '\x156', '\x5', '\xA3', 'R', '\x2', '\x156', '\x157', '\x5', '\xAD', 'W', + '\x2', '\x157', 'X', '\x3', '\x2', '\x2', '\x2', '\x158', '\x159', '\x5', + '\xA5', 'S', '\x2', '\x159', '\x15A', '\x5', '\xAF', 'X', '\x2', '\x15A', + '\x15B', '\x5', '\xA3', 'R', '\x2', '\x15B', '\x15C', '\x5', '\xAD', 'W', + '\x2', '\x15C', 'Z', '\x3', '\x2', '\x2', '\x2', '\x15D', '\x15E', '\x5', + '\xA9', 'U', '\x2', '\x15E', '\x15F', '\x5', '\x93', 'J', '\x2', '\x15F', + '\x160', '\x5', '\xB7', '\\', '\x2', '\x160', '\x161', '\x5', '\xB9', + ']', '\x2', '\x161', '\\', '\x3', '\x2', '\x2', '\x2', '\x162', '\x163', + '\x5', '\xA9', 'U', '\x2', '\x163', '\x164', '\x5', '\x9B', 'N', '\x2', + '\x164', '\x165', '\x5', '\x9D', 'O', '\x2', '\x165', '\x166', '\x5', + '\xB9', ']', '\x2', '\x166', '^', '\x3', '\x2', '\x2', '\x2', '\x167', + '\x168', '\x5', '\xA9', 'U', '\x2', '\x168', '\x169', '\x5', '\xA3', 'R', + '\x2', '\x169', '\x16A', '\x5', '\xA7', 'T', '\x2', '\x16A', '\x16B', + '\x5', '\x9B', 'N', '\x2', '\x16B', '`', '\x3', '\x2', '\x2', '\x2', '\x16C', + '\x16D', '\x5', '\xA9', 'U', '\x2', '\x16D', '\x16E', '\x5', '\xA3', 'R', + '\x2', '\x16E', '\x16F', '\x5', '\xAB', 'V', '\x2', '\x16F', '\x170', + '\x5', '\xA3', 'R', '\x2', '\x170', '\x171', '\x5', '\xB9', ']', '\x2', + '\x171', '\x62', '\x3', '\x2', '\x2', '\x2', '\x172', '\x173', '\x5', + '\xAD', 'W', '\x2', '\x173', '\x174', '\x5', '\xAF', 'X', '\x2', '\x174', + '\x175', '\x5', '\xB9', ']', '\x2', '\x175', '\x64', '\x3', '\x2', '\x2', + '\x2', '\x176', '\x177', '\a', 'p', '\x2', '\x2', '\x177', '\x178', '\a', + 'w', '\x2', '\x2', '\x178', '\x179', '\a', 'n', '\x2', '\x2', '\x179', + '\x17A', '\a', 'n', '\x2', '\x2', '\x17A', '\x66', '\x3', '\x2', '\x2', + '\x2', '\x17B', '\x17C', '\x5', '\xAF', 'X', '\x2', '\x17C', '\x17D', + '\x5', '\x9D', 'O', '\x2', '\x17D', '\x17E', '\x5', '\x9D', 'O', '\x2', + '\x17E', '\x17F', '\x5', '\xB7', '\\', '\x2', '\x17F', '\x180', '\x5', + '\x9B', 'N', '\x2', '\x180', '\x181', '\x5', '\xB9', ']', '\x2', '\x181', + 'h', '\x3', '\x2', '\x2', '\x2', '\x182', '\x183', '\x5', '\xAF', 'X', + '\x2', '\x183', '\x184', '\x5', '\xB5', '[', '\x2', '\x184', 'j', '\x3', + '\x2', '\x2', '\x2', '\x185', '\x186', '\x5', '\xAF', 'X', '\x2', '\x186', + '\x187', '\x5', '\xB5', '[', '\x2', '\x187', '\x188', '\x5', '\x99', 'M', + '\x2', '\x188', '\x189', '\x5', '\x9B', 'N', '\x2', '\x189', '\x18A', + '\x5', '\xB5', '[', '\x2', '\x18A', 'l', '\x3', '\x2', '\x2', '\x2', '\x18B', + '\x18C', '\x5', '\xB5', '[', '\x2', '\x18C', '\x18D', '\x5', '\xA3', 'R', + '\x2', '\x18D', '\x18E', '\x5', '\x9F', 'P', '\x2', '\x18E', '\x18F', + '\x5', '\xA1', 'Q', '\x2', '\x18F', '\x190', '\x5', '\xB9', ']', '\x2', + '\x190', 'n', '\x3', '\x2', '\x2', '\x2', '\x191', '\x192', '\x5', '\xB7', + '\\', '\x2', '\x192', '\x193', '\x5', '\x9B', 'N', '\x2', '\x193', '\x194', + '\x5', '\xA9', 'U', '\x2', '\x194', '\x195', '\x5', '\x9B', 'N', '\x2', + '\x195', '\x196', '\x5', '\x97', 'L', '\x2', '\x196', '\x197', '\x5', + '\xB9', ']', '\x2', '\x197', 'p', '\x3', '\x2', '\x2', '\x2', '\x198', + '\x199', '\x5', '\xB9', ']', '\x2', '\x199', '\x19A', '\x5', '\xAF', 'X', + '\x2', '\x19A', '\x19B', '\x5', '\xB1', 'Y', '\x2', '\x19B', 'r', '\x3', + '\x2', '\x2', '\x2', '\x19C', '\x19D', '\a', 'v', '\x2', '\x2', '\x19D', + '\x19E', '\a', 't', '\x2', '\x2', '\x19E', '\x19F', '\a', 'w', '\x2', + '\x2', '\x19F', '\x1A0', '\a', 'g', '\x2', '\x2', '\x1A0', 't', '\x3', + '\x2', '\x2', '\x2', '\x1A1', '\x1A2', '\a', 'w', '\x2', '\x2', '\x1A2', + '\x1A3', '\a', '\x66', '\x2', '\x2', '\x1A3', '\x1A4', '\a', 'h', '\x2', + '\x2', '\x1A4', 'v', '\x3', '\x2', '\x2', '\x2', '\x1A5', '\x1A6', '\a', + 'w', '\x2', '\x2', '\x1A6', '\x1A7', '\a', 'p', '\x2', '\x2', '\x1A7', + '\x1A8', '\a', '\x66', '\x2', '\x2', '\x1A8', '\x1A9', '\a', 'g', '\x2', + '\x2', '\x1A9', '\x1AA', '\a', 'h', '\x2', '\x2', '\x1AA', '\x1AB', '\a', + 'k', '\x2', '\x2', '\x1AB', '\x1AC', '\a', 'p', '\x2', '\x2', '\x1AC', + '\x1AD', '\a', 'g', '\x2', '\x2', '\x1AD', '\x1AE', '\a', '\x66', '\x2', + '\x2', '\x1AE', 'x', '\x3', '\x2', '\x2', '\x2', '\x1AF', '\x1B0', '\x5', + '\xBD', '_', '\x2', '\x1B0', '\x1B1', '\x5', '\x93', 'J', '\x2', '\x1B1', + '\x1B2', '\x5', '\xA9', 'U', '\x2', '\x1B2', '\x1B3', '\x5', '\xBB', '^', + '\x2', '\x1B3', '\x1B4', '\x5', '\x9B', 'N', '\x2', '\x1B4', 'z', '\x3', + '\x2', '\x2', '\x2', '\x1B5', '\x1B6', '\x5', '\xBF', '`', '\x2', '\x1B6', + '\x1B7', '\x5', '\xA1', 'Q', '\x2', '\x1B7', '\x1B8', '\x5', '\x9B', 'N', + '\x2', '\x1B8', '\x1B9', '\x5', '\xB5', '[', '\x2', '\x1B9', '\x1BA', + '\x5', '\x9B', 'N', '\x2', '\x1BA', '|', '\x3', '\x2', '\x2', '\x2', '\x1BB', + '\x1BD', '\t', '\x2', '\x2', '\x2', '\x1BC', '\x1BB', '\x3', '\x2', '\x2', + '\x2', '\x1BD', '\x1BE', '\x3', '\x2', '\x2', '\x2', '\x1BE', '\x1BC', + '\x3', '\x2', '\x2', '\x2', '\x1BE', '\x1BF', '\x3', '\x2', '\x2', '\x2', + '\x1BF', '\x1C0', '\x3', '\x2', '\x2', '\x2', '\x1C0', '\x1C1', '\b', + '?', '\x2', '\x2', '\x1C1', '~', '\x3', '\x2', '\x2', '\x2', '\x1C2', + '\x1C4', '\t', '\x3', '\x2', '\x2', '\x1C3', '\x1C2', '\x3', '\x2', '\x2', + '\x2', '\x1C3', '\x1C4', '\x3', '\x2', '\x2', '\x2', '\x1C4', '\x1C6', + '\x3', '\x2', '\x2', '\x2', '\x1C5', '\x1C7', '\x5', '\x91', 'I', '\x2', + '\x1C6', '\x1C5', '\x3', '\x2', '\x2', '\x2', '\x1C7', '\x1C8', '\x3', + '\x2', '\x2', '\x2', '\x1C8', '\x1C6', '\x3', '\x2', '\x2', '\x2', '\x1C8', + '\x1C9', '\x3', '\x2', '\x2', '\x2', '\x1C9', '\x1D1', '\x3', '\x2', '\x2', + '\x2', '\x1CA', '\x1CE', '\a', '\x30', '\x2', '\x2', '\x1CB', '\x1CD', + '\x5', '\x91', 'I', '\x2', '\x1CC', '\x1CB', '\x3', '\x2', '\x2', '\x2', + '\x1CD', '\x1D0', '\x3', '\x2', '\x2', '\x2', '\x1CE', '\x1CC', '\x3', + '\x2', '\x2', '\x2', '\x1CE', '\x1CF', '\x3', '\x2', '\x2', '\x2', '\x1CF', + '\x1D2', '\x3', '\x2', '\x2', '\x2', '\x1D0', '\x1CE', '\x3', '\x2', '\x2', + '\x2', '\x1D1', '\x1CA', '\x3', '\x2', '\x2', '\x2', '\x1D1', '\x1D2', + '\x3', '\x2', '\x2', '\x2', '\x1D2', '\x1DC', '\x3', '\x2', '\x2', '\x2', + '\x1D3', '\x1D5', '\x5', '\x9B', 'N', '\x2', '\x1D4', '\x1D6', '\t', '\x3', + '\x2', '\x2', '\x1D5', '\x1D4', '\x3', '\x2', '\x2', '\x2', '\x1D5', '\x1D6', + '\x3', '\x2', '\x2', '\x2', '\x1D6', '\x1D8', '\x3', '\x2', '\x2', '\x2', + '\x1D7', '\x1D9', '\x5', '\x91', 'I', '\x2', '\x1D8', '\x1D7', '\x3', + '\x2', '\x2', '\x2', '\x1D9', '\x1DA', '\x3', '\x2', '\x2', '\x2', '\x1DA', + '\x1D8', '\x3', '\x2', '\x2', '\x2', '\x1DA', '\x1DB', '\x3', '\x2', '\x2', + '\x2', '\x1DB', '\x1DD', '\x3', '\x2', '\x2', '\x2', '\x1DC', '\x1D3', + '\x3', '\x2', '\x2', '\x2', '\x1DC', '\x1DD', '\x3', '\x2', '\x2', '\x2', + '\x1DD', '\x1F3', '\x3', '\x2', '\x2', '\x2', '\x1DE', '\x1E0', '\t', + '\x3', '\x2', '\x2', '\x1DF', '\x1DE', '\x3', '\x2', '\x2', '\x2', '\x1DF', + '\x1E0', '\x3', '\x2', '\x2', '\x2', '\x1E0', '\x1E1', '\x3', '\x2', '\x2', + '\x2', '\x1E1', '\x1E3', '\a', '\x30', '\x2', '\x2', '\x1E2', '\x1E4', + '\x5', '\x91', 'I', '\x2', '\x1E3', '\x1E2', '\x3', '\x2', '\x2', '\x2', + '\x1E4', '\x1E5', '\x3', '\x2', '\x2', '\x2', '\x1E5', '\x1E3', '\x3', + '\x2', '\x2', '\x2', '\x1E5', '\x1E6', '\x3', '\x2', '\x2', '\x2', '\x1E6', + '\x1F0', '\x3', '\x2', '\x2', '\x2', '\x1E7', '\x1E9', '\x5', '\x9B', + 'N', '\x2', '\x1E8', '\x1EA', '\t', '\x3', '\x2', '\x2', '\x1E9', '\x1E8', + '\x3', '\x2', '\x2', '\x2', '\x1E9', '\x1EA', '\x3', '\x2', '\x2', '\x2', + '\x1EA', '\x1EC', '\x3', '\x2', '\x2', '\x2', '\x1EB', '\x1ED', '\x5', + '\x91', 'I', '\x2', '\x1EC', '\x1EB', '\x3', '\x2', '\x2', '\x2', '\x1ED', + '\x1EE', '\x3', '\x2', '\x2', '\x2', '\x1EE', '\x1EC', '\x3', '\x2', '\x2', + '\x2', '\x1EE', '\x1EF', '\x3', '\x2', '\x2', '\x2', '\x1EF', '\x1F1', + '\x3', '\x2', '\x2', '\x2', '\x1F0', '\x1E7', '\x3', '\x2', '\x2', '\x2', + '\x1F0', '\x1F1', '\x3', '\x2', '\x2', '\x2', '\x1F1', '\x1F3', '\x3', + '\x2', '\x2', '\x2', '\x1F2', '\x1C3', '\x3', '\x2', '\x2', '\x2', '\x1F2', + '\x1DF', '\x3', '\x2', '\x2', '\x2', '\x1F3', '\x80', '\x3', '\x2', '\x2', + '\x2', '\x1F4', '\x1F9', '\a', '$', '\x2', '\x2', '\x1F5', '\x1F8', '\x5', + '\x83', '\x42', '\x2', '\x1F6', '\x1F8', '\x5', '\x8B', '\x46', '\x2', + '\x1F7', '\x1F5', '\x3', '\x2', '\x2', '\x2', '\x1F7', '\x1F6', '\x3', + '\x2', '\x2', '\x2', '\x1F8', '\x1FB', '\x3', '\x2', '\x2', '\x2', '\x1F9', + '\x1F7', '\x3', '\x2', '\x2', '\x2', '\x1F9', '\x1FA', '\x3', '\x2', '\x2', + '\x2', '\x1FA', '\x1FC', '\x3', '\x2', '\x2', '\x2', '\x1FB', '\x1F9', + '\x3', '\x2', '\x2', '\x2', '\x1FC', '\x207', '\a', '$', '\x2', '\x2', + '\x1FD', '\x202', '\a', ')', '\x2', '\x2', '\x1FE', '\x201', '\x5', '\x83', + '\x42', '\x2', '\x1FF', '\x201', '\x5', '\x89', '\x45', '\x2', '\x200', + '\x1FE', '\x3', '\x2', '\x2', '\x2', '\x200', '\x1FF', '\x3', '\x2', '\x2', + '\x2', '\x201', '\x204', '\x3', '\x2', '\x2', '\x2', '\x202', '\x200', + '\x3', '\x2', '\x2', '\x2', '\x202', '\x203', '\x3', '\x2', '\x2', '\x2', + '\x203', '\x205', '\x3', '\x2', '\x2', '\x2', '\x204', '\x202', '\x3', + '\x2', '\x2', '\x2', '\x205', '\x207', '\a', ')', '\x2', '\x2', '\x206', + '\x1F4', '\x3', '\x2', '\x2', '\x2', '\x206', '\x1FD', '\x3', '\x2', '\x2', + '\x2', '\x207', '\x82', '\x3', '\x2', '\x2', '\x2', '\x208', '\x20B', + '\a', '^', '\x2', '\x2', '\x209', '\x20C', '\t', '\x4', '\x2', '\x2', + '\x20A', '\x20C', '\x5', '\x85', '\x43', '\x2', '\x20B', '\x209', '\x3', + '\x2', '\x2', '\x2', '\x20B', '\x20A', '\x3', '\x2', '\x2', '\x2', '\x20C', + '\x84', '\x3', '\x2', '\x2', '\x2', '\x20D', '\x20E', '\a', 'w', '\x2', + '\x2', '\x20E', '\x20F', '\x5', '\x87', '\x44', '\x2', '\x20F', '\x210', + '\x5', '\x87', '\x44', '\x2', '\x210', '\x211', '\x5', '\x87', '\x44', + '\x2', '\x211', '\x212', '\x5', '\x87', '\x44', '\x2', '\x212', '\x86', + '\x3', '\x2', '\x2', '\x2', '\x213', '\x214', '\t', '\x5', '\x2', '\x2', + '\x214', '\x88', '\x3', '\x2', '\x2', '\x2', '\x215', '\x216', '\n', '\x6', + '\x2', '\x2', '\x216', '\x8A', '\x3', '\x2', '\x2', '\x2', '\x217', '\x218', + '\n', '\a', '\x2', '\x2', '\x218', '\x8C', '\x3', '\x2', '\x2', '\x2', + '\x219', '\x223', '\x3', '\x2', '\x2', '\x2', '\x21A', '\x21F', '\t', + '\b', '\x2', '\x2', '\x21B', '\x21E', '\t', '\b', '\x2', '\x2', '\x21C', + '\x21E', '\x5', '\x91', 'I', '\x2', '\x21D', '\x21B', '\x3', '\x2', '\x2', + '\x2', '\x21D', '\x21C', '\x3', '\x2', '\x2', '\x2', '\x21E', '\x221', + '\x3', '\x2', '\x2', '\x2', '\x21F', '\x21D', '\x3', '\x2', '\x2', '\x2', + '\x21F', '\x220', '\x3', '\x2', '\x2', '\x2', '\x220', '\x223', '\x3', + '\x2', '\x2', '\x2', '\x221', '\x21F', '\x3', '\x2', '\x2', '\x2', '\x222', + '\x219', '\x3', '\x2', '\x2', '\x2', '\x222', '\x21A', '\x3', '\x2', '\x2', + '\x2', '\x223', '\x8E', '\x3', '\x2', '\x2', '\x2', '\x224', '\x225', + '\a', '\x42', '\x2', '\x2', '\x225', '\x226', '\x5', '\x8D', 'G', '\x2', + '\x226', '\x90', '\x3', '\x2', '\x2', '\x2', '\x227', '\x228', '\t', '\t', + '\x2', '\x2', '\x228', '\x92', '\x3', '\x2', '\x2', '\x2', '\x229', '\x22A', + '\t', '\n', '\x2', '\x2', '\x22A', '\x94', '\x3', '\x2', '\x2', '\x2', + '\x22B', '\x22C', '\t', '\v', '\x2', '\x2', '\x22C', '\x96', '\x3', '\x2', + '\x2', '\x2', '\x22D', '\x22E', '\t', '\f', '\x2', '\x2', '\x22E', '\x98', + '\x3', '\x2', '\x2', '\x2', '\x22F', '\x230', '\t', '\r', '\x2', '\x2', + '\x230', '\x9A', '\x3', '\x2', '\x2', '\x2', '\x231', '\x232', '\t', '\xE', + '\x2', '\x2', '\x232', '\x9C', '\x3', '\x2', '\x2', '\x2', '\x233', '\x234', + '\t', '\xF', '\x2', '\x2', '\x234', '\x9E', '\x3', '\x2', '\x2', '\x2', + '\x235', '\x236', '\t', '\x10', '\x2', '\x2', '\x236', '\xA0', '\x3', + '\x2', '\x2', '\x2', '\x237', '\x238', '\t', '\x11', '\x2', '\x2', '\x238', + '\xA2', '\x3', '\x2', '\x2', '\x2', '\x239', '\x23A', '\t', '\x12', '\x2', + '\x2', '\x23A', '\xA4', '\x3', '\x2', '\x2', '\x2', '\x23B', '\x23C', + '\t', '\x13', '\x2', '\x2', '\x23C', '\xA6', '\x3', '\x2', '\x2', '\x2', + '\x23D', '\x23E', '\t', '\x14', '\x2', '\x2', '\x23E', '\xA8', '\x3', + '\x2', '\x2', '\x2', '\x23F', '\x240', '\t', '\x15', '\x2', '\x2', '\x240', + '\xAA', '\x3', '\x2', '\x2', '\x2', '\x241', '\x242', '\t', '\x16', '\x2', + '\x2', '\x242', '\xAC', '\x3', '\x2', '\x2', '\x2', '\x243', '\x244', + '\t', '\x17', '\x2', '\x2', '\x244', '\xAE', '\x3', '\x2', '\x2', '\x2', + '\x245', '\x246', '\t', '\x18', '\x2', '\x2', '\x246', '\xB0', '\x3', + '\x2', '\x2', '\x2', '\x247', '\x248', '\t', '\x19', '\x2', '\x2', '\x248', + '\xB2', '\x3', '\x2', '\x2', '\x2', '\x249', '\x24A', '\t', '\x1A', '\x2', + '\x2', '\x24A', '\xB4', '\x3', '\x2', '\x2', '\x2', '\x24B', '\x24C', + '\t', '\x1B', '\x2', '\x2', '\x24C', '\xB6', '\x3', '\x2', '\x2', '\x2', + '\x24D', '\x24E', '\t', '\x1C', '\x2', '\x2', '\x24E', '\xB8', '\x3', + '\x2', '\x2', '\x2', '\x24F', '\x250', '\t', '\x1D', '\x2', '\x2', '\x250', + '\xBA', '\x3', '\x2', '\x2', '\x2', '\x251', '\x252', '\t', '\x1E', '\x2', + '\x2', '\x252', '\xBC', '\x3', '\x2', '\x2', '\x2', '\x253', '\x254', + '\t', '\x1F', '\x2', '\x2', '\x254', '\xBE', '\x3', '\x2', '\x2', '\x2', + '\x255', '\x256', '\t', ' ', '\x2', '\x2', '\x256', '\xC0', '\x3', '\x2', + '\x2', '\x2', '\x257', '\x258', '\t', '!', '\x2', '\x2', '\x258', '\xC2', + '\x3', '\x2', '\x2', '\x2', '\x259', '\x25A', '\t', '\"', '\x2', '\x2', + '\x25A', '\xC4', '\x3', '\x2', '\x2', '\x2', '\x25B', '\x25C', '\t', '#', + '\x2', '\x2', '\x25C', '\xC6', '\x3', '\x2', '\x2', '\x2', '\x1A', '\x2', + '\x1BE', '\x1C3', '\x1C8', '\x1CE', '\x1D1', '\x1D5', '\x1DA', '\x1DC', + '\x1DF', '\x1E5', '\x1E9', '\x1EE', '\x1F0', '\x1F2', '\x1F7', '\x1F9', + '\x200', '\x202', '\x206', '\x20B', '\x21D', '\x21F', '\x222', '\x3', + '\b', '\x2', '\x2', }; public static readonly ATN _ATN = diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Parser/sqlParser.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Parser/sqlParser.cs index 53293f9382..e68b8e18f5 100644 --- a/Microsoft.Azure.Cosmos/src/Query/Core/Parser/sqlParser.cs +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Parser/sqlParser.cs @@ -40,11 +40,11 @@ public const int T__17=18, T__18=19, T__19=20, T__20=21, T__21=22, T__22=23, T__23=24, T__24=25, T__25=26, T__26=27, K_ALL=28, K_AND=29, K_ARRAY=30, K_AS=31, K_ASC=32, K_BETWEEN=33, K_BY=34, K_DESC=35, K_DISTINCT=36, K_ESCAPE=37, - K_EXISTS=38, K_FALSE=39, K_FROM=40, K_GROUP=41, K_IN=42, K_JOIN=43, K_LEFT=44, - K_LIKE=45, K_LIMIT=46, K_NOT=47, K_NULL=48, K_OFFSET=49, K_OR=50, K_ORDER=51, - K_RIGHT=52, K_SELECT=53, K_TOP=54, K_TRUE=55, K_UDF=56, K_UNDEFINED=57, - K_VALUE=58, K_WHERE=59, WS=60, NUMERIC_LITERAL=61, STRING_LITERAL=62, - LEX_IDENTIFIER=63, PARAMETER=64; + K_EXISTS=38, K_FIRST=39, K_FALSE=40, K_FROM=41, K_GROUP=42, K_IN=43, K_JOIN=44, + K_LAST=45, K_LEFT=46, K_LIKE=47, K_LIMIT=48, K_NOT=49, K_NULL=50, K_OFFSET=51, + K_OR=52, K_ORDER=53, K_RIGHT=54, K_SELECT=55, K_TOP=56, K_TRUE=57, K_UDF=58, + K_UNDEFINED=59, K_VALUE=60, K_WHERE=61, WS=62, NUMERIC_LITERAL=63, STRING_LITERAL=64, + LEX_IDENTIFIER=65, PARAMETER=66; public const int RULE_program = 0, RULE_sql_query = 1, RULE_select_clause = 2, RULE_top_spec = 3, RULE_selection = 4, RULE_select_star_spec = 5, RULE_select_value_spec = 6, @@ -81,19 +81,20 @@ public const int null, "'*'", "','", "'('", "')'", "'.'", "'['", "']'", "'?'", "':'", "'??'", "'/'", "'%'", "'+'", "'-'", "'<'", "'>'", "'>='", "'<='", "'='", "'!='", "'&'", "'^'", "'|'", "'||'", "'~'", "'{'", "'}'", null, null, null, null, - null, null, null, null, null, null, null, "'false'", null, null, null, - null, null, null, null, null, "'null'", null, null, null, null, null, - null, "'true'", "'udf'", "'undefined'" + null, null, null, null, null, null, null, null, "'false'", null, null, + null, null, null, null, null, null, null, "'null'", null, null, null, + null, null, null, "'true'", "'udf'", "'undefined'" }; private static readonly string[] _SymbolicNames = { null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, "K_ALL", "K_AND", "K_ARRAY", "K_AS", "K_ASC", - "K_BETWEEN", "K_BY", "K_DESC", "K_DISTINCT", "K_ESCAPE", "K_EXISTS", "K_FALSE", - "K_FROM", "K_GROUP", "K_IN", "K_JOIN", "K_LEFT", "K_LIKE", "K_LIMIT", - "K_NOT", "K_NULL", "K_OFFSET", "K_OR", "K_ORDER", "K_RIGHT", "K_SELECT", - "K_TOP", "K_TRUE", "K_UDF", "K_UNDEFINED", "K_VALUE", "K_WHERE", "WS", - "NUMERIC_LITERAL", "STRING_LITERAL", "LEX_IDENTIFIER", "PARAMETER" + "K_BETWEEN", "K_BY", "K_DESC", "K_DISTINCT", "K_ESCAPE", "K_EXISTS", "K_FIRST", + "K_FALSE", "K_FROM", "K_GROUP", "K_IN", "K_JOIN", "K_LAST", "K_LEFT", + "K_LIKE", "K_LIMIT", "K_NOT", "K_NULL", "K_OFFSET", "K_OR", "K_ORDER", + "K_RIGHT", "K_SELECT", "K_TOP", "K_TRUE", "K_UDF", "K_UNDEFINED", "K_VALUE", + "K_WHERE", "WS", "NUMERIC_LITERAL", "STRING_LITERAL", "LEX_IDENTIFIER", + "PARAMETER" }; public static readonly IVocabulary DefaultVocabulary = new Vocabulary(_LiteralNames, _SymbolicNames); @@ -463,7 +464,9 @@ public SelectionContext selection() { case K_ALL: case K_ARRAY: case K_EXISTS: + case K_FIRST: case K_FALSE: + case K_LAST: case K_LEFT: case K_NOT: case K_NULL: @@ -994,6 +997,8 @@ public CollectionContext collection() { ErrorHandler.Sync(this); switch (TokenStream.LA(1)) { case K_ALL: + case K_FIRST: + case K_LAST: case LEX_IDENTIFIER: _localctx = new InputPathCollectionContext(_localctx); EnterOuterAlt(_localctx, 1); @@ -2808,7 +2813,9 @@ public Unary_scalar_expressionContext unary_scalar_expression() { case K_ALL: case K_ARRAY: case K_EXISTS: + case K_FIRST: case K_FALSE: + case K_LAST: case K_LEFT: case K_NULL: case K_RIGHT: @@ -2971,6 +2978,26 @@ public override TResult Accept(IParseTreeVisitor visitor) { else return visitor.VisitChildren(this); } } + public partial class FirstScalarExpressionContext : Primary_expressionContext { + public ITerminalNode K_FIRST() { return GetToken(sqlParser.K_FIRST, 0); } + public Sql_queryContext sql_query() { + return GetRuleContext(0); + } + public FirstScalarExpressionContext(Primary_expressionContext context) { CopyFrom(context); } + public override void EnterRule(IParseTreeListener listener) { + IsqlListener typedListener = listener as IsqlListener; + if (typedListener != null) typedListener.EnterFirstScalarExpression(this); + } + public override void ExitRule(IParseTreeListener listener) { + IsqlListener typedListener = listener as IsqlListener; + if (typedListener != null) typedListener.ExitFirstScalarExpression(this); + } + public override TResult Accept(IParseTreeVisitor visitor) { + IsqlVisitor typedVisitor = visitor as IsqlVisitor; + if (typedVisitor != null) return typedVisitor.VisitFirstScalarExpression(this); + else return visitor.VisitChildren(this); + } + } public partial class ArrayCreateScalarExpressionContext : Primary_expressionContext { public Scalar_expression_listContext scalar_expression_list() { return GetRuleContext(0); @@ -3145,6 +3172,26 @@ public override TResult Accept(IParseTreeVisitor visitor) { else return visitor.VisitChildren(this); } } + public partial class LastScalarExpressionContext : Primary_expressionContext { + public ITerminalNode K_LAST() { return GetToken(sqlParser.K_LAST, 0); } + public Sql_queryContext sql_query() { + return GetRuleContext(0); + } + public LastScalarExpressionContext(Primary_expressionContext context) { CopyFrom(context); } + public override void EnterRule(IParseTreeListener listener) { + IsqlListener typedListener = listener as IsqlListener; + if (typedListener != null) typedListener.EnterLastScalarExpression(this); + } + public override void ExitRule(IParseTreeListener listener) { + IsqlListener typedListener = listener as IsqlListener; + if (typedListener != null) typedListener.ExitLastScalarExpression(this); + } + public override TResult Accept(IParseTreeVisitor visitor) { + IsqlVisitor typedVisitor = visitor as IsqlVisitor; + if (typedVisitor != null) return typedVisitor.VisitLastScalarExpression(this); + else return visitor.VisitChildren(this); + } + } public partial class PropertyRefScalarExpressionRecursiveContext : Primary_expressionContext { public Primary_expressionContext primary_expression() { return GetRuleContext(0); @@ -3185,7 +3232,7 @@ private Primary_expressionContext primary_expression(int _p) { int _alt; EnterOuterAlt(_localctx, 1); { - State = 397; + State = 407; ErrorHandler.Sync(this); switch ( Interpreter.AdaptivePredict(TokenStream,35,Context) ) { case 1: @@ -3222,7 +3269,7 @@ private Primary_expressionContext primary_expression(int _p) { State = 365; ErrorHandler.Sync(this); _la = TokenStream.LA(1); - if (((((_la - 3)) & ~0x3f) == 0 && ((1L << (_la - 3)) & ((1L << (T__2 - 3)) | (1L << (T__5 - 3)) | (1L << (T__12 - 3)) | (1L << (T__13 - 3)) | (1L << (T__24 - 3)) | (1L << (T__25 - 3)) | (1L << (K_ALL - 3)) | (1L << (K_ARRAY - 3)) | (1L << (K_EXISTS - 3)) | (1L << (K_FALSE - 3)) | (1L << (K_LEFT - 3)) | (1L << (K_NOT - 3)) | (1L << (K_NULL - 3)) | (1L << (K_RIGHT - 3)) | (1L << (K_TRUE - 3)) | (1L << (K_UDF - 3)) | (1L << (K_UNDEFINED - 3)) | (1L << (NUMERIC_LITERAL - 3)) | (1L << (STRING_LITERAL - 3)) | (1L << (LEX_IDENTIFIER - 3)) | (1L << (PARAMETER - 3)))) != 0)) { + if (((((_la - 3)) & ~0x3f) == 0 && ((1L << (_la - 3)) & ((1L << (T__2 - 3)) | (1L << (T__5 - 3)) | (1L << (T__12 - 3)) | (1L << (T__13 - 3)) | (1L << (T__24 - 3)) | (1L << (T__25 - 3)) | (1L << (K_ALL - 3)) | (1L << (K_ARRAY - 3)) | (1L << (K_EXISTS - 3)) | (1L << (K_FIRST - 3)) | (1L << (K_FALSE - 3)) | (1L << (K_LAST - 3)) | (1L << (K_LEFT - 3)) | (1L << (K_NOT - 3)) | (1L << (K_NULL - 3)) | (1L << (K_RIGHT - 3)) | (1L << (K_TRUE - 3)) | (1L << (K_UDF - 3)) | (1L << (K_UNDEFINED - 3)) | (1L << (NUMERIC_LITERAL - 3)) | (1L << (STRING_LITERAL - 3)) | (1L << (LEX_IDENTIFIER - 3)) | (1L << (PARAMETER - 3)))) != 0)) { { State = 364; scalar_expression_list(); } @@ -3303,16 +3350,38 @@ private Primary_expressionContext primary_expression(int _p) { } break; case 11: + { + _localctx = new FirstScalarExpressionContext(_localctx); + Context = _localctx; + _prevctx = _localctx; + State = 396; Match(K_FIRST); + State = 397; Match(T__2); + State = 398; sql_query(); + State = 399; Match(T__3); + } + break; + case 12: + { + _localctx = new LastScalarExpressionContext(_localctx); + Context = _localctx; + _prevctx = _localctx; + State = 401; Match(K_LAST); + State = 402; Match(T__2); + State = 403; sql_query(); + State = 404; Match(T__3); + } + break; + case 13: { _localctx = new FunctionCallScalarExpressionContext(_localctx); Context = _localctx; _prevctx = _localctx; - State = 396; function_call_scalar_expression(); + State = 406; function_call_scalar_expression(); } break; } Context.Stop = TokenStream.LT(-1); - State = 409; + State = 419; ErrorHandler.Sync(this); _alt = Interpreter.AdaptivePredict(TokenStream,37,Context); while ( _alt!=2 && _alt!=global::Antlr4.Runtime.Atn.ATN.INVALID_ALT_NUMBER ) { @@ -3321,34 +3390,34 @@ private Primary_expressionContext primary_expression(int _p) { TriggerExitRuleEvent(); _prevctx = _localctx; { - State = 407; + State = 417; ErrorHandler.Sync(this); switch ( Interpreter.AdaptivePredict(TokenStream,36,Context) ) { case 1: { _localctx = new PropertyRefScalarExpressionRecursiveContext(new Primary_expressionContext(_parentctx, _parentState)); PushNewRecursionContext(_localctx, _startState, RULE_primary_expression); - State = 399; - if (!(Precpred(Context, 6))) throw new FailedPredicateException(this, "Precpred(Context, 6)"); - State = 400; Match(T__4); - State = 401; identifier(); + State = 409; + if (!(Precpred(Context, 8))) throw new FailedPredicateException(this, "Precpred(Context, 8)"); + State = 410; Match(T__4); + State = 411; identifier(); } break; case 2: { _localctx = new MemberIndexerScalarExpressionContext(new Primary_expressionContext(_parentctx, _parentState)); PushNewRecursionContext(_localctx, _startState, RULE_primary_expression); - State = 402; - if (!(Precpred(Context, 5))) throw new FailedPredicateException(this, "Precpred(Context, 5)"); - State = 403; Match(T__5); - State = 404; scalar_expression(0); - State = 405; Match(T__6); + State = 412; + if (!(Precpred(Context, 7))) throw new FailedPredicateException(this, "Precpred(Context, 7)"); + State = 413; Match(T__5); + State = 414; scalar_expression(0); + State = 415; Match(T__6); } break; } } } - State = 411; + State = 421; ErrorHandler.Sync(this); _alt = Interpreter.AdaptivePredict(TokenStream,37,Context); } @@ -3401,70 +3470,72 @@ public Function_call_scalar_expressionContext function_call_scalar_expression() EnterRule(_localctx, 78, RULE_function_call_scalar_expression); int _la; try { - State = 435; + State = 445; ErrorHandler.Sync(this); switch (TokenStream.LA(1)) { case K_ALL: + case K_FIRST: + case K_LAST: case K_UDF: case LEX_IDENTIFIER: EnterOuterAlt(_localctx, 1); { - State = 414; + State = 424; ErrorHandler.Sync(this); _la = TokenStream.LA(1); if (_la==K_UDF) { { - State = 412; Match(K_UDF); - State = 413; Match(T__4); + State = 422; Match(K_UDF); + State = 423; Match(T__4); } } - State = 416; identifier(); - State = 417; Match(T__2); - State = 419; + State = 426; identifier(); + State = 427; Match(T__2); + State = 429; ErrorHandler.Sync(this); _la = TokenStream.LA(1); - if (((((_la - 3)) & ~0x3f) == 0 && ((1L << (_la - 3)) & ((1L << (T__2 - 3)) | (1L << (T__5 - 3)) | (1L << (T__12 - 3)) | (1L << (T__13 - 3)) | (1L << (T__24 - 3)) | (1L << (T__25 - 3)) | (1L << (K_ALL - 3)) | (1L << (K_ARRAY - 3)) | (1L << (K_EXISTS - 3)) | (1L << (K_FALSE - 3)) | (1L << (K_LEFT - 3)) | (1L << (K_NOT - 3)) | (1L << (K_NULL - 3)) | (1L << (K_RIGHT - 3)) | (1L << (K_TRUE - 3)) | (1L << (K_UDF - 3)) | (1L << (K_UNDEFINED - 3)) | (1L << (NUMERIC_LITERAL - 3)) | (1L << (STRING_LITERAL - 3)) | (1L << (LEX_IDENTIFIER - 3)) | (1L << (PARAMETER - 3)))) != 0)) { + if (((((_la - 3)) & ~0x3f) == 0 && ((1L << (_la - 3)) & ((1L << (T__2 - 3)) | (1L << (T__5 - 3)) | (1L << (T__12 - 3)) | (1L << (T__13 - 3)) | (1L << (T__24 - 3)) | (1L << (T__25 - 3)) | (1L << (K_ALL - 3)) | (1L << (K_ARRAY - 3)) | (1L << (K_EXISTS - 3)) | (1L << (K_FIRST - 3)) | (1L << (K_FALSE - 3)) | (1L << (K_LAST - 3)) | (1L << (K_LEFT - 3)) | (1L << (K_NOT - 3)) | (1L << (K_NULL - 3)) | (1L << (K_RIGHT - 3)) | (1L << (K_TRUE - 3)) | (1L << (K_UDF - 3)) | (1L << (K_UNDEFINED - 3)) | (1L << (NUMERIC_LITERAL - 3)) | (1L << (STRING_LITERAL - 3)) | (1L << (LEX_IDENTIFIER - 3)) | (1L << (PARAMETER - 3)))) != 0)) { { - State = 418; scalar_expression_list(); + State = 428; scalar_expression_list(); } } - State = 421; Match(T__3); + State = 431; Match(T__3); } break; case K_LEFT: EnterOuterAlt(_localctx, 2); { - State = 423; Match(K_LEFT); - State = 424; Match(T__2); - State = 426; + State = 433; Match(K_LEFT); + State = 434; Match(T__2); + State = 436; ErrorHandler.Sync(this); _la = TokenStream.LA(1); - if (((((_la - 3)) & ~0x3f) == 0 && ((1L << (_la - 3)) & ((1L << (T__2 - 3)) | (1L << (T__5 - 3)) | (1L << (T__12 - 3)) | (1L << (T__13 - 3)) | (1L << (T__24 - 3)) | (1L << (T__25 - 3)) | (1L << (K_ALL - 3)) | (1L << (K_ARRAY - 3)) | (1L << (K_EXISTS - 3)) | (1L << (K_FALSE - 3)) | (1L << (K_LEFT - 3)) | (1L << (K_NOT - 3)) | (1L << (K_NULL - 3)) | (1L << (K_RIGHT - 3)) | (1L << (K_TRUE - 3)) | (1L << (K_UDF - 3)) | (1L << (K_UNDEFINED - 3)) | (1L << (NUMERIC_LITERAL - 3)) | (1L << (STRING_LITERAL - 3)) | (1L << (LEX_IDENTIFIER - 3)) | (1L << (PARAMETER - 3)))) != 0)) { + if (((((_la - 3)) & ~0x3f) == 0 && ((1L << (_la - 3)) & ((1L << (T__2 - 3)) | (1L << (T__5 - 3)) | (1L << (T__12 - 3)) | (1L << (T__13 - 3)) | (1L << (T__24 - 3)) | (1L << (T__25 - 3)) | (1L << (K_ALL - 3)) | (1L << (K_ARRAY - 3)) | (1L << (K_EXISTS - 3)) | (1L << (K_FIRST - 3)) | (1L << (K_FALSE - 3)) | (1L << (K_LAST - 3)) | (1L << (K_LEFT - 3)) | (1L << (K_NOT - 3)) | (1L << (K_NULL - 3)) | (1L << (K_RIGHT - 3)) | (1L << (K_TRUE - 3)) | (1L << (K_UDF - 3)) | (1L << (K_UNDEFINED - 3)) | (1L << (NUMERIC_LITERAL - 3)) | (1L << (STRING_LITERAL - 3)) | (1L << (LEX_IDENTIFIER - 3)) | (1L << (PARAMETER - 3)))) != 0)) { { - State = 425; scalar_expression_list(); + State = 435; scalar_expression_list(); } } - State = 428; Match(T__3); + State = 438; Match(T__3); } break; case K_RIGHT: EnterOuterAlt(_localctx, 3); { - State = 429; Match(K_RIGHT); - State = 430; Match(T__2); - State = 432; + State = 439; Match(K_RIGHT); + State = 440; Match(T__2); + State = 442; ErrorHandler.Sync(this); _la = TokenStream.LA(1); - if (((((_la - 3)) & ~0x3f) == 0 && ((1L << (_la - 3)) & ((1L << (T__2 - 3)) | (1L << (T__5 - 3)) | (1L << (T__12 - 3)) | (1L << (T__13 - 3)) | (1L << (T__24 - 3)) | (1L << (T__25 - 3)) | (1L << (K_ALL - 3)) | (1L << (K_ARRAY - 3)) | (1L << (K_EXISTS - 3)) | (1L << (K_FALSE - 3)) | (1L << (K_LEFT - 3)) | (1L << (K_NOT - 3)) | (1L << (K_NULL - 3)) | (1L << (K_RIGHT - 3)) | (1L << (K_TRUE - 3)) | (1L << (K_UDF - 3)) | (1L << (K_UNDEFINED - 3)) | (1L << (NUMERIC_LITERAL - 3)) | (1L << (STRING_LITERAL - 3)) | (1L << (LEX_IDENTIFIER - 3)) | (1L << (PARAMETER - 3)))) != 0)) { + if (((((_la - 3)) & ~0x3f) == 0 && ((1L << (_la - 3)) & ((1L << (T__2 - 3)) | (1L << (T__5 - 3)) | (1L << (T__12 - 3)) | (1L << (T__13 - 3)) | (1L << (T__24 - 3)) | (1L << (T__25 - 3)) | (1L << (K_ALL - 3)) | (1L << (K_ARRAY - 3)) | (1L << (K_EXISTS - 3)) | (1L << (K_FIRST - 3)) | (1L << (K_FALSE - 3)) | (1L << (K_LAST - 3)) | (1L << (K_LEFT - 3)) | (1L << (K_NOT - 3)) | (1L << (K_NULL - 3)) | (1L << (K_RIGHT - 3)) | (1L << (K_TRUE - 3)) | (1L << (K_UDF - 3)) | (1L << (K_UNDEFINED - 3)) | (1L << (NUMERIC_LITERAL - 3)) | (1L << (STRING_LITERAL - 3)) | (1L << (LEX_IDENTIFIER - 3)) | (1L << (PARAMETER - 3)))) != 0)) { { - State = 431; scalar_expression_list(); + State = 441; scalar_expression_list(); } } - State = 434; Match(T__3); + State = 444; Match(T__3); } break; default: @@ -3517,18 +3588,18 @@ public Scalar_expression_listContext scalar_expression_list() { try { EnterOuterAlt(_localctx, 1); { - State = 437; scalar_expression(0); - State = 442; + State = 447; scalar_expression(0); + State = 452; ErrorHandler.Sync(this); _la = TokenStream.LA(1); while (_la==T__1) { { { - State = 438; Match(T__1); - State = 439; scalar_expression(0); + State = 448; Match(T__1); + State = 449; scalar_expression(0); } } - State = 444; + State = 454; ErrorHandler.Sync(this); _la = TokenStream.LA(1); } @@ -3580,18 +3651,18 @@ public Object_property_listContext object_property_list() { try { EnterOuterAlt(_localctx, 1); { - State = 445; object_property(); - State = 450; + State = 455; object_property(); + State = 460; ErrorHandler.Sync(this); _la = TokenStream.LA(1); while (_la==T__1) { { { - State = 446; Match(T__1); - State = 447; object_property(); + State = 456; Match(T__1); + State = 457; object_property(); } } - State = 452; + State = 462; ErrorHandler.Sync(this); _la = TokenStream.LA(1); } @@ -3640,9 +3711,9 @@ public Object_propertyContext object_property() { try { EnterOuterAlt(_localctx, 1); { - State = 453; Match(STRING_LITERAL); - State = 454; Match(T__8); - State = 455; scalar_expression(0); + State = 463; Match(STRING_LITERAL); + State = 464; Match(T__8); + State = 465; scalar_expression(0); } } catch (RecognitionException re) { @@ -3659,6 +3730,8 @@ public Object_propertyContext object_property() { public partial class IdentifierContext : ParserRuleContext { public ITerminalNode LEX_IDENTIFIER() { return GetToken(sqlParser.LEX_IDENTIFIER, 0); } public ITerminalNode K_ALL() { return GetToken(sqlParser.K_ALL, 0); } + public ITerminalNode K_FIRST() { return GetToken(sqlParser.K_FIRST, 0); } + public ITerminalNode K_LAST() { return GetToken(sqlParser.K_LAST, 0); } public IdentifierContext(ParserRuleContext parent, int invokingState) : base(parent, invokingState) { @@ -3687,9 +3760,9 @@ public IdentifierContext identifier() { try { EnterOuterAlt(_localctx, 1); { - State = 457; + State = 467; _la = TokenStream.LA(1); - if ( !(_la==K_ALL || _la==LEX_IDENTIFIER) ) { + if ( !(((((_la - 28)) & ~0x3f) == 0 && ((1L << (_la - 28)) & ((1L << (K_ALL - 28)) | (1L << (K_FIRST - 28)) | (1L << (K_LAST - 28)) | (1L << (LEX_IDENTIFIER - 28)))) != 0)) ) { ErrorHandler.RecoverInline(this); } else { @@ -3744,9 +3817,9 @@ public LiteralContext literal() { try { EnterOuterAlt(_localctx, 1); { - State = 459; + State = 469; _la = TokenStream.LA(1); - if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << K_FALSE) | (1L << K_NULL) | (1L << K_TRUE) | (1L << K_UNDEFINED) | (1L << NUMERIC_LITERAL) | (1L << STRING_LITERAL))) != 0)) ) { + if ( !(((((_la - 40)) & ~0x3f) == 0 && ((1L << (_la - 40)) & ((1L << (K_FALSE - 40)) | (1L << (K_NULL - 40)) | (1L << (K_TRUE - 40)) | (1L << (K_UNDEFINED - 40)) | (1L << (NUMERIC_LITERAL - 40)) | (1L << (STRING_LITERAL - 40)))) != 0)) ) { ErrorHandler.RecoverInline(this); } else { @@ -3820,15 +3893,15 @@ private bool binary_scalar_expression_sempred(Binary_scalar_expressionContext _l } private bool primary_expression_sempred(Primary_expressionContext _localctx, int predIndex) { switch (predIndex) { - case 16: return Precpred(Context, 6); - case 17: return Precpred(Context, 5); + case 16: return Precpred(Context, 8); + case 17: return Precpred(Context, 7); } return true; } private static char[] _serializedATN = { '\x3', '\x608B', '\xA72A', '\x8133', '\xB9ED', '\x417C', '\x3BE7', '\x7786', - '\x5964', '\x3', '\x42', '\x1D0', '\x4', '\x2', '\t', '\x2', '\x4', '\x3', + '\x5964', '\x3', '\x44', '\x1DA', '\x4', '\x2', '\t', '\x2', '\x4', '\x3', '\t', '\x3', '\x4', '\x4', '\t', '\x4', '\x4', '\x5', '\t', '\x5', '\x4', '\x6', '\t', '\x6', '\x4', '\a', '\t', '\a', '\x4', '\b', '\t', '\b', '\x4', '\t', '\t', '\t', '\x4', '\n', '\t', '\n', '\x4', '\v', '\t', '\v', @@ -3906,29 +3979,31 @@ private bool primary_expression_sempred(Primary_expressionContext _localctx, int '\x3', '(', '\x3', '(', '\x3', '(', '\x3', '(', '\x3', '(', '\x3', '(', '\x3', '(', '\x3', '(', '\x3', '(', '\x3', '(', '\x3', '(', '\x3', '(', '\x3', '(', '\x3', '(', '\x3', '(', '\x3', '(', '\x3', '(', '\x3', '(', - '\x3', '(', '\x3', '(', '\x5', '(', '\x190', '\n', '(', '\x3', '(', '\x3', - '(', '\x3', '(', '\x3', '(', '\x3', '(', '\x3', '(', '\x3', '(', '\x3', - '(', '\a', '(', '\x19A', '\n', '(', '\f', '(', '\xE', '(', '\x19D', '\v', - '(', '\x3', ')', '\x3', ')', '\x5', ')', '\x1A1', '\n', ')', '\x3', ')', - '\x3', ')', '\x3', ')', '\x5', ')', '\x1A6', '\n', ')', '\x3', ')', '\x3', - ')', '\x3', ')', '\x3', ')', '\x3', ')', '\x5', ')', '\x1AD', '\n', ')', - '\x3', ')', '\x3', ')', '\x3', ')', '\x3', ')', '\x5', ')', '\x1B3', '\n', - ')', '\x3', ')', '\x5', ')', '\x1B6', '\n', ')', '\x3', '*', '\x3', '*', - '\x3', '*', '\a', '*', '\x1BB', '\n', '*', '\f', '*', '\xE', '*', '\x1BE', - '\v', '*', '\x3', '+', '\x3', '+', '\x3', '+', '\a', '+', '\x1C3', '\n', - '+', '\f', '+', '\xE', '+', '\x1C6', '\v', '+', '\x3', ',', '\x3', ',', - '\x3', ',', '\x3', ',', '\x3', '-', '\x3', '-', '\x3', '.', '\x3', '.', - '\x3', '.', '\x2', '\b', '\x16', '\x1A', '.', '\x30', '\x38', 'N', '/', - '\x2', '\x4', '\x6', '\b', '\n', '\f', '\xE', '\x10', '\x12', '\x14', - '\x16', '\x18', '\x1A', '\x1C', '\x1E', ' ', '\"', '$', '&', '(', '*', - ',', '.', '\x30', '\x32', '\x34', '\x36', '\x38', ':', '<', '>', '@', - '\x42', '\x44', '\x46', 'H', 'J', 'L', 'N', 'P', 'R', 'T', 'V', 'X', 'Z', - '\x2', '\v', '\x4', '\x2', '?', '?', '\x42', '\x42', '\x4', '\x2', '\"', - '\"', '%', '%', '\x4', '\x2', '\x3', '\x3', '\r', '\xE', '\x3', '\x2', - '\xF', '\x10', '\x3', '\x2', '\x11', '\x14', '\x3', '\x2', '\x15', '\x16', - '\x5', '\x2', '\xF', '\x10', '\x1B', '\x1B', '\x31', '\x31', '\x4', '\x2', - '\x1E', '\x1E', '\x41', '\x41', '\a', '\x2', ')', ')', '\x32', '\x32', - '\x39', '\x39', ';', ';', '?', '@', '\x2', '\x1E2', '\x2', '\\', '\x3', + '\x3', '(', '\x3', '(', '\x3', '(', '\x3', '(', '\x3', '(', '\x3', '(', + '\x3', '(', '\x3', '(', '\x3', '(', '\x3', '(', '\x3', '(', '\x3', '(', + '\x5', '(', '\x19A', '\n', '(', '\x3', '(', '\x3', '(', '\x3', '(', '\x3', + '(', '\x3', '(', '\x3', '(', '\x3', '(', '\x3', '(', '\a', '(', '\x1A4', + '\n', '(', '\f', '(', '\xE', '(', '\x1A7', '\v', '(', '\x3', ')', '\x3', + ')', '\x5', ')', '\x1AB', '\n', ')', '\x3', ')', '\x3', ')', '\x3', ')', + '\x5', ')', '\x1B0', '\n', ')', '\x3', ')', '\x3', ')', '\x3', ')', '\x3', + ')', '\x3', ')', '\x5', ')', '\x1B7', '\n', ')', '\x3', ')', '\x3', ')', + '\x3', ')', '\x3', ')', '\x5', ')', '\x1BD', '\n', ')', '\x3', ')', '\x5', + ')', '\x1C0', '\n', ')', '\x3', '*', '\x3', '*', '\x3', '*', '\a', '*', + '\x1C5', '\n', '*', '\f', '*', '\xE', '*', '\x1C8', '\v', '*', '\x3', + '+', '\x3', '+', '\x3', '+', '\a', '+', '\x1CD', '\n', '+', '\f', '+', + '\xE', '+', '\x1D0', '\v', '+', '\x3', ',', '\x3', ',', '\x3', ',', '\x3', + ',', '\x3', '-', '\x3', '-', '\x3', '.', '\x3', '.', '\x3', '.', '\x2', + '\b', '\x16', '\x1A', '.', '\x30', '\x38', 'N', '/', '\x2', '\x4', '\x6', + '\b', '\n', '\f', '\xE', '\x10', '\x12', '\x14', '\x16', '\x18', '\x1A', + '\x1C', '\x1E', ' ', '\"', '$', '&', '(', '*', ',', '.', '\x30', '\x32', + '\x34', '\x36', '\x38', ':', '<', '>', '@', '\x42', '\x44', '\x46', 'H', + 'J', 'L', 'N', 'P', 'R', 'T', 'V', 'X', 'Z', '\x2', '\v', '\x4', '\x2', + '\x41', '\x41', '\x44', '\x44', '\x4', '\x2', '\"', '\"', '%', '%', '\x4', + '\x2', '\x3', '\x3', '\r', '\xE', '\x3', '\x2', '\xF', '\x10', '\x3', + '\x2', '\x11', '\x14', '\x3', '\x2', '\x15', '\x16', '\x5', '\x2', '\xF', + '\x10', '\x1B', '\x1B', '\x33', '\x33', '\x6', '\x2', '\x1E', '\x1E', + ')', ')', '/', '/', '\x43', '\x43', '\a', '\x2', '*', '*', '\x34', '\x34', + ';', ';', '=', '=', '\x41', '\x42', '\x2', '\x1EE', '\x2', '\\', '\x3', '\x2', '\x2', '\x2', '\x4', '_', '\x3', '\x2', '\x2', '\x2', '\x6', 'o', '\x3', '\x2', '\x2', '\x2', '\b', 'x', '\x3', '\x2', '\x2', '\x2', '\n', '~', '\x3', '\x2', '\x2', '\x2', '\f', '\x80', '\x3', '\x2', '\x2', '\x2', @@ -3950,11 +4025,11 @@ private bool primary_expression_sempred(Primary_expressionContext _localctx, int '\x2', '\x2', '\x2', '\x42', '\x159', '\x3', '\x2', '\x2', '\x2', '\x44', '\x15B', '\x3', '\x2', '\x2', '\x2', '\x46', '\x15D', '\x3', '\x2', '\x2', '\x2', 'H', '\x15F', '\x3', '\x2', '\x2', '\x2', 'J', '\x165', '\x3', - '\x2', '\x2', '\x2', 'L', '\x167', '\x3', '\x2', '\x2', '\x2', 'N', '\x18F', - '\x3', '\x2', '\x2', '\x2', 'P', '\x1B5', '\x3', '\x2', '\x2', '\x2', - 'R', '\x1B7', '\x3', '\x2', '\x2', '\x2', 'T', '\x1BF', '\x3', '\x2', - '\x2', '\x2', 'V', '\x1C7', '\x3', '\x2', '\x2', '\x2', 'X', '\x1CB', - '\x3', '\x2', '\x2', '\x2', 'Z', '\x1CD', '\x3', '\x2', '\x2', '\x2', + '\x2', '\x2', '\x2', 'L', '\x167', '\x3', '\x2', '\x2', '\x2', 'N', '\x199', + '\x3', '\x2', '\x2', '\x2', 'P', '\x1BF', '\x3', '\x2', '\x2', '\x2', + 'R', '\x1C1', '\x3', '\x2', '\x2', '\x2', 'T', '\x1C9', '\x3', '\x2', + '\x2', '\x2', 'V', '\x1D1', '\x3', '\x2', '\x2', '\x2', 'X', '\x1D5', + '\x3', '\x2', '\x2', '\x2', 'Z', '\x1D7', '\x3', '\x2', '\x2', '\x2', '\\', ']', '\x5', '\x4', '\x3', '\x2', ']', '^', '\a', '\x2', '\x2', '\x3', '^', '\x3', '\x3', '\x2', '\x2', '\x2', '_', '\x61', '\x5', '\x6', '\x4', '\x2', '`', '\x62', '\x5', '\x14', '\v', '\x2', '\x61', '`', '\x3', '\x2', @@ -3968,89 +4043,89 @@ private bool primary_expression_sempred(Primary_expressionContext _localctx, int 'j', 'k', '\x3', '\x2', '\x2', '\x2', 'k', 'm', '\x3', '\x2', '\x2', '\x2', 'l', 'n', '\x5', '(', '\x15', '\x2', 'm', 'l', '\x3', '\x2', '\x2', '\x2', 'm', 'n', '\x3', '\x2', '\x2', '\x2', 'n', '\x5', '\x3', '\x2', '\x2', - '\x2', 'o', 'q', '\a', '\x37', '\x2', '\x2', 'p', 'r', '\a', '&', '\x2', + '\x2', 'o', 'q', '\a', '\x39', '\x2', '\x2', 'p', 'r', '\a', '&', '\x2', '\x2', 'q', 'p', '\x3', '\x2', '\x2', '\x2', 'q', 'r', '\x3', '\x2', '\x2', '\x2', 'r', 't', '\x3', '\x2', '\x2', '\x2', 's', 'u', '\x5', '\b', '\x5', '\x2', 't', 's', '\x3', '\x2', '\x2', '\x2', 't', 'u', '\x3', '\x2', '\x2', '\x2', 'u', 'v', '\x3', '\x2', '\x2', '\x2', 'v', 'w', '\x5', '\n', '\x6', - '\x2', 'w', '\a', '\x3', '\x2', '\x2', '\x2', 'x', 'y', '\a', '\x38', - '\x2', '\x2', 'y', 'z', '\t', '\x2', '\x2', '\x2', 'z', '\t', '\x3', '\x2', - '\x2', '\x2', '{', '\x7F', '\x5', '\f', '\a', '\x2', '|', '\x7F', '\x5', - '\xE', '\b', '\x2', '}', '\x7F', '\x5', '\x10', '\t', '\x2', '~', '{', - '\x3', '\x2', '\x2', '\x2', '~', '|', '\x3', '\x2', '\x2', '\x2', '~', - '}', '\x3', '\x2', '\x2', '\x2', '\x7F', '\v', '\x3', '\x2', '\x2', '\x2', - '\x80', '\x81', '\a', '\x3', '\x2', '\x2', '\x81', '\r', '\x3', '\x2', - '\x2', '\x2', '\x82', '\x83', '\a', '<', '\x2', '\x2', '\x83', '\x84', - '\x5', '.', '\x18', '\x2', '\x84', '\xF', '\x3', '\x2', '\x2', '\x2', - '\x85', '\x8A', '\x5', '\x12', '\n', '\x2', '\x86', '\x87', '\a', '\x4', - '\x2', '\x2', '\x87', '\x89', '\x5', '\x12', '\n', '\x2', '\x88', '\x86', - '\x3', '\x2', '\x2', '\x2', '\x89', '\x8C', '\x3', '\x2', '\x2', '\x2', - '\x8A', '\x88', '\x3', '\x2', '\x2', '\x2', '\x8A', '\x8B', '\x3', '\x2', - '\x2', '\x2', '\x8B', '\x11', '\x3', '\x2', '\x2', '\x2', '\x8C', '\x8A', - '\x3', '\x2', '\x2', '\x2', '\x8D', '\x90', '\x5', '.', '\x18', '\x2', - '\x8E', '\x8F', '\a', '!', '\x2', '\x2', '\x8F', '\x91', '\x5', 'X', '-', - '\x2', '\x90', '\x8E', '\x3', '\x2', '\x2', '\x2', '\x90', '\x91', '\x3', - '\x2', '\x2', '\x2', '\x91', '\x13', '\x3', '\x2', '\x2', '\x2', '\x92', - '\x93', '\a', '*', '\x2', '\x2', '\x93', '\x94', '\x5', '\x16', '\f', - '\x2', '\x94', '\x15', '\x3', '\x2', '\x2', '\x2', '\x95', '\x96', '\b', - '\f', '\x1', '\x2', '\x96', '\x9B', '\x5', '\x18', '\r', '\x2', '\x97', - '\x99', '\a', '!', '\x2', '\x2', '\x98', '\x97', '\x3', '\x2', '\x2', - '\x2', '\x98', '\x99', '\x3', '\x2', '\x2', '\x2', '\x99', '\x9A', '\x3', - '\x2', '\x2', '\x2', '\x9A', '\x9C', '\x5', 'X', '-', '\x2', '\x9B', '\x98', - '\x3', '\x2', '\x2', '\x2', '\x9B', '\x9C', '\x3', '\x2', '\x2', '\x2', - '\x9C', '\xA2', '\x3', '\x2', '\x2', '\x2', '\x9D', '\x9E', '\x5', 'X', - '-', '\x2', '\x9E', '\x9F', '\a', ',', '\x2', '\x2', '\x9F', '\xA0', '\x5', - '\x18', '\r', '\x2', '\xA0', '\xA2', '\x3', '\x2', '\x2', '\x2', '\xA1', - '\x95', '\x3', '\x2', '\x2', '\x2', '\xA1', '\x9D', '\x3', '\x2', '\x2', - '\x2', '\xA2', '\xA8', '\x3', '\x2', '\x2', '\x2', '\xA3', '\xA4', '\f', - '\x3', '\x2', '\x2', '\xA4', '\xA5', '\a', '-', '\x2', '\x2', '\xA5', - '\xA7', '\x5', '\x16', '\f', '\x4', '\xA6', '\xA3', '\x3', '\x2', '\x2', - '\x2', '\xA7', '\xAA', '\x3', '\x2', '\x2', '\x2', '\xA8', '\xA6', '\x3', - '\x2', '\x2', '\x2', '\xA8', '\xA9', '\x3', '\x2', '\x2', '\x2', '\xA9', - '\x17', '\x3', '\x2', '\x2', '\x2', '\xAA', '\xA8', '\x3', '\x2', '\x2', - '\x2', '\xAB', '\xAD', '\x5', 'X', '-', '\x2', '\xAC', '\xAE', '\x5', - '\x1A', '\xE', '\x2', '\xAD', '\xAC', '\x3', '\x2', '\x2', '\x2', '\xAD', - '\xAE', '\x3', '\x2', '\x2', '\x2', '\xAE', '\xB4', '\x3', '\x2', '\x2', - '\x2', '\xAF', '\xB0', '\a', '\x5', '\x2', '\x2', '\xB0', '\xB1', '\x5', - '\x4', '\x3', '\x2', '\xB1', '\xB2', '\a', '\x6', '\x2', '\x2', '\xB2', - '\xB4', '\x3', '\x2', '\x2', '\x2', '\xB3', '\xAB', '\x3', '\x2', '\x2', - '\x2', '\xB3', '\xAF', '\x3', '\x2', '\x2', '\x2', '\xB4', '\x19', '\x3', - '\x2', '\x2', '\x2', '\xB5', '\xC3', '\b', '\xE', '\x1', '\x2', '\xB6', - '\xB7', '\f', '\x6', '\x2', '\x2', '\xB7', '\xB8', '\a', '\a', '\x2', - '\x2', '\xB8', '\xC2', '\x5', 'X', '-', '\x2', '\xB9', '\xBA', '\f', '\x5', - '\x2', '\x2', '\xBA', '\xBB', '\a', '\b', '\x2', '\x2', '\xBB', '\xBC', - '\a', '?', '\x2', '\x2', '\xBC', '\xC2', '\a', '\t', '\x2', '\x2', '\xBD', - '\xBE', '\f', '\x4', '\x2', '\x2', '\xBE', '\xBF', '\a', '\b', '\x2', - '\x2', '\xBF', '\xC0', '\a', '@', '\x2', '\x2', '\xC0', '\xC2', '\a', - '\t', '\x2', '\x2', '\xC1', '\xB6', '\x3', '\x2', '\x2', '\x2', '\xC1', - '\xB9', '\x3', '\x2', '\x2', '\x2', '\xC1', '\xBD', '\x3', '\x2', '\x2', - '\x2', '\xC2', '\xC5', '\x3', '\x2', '\x2', '\x2', '\xC3', '\xC1', '\x3', - '\x2', '\x2', '\x2', '\xC3', '\xC4', '\x3', '\x2', '\x2', '\x2', '\xC4', - '\x1B', '\x3', '\x2', '\x2', '\x2', '\xC5', '\xC3', '\x3', '\x2', '\x2', - '\x2', '\xC6', '\xC7', '\a', '=', '\x2', '\x2', '\xC7', '\xC8', '\x5', - '.', '\x18', '\x2', '\xC8', '\x1D', '\x3', '\x2', '\x2', '\x2', '\xC9', - '\xCA', '\a', '+', '\x2', '\x2', '\xCA', '\xCB', '\a', '$', '\x2', '\x2', - '\xCB', '\xCC', '\x5', 'R', '*', '\x2', '\xCC', '\x1F', '\x3', '\x2', - '\x2', '\x2', '\xCD', '\xCE', '\a', '\x35', '\x2', '\x2', '\xCE', '\xCF', - '\a', '$', '\x2', '\x2', '\xCF', '\xD0', '\x5', '\"', '\x12', '\x2', '\xD0', - '!', '\x3', '\x2', '\x2', '\x2', '\xD1', '\xD6', '\x5', '$', '\x13', '\x2', - '\xD2', '\xD3', '\a', '\x4', '\x2', '\x2', '\xD3', '\xD5', '\x5', '$', - '\x13', '\x2', '\xD4', '\xD2', '\x3', '\x2', '\x2', '\x2', '\xD5', '\xD8', - '\x3', '\x2', '\x2', '\x2', '\xD6', '\xD4', '\x3', '\x2', '\x2', '\x2', - '\xD6', '\xD7', '\x3', '\x2', '\x2', '\x2', '\xD7', '#', '\x3', '\x2', - '\x2', '\x2', '\xD8', '\xD6', '\x3', '\x2', '\x2', '\x2', '\xD9', '\xDB', - '\x5', '.', '\x18', '\x2', '\xDA', '\xDC', '\x5', '&', '\x14', '\x2', - '\xDB', '\xDA', '\x3', '\x2', '\x2', '\x2', '\xDB', '\xDC', '\x3', '\x2', - '\x2', '\x2', '\xDC', '%', '\x3', '\x2', '\x2', '\x2', '\xDD', '\xDE', - '\t', '\x3', '\x2', '\x2', '\xDE', '\'', '\x3', '\x2', '\x2', '\x2', '\xDF', - '\xE0', '\a', '\x33', '\x2', '\x2', '\xE0', '\xE1', '\x5', '*', '\x16', - '\x2', '\xE1', '\xE2', '\a', '\x30', '\x2', '\x2', '\xE2', '\xE3', '\x5', + '\x2', 'w', '\a', '\x3', '\x2', '\x2', '\x2', 'x', 'y', '\a', ':', '\x2', + '\x2', 'y', 'z', '\t', '\x2', '\x2', '\x2', 'z', '\t', '\x3', '\x2', '\x2', + '\x2', '{', '\x7F', '\x5', '\f', '\a', '\x2', '|', '\x7F', '\x5', '\xE', + '\b', '\x2', '}', '\x7F', '\x5', '\x10', '\t', '\x2', '~', '{', '\x3', + '\x2', '\x2', '\x2', '~', '|', '\x3', '\x2', '\x2', '\x2', '~', '}', '\x3', + '\x2', '\x2', '\x2', '\x7F', '\v', '\x3', '\x2', '\x2', '\x2', '\x80', + '\x81', '\a', '\x3', '\x2', '\x2', '\x81', '\r', '\x3', '\x2', '\x2', + '\x2', '\x82', '\x83', '\a', '>', '\x2', '\x2', '\x83', '\x84', '\x5', + '.', '\x18', '\x2', '\x84', '\xF', '\x3', '\x2', '\x2', '\x2', '\x85', + '\x8A', '\x5', '\x12', '\n', '\x2', '\x86', '\x87', '\a', '\x4', '\x2', + '\x2', '\x87', '\x89', '\x5', '\x12', '\n', '\x2', '\x88', '\x86', '\x3', + '\x2', '\x2', '\x2', '\x89', '\x8C', '\x3', '\x2', '\x2', '\x2', '\x8A', + '\x88', '\x3', '\x2', '\x2', '\x2', '\x8A', '\x8B', '\x3', '\x2', '\x2', + '\x2', '\x8B', '\x11', '\x3', '\x2', '\x2', '\x2', '\x8C', '\x8A', '\x3', + '\x2', '\x2', '\x2', '\x8D', '\x90', '\x5', '.', '\x18', '\x2', '\x8E', + '\x8F', '\a', '!', '\x2', '\x2', '\x8F', '\x91', '\x5', 'X', '-', '\x2', + '\x90', '\x8E', '\x3', '\x2', '\x2', '\x2', '\x90', '\x91', '\x3', '\x2', + '\x2', '\x2', '\x91', '\x13', '\x3', '\x2', '\x2', '\x2', '\x92', '\x93', + '\a', '+', '\x2', '\x2', '\x93', '\x94', '\x5', '\x16', '\f', '\x2', '\x94', + '\x15', '\x3', '\x2', '\x2', '\x2', '\x95', '\x96', '\b', '\f', '\x1', + '\x2', '\x96', '\x9B', '\x5', '\x18', '\r', '\x2', '\x97', '\x99', '\a', + '!', '\x2', '\x2', '\x98', '\x97', '\x3', '\x2', '\x2', '\x2', '\x98', + '\x99', '\x3', '\x2', '\x2', '\x2', '\x99', '\x9A', '\x3', '\x2', '\x2', + '\x2', '\x9A', '\x9C', '\x5', 'X', '-', '\x2', '\x9B', '\x98', '\x3', + '\x2', '\x2', '\x2', '\x9B', '\x9C', '\x3', '\x2', '\x2', '\x2', '\x9C', + '\xA2', '\x3', '\x2', '\x2', '\x2', '\x9D', '\x9E', '\x5', 'X', '-', '\x2', + '\x9E', '\x9F', '\a', '-', '\x2', '\x2', '\x9F', '\xA0', '\x5', '\x18', + '\r', '\x2', '\xA0', '\xA2', '\x3', '\x2', '\x2', '\x2', '\xA1', '\x95', + '\x3', '\x2', '\x2', '\x2', '\xA1', '\x9D', '\x3', '\x2', '\x2', '\x2', + '\xA2', '\xA8', '\x3', '\x2', '\x2', '\x2', '\xA3', '\xA4', '\f', '\x3', + '\x2', '\x2', '\xA4', '\xA5', '\a', '.', '\x2', '\x2', '\xA5', '\xA7', + '\x5', '\x16', '\f', '\x4', '\xA6', '\xA3', '\x3', '\x2', '\x2', '\x2', + '\xA7', '\xAA', '\x3', '\x2', '\x2', '\x2', '\xA8', '\xA6', '\x3', '\x2', + '\x2', '\x2', '\xA8', '\xA9', '\x3', '\x2', '\x2', '\x2', '\xA9', '\x17', + '\x3', '\x2', '\x2', '\x2', '\xAA', '\xA8', '\x3', '\x2', '\x2', '\x2', + '\xAB', '\xAD', '\x5', 'X', '-', '\x2', '\xAC', '\xAE', '\x5', '\x1A', + '\xE', '\x2', '\xAD', '\xAC', '\x3', '\x2', '\x2', '\x2', '\xAD', '\xAE', + '\x3', '\x2', '\x2', '\x2', '\xAE', '\xB4', '\x3', '\x2', '\x2', '\x2', + '\xAF', '\xB0', '\a', '\x5', '\x2', '\x2', '\xB0', '\xB1', '\x5', '\x4', + '\x3', '\x2', '\xB1', '\xB2', '\a', '\x6', '\x2', '\x2', '\xB2', '\xB4', + '\x3', '\x2', '\x2', '\x2', '\xB3', '\xAB', '\x3', '\x2', '\x2', '\x2', + '\xB3', '\xAF', '\x3', '\x2', '\x2', '\x2', '\xB4', '\x19', '\x3', '\x2', + '\x2', '\x2', '\xB5', '\xC3', '\b', '\xE', '\x1', '\x2', '\xB6', '\xB7', + '\f', '\x6', '\x2', '\x2', '\xB7', '\xB8', '\a', '\a', '\x2', '\x2', '\xB8', + '\xC2', '\x5', 'X', '-', '\x2', '\xB9', '\xBA', '\f', '\x5', '\x2', '\x2', + '\xBA', '\xBB', '\a', '\b', '\x2', '\x2', '\xBB', '\xBC', '\a', '\x41', + '\x2', '\x2', '\xBC', '\xC2', '\a', '\t', '\x2', '\x2', '\xBD', '\xBE', + '\f', '\x4', '\x2', '\x2', '\xBE', '\xBF', '\a', '\b', '\x2', '\x2', '\xBF', + '\xC0', '\a', '\x42', '\x2', '\x2', '\xC0', '\xC2', '\a', '\t', '\x2', + '\x2', '\xC1', '\xB6', '\x3', '\x2', '\x2', '\x2', '\xC1', '\xB9', '\x3', + '\x2', '\x2', '\x2', '\xC1', '\xBD', '\x3', '\x2', '\x2', '\x2', '\xC2', + '\xC5', '\x3', '\x2', '\x2', '\x2', '\xC3', '\xC1', '\x3', '\x2', '\x2', + '\x2', '\xC3', '\xC4', '\x3', '\x2', '\x2', '\x2', '\xC4', '\x1B', '\x3', + '\x2', '\x2', '\x2', '\xC5', '\xC3', '\x3', '\x2', '\x2', '\x2', '\xC6', + '\xC7', '\a', '?', '\x2', '\x2', '\xC7', '\xC8', '\x5', '.', '\x18', '\x2', + '\xC8', '\x1D', '\x3', '\x2', '\x2', '\x2', '\xC9', '\xCA', '\a', ',', + '\x2', '\x2', '\xCA', '\xCB', '\a', '$', '\x2', '\x2', '\xCB', '\xCC', + '\x5', 'R', '*', '\x2', '\xCC', '\x1F', '\x3', '\x2', '\x2', '\x2', '\xCD', + '\xCE', '\a', '\x37', '\x2', '\x2', '\xCE', '\xCF', '\a', '$', '\x2', + '\x2', '\xCF', '\xD0', '\x5', '\"', '\x12', '\x2', '\xD0', '!', '\x3', + '\x2', '\x2', '\x2', '\xD1', '\xD6', '\x5', '$', '\x13', '\x2', '\xD2', + '\xD3', '\a', '\x4', '\x2', '\x2', '\xD3', '\xD5', '\x5', '$', '\x13', + '\x2', '\xD4', '\xD2', '\x3', '\x2', '\x2', '\x2', '\xD5', '\xD8', '\x3', + '\x2', '\x2', '\x2', '\xD6', '\xD4', '\x3', '\x2', '\x2', '\x2', '\xD6', + '\xD7', '\x3', '\x2', '\x2', '\x2', '\xD7', '#', '\x3', '\x2', '\x2', + '\x2', '\xD8', '\xD6', '\x3', '\x2', '\x2', '\x2', '\xD9', '\xDB', '\x5', + '.', '\x18', '\x2', '\xDA', '\xDC', '\x5', '&', '\x14', '\x2', '\xDB', + '\xDA', '\x3', '\x2', '\x2', '\x2', '\xDB', '\xDC', '\x3', '\x2', '\x2', + '\x2', '\xDC', '%', '\x3', '\x2', '\x2', '\x2', '\xDD', '\xDE', '\t', + '\x3', '\x2', '\x2', '\xDE', '\'', '\x3', '\x2', '\x2', '\x2', '\xDF', + '\xE0', '\a', '\x35', '\x2', '\x2', '\xE0', '\xE1', '\x5', '*', '\x16', + '\x2', '\xE1', '\xE2', '\a', '\x32', '\x2', '\x2', '\xE2', '\xE3', '\x5', ',', '\x17', '\x2', '\xE3', ')', '\x3', '\x2', '\x2', '\x2', '\xE4', '\xE5', '\t', '\x2', '\x2', '\x2', '\xE5', '+', '\x3', '\x2', '\x2', '\x2', '\xE6', '\xE7', '\t', '\x2', '\x2', '\x2', '\xE7', '-', '\x3', '\x2', '\x2', '\x2', '\xE8', '\xE9', '\b', '\x18', '\x1', '\x2', '\xE9', '\xF4', '\x5', '\x30', '\x19', '\x2', '\xEA', '\xEC', '\x5', '\x38', '\x1D', '\x2', '\xEB', '\xED', - '\a', '\x31', '\x2', '\x2', '\xEC', '\xEB', '\x3', '\x2', '\x2', '\x2', + '\a', '\x33', '\x2', '\x2', '\xEC', '\xEB', '\x3', '\x2', '\x2', '\x2', '\xEC', '\xED', '\x3', '\x2', '\x2', '\x2', '\xED', '\xEE', '\x3', '\x2', '\x2', '\x2', '\xEE', '\xEF', '\a', '#', '\x2', '\x2', '\xEF', '\xF0', '\x5', '\x38', '\x1D', '\x2', '\xF0', '\xF1', '\a', '\x1F', '\x2', '\x2', @@ -4074,27 +4149,27 @@ private bool primary_expression_sempred(Primary_expressionContext _localctx, int '\x2', '\x108', '\x111', '\x3', '\x2', '\x2', '\x2', '\x109', '\x10A', '\f', '\x4', '\x2', '\x2', '\x10A', '\x10B', '\a', '\x1F', '\x2', '\x2', '\x10B', '\x110', '\x5', '\x30', '\x19', '\x5', '\x10C', '\x10D', '\f', - '\x3', '\x2', '\x2', '\x10D', '\x10E', '\a', '\x34', '\x2', '\x2', '\x10E', + '\x3', '\x2', '\x2', '\x10D', '\x10E', '\a', '\x36', '\x2', '\x2', '\x10E', '\x110', '\x5', '\x30', '\x19', '\x4', '\x10F', '\x109', '\x3', '\x2', '\x2', '\x2', '\x10F', '\x10C', '\x3', '\x2', '\x2', '\x2', '\x110', '\x113', '\x3', '\x2', '\x2', '\x2', '\x111', '\x10F', '\x3', '\x2', '\x2', '\x2', '\x111', '\x112', '\x3', '\x2', '\x2', '\x2', '\x112', '\x31', '\x3', '\x2', '\x2', '\x2', '\x113', '\x111', '\x3', '\x2', '\x2', '\x2', '\x114', - '\x116', '\x5', '\x38', '\x1D', '\x2', '\x115', '\x117', '\a', '\x31', + '\x116', '\x5', '\x38', '\x1D', '\x2', '\x115', '\x117', '\a', '\x33', '\x2', '\x2', '\x116', '\x115', '\x3', '\x2', '\x2', '\x2', '\x116', '\x117', '\x3', '\x2', '\x2', '\x2', '\x117', '\x118', '\x3', '\x2', '\x2', '\x2', - '\x118', '\x119', '\a', ',', '\x2', '\x2', '\x119', '\x11A', '\a', '\x5', + '\x118', '\x119', '\a', '-', '\x2', '\x2', '\x119', '\x11A', '\a', '\x5', '\x2', '\x2', '\x11A', '\x11B', '\x5', 'R', '*', '\x2', '\x11B', '\x11C', '\a', '\x6', '\x2', '\x2', '\x11C', '\x33', '\x3', '\x2', '\x2', '\x2', '\x11D', '\x11F', '\x5', '\x38', '\x1D', '\x2', '\x11E', '\x120', '\a', - '\x31', '\x2', '\x2', '\x11F', '\x11E', '\x3', '\x2', '\x2', '\x2', '\x11F', + '\x33', '\x2', '\x2', '\x11F', '\x11E', '\x3', '\x2', '\x2', '\x2', '\x11F', '\x120', '\x3', '\x2', '\x2', '\x2', '\x120', '\x121', '\x3', '\x2', '\x2', - '\x2', '\x121', '\x122', '\a', '/', '\x2', '\x2', '\x122', '\x124', '\x5', - '\x38', '\x1D', '\x2', '\x123', '\x125', '\x5', '\x36', '\x1C', '\x2', - '\x124', '\x123', '\x3', '\x2', '\x2', '\x2', '\x124', '\x125', '\x3', - '\x2', '\x2', '\x2', '\x125', '\x35', '\x3', '\x2', '\x2', '\x2', '\x126', - '\x127', '\a', '\'', '\x2', '\x2', '\x127', '\x128', '\a', '@', '\x2', - '\x2', '\x128', '\x37', '\x3', '\x2', '\x2', '\x2', '\x129', '\x12A', + '\x2', '\x121', '\x122', '\a', '\x31', '\x2', '\x2', '\x122', '\x124', + '\x5', '\x38', '\x1D', '\x2', '\x123', '\x125', '\x5', '\x36', '\x1C', + '\x2', '\x124', '\x123', '\x3', '\x2', '\x2', '\x2', '\x124', '\x125', + '\x3', '\x2', '\x2', '\x2', '\x125', '\x35', '\x3', '\x2', '\x2', '\x2', + '\x126', '\x127', '\a', '\'', '\x2', '\x2', '\x127', '\x128', '\a', '\x42', + '\x2', '\x2', '\x128', '\x37', '\x3', '\x2', '\x2', '\x2', '\x129', '\x12A', '\b', '\x1D', '\x1', '\x2', '\x12A', '\x12B', '\x5', 'J', '&', '\x2', '\x12B', '\x14E', '\x3', '\x2', '\x2', '\x2', '\x12C', '\x12D', '\f', '\n', '\x2', '\x2', '\x12D', '\x12E', '\x5', ':', '\x1E', '\x2', '\x12E', @@ -4140,87 +4215,95 @@ private bool primary_expression_sempred(Primary_expressionContext _localctx, int '\x3', '\x2', '\x2', '\x2', '\x165', '\x162', '\x3', '\x2', '\x2', '\x2', '\x166', 'K', '\x3', '\x2', '\x2', '\x2', '\x167', '\x168', '\t', '\b', '\x2', '\x2', '\x168', 'M', '\x3', '\x2', '\x2', '\x2', '\x169', '\x16A', - '\b', '(', '\x1', '\x2', '\x16A', '\x190', '\x5', 'X', '-', '\x2', '\x16B', - '\x190', '\a', '\x42', '\x2', '\x2', '\x16C', '\x190', '\x5', 'Z', '.', + '\b', '(', '\x1', '\x2', '\x16A', '\x19A', '\x5', 'X', '-', '\x2', '\x16B', + '\x19A', '\a', '\x44', '\x2', '\x2', '\x16C', '\x19A', '\x5', 'Z', '.', '\x2', '\x16D', '\x16F', '\a', '\b', '\x2', '\x2', '\x16E', '\x170', '\x5', 'R', '*', '\x2', '\x16F', '\x16E', '\x3', '\x2', '\x2', '\x2', '\x16F', '\x170', '\x3', '\x2', '\x2', '\x2', '\x170', '\x171', '\x3', '\x2', '\x2', - '\x2', '\x171', '\x190', '\a', '\t', '\x2', '\x2', '\x172', '\x174', '\a', + '\x2', '\x171', '\x19A', '\a', '\t', '\x2', '\x2', '\x172', '\x174', '\a', '\x1C', '\x2', '\x2', '\x173', '\x175', '\x5', 'T', '+', '\x2', '\x174', '\x173', '\x3', '\x2', '\x2', '\x2', '\x174', '\x175', '\x3', '\x2', '\x2', - '\x2', '\x175', '\x176', '\x3', '\x2', '\x2', '\x2', '\x176', '\x190', + '\x2', '\x175', '\x176', '\x3', '\x2', '\x2', '\x2', '\x176', '\x19A', '\a', '\x1D', '\x2', '\x2', '\x177', '\x178', '\a', '\x5', '\x2', '\x2', '\x178', '\x179', '\x5', '.', '\x18', '\x2', '\x179', '\x17A', '\a', '\x6', - '\x2', '\x2', '\x17A', '\x190', '\x3', '\x2', '\x2', '\x2', '\x17B', '\x17C', + '\x2', '\x2', '\x17A', '\x19A', '\x3', '\x2', '\x2', '\x2', '\x17B', '\x17C', '\a', '\x5', '\x2', '\x2', '\x17C', '\x17D', '\x5', '\x4', '\x3', '\x2', - '\x17D', '\x17E', '\a', '\x6', '\x2', '\x2', '\x17E', '\x190', '\x3', + '\x17D', '\x17E', '\a', '\x6', '\x2', '\x2', '\x17E', '\x19A', '\x3', '\x2', '\x2', '\x2', '\x17F', '\x180', '\a', '(', '\x2', '\x2', '\x180', '\x181', '\a', '\x5', '\x2', '\x2', '\x181', '\x182', '\x5', '\x4', '\x3', - '\x2', '\x182', '\x183', '\a', '\x6', '\x2', '\x2', '\x183', '\x190', + '\x2', '\x182', '\x183', '\a', '\x6', '\x2', '\x2', '\x183', '\x19A', '\x3', '\x2', '\x2', '\x2', '\x184', '\x185', '\a', ' ', '\x2', '\x2', '\x185', '\x186', '\a', '\x5', '\x2', '\x2', '\x186', '\x187', '\x5', '\x4', '\x3', '\x2', '\x187', '\x188', '\a', '\x6', '\x2', '\x2', '\x188', - '\x190', '\x3', '\x2', '\x2', '\x2', '\x189', '\x18A', '\a', '\x1E', '\x2', + '\x19A', '\x3', '\x2', '\x2', '\x2', '\x189', '\x18A', '\a', '\x1E', '\x2', '\x2', '\x18A', '\x18B', '\a', '\x5', '\x2', '\x2', '\x18B', '\x18C', '\x5', '\x4', '\x3', '\x2', '\x18C', '\x18D', '\a', '\x6', '\x2', '\x2', - '\x18D', '\x190', '\x3', '\x2', '\x2', '\x2', '\x18E', '\x190', '\x5', - 'P', ')', '\x2', '\x18F', '\x169', '\x3', '\x2', '\x2', '\x2', '\x18F', - '\x16B', '\x3', '\x2', '\x2', '\x2', '\x18F', '\x16C', '\x3', '\x2', '\x2', - '\x2', '\x18F', '\x16D', '\x3', '\x2', '\x2', '\x2', '\x18F', '\x172', - '\x3', '\x2', '\x2', '\x2', '\x18F', '\x177', '\x3', '\x2', '\x2', '\x2', - '\x18F', '\x17B', '\x3', '\x2', '\x2', '\x2', '\x18F', '\x17F', '\x3', - '\x2', '\x2', '\x2', '\x18F', '\x184', '\x3', '\x2', '\x2', '\x2', '\x18F', - '\x189', '\x3', '\x2', '\x2', '\x2', '\x18F', '\x18E', '\x3', '\x2', '\x2', - '\x2', '\x190', '\x19B', '\x3', '\x2', '\x2', '\x2', '\x191', '\x192', - '\f', '\b', '\x2', '\x2', '\x192', '\x193', '\a', '\a', '\x2', '\x2', - '\x193', '\x19A', '\x5', 'X', '-', '\x2', '\x194', '\x195', '\f', '\a', - '\x2', '\x2', '\x195', '\x196', '\a', '\b', '\x2', '\x2', '\x196', '\x197', - '\x5', '.', '\x18', '\x2', '\x197', '\x198', '\a', '\t', '\x2', '\x2', - '\x198', '\x19A', '\x3', '\x2', '\x2', '\x2', '\x199', '\x191', '\x3', - '\x2', '\x2', '\x2', '\x199', '\x194', '\x3', '\x2', '\x2', '\x2', '\x19A', - '\x19D', '\x3', '\x2', '\x2', '\x2', '\x19B', '\x199', '\x3', '\x2', '\x2', - '\x2', '\x19B', '\x19C', '\x3', '\x2', '\x2', '\x2', '\x19C', 'O', '\x3', - '\x2', '\x2', '\x2', '\x19D', '\x19B', '\x3', '\x2', '\x2', '\x2', '\x19E', - '\x19F', '\a', ':', '\x2', '\x2', '\x19F', '\x1A1', '\a', '\a', '\x2', - '\x2', '\x1A0', '\x19E', '\x3', '\x2', '\x2', '\x2', '\x1A0', '\x1A1', - '\x3', '\x2', '\x2', '\x2', '\x1A1', '\x1A2', '\x3', '\x2', '\x2', '\x2', - '\x1A2', '\x1A3', '\x5', 'X', '-', '\x2', '\x1A3', '\x1A5', '\a', '\x5', - '\x2', '\x2', '\x1A4', '\x1A6', '\x5', 'R', '*', '\x2', '\x1A5', '\x1A4', - '\x3', '\x2', '\x2', '\x2', '\x1A5', '\x1A6', '\x3', '\x2', '\x2', '\x2', - '\x1A6', '\x1A7', '\x3', '\x2', '\x2', '\x2', '\x1A7', '\x1A8', '\a', - '\x6', '\x2', '\x2', '\x1A8', '\x1B6', '\x3', '\x2', '\x2', '\x2', '\x1A9', - '\x1AA', '\a', '.', '\x2', '\x2', '\x1AA', '\x1AC', '\a', '\x5', '\x2', - '\x2', '\x1AB', '\x1AD', '\x5', 'R', '*', '\x2', '\x1AC', '\x1AB', '\x3', - '\x2', '\x2', '\x2', '\x1AC', '\x1AD', '\x3', '\x2', '\x2', '\x2', '\x1AD', - '\x1AE', '\x3', '\x2', '\x2', '\x2', '\x1AE', '\x1B6', '\a', '\x6', '\x2', - '\x2', '\x1AF', '\x1B0', '\a', '\x36', '\x2', '\x2', '\x1B0', '\x1B2', - '\a', '\x5', '\x2', '\x2', '\x1B1', '\x1B3', '\x5', 'R', '*', '\x2', '\x1B2', - '\x1B1', '\x3', '\x2', '\x2', '\x2', '\x1B2', '\x1B3', '\x3', '\x2', '\x2', - '\x2', '\x1B3', '\x1B4', '\x3', '\x2', '\x2', '\x2', '\x1B4', '\x1B6', - '\a', '\x6', '\x2', '\x2', '\x1B5', '\x1A0', '\x3', '\x2', '\x2', '\x2', - '\x1B5', '\x1A9', '\x3', '\x2', '\x2', '\x2', '\x1B5', '\x1AF', '\x3', - '\x2', '\x2', '\x2', '\x1B6', 'Q', '\x3', '\x2', '\x2', '\x2', '\x1B7', - '\x1BC', '\x5', '.', '\x18', '\x2', '\x1B8', '\x1B9', '\a', '\x4', '\x2', - '\x2', '\x1B9', '\x1BB', '\x5', '.', '\x18', '\x2', '\x1BA', '\x1B8', - '\x3', '\x2', '\x2', '\x2', '\x1BB', '\x1BE', '\x3', '\x2', '\x2', '\x2', - '\x1BC', '\x1BA', '\x3', '\x2', '\x2', '\x2', '\x1BC', '\x1BD', '\x3', - '\x2', '\x2', '\x2', '\x1BD', 'S', '\x3', '\x2', '\x2', '\x2', '\x1BE', - '\x1BC', '\x3', '\x2', '\x2', '\x2', '\x1BF', '\x1C4', '\x5', 'V', ',', - '\x2', '\x1C0', '\x1C1', '\a', '\x4', '\x2', '\x2', '\x1C1', '\x1C3', - '\x5', 'V', ',', '\x2', '\x1C2', '\x1C0', '\x3', '\x2', '\x2', '\x2', - '\x1C3', '\x1C6', '\x3', '\x2', '\x2', '\x2', '\x1C4', '\x1C2', '\x3', - '\x2', '\x2', '\x2', '\x1C4', '\x1C5', '\x3', '\x2', '\x2', '\x2', '\x1C5', - 'U', '\x3', '\x2', '\x2', '\x2', '\x1C6', '\x1C4', '\x3', '\x2', '\x2', - '\x2', '\x1C7', '\x1C8', '\a', '@', '\x2', '\x2', '\x1C8', '\x1C9', '\a', - '\v', '\x2', '\x2', '\x1C9', '\x1CA', '\x5', '.', '\x18', '\x2', '\x1CA', - 'W', '\x3', '\x2', '\x2', '\x2', '\x1CB', '\x1CC', '\t', '\t', '\x2', - '\x2', '\x1CC', 'Y', '\x3', '\x2', '\x2', '\x2', '\x1CD', '\x1CE', '\t', - '\n', '\x2', '\x2', '\x1CE', '[', '\x3', '\x2', '\x2', '\x2', '/', '\x61', - '\x64', 'g', 'j', 'm', 'q', 't', '~', '\x8A', '\x90', '\x98', '\x9B', - '\xA1', '\xA8', '\xAD', '\xB3', '\xC1', '\xC3', '\xD6', '\xDB', '\xEC', - '\xF3', '\xFE', '\x100', '\x107', '\x10F', '\x111', '\x116', '\x11F', - '\x124', '\x14C', '\x14E', '\x165', '\x16F', '\x174', '\x18F', '\x199', - '\x19B', '\x1A0', '\x1A5', '\x1AC', '\x1B2', '\x1B5', '\x1BC', '\x1C4', + '\x18D', '\x19A', '\x3', '\x2', '\x2', '\x2', '\x18E', '\x18F', '\a', + ')', '\x2', '\x2', '\x18F', '\x190', '\a', '\x5', '\x2', '\x2', '\x190', + '\x191', '\x5', '\x4', '\x3', '\x2', '\x191', '\x192', '\a', '\x6', '\x2', + '\x2', '\x192', '\x19A', '\x3', '\x2', '\x2', '\x2', '\x193', '\x194', + '\a', '/', '\x2', '\x2', '\x194', '\x195', '\a', '\x5', '\x2', '\x2', + '\x195', '\x196', '\x5', '\x4', '\x3', '\x2', '\x196', '\x197', '\a', + '\x6', '\x2', '\x2', '\x197', '\x19A', '\x3', '\x2', '\x2', '\x2', '\x198', + '\x19A', '\x5', 'P', ')', '\x2', '\x199', '\x169', '\x3', '\x2', '\x2', + '\x2', '\x199', '\x16B', '\x3', '\x2', '\x2', '\x2', '\x199', '\x16C', + '\x3', '\x2', '\x2', '\x2', '\x199', '\x16D', '\x3', '\x2', '\x2', '\x2', + '\x199', '\x172', '\x3', '\x2', '\x2', '\x2', '\x199', '\x177', '\x3', + '\x2', '\x2', '\x2', '\x199', '\x17B', '\x3', '\x2', '\x2', '\x2', '\x199', + '\x17F', '\x3', '\x2', '\x2', '\x2', '\x199', '\x184', '\x3', '\x2', '\x2', + '\x2', '\x199', '\x189', '\x3', '\x2', '\x2', '\x2', '\x199', '\x18E', + '\x3', '\x2', '\x2', '\x2', '\x199', '\x193', '\x3', '\x2', '\x2', '\x2', + '\x199', '\x198', '\x3', '\x2', '\x2', '\x2', '\x19A', '\x1A5', '\x3', + '\x2', '\x2', '\x2', '\x19B', '\x19C', '\f', '\n', '\x2', '\x2', '\x19C', + '\x19D', '\a', '\a', '\x2', '\x2', '\x19D', '\x1A4', '\x5', 'X', '-', + '\x2', '\x19E', '\x19F', '\f', '\t', '\x2', '\x2', '\x19F', '\x1A0', '\a', + '\b', '\x2', '\x2', '\x1A0', '\x1A1', '\x5', '.', '\x18', '\x2', '\x1A1', + '\x1A2', '\a', '\t', '\x2', '\x2', '\x1A2', '\x1A4', '\x3', '\x2', '\x2', + '\x2', '\x1A3', '\x19B', '\x3', '\x2', '\x2', '\x2', '\x1A3', '\x19E', + '\x3', '\x2', '\x2', '\x2', '\x1A4', '\x1A7', '\x3', '\x2', '\x2', '\x2', + '\x1A5', '\x1A3', '\x3', '\x2', '\x2', '\x2', '\x1A5', '\x1A6', '\x3', + '\x2', '\x2', '\x2', '\x1A6', 'O', '\x3', '\x2', '\x2', '\x2', '\x1A7', + '\x1A5', '\x3', '\x2', '\x2', '\x2', '\x1A8', '\x1A9', '\a', '<', '\x2', + '\x2', '\x1A9', '\x1AB', '\a', '\a', '\x2', '\x2', '\x1AA', '\x1A8', '\x3', + '\x2', '\x2', '\x2', '\x1AA', '\x1AB', '\x3', '\x2', '\x2', '\x2', '\x1AB', + '\x1AC', '\x3', '\x2', '\x2', '\x2', '\x1AC', '\x1AD', '\x5', 'X', '-', + '\x2', '\x1AD', '\x1AF', '\a', '\x5', '\x2', '\x2', '\x1AE', '\x1B0', + '\x5', 'R', '*', '\x2', '\x1AF', '\x1AE', '\x3', '\x2', '\x2', '\x2', + '\x1AF', '\x1B0', '\x3', '\x2', '\x2', '\x2', '\x1B0', '\x1B1', '\x3', + '\x2', '\x2', '\x2', '\x1B1', '\x1B2', '\a', '\x6', '\x2', '\x2', '\x1B2', + '\x1C0', '\x3', '\x2', '\x2', '\x2', '\x1B3', '\x1B4', '\a', '\x30', '\x2', + '\x2', '\x1B4', '\x1B6', '\a', '\x5', '\x2', '\x2', '\x1B5', '\x1B7', + '\x5', 'R', '*', '\x2', '\x1B6', '\x1B5', '\x3', '\x2', '\x2', '\x2', + '\x1B6', '\x1B7', '\x3', '\x2', '\x2', '\x2', '\x1B7', '\x1B8', '\x3', + '\x2', '\x2', '\x2', '\x1B8', '\x1C0', '\a', '\x6', '\x2', '\x2', '\x1B9', + '\x1BA', '\a', '\x38', '\x2', '\x2', '\x1BA', '\x1BC', '\a', '\x5', '\x2', + '\x2', '\x1BB', '\x1BD', '\x5', 'R', '*', '\x2', '\x1BC', '\x1BB', '\x3', + '\x2', '\x2', '\x2', '\x1BC', '\x1BD', '\x3', '\x2', '\x2', '\x2', '\x1BD', + '\x1BE', '\x3', '\x2', '\x2', '\x2', '\x1BE', '\x1C0', '\a', '\x6', '\x2', + '\x2', '\x1BF', '\x1AA', '\x3', '\x2', '\x2', '\x2', '\x1BF', '\x1B3', + '\x3', '\x2', '\x2', '\x2', '\x1BF', '\x1B9', '\x3', '\x2', '\x2', '\x2', + '\x1C0', 'Q', '\x3', '\x2', '\x2', '\x2', '\x1C1', '\x1C6', '\x5', '.', + '\x18', '\x2', '\x1C2', '\x1C3', '\a', '\x4', '\x2', '\x2', '\x1C3', '\x1C5', + '\x5', '.', '\x18', '\x2', '\x1C4', '\x1C2', '\x3', '\x2', '\x2', '\x2', + '\x1C5', '\x1C8', '\x3', '\x2', '\x2', '\x2', '\x1C6', '\x1C4', '\x3', + '\x2', '\x2', '\x2', '\x1C6', '\x1C7', '\x3', '\x2', '\x2', '\x2', '\x1C7', + 'S', '\x3', '\x2', '\x2', '\x2', '\x1C8', '\x1C6', '\x3', '\x2', '\x2', + '\x2', '\x1C9', '\x1CE', '\x5', 'V', ',', '\x2', '\x1CA', '\x1CB', '\a', + '\x4', '\x2', '\x2', '\x1CB', '\x1CD', '\x5', 'V', ',', '\x2', '\x1CC', + '\x1CA', '\x3', '\x2', '\x2', '\x2', '\x1CD', '\x1D0', '\x3', '\x2', '\x2', + '\x2', '\x1CE', '\x1CC', '\x3', '\x2', '\x2', '\x2', '\x1CE', '\x1CF', + '\x3', '\x2', '\x2', '\x2', '\x1CF', 'U', '\x3', '\x2', '\x2', '\x2', + '\x1D0', '\x1CE', '\x3', '\x2', '\x2', '\x2', '\x1D1', '\x1D2', '\a', + '\x42', '\x2', '\x2', '\x1D2', '\x1D3', '\a', '\v', '\x2', '\x2', '\x1D3', + '\x1D4', '\x5', '.', '\x18', '\x2', '\x1D4', 'W', '\x3', '\x2', '\x2', + '\x2', '\x1D5', '\x1D6', '\t', '\t', '\x2', '\x2', '\x1D6', 'Y', '\x3', + '\x2', '\x2', '\x2', '\x1D7', '\x1D8', '\t', '\n', '\x2', '\x2', '\x1D8', + '[', '\x3', '\x2', '\x2', '\x2', '/', '\x61', '\x64', 'g', 'j', 'm', 'q', + 't', '~', '\x8A', '\x90', '\x98', '\x9B', '\xA1', '\xA8', '\xAD', '\xB3', + '\xC1', '\xC3', '\xD6', '\xDB', '\xEC', '\xF3', '\xFE', '\x100', '\x107', + '\x10F', '\x111', '\x116', '\x11F', '\x124', '\x14C', '\x14E', '\x165', + '\x16F', '\x174', '\x199', '\x1A3', '\x1A5', '\x1AA', '\x1AF', '\x1B6', + '\x1BC', '\x1BF', '\x1C6', '\x1CE', }; public static readonly ATN _ATN = diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/CosmosQueryExecutionContextFactory.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/CosmosQueryExecutionContextFactory.cs index a7f7f17934..e276466f9d 100644 --- a/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/CosmosQueryExecutionContextFactory.cs +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/CosmosQueryExecutionContextFactory.cs @@ -214,7 +214,7 @@ private static async Task> TryCreateCoreContextAsy List targetRanges = await cosmosQueryContext.QueryClient.GetTargetPartitionKeyRangesByEpkStringAsync( cosmosQueryContext.ResourceLink, containerQueryProperties.ResourceId, - inputParameters.PartitionKey.Value.InternalKey.GetEffectivePartitionKeyString(partitionKeyDefinition), + containerQueryProperties.EffectivePartitionKeyString, forceRefresh: false, createQueryPipelineTrace); @@ -779,7 +779,7 @@ private static Documents.PartitionKeyDefinition GetPartitionKeyDefinition(InputP targetRanges = await cosmosQueryContext.QueryClient.GetTargetPartitionKeyRangesByEpkStringAsync( cosmosQueryContext.ResourceLink, containerQueryProperties.ResourceId, - inputParameters.PartitionKey.Value.InternalKey.GetEffectivePartitionKeyString(partitionKeyDefinition), + containerQueryProperties.EffectivePartitionKeyString, forceRefresh: false, trace); } @@ -1004,6 +1004,12 @@ public override bool Visit(SqlExistsScalarExpression sqlExistsScalarExpression) return false; } + public override bool Visit(SqlFirstScalarExpression sqlFirstScalarExpression) + { + // No need to worry about aggregates within the subquery (they will recursively get rewritten). + return false; + } + public override bool Visit(SqlFunctionCallScalarExpression sqlFunctionCallScalarExpression) { return !sqlFunctionCallScalarExpression.IsUdf && @@ -1021,6 +1027,12 @@ public override bool Visit(SqlInScalarExpression sqlInScalarExpression) return hasAggregates; } + public override bool Visit(SqlLastScalarExpression sqlLastScalarExpression) + { + // No need to worry about aggregates within the subquery (they will recursively get rewritten). + return false; + } + public override bool Visit(SqlLiteralScalarExpression sqlLiteralScalarExpression) { return false; diff --git a/Microsoft.Azure.Cosmos/src/Query/v3Query/QueryIterator.cs b/Microsoft.Azure.Cosmos/src/Query/v3Query/QueryIterator.cs index a820a0a49a..7dfcea9818 100644 --- a/Microsoft.Azure.Cosmos/src/Query/v3Query/QueryIterator.cs +++ b/Microsoft.Azure.Cosmos/src/Query/v3Query/QueryIterator.cs @@ -129,9 +129,9 @@ public static QueryIterator Create( default: throw new ArgumentOutOfRangeException($"Unknown {nameof(ExecutionEnvironment)}: {queryRequestOptions.ExecutionEnvironment.Value}."); - } - - CosmosQueryExecutionContextFactory.InputParameters inputParameters = new CosmosQueryExecutionContextFactory.InputParameters( + } + + CosmosQueryExecutionContextFactory.InputParameters inputParameters = new CosmosQueryExecutionContextFactory.InputParameters( sqlQuerySpec: sqlQuerySpec, initialUserContinuationToken: requestContinuationToken, initialFeedRange: feedRangeInternal, diff --git a/Microsoft.Azure.Cosmos/src/RMResources.Designer.cs b/Microsoft.Azure.Cosmos/src/RMResources.Designer.cs index bdb2de33b0..294ed6c3ad 100644 --- a/Microsoft.Azure.Cosmos/src/RMResources.Designer.cs +++ b/Microsoft.Azure.Cosmos/src/RMResources.Designer.cs @@ -612,6 +612,50 @@ internal static string DeserializationError } } + /// + /// Looks up a localized string similar to The given default identity for {0} is not valid. The format for the default identity is not valid, please use 'FirstPartyIdentity'/'SystemAssignedIdentity'/'UserAssignedIdentity=<UA_resource_id>'. + /// + internal static string DefaultIdentityNotValidFormat + { + get + { + return ResourceManager.GetString("DefaultIdentityNotValidFormat", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The given default identity for {0} is not valid. The default identity points to a delegated identity that does not exist in {0}.. + /// + internal static string DefaultIdentityWithoutCorrespondingDelegatedIdentity + { + get + { + return ResourceManager.GetString("DefaultIdentityWithoutCorrespondingDelegatedIdentity", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The given default identity for {0} is not valid. The default identity points to a system identity that does not exist in {0}.. + /// + internal static string DefaultIdentityWithoutCorrespondingSystemIdentity + { + get + { + return ResourceManager.GetString("DefaultIdentityWithoutCorrespondingSystemIdentity", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The given default identity for {0} is not valid. The default identity points to an user identity that does not exist in {0}.. + /// + internal static string DefaultIdentityWithoutCorrespondingUserIdentity + { + get + { + return ResourceManager.GetString("DefaultIdentityWithoutCorrespondingUserIdentity", resourceCulture); + } + } + /// /// Looks up a localized string similar to DNS resolution failed.. /// @@ -1343,6 +1387,18 @@ internal static string InvalidFailoverPriority } } + + /// + /// Looks up a localized string similar to Federation cap action is not currently supported. + /// + internal static string InvalidFederationCapAction + { + get + { + return ResourceManager.GetString("InvalidFederationCapAction", resourceCulture); + } + } + /// /// Looks up a localized string similar to Value '{0}' specified for the header '{1}' is invalid. . /// @@ -2747,6 +2803,17 @@ internal static string RbacMissingUserId } } + /// + /// Looks up a localized string similar to Request is blocked because ResourceId [{0}] cannot be resolved. Principal = [{1}], Action = [{2}], ResourceType = [{3}].. + /// + internal static string RbacCannotResolveResourceRid + { + get + { + return ResourceManager.GetString("RbacCannotResolveResourceRid", resourceCulture); + } + } + /// /// Looks up a localized string similar to Read Quorum size of {0} is not met for the request.. /// @@ -3319,6 +3386,149 @@ internal static string CrossTenantCMKDatabaseAccountLogstoreFeaturesNotSupported } } + /// + /// Looks up a localized string similar to The server encountered an unexpected condition that prevented it from fulfilling the Azure Key Vault resource request. + /// + internal static string UnexpectedExceptionCaughtonKeyVaultAccessClient + { + get + { + return ResourceManager.GetString("UnexpectedExceptionCaughtonKeyVaultAccessClient", resourceCulture); + } + } + + /// + /// The expected scope array should be of length 1. Instead received scope with length {0}. + /// + internal static string InvalidMSALScopeLength + { + get + { + return ResourceManager.GetString("InvalidMSALScopeLength", resourceCulture); + } + } + + /// + /// The requested scope is not a well formed URI string. + /// + internal static string InvalidRequestedScopeFormat + { + get + { + return ResourceManager.GetString("InvalidRequestedScopeFormat", resourceCulture); + } + } + + /// + /// The requested scope is not https. + /// + internal static string InvalidSchemeInScope + { + get + { + return ResourceManager.GetString("InvalidSchemeInScope", resourceCulture); + } + } + + /// + /// The requested scope contains unexpected segments. + /// + internal static string InvalildScopeSegments + { + get + { + return ResourceManager.GetString("InvalildScopeSegments", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Error contacting the Azure Key Vault resource. Please try again. + /// + internal static string KeyVaultServiceUnavailable + { + get + { + return ResourceManager.GetString("KeyVaultServiceUnavailable", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The provided Azure Key Vault resource key URI is invalid. Please follow the format: https://{vault-name}.vault.azure.net/keys/{key-name} or https://{vault-name}.vault.azure.net/certificates/{certificate-name} or https://{vault-name}.vault.azure.net/secrets/{secret-name} . + /// + internal static string InvalidKeyVaultKeyAndCertURI + { + get + { + return ResourceManager.GetString("InvalidKeyVaultKeyAndCertURI", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The provided Azure Key Vault resource key URI is invalid. Please follow the format: https://{vault-name}.vault.azure.net/secrets/{secret-name} . + /// + internal static string InvalidKeyVaulSecretURI + { + get + { + return ResourceManager.GetString("InvalidKeyVaulSecretURI", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The remote name could not be resolved for the Azure Key Vault resource. Please provide a valid URI for an existing Key vault. + /// + internal static string KeyVaultDNSNotResolved + { + get + { + return ResourceManager.GetString("KeyVaultDNSNotResolved", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Could not find any secret with the.pem extension related to the provided certificate. + /// + internal static string KeyVaultCertificateException + { + get + { + return ResourceManager.GetString("KeyVaultCertificateException", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The Input provided is not a valid base 64 string. + /// + internal static string KeyVaultInvalidInputBytes + { + get + { + return ResourceManager.GetString("KeyVaultInvalidInputBytes", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Failed to acquire the access token needed to access the Azure Key Vault resource. Please verify that the tenant has all corresponding permissions assigned. + /// + internal static string KeyVaultAadClientCredentialsGrantFailure + { + get + { + return ResourceManager.GetString("KeyVaultAadClientCredentialsGrantFailure", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The Status Code for the first Azure Key Vault resource access try should be Unauthorized. + /// + internal static string FirstKeyVaultAccessAttemptShouldBeUnauthorized + { + get + { + return ResourceManager.GetString("FirstKeyVaultAccessAttemptShouldBeUnauthorized", resourceCulture); + } + } + /// /// Looks up a localized string similar to Network timeout or connectivity failure. /// @@ -4332,5 +4542,27 @@ internal static string PhysicalPartitionIdinTargetOrSourceDoesNotExist return ResourceManager.GetString("PhysicalPartitionIdinTargetOrSourceDoesNotExist", resourceCulture); } } + + /// + /// Looks up a localized string similar to Collection name '{0}' is invalid for MongoDB API.. + /// + internal static string InvalidMongoCollectionName + { + get + { + return ResourceManager.GetString("InvalidMongoCollectionName", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Database name '{0}' is invalid for MongoDB API.. + /// + internal static string InvalidMongoDatabaseName + { + get + { + return ResourceManager.GetString("InvalidMongoDatabaseName", resourceCulture); + } + } } } \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/RMResources.resx b/Microsoft.Azure.Cosmos/src/RMResources.resx index 2cf687e8e4..a630919dc0 100644 --- a/Microsoft.Azure.Cosmos/src/RMResources.resx +++ b/Microsoft.Azure.Cosmos/src/RMResources.resx @@ -1,17 +1,17 @@  - @@ -586,7 +586,7 @@ The value of offer throughput specified exceeded supported maximum throughput for Fixed size container. Please enter value less than {0}. - For containers migrated from fixed to unlimited, scale operation can be performed only if the container has documents populated with partition key. Please retry the throughput scale operation after populating documents with partition key. + For containers migrated from fixed to unlimited, scale operation can be performed only if the container has documents populated with partition key. Please retry the throughput scale operation after populating documents with partition key. Please see https://aka.ms/migrate-to-partitioned-collection for more information. The value of offer throughput specified is invalid. Please specify a value between {0} and {1} inclusive in increments of {2}. Please contact https://azure.microsoft.com/support to request limit increases beyond {1} RU/s. @@ -1033,9 +1033,6 @@ If you would like to serve this query through continuation tokens, then please r Zone Redundant Accounts are not supported in {0} Location yet. Please try other locations. - - Serverless accounts do not support analytics storage(i.e. EnableAnalyticsStorage=true). - Serverless accounts do not support multiple write locations(i.e. EnableMultipleWriteLocations=true). @@ -1229,12 +1226,30 @@ If you would like to serve this query through continuation tokens, then please r Unexpected status code for first Azure Key Vault Access. First request to get Azure Key Vault metadata should always return Unauthorized. - + + The expected scope array should be of length 1. Instead received scope with length {0}. + + + The requested scope is not a well formed URI string. + + + The requested scope is not https. + + + The requested scope contains unexpected segments. + + Cannot perform failover as it is disabled for the account. This partition key definition kind is not supported for partial partition key operations + + Collection name '{0}' is invalid for MongoDB API. + + + Database name '{0}' is invalid for MongoDB API. + There cannot be duplicate physical partition ids in x-ms-cosmos-target-partition-throughput-info header. @@ -1307,4 +1322,19 @@ If you would like to serve this query through continuation tokens, then please r Cross-tenant CMK is not supported with System Assigned identities as Default identities. Please use an User Assigned Identity instead. + + Federation cap action is not currently supported. + + + The given default identity for {0} is not valid. The format for the default identity is not valid, please use 'FirstPartyIdentity'/'SystemAssignedIdentity'/'UserAssignedIdentity=<UA_resource_id>' + + + The given default identity for {0} is not valid. The default identity points to a delegated identity that does not exist in {0}. + + + The given default identity for {0} is not valid. The default identity points to a system identity that does not exist in {0}. + + + The given default identity for {0} is not valid. The default identity points to an user identity that does not exist in {0}. + \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/ReadManyQueryHelper.cs b/Microsoft.Azure.Cosmos/src/ReadManyQueryHelper.cs index e69476129c..6ebcda267c 100644 --- a/Microsoft.Azure.Cosmos/src/ReadManyQueryHelper.cs +++ b/Microsoft.Azure.Cosmos/src/ReadManyQueryHelper.cs @@ -249,10 +249,13 @@ private QueryDefinition CreateReadManyQueryDefinitionForId(List<(string, Partiti { int totalItemCount = Math.Min(items.Count, startIndex + this.maxItemsPerQuery); StringBuilder queryStringBuilder = new StringBuilder(); + SqlParameterCollection sqlParameters = new SqlParameterCollection(); queryStringBuilder.Append("SELECT * FROM c WHERE c.id IN ( "); for (int i = startIndex; i < totalItemCount; i++) { - queryStringBuilder.Append($"'{items[i].Item1}'"); + string idParamName = "@param_id" + i; + sqlParameters.Add(new SqlParameter(idParamName, items[i].Item1)); + queryStringBuilder.Append(idParamName); if (i < totalItemCount - 1) { queryStringBuilder.Append(","); @@ -260,7 +263,8 @@ private QueryDefinition CreateReadManyQueryDefinitionForId(List<(string, Partiti } queryStringBuilder.Append(" )"); - return new QueryDefinition(queryStringBuilder.ToString()); + return QueryDefinition.CreateFromQuerySpec(new SqlQuerySpec(queryStringBuilder.ToString(), + sqlParameters)); } private QueryDefinition CreateReadManyQueryDefinitionForOther(List<(string, PartitionKey)> items, diff --git a/Microsoft.Azure.Cosmos/src/Resource/Container/ContainerCore.Items.cs b/Microsoft.Azure.Cosmos/src/Resource/Container/ContainerCore.Items.cs index 0018eca9b7..a694b78019 100644 --- a/Microsoft.Azure.Cosmos/src/Resource/Container/ContainerCore.Items.cs +++ b/Microsoft.Azure.Cosmos/src/Resource/Container/ContainerCore.Items.cs @@ -505,14 +505,11 @@ public override IOrderedQueryable GetItemLinqQueryable( { requestOptions ??= new QueryRequestOptions(); - if (linqSerializerOptions == null && this.ClientContext.ClientOptions != null) + if (linqSerializerOptions == null && this.ClientContext.ClientOptions.SerializerOptions != null) { linqSerializerOptions = new CosmosLinqSerializerOptions { - PropertyNamingPolicy = this.ClientContext.ClientOptions.SerializerOptions != null - ? this.ClientContext.ClientOptions.SerializerOptions.PropertyNamingPolicy - : CosmosPropertyNamingPolicy.Default, - CustomCosmosSerializer = this.ClientContext.ClientOptions.Serializer + PropertyNamingPolicy = this.ClientContext.ClientOptions.SerializerOptions.PropertyNamingPolicy }; } @@ -959,12 +956,6 @@ private async Task ExtractPartitionKeyAndProcessItemStreamAsync // User specified PK value, no need to extract it if (partitionKey.HasValue) { - PartitionKeyDefinition pKeyDefinition = await this.GetPartitionKeyDefinitionAsync(); - if (partitionKey.HasValue && partitionKey.Value != PartitionKey.None && partitionKey.Value.InternalKey.Components.Count != pKeyDefinition.Paths.Count) - { - throw new ArgumentException(RMResources.MissingPartitionKeyValue); - } - return await this.ProcessItemStreamAsync( partitionKey, itemId, diff --git a/Microsoft.Azure.Cosmos/src/Resource/Database/Database.cs b/Microsoft.Azure.Cosmos/src/Resource/Database/Database.cs index a59dcb8be9..8a62f9ec56 100644 --- a/Microsoft.Azure.Cosmos/src/Resource/Database/Database.cs +++ b/Microsoft.Azure.Cosmos/src/Resource/Database/Database.cs @@ -31,8 +31,8 @@ public abstract class Database /// public abstract CosmosClient Client { get; } - /// - /// Reads a from the Azure Cosmos service as an asynchronous operation. + /// + /// Reads a from the Azure Cosmos service as an asynchronous operation. /// /// (Optional) The options for the request. /// (Optional) representing request cancellation. @@ -40,6 +40,9 @@ public abstract class Database /// A containing a which wraps a containing the read resource record. /// /// https://aka.ms/cosmosdb-dot-net-exceptions + /// + /// contains the that include the resource information. + /// /// /// /// /// Operations for reading or deleting an existing database. /// @@ -219,7 +216,6 @@ public async Task CreateContainerIfNotExistsAsync( nameof(containerProperties.PartitionKey)); } } -#if PREVIEW else { IReadOnlyList retrivedPartitionKeyPaths = retrivedContainerResponse.Resource.PartitionKeyPaths; @@ -236,7 +232,7 @@ public async Task CreateContainerIfNotExistsAsync( nameof(containerProperties.PartitionKey)); } } -#endif + return retrivedContainerResponse; } } diff --git a/Microsoft.Azure.Cosmos/src/Resource/Settings/ContainerProperties.cs b/Microsoft.Azure.Cosmos/src/Resource/Settings/ContainerProperties.cs index b95efb99c8..94cb93cff5 100644 --- a/Microsoft.Azure.Cosmos/src/Resource/Settings/ContainerProperties.cs +++ b/Microsoft.Azure.Cosmos/src/Resource/Settings/ContainerProperties.cs @@ -112,14 +112,8 @@ public ContainerProperties(string id, string partitionKeyPath) /// Initializes a new instance of the class for the Azure Cosmos DB service. /// /// The Id of the resource in the Azure Cosmos service. - /// The path to the partition key. Example: /location -#if PREVIEW - public -#else - internal -#endif - - ContainerProperties(string id, IReadOnlyList partitionKeyPaths) + /// The paths of the hierarchical partition keys. Example: ["/tenantId", "/userId"] + public ContainerProperties(string id, IReadOnlyList partitionKeyPaths) { this.Id = id; @@ -347,12 +341,11 @@ public string PartitionKeyPath { get { -#if PREVIEW if (this.PartitionKey?.Kind == PartitionKind.MultiHash && this.PartitionKey?.Paths.Count > 1) { - throw new NotImplementedException($"This MultiHash collection has more than 1 partition key path please use `PartitionKeyPaths`"); + throw new NotImplementedException($"This subpartitioned container has more than 1 partition key path please use `PartitionKeyPaths`"); } -#endif + return this.PartitionKey?.Paths != null && this.PartitionKey.Paths.Count > 0 ? this.PartitionKey?.Paths[0] : null; } set @@ -377,15 +370,10 @@ public string PartitionKeyPath } /// - /// JSON path used for containers partitioning + /// List of JSON paths used for containers with hierarchical partition keys /// [JsonIgnore] -#if PREVIEW - public -#else - internal -#endif - IReadOnlyList PartitionKeyPaths + public IReadOnlyList PartitionKeyPaths { get => this.PartitionKey?.Paths; set @@ -657,12 +645,10 @@ internal IReadOnlyList> PartitionKeyPathTokens throw new ArgumentOutOfRangeException($"Container {this.Id} is not partitioned"); } -#if PREVIEW if (this.PartitionKey.Kind == Documents.PartitionKind.MultiHash && this.PartitionKeyPaths == null) { throw new ArgumentOutOfRangeException($"Container {this.Id} is not partitioned"); } -#endif List> partitionKeyPathTokensList = new List>(); foreach (string path in this.PartitionKey?.Paths) diff --git a/Microsoft.Azure.Cosmos/src/Routing/AsyncCacheNonBlocking.cs b/Microsoft.Azure.Cosmos/src/Routing/AsyncCacheNonBlocking.cs index 452eb161c3..9fb908d83f 100644 --- a/Microsoft.Azure.Cosmos/src/Routing/AsyncCacheNonBlocking.cs +++ b/Microsoft.Azure.Cosmos/src/Routing/AsyncCacheNonBlocking.cs @@ -124,7 +124,7 @@ public async Task GetAsync( key: key, initialValue: initialLazyValue, callbackDelegate: singleValueInitFunc, - operationName: "GetAsync"); + operationName: nameof(GetAsync)); } // The AsyncLazyWithRefreshTask is lazy and won't create the task until GetValue is called. @@ -193,7 +193,7 @@ await this.UpdateCacheAndGetValueFromBackgroundTaskAsync( key: key, initialValue: initialLazyValue, callbackDelegate: singleValueInitFunc, - operationName: "RefreshAsync"); + operationName: nameof(RefreshAsync)); } } @@ -308,7 +308,7 @@ public async Task CreateAndWaitForBackgroundRefreshTaskAsync( Func> createRefreshTask) { this.cancellationToken.ThrowIfCancellationRequested(); - + // The original task is still being created. Just return the original task. Task valueSnapshot = this.value; if (AsyncLazyWithRefreshTask.IsTaskRunning(valueSnapshot)) diff --git a/Microsoft.Azure.Cosmos/src/Routing/GatewayAddressCache.cs b/Microsoft.Azure.Cosmos/src/Routing/GatewayAddressCache.cs index b577443761..eba425fb0d 100644 --- a/Microsoft.Azure.Cosmos/src/Routing/GatewayAddressCache.cs +++ b/Microsoft.Azure.Cosmos/src/Routing/GatewayAddressCache.cs @@ -387,7 +387,13 @@ private static void LogPartitionCacheRefresh( } } - public void TryRemoveAddresses( + /// + /// Marks the to Unhealthy that matches with the faulted + /// server key. + /// + /// An instance of that contains the host and + /// port of the backend replica. + public async Task MarkAddressesToUnhealthyAsync( ServerKey serverKey) { if (serverKey == null) @@ -395,7 +401,7 @@ public void TryRemoveAddresses( throw new ArgumentNullException(nameof(serverKey)); } - if (this.serverPartitionAddressToPkRangeIdMap.TryRemove(serverKey, out HashSet pkRangeIds)) + if (this.serverPartitionAddressToPkRangeIdMap.TryGetValue(serverKey, out HashSet pkRangeIds)) { PartitionKeyRangeIdentity[] pkRangeIdsCopy; lock (pkRangeIds) @@ -405,36 +411,35 @@ public void TryRemoveAddresses( foreach (PartitionKeyRangeIdentity pkRangeId in pkRangeIdsCopy) { - DefaultTrace.TraceInformation("Remove addresses for collectionRid :{0}, pkRangeId: {1}, serviceEndpoint: {2}", - pkRangeId.CollectionRid, - pkRangeId.PartitionKeyRangeId, - this.serviceEndpoint); - - this.serverPartitionAddressCache.TryRemove(pkRangeId); - } - } - } - - public async Task UpdateAsync( - PartitionKeyRangeIdentity partitionKeyRangeIdentity, - CancellationToken cancellationToken) - { - if (partitionKeyRangeIdentity == null) - { - throw new ArgumentNullException(nameof(partitionKeyRangeIdentity)); - } - - cancellationToken.ThrowIfCancellationRequested(); - - return await this.serverPartitionAddressCache.GetAsync( - key: partitionKeyRangeIdentity, + // The forceRefresh flag is set to true for the callback delegate is because, if the GetAsync() from the async + // non-blocking cache fails to look up the pkRangeId, then there are some inconsistency present in the cache, and it is + // more safe to do a force refresh to fetch the addresses from the gateway, instead of fetching it from the cache itself. + // Please note that, the chances of encountering such scenario is highly unlikely. + PartitionAddressInformation addressInfo = await this.serverPartitionAddressCache.GetAsync( + key: pkRangeId, singleValueInitFunc: (_) => this.GetAddressesForRangeIdAsync( null, cachedAddresses: null, - partitionKeyRangeIdentity.CollectionRid, - partitionKeyRangeIdentity.PartitionKeyRangeId, + pkRangeId.CollectionRid, + pkRangeId.PartitionKeyRangeId, forceRefresh: true), - forceRefresh: (_) => true); + forceRefresh: (_) => false); + + IReadOnlyList transportAddresses = addressInfo.Get(Protocol.Tcp)?.ReplicaTransportAddressUris; + foreach (TransportAddressUri address in from TransportAddressUri transportAddress in transportAddresses + where serverKey.Equals(transportAddress.ReplicaServerKey) + select transportAddress) + { + DefaultTrace.TraceInformation("Marking a backend replica to Unhealthy for collectionRid :{0}, pkRangeId: {1}, serviceEndpoint: {2}, transportAddress: {3}", + pkRangeId.CollectionRid, + pkRangeId.PartitionKeyRangeId, + this.serviceEndpoint, + address.ToString()); + + address.SetUnhealthy(); + } + } + } } private async Task> ResolveMasterAsync(DocumentServiceRequest request, bool forceRefresh) diff --git a/Microsoft.Azure.Cosmos/src/Routing/GlobalAddressResolver.cs b/Microsoft.Azure.Cosmos/src/Routing/GlobalAddressResolver.cs index 51a6c6d2f3..344f994395 100644 --- a/Microsoft.Azure.Cosmos/src/Routing/GlobalAddressResolver.cs +++ b/Microsoft.Azure.Cosmos/src/Routing/GlobalAddressResolver.cs @@ -228,33 +228,16 @@ public async Task ResolveAsync( } public async Task UpdateAsync( - IReadOnlyList addressCacheTokens, - CancellationToken cancellationToken) - { - List tasks = new List(); - - foreach (AddressCacheToken cacheToken in addressCacheTokens) - { - if (this.addressCacheByEndpoint.TryGetValue(cacheToken.ServiceEndpoint, out EndpointCache endpointCache)) - { - tasks.Add(endpointCache.AddressCache.UpdateAsync(cacheToken.PartitionKeyRangeIdentity, cancellationToken)); - } - } - - await Task.WhenAll(tasks); - } - - public Task UpdateAsync( ServerKey serverKey, CancellationToken cancellationToken) { foreach (KeyValuePair addressCache in this.addressCacheByEndpoint) { - // since we don't know which address cache contains the pkRanges mapped to this node, we do a tryRemove on all AddressCaches of all regions - addressCache.Value.AddressCache.TryRemoveAddresses(serverKey); + // since we don't know which address cache contains the pkRanges mapped to this node, + // we mark all transport uris that has the same server key to unhealthy status in the + // AddressCaches of all regions. + await addressCache.Value.AddressCache.MarkAddressesToUnhealthyAsync(serverKey); } - - return Task.CompletedTask; } /// diff --git a/Microsoft.Azure.Cosmos/src/Serializer/CosmosLinqSerializerOptions.cs b/Microsoft.Azure.Cosmos/src/Serializer/CosmosLinqSerializerOptions.cs index 0affdde976..b7523b2c6a 100644 --- a/Microsoft.Azure.Cosmos/src/Serializer/CosmosLinqSerializerOptions.cs +++ b/Microsoft.Azure.Cosmos/src/Serializer/CosmosLinqSerializerOptions.cs @@ -22,15 +22,6 @@ public CosmosLinqSerializerOptions() this.PropertyNamingPolicy = CosmosPropertyNamingPolicy.Default; } - /// - /// Gets or sets the user defined customer serializer. If no customer serializer was defined, - /// then the value is set to the default value - /// - /// - /// The default value is null - /// - internal CosmosSerializer CustomCosmosSerializer { get; set; } - /// /// Gets or sets whether the naming policy used to convert a string-based name to another format, /// such as a camel-casing format. diff --git a/Microsoft.Azure.Cosmos/src/SqlObjects/SqlFirstScalarExpression.cs b/Microsoft.Azure.Cosmos/src/SqlObjects/SqlFirstScalarExpression.cs new file mode 100644 index 0000000000..556da872e8 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/SqlObjects/SqlFirstScalarExpression.cs @@ -0,0 +1,40 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.SqlObjects +{ + using System; + using Microsoft.Azure.Cosmos.SqlObjects.Visitors; + +#if INTERNAL +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member +#pragma warning disable SA1600 // Elements should be documented + public +#else + internal +#endif + sealed class SqlFirstScalarExpression : SqlScalarExpression + { + private SqlFirstScalarExpression(SqlQuery subquery) + { + this.Subquery = subquery ?? throw new ArgumentNullException(nameof(subquery)); + } + + public SqlQuery Subquery { get; } + + public static SqlFirstScalarExpression Create(SqlQuery subquery) => new SqlFirstScalarExpression(subquery); + + public override void Accept(SqlObjectVisitor visitor) => visitor.Visit(this); + + public override TResult Accept(SqlObjectVisitor visitor) => visitor.Visit(this); + + public override TResult Accept(SqlObjectVisitor visitor, T input) => visitor.Visit(this, input); + + public override void Accept(SqlScalarExpressionVisitor visitor) => visitor.Visit(this); + + public override TResult Accept(SqlScalarExpressionVisitor visitor) => visitor.Visit(this); + + public override TResult Accept(SqlScalarExpressionVisitor visitor, T input) => visitor.Visit(this, input); + } +} diff --git a/Microsoft.Azure.Cosmos/src/SqlObjects/SqlLastScalarExpression.cs b/Microsoft.Azure.Cosmos/src/SqlObjects/SqlLastScalarExpression.cs new file mode 100644 index 0000000000..36707d1c80 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/SqlObjects/SqlLastScalarExpression.cs @@ -0,0 +1,40 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.SqlObjects +{ + using System; + using Microsoft.Azure.Cosmos.SqlObjects.Visitors; + +#if INTERNAL +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member +#pragma warning disable SA1600 // Elements should be documented + public +#else + internal +#endif + sealed class SqlLastScalarExpression : SqlScalarExpression + { + private SqlLastScalarExpression(SqlQuery subquery) + { + this.Subquery = subquery ?? throw new ArgumentNullException(nameof(subquery)); + } + + public SqlQuery Subquery { get; } + + public static SqlLastScalarExpression Create(SqlQuery subquery) => new SqlLastScalarExpression(subquery); + + public override void Accept(SqlObjectVisitor visitor) => visitor.Visit(this); + + public override TResult Accept(SqlObjectVisitor visitor) => visitor.Visit(this); + + public override TResult Accept(SqlObjectVisitor visitor, T input) => visitor.Visit(this, input); + + public override void Accept(SqlScalarExpressionVisitor visitor) => visitor.Visit(this); + + public override TResult Accept(SqlScalarExpressionVisitor visitor) => visitor.Visit(this); + + public override TResult Accept(SqlScalarExpressionVisitor visitor, T input) => visitor.Visit(this, input); + } +} diff --git a/Microsoft.Azure.Cosmos/src/SqlObjects/Visitors/SqlObjectEqualityVisitor.cs b/Microsoft.Azure.Cosmos/src/SqlObjects/Visitors/SqlObjectEqualityVisitor.cs index 3a9bf01970..8d7770ba9e 100644 --- a/Microsoft.Azure.Cosmos/src/SqlObjects/Visitors/SqlObjectEqualityVisitor.cs +++ b/Microsoft.Azure.Cosmos/src/SqlObjects/Visitors/SqlObjectEqualityVisitor.cs @@ -231,6 +231,21 @@ public override bool Visit(SqlExistsScalarExpression first, SqlObject secondAsOb return true; } + public override bool Visit(SqlFirstScalarExpression first, SqlObject secondAsObject) + { + if (!(secondAsObject is SqlFirstScalarExpression second)) + { + return false; + } + + if (!Equals(first.Subquery, second.Subquery)) + { + return false; + } + + return true; + } + public override bool Visit(SqlFromClause first, SqlObject secondAsObject) { if (!(secondAsObject is SqlFromClause second)) @@ -386,6 +401,21 @@ public override bool Visit(SqlJoinCollectionExpression first, SqlObject secondAs return true; } + public override bool Visit(SqlLastScalarExpression first, SqlObject secondAsObject) + { + if (!(secondAsObject is SqlLastScalarExpression second)) + { + return false; + } + + if (!Equals(first.Subquery, second.Subquery)) + { + return false; + } + + return true; + } + public override bool Visit(SqlLikeScalarExpression first, SqlObject secondAsObject) { if (!(secondAsObject is SqlLikeScalarExpression second)) diff --git a/Microsoft.Azure.Cosmos/src/SqlObjects/Visitors/SqlObjectHasher.cs b/Microsoft.Azure.Cosmos/src/SqlObjects/Visitors/SqlObjectHasher.cs index dfbab84bc0..f4f55009ec 100644 --- a/Microsoft.Azure.Cosmos/src/SqlObjects/Visitors/SqlObjectHasher.cs +++ b/Microsoft.Azure.Cosmos/src/SqlObjects/Visitors/SqlObjectHasher.cs @@ -25,6 +25,7 @@ internal sealed class SqlObjectHasher : SqlObjectVisitor private const int SqlCoalesceScalarExpressionHashCode = -1400659633; private const int SqlConditionalScalarExpressionHashCode = -421337832; private const int SqlExistsScalarExpressionHashCode = 1168675587; + private const int SqlFirstScalarExpressionHashCode = -754458752; private const int SqlFromClauseHashCode = 52588336; private const int SqlFunctionCallScalarExpressionHashCode = 496783446; private const int SqlFunctionCallScalarExpressionUdfHashCode = 1547906315; @@ -35,6 +36,7 @@ internal sealed class SqlObjectHasher : SqlObjectVisitor private const int SqlInScalarExpressionHashCode = 1439386783; private const int SqlInScalarExpressionNotHashCode = -1131398119; private const int SqlJoinCollectionExpressionHashCode = 1000382226; + private const int SqlLastScalarExpressionHashCode = 2018370813; private const int SqlLikeScalarExpressionHashCode = 317861; private const int SqlLimitSpecHashCode = 92601316; private const int SqlLiteralScalarExpressionHashCode = -158339101; @@ -207,6 +209,13 @@ public override int Visit(SqlExistsScalarExpression sqlExistsScalarExpression) return hashCode; } + public override int Visit(SqlFirstScalarExpression sqlFirstScalarExpression) + { + int hashCode = SqlFirstScalarExpressionHashCode; + hashCode = CombineHashes(hashCode, sqlFirstScalarExpression.Subquery.Accept(this)); + return hashCode; + } + public override int Visit(SqlFromClause sqlFromClause) { int hashCode = SqlFromClauseHashCode; @@ -298,6 +307,13 @@ public override int Visit(SqlJoinCollectionExpression sqlJoinCollectionExpressio return hashCode; } + public override int Visit(SqlLastScalarExpression sqlLastScalarExpression) + { + int hashCode = SqlLastScalarExpressionHashCode; + hashCode = CombineHashes(hashCode, sqlLastScalarExpression.Subquery.Accept(this)); + return hashCode; + } + public override int Visit(SqlLimitSpec sqlObject) { int hashCode = SqlLimitSpecHashCode; diff --git a/Microsoft.Azure.Cosmos/src/SqlObjects/Visitors/SqlObjectObfuscator.cs b/Microsoft.Azure.Cosmos/src/SqlObjects/Visitors/SqlObjectObfuscator.cs index 5e6faaef45..2120f16567 100644 --- a/Microsoft.Azure.Cosmos/src/SqlObjects/Visitors/SqlObjectObfuscator.cs +++ b/Microsoft.Azure.Cosmos/src/SqlObjects/Visitors/SqlObjectObfuscator.cs @@ -46,7 +46,7 @@ public override SqlObject Visit(SqlAliasedCollectionExpression sqlAliasedCollect public override SqlObject Visit(SqlAllScalarExpression sqlAllScalarExpression) { - return SqlExistsScalarExpression.Create(sqlAllScalarExpression.Subquery.Accept(this) as SqlQuery); + return SqlAllScalarExpression.Create(sqlAllScalarExpression.Subquery.Accept(this) as SqlQuery); } public override SqlObject Visit(SqlArrayCreateScalarExpression sqlArrayCreateScalarExpression) @@ -115,6 +115,11 @@ public override SqlObject Visit(SqlExistsScalarExpression sqlExistsScalarExpress return SqlExistsScalarExpression.Create(sqlExistsScalarExpression.Subquery.Accept(this) as SqlQuery); } + public override SqlObject Visit(SqlFirstScalarExpression sqlFirstScalarExpression) + { + return SqlFirstScalarExpression.Create(sqlFirstScalarExpression.Subquery.Accept(this) as SqlQuery); + } + public override SqlObject Visit(SqlFromClause sqlFromClause) { return SqlFromClause.Create(sqlFromClause.Expression.Accept(this) as SqlCollectionExpression); @@ -189,6 +194,11 @@ public override SqlObject Visit(SqlJoinCollectionExpression sqlJoinCollectionExp sqlJoinCollectionExpression.Right.Accept(this) as SqlCollectionExpression); } + public override SqlObject Visit(SqlLastScalarExpression sqlLastScalarExpression) + { + return SqlLastScalarExpression.Create(sqlLastScalarExpression.Subquery.Accept(this) as SqlQuery); + } + public override SqlObject Visit(SqlLikeScalarExpression sqlLikeScalarExpression) { return SqlLikeScalarExpression.Create( diff --git a/Microsoft.Azure.Cosmos/src/SqlObjects/Visitors/SqlObjectTextSerializer.cs b/Microsoft.Azure.Cosmos/src/SqlObjects/Visitors/SqlObjectTextSerializer.cs index 75076e512c..a29435744d 100644 --- a/Microsoft.Azure.Cosmos/src/SqlObjects/Visitors/SqlObjectTextSerializer.cs +++ b/Microsoft.Azure.Cosmos/src/SqlObjects/Visitors/SqlObjectTextSerializer.cs @@ -154,6 +154,14 @@ public override void Visit(SqlExistsScalarExpression sqlExistsScalarExpression) this.WriteEndContext(")"); } + public override void Visit(SqlFirstScalarExpression sqlFirstScalarExpression) + { + this.writer.Write("FIRST"); + this.WriteStartContext("("); + sqlFirstScalarExpression.Subquery.Accept(this); + this.WriteEndContext(")"); + } + public override void Visit(SqlFromClause sqlFromClause) { this.writer.Write("FROM "); @@ -284,6 +292,14 @@ public override void Visit(SqlJoinCollectionExpression sqlJoinCollectionExpressi sqlJoinCollectionExpression.Right.Accept(this); } + public override void Visit(SqlLastScalarExpression sqlLastScalarExpression) + { + this.writer.Write("LAST"); + this.WriteStartContext("("); + sqlLastScalarExpression.Subquery.Accept(this); + this.WriteEndContext(")"); + } + public override void Visit(SqlLimitSpec sqlObject) { this.writer.Write("LIMIT "); diff --git a/Microsoft.Azure.Cosmos/src/SqlObjects/Visitors/SqlObjectVisitor.cs b/Microsoft.Azure.Cosmos/src/SqlObjects/Visitors/SqlObjectVisitor.cs index d8d8899395..3dfe3a9193 100644 --- a/Microsoft.Azure.Cosmos/src/SqlObjects/Visitors/SqlObjectVisitor.cs +++ b/Microsoft.Azure.Cosmos/src/SqlObjects/Visitors/SqlObjectVisitor.cs @@ -24,6 +24,7 @@ abstract class SqlObjectVisitor public abstract void Visit(SqlCoalesceScalarExpression sqlObject); public abstract void Visit(SqlConditionalScalarExpression sqlObject); public abstract void Visit(SqlExistsScalarExpression sqlObject); + public abstract void Visit(SqlFirstScalarExpression sqlObject); public abstract void Visit(SqlFromClause sqlObject); public abstract void Visit(SqlFunctionCallScalarExpression sqlObject); public abstract void Visit(SqlGroupByClause sqlObject); @@ -32,6 +33,7 @@ abstract class SqlObjectVisitor public abstract void Visit(SqlInputPathCollection sqlObject); public abstract void Visit(SqlInScalarExpression sqlObject); public abstract void Visit(SqlJoinCollectionExpression sqlObject); + public abstract void Visit(SqlLastScalarExpression sqlObject); public abstract void Visit(SqlLikeScalarExpression sqlObject); public abstract void Visit(SqlLimitSpec sqlObject); public abstract void Visit(SqlLiteralScalarExpression sqlObject); diff --git a/Microsoft.Azure.Cosmos/src/SqlObjects/Visitors/SqlObjectVisitor{TArg,TOutput}.cs b/Microsoft.Azure.Cosmos/src/SqlObjects/Visitors/SqlObjectVisitor{TArg,TOutput}.cs index 3ba9878ae6..449cd6adaf 100644 --- a/Microsoft.Azure.Cosmos/src/SqlObjects/Visitors/SqlObjectVisitor{TArg,TOutput}.cs +++ b/Microsoft.Azure.Cosmos/src/SqlObjects/Visitors/SqlObjectVisitor{TArg,TOutput}.cs @@ -24,6 +24,7 @@ abstract class SqlObjectVisitor public abstract TOutput Visit(SqlCoalesceScalarExpression sqlObject, TArg input); public abstract TOutput Visit(SqlConditionalScalarExpression sqlObject, TArg input); public abstract TOutput Visit(SqlExistsScalarExpression sqlObject, TArg input); + public abstract TOutput Visit(SqlFirstScalarExpression sqlObject, TArg input); public abstract TOutput Visit(SqlFromClause sqlObject, TArg input); public abstract TOutput Visit(SqlFunctionCallScalarExpression sqlObject, TArg input); public abstract TOutput Visit(SqlGroupByClause sqlObject, TArg input); @@ -32,6 +33,7 @@ abstract class SqlObjectVisitor public abstract TOutput Visit(SqlInputPathCollection sqlObject, TArg input); public abstract TOutput Visit(SqlInScalarExpression sqlObject, TArg input); public abstract TOutput Visit(SqlJoinCollectionExpression sqlObject, TArg input); + public abstract TOutput Visit(SqlLastScalarExpression sqlObject, TArg input); public abstract TOutput Visit(SqlLikeScalarExpression sqlObject, TArg input); public abstract TOutput Visit(SqlLimitSpec sqlObject, TArg input); public abstract TOutput Visit(SqlLiteralScalarExpression sqlObject, TArg input); diff --git a/Microsoft.Azure.Cosmos/src/SqlObjects/Visitors/SqlObjectVisitor{TResult}.cs b/Microsoft.Azure.Cosmos/src/SqlObjects/Visitors/SqlObjectVisitor{TResult}.cs index 6f0ce75e99..3d1000a171 100644 --- a/Microsoft.Azure.Cosmos/src/SqlObjects/Visitors/SqlObjectVisitor{TResult}.cs +++ b/Microsoft.Azure.Cosmos/src/SqlObjects/Visitors/SqlObjectVisitor{TResult}.cs @@ -24,6 +24,7 @@ abstract class SqlObjectVisitor public abstract TResult Visit(SqlCoalesceScalarExpression sqlObject); public abstract TResult Visit(SqlConditionalScalarExpression sqlObject); public abstract TResult Visit(SqlExistsScalarExpression sqlObject); + public abstract TResult Visit(SqlFirstScalarExpression sqlObject); public abstract TResult Visit(SqlFromClause sqlObject); public abstract TResult Visit(SqlFunctionCallScalarExpression sqlObject); public abstract TResult Visit(SqlGroupByClause sqlObject); @@ -31,6 +32,7 @@ abstract class SqlObjectVisitor public abstract TResult Visit(SqlIdentifierPathExpression sqlObject); public abstract TResult Visit(SqlInputPathCollection sqlObject); public abstract TResult Visit(SqlJoinCollectionExpression sqlObject); + public abstract TResult Visit(SqlLastScalarExpression sqlObject); public abstract TResult Visit(SqlLikeScalarExpression sqlObject); public abstract TResult Visit(SqlInScalarExpression sqlObject); public abstract TResult Visit(SqlLimitSpec sqlObject); diff --git a/Microsoft.Azure.Cosmos/src/SqlObjects/Visitors/SqlScalarExpressionVisitor.cs b/Microsoft.Azure.Cosmos/src/SqlObjects/Visitors/SqlScalarExpressionVisitor.cs index 8e6e75b7f0..d807395055 100644 --- a/Microsoft.Azure.Cosmos/src/SqlObjects/Visitors/SqlScalarExpressionVisitor.cs +++ b/Microsoft.Azure.Cosmos/src/SqlObjects/Visitors/SqlScalarExpressionVisitor.cs @@ -20,8 +20,10 @@ abstract class SqlScalarExpressionVisitor public abstract void Visit(SqlCoalesceScalarExpression scalarExpression); public abstract void Visit(SqlConditionalScalarExpression scalarExpression); public abstract void Visit(SqlExistsScalarExpression scalarExpression); + public abstract void Visit(SqlFirstScalarExpression scalarExpression); public abstract void Visit(SqlFunctionCallScalarExpression scalarExpression); public abstract void Visit(SqlInScalarExpression scalarExpression); + public abstract void Visit(SqlLastScalarExpression scalarExpression); public abstract void Visit(SqlLikeScalarExpression scalarExpression); public abstract void Visit(SqlLiteralScalarExpression scalarExpression); public abstract void Visit(SqlMemberIndexerScalarExpression scalarExpression); diff --git a/Microsoft.Azure.Cosmos/src/SqlObjects/Visitors/SqlScalarExpressionVisitor{TArg,TOutput}.cs b/Microsoft.Azure.Cosmos/src/SqlObjects/Visitors/SqlScalarExpressionVisitor{TArg,TOutput}.cs index ff5cdbc019..256482b151 100644 --- a/Microsoft.Azure.Cosmos/src/SqlObjects/Visitors/SqlScalarExpressionVisitor{TArg,TOutput}.cs +++ b/Microsoft.Azure.Cosmos/src/SqlObjects/Visitors/SqlScalarExpressionVisitor{TArg,TOutput}.cs @@ -21,8 +21,10 @@ abstract class SqlScalarExpressionVisitor public abstract TOutput Visit(SqlCoalesceScalarExpression scalarExpression, TArg input); public abstract TOutput Visit(SqlConditionalScalarExpression scalarExpression, TArg input); public abstract TOutput Visit(SqlExistsScalarExpression scalarExpression, TArg input); + public abstract TOutput Visit(SqlFirstScalarExpression scalarExpression, TArg input); public abstract TOutput Visit(SqlFunctionCallScalarExpression scalarExpression, TArg input); public abstract TOutput Visit(SqlInScalarExpression scalarExpression, TArg input); + public abstract TOutput Visit(SqlLastScalarExpression scalarExpression, TArg input); public abstract TOutput Visit(SqlLikeScalarExpression scalarExpression, TArg input); public abstract TOutput Visit(SqlLiteralScalarExpression scalarExpression, TArg input); public abstract TOutput Visit(SqlMemberIndexerScalarExpression scalarExpression, TArg input); diff --git a/Microsoft.Azure.Cosmos/src/SqlObjects/Visitors/SqlScalarExpressionVisitor{TResult}.cs b/Microsoft.Azure.Cosmos/src/SqlObjects/Visitors/SqlScalarExpressionVisitor{TResult}.cs index bdc7b5f04f..e419b9758d 100644 --- a/Microsoft.Azure.Cosmos/src/SqlObjects/Visitors/SqlScalarExpressionVisitor{TResult}.cs +++ b/Microsoft.Azure.Cosmos/src/SqlObjects/Visitors/SqlScalarExpressionVisitor{TResult}.cs @@ -21,8 +21,10 @@ abstract class SqlScalarExpressionVisitor public abstract TResult Visit(SqlCoalesceScalarExpression scalarExpression); public abstract TResult Visit(SqlConditionalScalarExpression scalarExpression); public abstract TResult Visit(SqlExistsScalarExpression scalarExpression); + public abstract TResult Visit(SqlFirstScalarExpression scalarExpression); public abstract TResult Visit(SqlFunctionCallScalarExpression scalarExpression); public abstract TResult Visit(SqlInScalarExpression scalarExpression); + public abstract TResult Visit(SqlLastScalarExpression scalarExpression); public abstract TResult Visit(SqlLikeScalarExpression scalarExpression); public abstract TResult Visit(SqlLiteralScalarExpression scalarExpression); public abstract TResult Visit(SqlMemberIndexerScalarExpression scalarExpression); diff --git a/Microsoft.Azure.Cosmos/src/Telemetry/ClientTelemetry.cs b/Microsoft.Azure.Cosmos/src/Telemetry/ClientTelemetry.cs index 3f124e2ee0..d0ca7d8ac8 100644 --- a/Microsoft.Azure.Cosmos/src/Telemetry/ClientTelemetry.cs +++ b/Microsoft.Azure.Cosmos/src/Telemetry/ClientTelemetry.cs @@ -8,8 +8,6 @@ namespace Microsoft.Azure.Cosmos.Telemetry using System.Collections.Concurrent; using System.Collections.Generic; using System.Net; - using System.Net.Http; - using System.Text; using System.Threading; using System.Threading.Tasks; using Handler; @@ -17,11 +15,11 @@ namespace Microsoft.Azure.Cosmos.Telemetry using Microsoft.Azure.Cosmos.Core.Trace; using Microsoft.Azure.Cosmos.Routing; using Microsoft.Azure.Cosmos.Telemetry.Models; + using Microsoft.Azure.Cosmos.Tracing; + using Microsoft.Azure.Cosmos.Tracing.TraceData; using Microsoft.Azure.Documents; - using Microsoft.Azure.Documents.Collections; - using Microsoft.Azure.Documents.Rntbd; - using Newtonsoft.Json; using Util; + using static Microsoft.Azure.Cosmos.Tracing.TraceData.ClientSideRequestStatisticsTraceDatum; /// /// This class collects and send all the telemetry information. @@ -33,12 +31,10 @@ internal class ClientTelemetry : IDisposable { private const int allowedNumberOfFailures = 3; - private static readonly Uri endpointUrl = ClientTelemetryOptions.GetClientTelemetryEndpoint(); private static readonly TimeSpan observingWindow = ClientTelemetryOptions.GetScheduledTimeSpan(); private readonly ClientTelemetryProperties clientTelemetryInfo; - private readonly CosmosHttpClient httpClient; - private readonly AuthorizationTokenProvider tokenProvider; + private readonly ClientTelemetryProcessor processor; private readonly DiagnosticsHandlerHelper diagnosticsHelper; private readonly CancellationTokenSource cancellationTokenSource; @@ -53,6 +49,9 @@ internal class ClientTelemetry : IDisposable private ConcurrentDictionary cacheRefreshInfoMap = new ConcurrentDictionary(); + private ConcurrentDictionary requestInfoMap + = new ConcurrentDictionary(); + private int numberOfFailures = 0; /// @@ -102,7 +101,7 @@ public static ClientTelemetry CreateAndStartBackgroundTelemetry( return clientTelemetry; } - private ClientTelemetry( + internal ClientTelemetry( string clientId, CosmosHttpClient httpClient, string userAgent, @@ -112,9 +111,8 @@ private ClientTelemetry( IReadOnlyList preferredRegions, GlobalEndpointManager globalEndpointManager) { - this.httpClient = httpClient ?? throw new ArgumentNullException(nameof(httpClient)); this.diagnosticsHelper = diagnosticsHelper ?? throw new ArgumentNullException(nameof(diagnosticsHelper)); - this.tokenProvider = authorizationTokenProvider ?? throw new ArgumentNullException(nameof(authorizationTokenProvider)); + this.processor = new ClientTelemetryProcessor(httpClient, authorizationTokenProvider); this.clientTelemetryInfo = new ClientTelemetryProperties( clientId: clientId, @@ -164,6 +162,7 @@ private async Task EnrichAndSendAsync() await Task.Delay(observingWindow, this.cancellationTokenSource.Token); + this.clientTelemetryInfo.DateTimeUtc = DateTime.UtcNow.ToString(ClientTelemetryOptions.DateFormat); this.clientTelemetryInfo.MachineId = VmMetadataApiHandler.GetMachineId(); // Load host information from cache @@ -171,33 +170,42 @@ private async Task EnrichAndSendAsync() this.clientTelemetryInfo.ApplicationRegion = vmInformation?.Location; this.clientTelemetryInfo.HostEnvInfo = ClientTelemetryOptions.GetHostInformation(vmInformation); - // If cancellation is requested after the delay then return from here. - if (this.cancellationTokenSource.IsCancellationRequested) - { - DefaultTrace.TraceInformation("Observer Task Cancelled."); - - break; - } - - this.RecordSystemUtilization(); - - this.clientTelemetryInfo.DateTimeUtc = DateTime.UtcNow.ToString(ClientTelemetryOptions.DateFormat); + this.clientTelemetryInfo.SystemInfo = ClientTelemetryHelper.RecordSystemUtilization(this.diagnosticsHelper, + this.clientTelemetryInfo.IsDirectConnectionMode); - ConcurrentDictionary operationInfoSnapshot + // Take the copy for further processing i.e. serializing and dividing into chunks + ConcurrentDictionary operationInfoSnapshot = Interlocked.Exchange(ref this.operationInfoMap, new ConcurrentDictionary()); ConcurrentDictionary cacheRefreshInfoSnapshot - = Interlocked.Exchange(ref this.cacheRefreshInfoMap, new ConcurrentDictionary()); + = Interlocked.Exchange(ref this.cacheRefreshInfoMap, new ConcurrentDictionary()); - this.clientTelemetryInfo.OperationInfo = ClientTelemetryHelper.ToListWithMetricsInfo(operationInfoSnapshot); - this.clientTelemetryInfo.CacheRefreshInfo = ClientTelemetryHelper.ToListWithMetricsInfo(cacheRefreshInfoSnapshot); + ConcurrentDictionary requestInfoSnapshot + = Interlocked.Exchange(ref this.requestInfoMap, new ConcurrentDictionary()); - await this.SendAsync(); + try + { + await this.processor + .ProcessAndSendAsync( + clientTelemetryInfo: this.clientTelemetryInfo, + operationInfoSnapshot: operationInfoSnapshot, + cacheRefreshInfoSnapshot: cacheRefreshInfoSnapshot, + requestInfoSnapshot: requestInfoSnapshot, + cancellationToken: this.cancellationTokenSource.Token); + + this.numberOfFailures = 0; + } + catch (Exception ex) + { + this.numberOfFailures++; + + DefaultTrace.TraceError("Telemetry Job Processor failed with error : {0}", ex); + } } } catch (Exception ex) { - DefaultTrace.TraceError("Exception in EnrichAndSendAsync() : {0}", ex.Message); + DefaultTrace.TraceError("Exception in EnrichAndSendAsync() : {0}", ex); } DefaultTrace.TraceInformation("Telemetry Job Stopped."); @@ -223,7 +231,7 @@ internal void CollectCacheInfo(string cacheRefreshSource, throw new ArgumentNullException(nameof(cacheRefreshSource)); } - DefaultTrace.TraceVerbose($"Collecting cacheRefreshSource {cacheRefreshSource} data for Telemetry."); + DefaultTrace.TraceVerbose($"Collecting cacheRefreshSource {0} data for Telemetry.", cacheRefreshSource); string regionsContacted = ClientTelemetryHelper.GetContactedRegions(regionsContactedList); @@ -249,7 +257,7 @@ internal void CollectCacheInfo(string cacheRefreshSource, } catch (Exception ex) { - DefaultTrace.TraceError("Latency Recording Failed by Telemetry. Exception : {0}", ex.Message); + DefaultTrace.TraceError("Latency Recording Failed by Telemetry. Exception : {0}", ex); } } @@ -266,6 +274,7 @@ internal void CollectCacheInfo(string cacheRefreshSource, /// /// /// + /// internal void CollectOperationInfo(CosmosDiagnostics cosmosDiagnostics, HttpStatusCode statusCode, long responseSizeInBytes, @@ -275,7 +284,8 @@ internal void CollectOperationInfo(CosmosDiagnostics cosmosDiagnostics, ResourceType resourceType, string consistencyLevel, double requestCharge, - SubStatusCodes subStatusCode) + SubStatusCodes subStatusCode, + ITrace trace) { DefaultTrace.TraceVerbose("Collecting Operation data for Telemetry."); @@ -284,6 +294,10 @@ internal void CollectOperationInfo(CosmosDiagnostics cosmosDiagnostics, throw new ArgumentNullException(nameof(cosmosDiagnostics)); } + // Record Network/Replica Information + SummaryDiagnostics summaryDiagnostics = new SummaryDiagnostics(trace); + this.RecordRntbdResponses(containerId, databaseId, summaryDiagnostics.StoreResponseStatistics.Value); + string regionsContacted = ClientTelemetryHelper.GetContactedRegions(cosmosDiagnostics.GetContactedRegions()); // Recording Request Latency and Request Charge @@ -307,10 +321,10 @@ internal void CollectOperationInfo(CosmosDiagnostics cosmosDiagnostics, try { latency.RecordValue(cosmosDiagnostics.GetClientElapsedTime().Ticks); - } + } catch (Exception ex) { - DefaultTrace.TraceError("Latency Recording Failed by Telemetry. Exception : {0}", ex.Message); + DefaultTrace.TraceError("Latency Recording Failed by Telemetry. Exception : {0}", ex); } long requestChargeToRecord = (long)(requestCharge * ClientTelemetryOptions.HistogramPrecisionFactor); @@ -320,130 +334,41 @@ internal void CollectOperationInfo(CosmosDiagnostics cosmosDiagnostics, } catch (Exception ex) { - DefaultTrace.TraceError("Request Charge Recording Failed by Telemetry. Request Charge Value : {0} Exception : {1} ", requestChargeToRecord, ex.Message); + DefaultTrace.TraceError("Request Charge Recording Failed by Telemetry. Request Charge Value : {0} Exception : {1} ", requestChargeToRecord, ex); } } /// - /// Record CPU and memory usage which will be sent as part of telemetry information + /// Records RNTBD calls statistics /// - private void RecordSystemUtilization() - { - try - { - DefaultTrace.TraceVerbose("Started Recording System Usage for telemetry."); - - SystemUsageHistory systemUsageHistory = this.diagnosticsHelper.GetClientTelemetrySystemHistory(); - - if (systemUsageHistory != null ) - { - ClientTelemetryHelper.RecordSystemUsage( - systemUsageHistory: systemUsageHistory, - systemInfoCollection: this.clientTelemetryInfo.SystemInfo, - isDirectConnectionMode: this.clientTelemetryInfo.IsDirectConnectionMode); - } - else - { - DefaultTrace.TraceWarning("System Usage History not available"); - } - } - catch (Exception ex) - { - DefaultTrace.TraceError("System Usage Recording Error : {0}", ex.Message); - } - } - - /// - /// Task to send telemetry information to configured Juno endpoint. - /// If endpoint is not configured then it won't even try to send information. It will just trace an error message. - /// In any case it resets the telemetry information to collect the latest one. - /// - /// Async Task - private async Task SendAsync() + /// + /// + /// + private void RecordRntbdResponses(string containerId, string databaseId, List storeResponseStatistics) { - if (endpointUrl == null) + foreach (StoreResponseStatistics storetatistics in storeResponseStatistics) { - DefaultTrace.TraceError("Telemetry is enabled but endpoint is not configured"); - return; - } - - try - { - DefaultTrace.TraceInformation("Sending Telemetry Data to {0}", endpointUrl.AbsoluteUri); - - string json = JsonConvert.SerializeObject(this.clientTelemetryInfo, ClientTelemetryOptions.JsonSerializerSettings); - - using HttpRequestMessage request = new HttpRequestMessage + if (ClientTelemetryOptions.IsEligible((int)storetatistics.StoreResult.StatusCode, (int)storetatistics.StoreResult.SubStatusCode, storetatistics.RequestLatency)) { - Method = HttpMethod.Post, - RequestUri = endpointUrl, - Content = new StringContent(json, Encoding.UTF8, "application/json") - }; - - async ValueTask CreateRequestMessage() - { - INameValueCollection headersCollection = new StoreResponseNameValueCollection(); - await this.tokenProvider.AddAuthorizationHeaderAsync( - headersCollection, - endpointUrl, - "POST", - AuthorizationTokenType.PrimaryMasterKey); - - foreach (string key in headersCollection.AllKeys()) - { - request.Headers.Add(key, headersCollection[key]); - } - - request.Headers.Add(HttpConstants.HttpHeaders.DatabaseAccountName, this.clientTelemetryInfo.GlobalDatabaseAccountName); - String envName = ClientTelemetryOptions.GetEnvironmentName(); - if (!String.IsNullOrEmpty(envName)) + RequestInfo requestInfo = new RequestInfo() { - request.Headers.Add(HttpConstants.HttpHeaders.EnvironmentName, envName); - } - - return request; + DatabaseName = databaseId, + ContainerName = containerId, + Uri = storetatistics.StoreResult.StorePhysicalAddress.ToString(), + StatusCode = (int)storetatistics.StoreResult.StatusCode, + SubStatusCode = (int)storetatistics.StoreResult.SubStatusCode, + Resource = storetatistics.RequestResourceType.ToString(), + Operation = storetatistics.RequestOperationType.ToString(), + }; + + LongConcurrentHistogram latencyHist = this.requestInfoMap.GetOrAdd(requestInfo, x => new LongConcurrentHistogram(ClientTelemetryOptions.RequestLatencyMin, + ClientTelemetryOptions.RequestLatencyMax, + ClientTelemetryOptions.RequestLatencyPrecision)); + latencyHist.RecordValue(storetatistics.RequestLatency.Ticks); } - - using HttpResponseMessage response = await this.httpClient.SendHttpAsync(CreateRequestMessage, - ResourceType.Telemetry, - HttpTimeoutPolicyNoRetry.Instance, - null, - this.cancellationTokenSource.Token); - - if (!response.IsSuccessStatusCode) - { - this.numberOfFailures++; - - DefaultTrace.TraceError("Juno API response not successful. Status Code : {0}, Message : {1}", response.StatusCode, response.ReasonPhrase); - } - else - { - this.numberOfFailures = 0; // Ressetting failure counts on success call. - DefaultTrace.TraceInformation("Telemetry data sent successfully."); - } - - } - catch (Exception ex) - { - this.numberOfFailures++; - - DefaultTrace.TraceError("Exception while sending telemetry data : {0}", ex.Message); - } - finally - { - // Reset SystemInfo Dictionary for new data. - this.Reset(); } } - /// - /// Reset all the operation, System Utilization and Cache refresh related collections - /// - private void Reset() - { - this.clientTelemetryInfo.SystemInfo.Clear(); - } - /// /// Dispose of cosmos client.It will get disposed with client so not making it thread safe. /// diff --git a/Microsoft.Azure.Cosmos/src/Telemetry/ClientTelemetryHelper.cs b/Microsoft.Azure.Cosmos/src/Telemetry/ClientTelemetryHelper.cs index dca2ef6b94..2399bcb9fb 100644 --- a/Microsoft.Azure.Cosmos/src/Telemetry/ClientTelemetryHelper.cs +++ b/Microsoft.Azure.Cosmos/src/Telemetry/ClientTelemetryHelper.cs @@ -6,15 +6,12 @@ namespace Microsoft.Azure.Cosmos.Telemetry using System; using System.Collections.Generic; using System.Linq; - using System.Net.Http; using System.Text; - using System.Threading; using System.Threading.Tasks; - using HdrHistogram; using Microsoft.Azure.Cosmos.Core.Trace; + using Microsoft.Azure.Cosmos.Handler; using Microsoft.Azure.Cosmos.Routing; using Microsoft.Azure.Cosmos.Telemetry.Models; - using Microsoft.Azure.Documents; using Microsoft.Azure.Documents.Rntbd; internal static class ClientTelemetryHelper @@ -49,87 +46,62 @@ internal static async Task SetAccountNameAsync(GlobalEndpoint /// /// /// - /// /// - internal static void RecordSystemUsage( + private static List RecordSystemUsage( SystemUsageHistory systemUsageHistory, - List systemInfoCollection, bool isDirectConnectionMode) { if (systemUsageHistory.Values == null) { - return; + return null; } DefaultTrace.TraceVerbose("System Usage recorded by telemetry is : {0}", systemUsageHistory); - - systemInfoCollection.Add(TelemetrySystemUsage.GetCpuInfo(systemUsageHistory.Values)); - systemInfoCollection.Add(TelemetrySystemUsage.GetMemoryRemainingInfo(systemUsageHistory.Values)); - systemInfoCollection.Add(TelemetrySystemUsage.GetAvailableThreadsInfo(systemUsageHistory.Values)); - systemInfoCollection.Add(TelemetrySystemUsage.GetThreadWaitIntervalInMs(systemUsageHistory.Values)); - systemInfoCollection.Add(TelemetrySystemUsage.GetThreadStarvationSignalCount(systemUsageHistory.Values)); + + List systemInfoCollection = new List(6) + { + TelemetrySystemUsage.GetCpuInfo(systemUsageHistory.Values), + TelemetrySystemUsage.GetMemoryRemainingInfo(systemUsageHistory.Values), + TelemetrySystemUsage.GetAvailableThreadsInfo(systemUsageHistory.Values), + TelemetrySystemUsage.GetThreadWaitIntervalInMs(systemUsageHistory.Values), + TelemetrySystemUsage.GetThreadStarvationSignalCount(systemUsageHistory.Values) + }; // Reset System Information if (isDirectConnectionMode) { systemInfoCollection.Add(TelemetrySystemUsage.GetTcpConnectionCount(systemUsageHistory.Values)); } + return systemInfoCollection; } - + /// - /// Convert map with operation information to list of operations along with request latency and request charge metrics + /// Record CPU and memory usage which will be sent as part of telemetry information /// - /// - /// Collection of ReportPayload - internal static List ToListWithMetricsInfo( - IDictionary metrics) + internal static List RecordSystemUtilization(DiagnosticsHandlerHelper helper, bool isDirectMode) { - DefaultTrace.TraceVerbose("Aggregating operation information to list started"); - - List payloadWithMetricInformation = new List(); - foreach (KeyValuePair entry in metrics) + try { - OperationInfo payloadForLatency = entry.Key; - payloadForLatency.MetricInfo = new MetricInfo(ClientTelemetryOptions.RequestLatencyName, ClientTelemetryOptions.RequestLatencyUnit); - payloadForLatency.SetAggregators(entry.Value.latency, ClientTelemetryOptions.TicksToMsFactor); + DefaultTrace.TraceVerbose("Started Recording System Usage for telemetry."); - payloadWithMetricInformation.Add(payloadForLatency); + SystemUsageHistory systemUsageHistory = helper.GetClientTelemetrySystemHistory(); - OperationInfo payloadForRequestCharge = payloadForLatency.Copy(); - payloadForRequestCharge.MetricInfo = new MetricInfo(ClientTelemetryOptions.RequestChargeName, ClientTelemetryOptions.RequestChargeUnit); - payloadForRequestCharge.SetAggregators(entry.Value.requestcharge, ClientTelemetryOptions.HistogramPrecisionFactor); - - payloadWithMetricInformation.Add(payloadForRequestCharge); + if (systemUsageHistory != null) + { + return ClientTelemetryHelper.RecordSystemUsage( + systemUsageHistory: systemUsageHistory, + isDirectConnectionMode: isDirectMode); + } + else + { + DefaultTrace.TraceWarning("System Usage History not available"); + } } - - DefaultTrace.TraceInformation("Aggregating operation information to list done"); - - return payloadWithMetricInformation; - } - - /// - /// Convert map with CacheRefreshInfo information to list of operations along with request latency and request charge metrics - /// - /// - /// Collection of ReportPayload - internal static List ToListWithMetricsInfo(IDictionary metrics) - { - DefaultTrace.TraceVerbose("Aggregating CacheRefreshInfo information to list started"); - - List payloadWithMetricInformation = new List(); - foreach (KeyValuePair entry in metrics) + catch (Exception ex) { - CacheRefreshInfo payloadForLatency = entry.Key; - payloadForLatency.MetricInfo = new MetricInfo(ClientTelemetryOptions.RequestLatencyName, ClientTelemetryOptions.RequestLatencyUnit); - payloadForLatency.SetAggregators(entry.Value, ClientTelemetryOptions.TicksToMsFactor); - - payloadWithMetricInformation.Add(payloadForLatency); + DefaultTrace.TraceError("System Usage Recording Error : {0} ", ex); } - - DefaultTrace.TraceVerbose("Aggregating CacheRefreshInfo information to list done"); - - return payloadWithMetricInformation; + return null; } /// diff --git a/Microsoft.Azure.Cosmos/src/Telemetry/ClientTelemetryOptions.cs b/Microsoft.Azure.Cosmos/src/Telemetry/ClientTelemetryOptions.cs index f114483b07..f2caaf50d5 100644 --- a/Microsoft.Azure.Cosmos/src/Telemetry/ClientTelemetryOptions.cs +++ b/Microsoft.Azure.Cosmos/src/Telemetry/ClientTelemetryOptions.cs @@ -4,11 +4,11 @@ namespace Microsoft.Azure.Cosmos.Telemetry { using System; + using System.Collections.Generic; using Microsoft.Azure.Cosmos.Core.Trace; using Microsoft.Azure.Cosmos.Telemetry.Models; using Microsoft.Azure.Documents; using Newtonsoft.Json; - using Util; internal static class ClientTelemetryOptions { @@ -18,7 +18,7 @@ internal static class ClientTelemetryOptions internal const int KbToMbFactor = 1024; internal const int OneKbToBytes = 1024; - + // Expecting histogram to have Minimum Latency of 1 and Maximum Latency of 1 hour (which is never going to happen) internal const long RequestLatencyMax = TimeSpan.TicksPerHour; internal const long RequestLatencyMin = 1; @@ -79,7 +79,7 @@ internal static class ClientTelemetryOptions 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"; @@ -87,17 +87,22 @@ internal static class ClientTelemetryOptions internal const string EnvPropsClientTelemetryEnvironmentName = "COSMOS.ENVIRONMENT_NAME"; internal static readonly ResourceType AllowedResourceTypes = ResourceType.Document; - + // Why 5 sec? As of now, if any network request is taking more than 5 millisecond sec, we will consider it slow request this value can be revisited in future + private static readonly TimeSpan NetworkLatencyThreshold = TimeSpan.FromMilliseconds(5); internal static readonly JsonSerializerSettings JsonSerializerSettings = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore, MaxDepth = 64, // https://github.com/advisories/GHSA-5crp-9r3c-p9vr }; + + private static readonly List ExcludedStatusCodes = new List { 404, 409 }; + + internal static int PayloadSizeThreshold = 1024 * 1024 * 2; // 2MB private static Uri clientTelemetryEndpoint; private static string environmentName; private static TimeSpan scheduledTimeSpan = TimeSpan.Zero; - + internal static bool IsClientTelemetryEnabled() { bool isTelemetryEnabled = ConfigurationManager @@ -175,5 +180,32 @@ internal static string GetEnvironmentName() } return environmentName; } + + /// + /// This method will return true if the request is failed with User or Server Exception and not excluded from telemetry. + /// This method will return true if the request latency is more than the threshold. + /// otherwise return false + /// + /// + /// + /// + /// true/false + internal static bool IsEligible(int statusCode, int subStatusCode, TimeSpan latencyInMs) + { + return + ClientTelemetryOptions.IsStatusCodeNotExcluded(statusCode, subStatusCode) && + (ClientTelemetryOptions.IsUserOrServerError(statusCode) || latencyInMs >= ClientTelemetryOptions.NetworkLatencyThreshold); + } + + private static bool IsUserOrServerError(int statusCode) + { + return statusCode >= 400 && statusCode <= 599; + } + + private static bool IsStatusCodeNotExcluded(int statusCode, int subStatusCode) + { + return !(ClientTelemetryOptions.ExcludedStatusCodes.Contains(statusCode) && subStatusCode == 0); + } + } } diff --git a/Microsoft.Azure.Cosmos/src/Telemetry/ClientTelemetryPayloadWriter.cs b/Microsoft.Azure.Cosmos/src/Telemetry/ClientTelemetryPayloadWriter.cs new file mode 100644 index 0000000000..1158c7d639 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Telemetry/ClientTelemetryPayloadWriter.cs @@ -0,0 +1,161 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Telemetry +{ + using System; + using System.Collections.Concurrent; + using System.Collections.Generic; + using System.IO; + using System.Linq; + using System.Text; + using System.Threading.Tasks; + using HdrHistogram; + using Microsoft.Azure.Cosmos.Telemetry.Models; + using Newtonsoft.Json; + + internal static class ClientTelemetryPayloadWriter + { + public static async Task SerializedPayloadChunksAsync( + ClientTelemetryProperties properties, + ConcurrentDictionary operationInfoSnapshot, + ConcurrentDictionary cacheRefreshInfoSnapshot, + ConcurrentDictionary requestInfoSnapshot, + Func callback) + { + if (properties == null) + { + throw new ArgumentNullException(nameof(properties)); + } + + StringBuilder stringBuilder = new StringBuilder(ClientTelemetryOptions.PayloadSizeThreshold); + + JsonWriter writer = ClientTelemetryPayloadWriter.GetWriterWithSectionStartTag(stringBuilder, properties, "operationInfo"); + + if (operationInfoSnapshot?.Any() == true) + { + foreach (KeyValuePair entry in operationInfoSnapshot) + { + long lengthNow = stringBuilder.Length; + + OperationInfo payloadForLatency = entry.Key; + payloadForLatency.MetricInfo = new MetricInfo(ClientTelemetryOptions.RequestLatencyName, ClientTelemetryOptions.RequestLatencyUnit); + payloadForLatency.SetAggregators(entry.Value.latency, ClientTelemetryOptions.TicksToMsFactor); + + OperationInfo payloadForRequestCharge = payloadForLatency.Copy(); + payloadForRequestCharge.MetricInfo = new MetricInfo(ClientTelemetryOptions.RequestChargeName, ClientTelemetryOptions.RequestChargeUnit); + payloadForRequestCharge.SetAggregators(entry.Value.requestcharge, ClientTelemetryOptions.HistogramPrecisionFactor); + + string latencyMetrics = JsonConvert.SerializeObject(payloadForLatency); + string requestChargeMetrics = JsonConvert.SerializeObject(payloadForRequestCharge); + + if (lengthNow + latencyMetrics.Length + requestChargeMetrics.Length > ClientTelemetryOptions.PayloadSizeThreshold) + { + writer.WriteEndArray(); + writer.WriteEndObject(); + + await callback.Invoke(stringBuilder.ToString()); + + writer = ClientTelemetryPayloadWriter.GetWriterWithSectionStartTag(stringBuilder, properties, "operationInfo"); + } + + writer.WriteRawValue(latencyMetrics); + writer.WriteRawValue(requestChargeMetrics); + } + + } + writer.WriteEndArray(); + + if (cacheRefreshInfoSnapshot?.Any() == true) + { + writer.WritePropertyName("cacheRefreshInfo"); + writer.WriteStartArray(); + + foreach (KeyValuePair entry in cacheRefreshInfoSnapshot) + { + long lengthNow = stringBuilder.Length; + + CacheRefreshInfo payloadForLatency = entry.Key; + payloadForLatency.MetricInfo = new MetricInfo(ClientTelemetryOptions.RequestLatencyName, ClientTelemetryOptions.RequestLatencyUnit); + payloadForLatency.SetAggregators(entry.Value, ClientTelemetryOptions.TicksToMsFactor); + + string latencyMetrics = JsonConvert.SerializeObject(payloadForLatency); + + if (lengthNow + latencyMetrics.Length > ClientTelemetryOptions.PayloadSizeThreshold) + { + writer.WriteEndArray(); + writer.WriteEndObject(); + + await callback.Invoke(stringBuilder.ToString()); + + writer = ClientTelemetryPayloadWriter.GetWriterWithSectionStartTag(stringBuilder, properties, "cacheRefreshInfo"); + } + + writer.WriteRawValue(latencyMetrics); + } + writer.WriteEndArray(); + + } + + if (requestInfoSnapshot?.Any() == true) + { + writer.WritePropertyName("requestInfo"); + writer.WriteStartArray(); + + foreach (KeyValuePair entry in requestInfoSnapshot) + { + long lengthNow = stringBuilder.Length; + + MetricInfo metricInfo = new MetricInfo(ClientTelemetryOptions.RequestLatencyName, ClientTelemetryOptions.RequestLatencyUnit); + metricInfo.SetAggregators(entry.Value, ClientTelemetryOptions.TicksToMsFactor); + + RequestInfo payloadForLatency = entry.Key; + payloadForLatency.Metrics.Add(metricInfo); + string latencyMetrics = JsonConvert.SerializeObject(payloadForLatency); + + if (lengthNow + latencyMetrics.Length > ClientTelemetryOptions.PayloadSizeThreshold) + { + writer.WriteEndArray(); + writer.WriteEndObject(); + + await callback.Invoke(stringBuilder.ToString()); + + writer = ClientTelemetryPayloadWriter.GetWriterWithSectionStartTag(stringBuilder, properties, "requestInfo"); + } + + writer.WriteRawValue(latencyMetrics); + } + writer.WriteEndArray(); + } + + writer.WriteEndObject(); + + await callback.Invoke(stringBuilder.ToString()); + } + + private static JsonWriter GetWriterWithSectionStartTag( + StringBuilder stringBuilder, + ClientTelemetryProperties properties, + string sectionName) + { + stringBuilder.Clear(); + + StringWriter stringWriter = new StringWriter(stringBuilder); + + JsonWriter writer = new JsonTextWriter(stringWriter) + { + AutoCompleteOnClose = false + }; + + writer.WriteStartObject(); + + properties.Write(writer); + + writer.WritePropertyName(sectionName); + + writer.WriteStartArray(); + return writer; + } + } +} diff --git a/Microsoft.Azure.Cosmos/src/Telemetry/ClientTelemetryProcessor.cs b/Microsoft.Azure.Cosmos/src/Telemetry/ClientTelemetryProcessor.cs new file mode 100644 index 0000000000..b91eb96832 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Telemetry/ClientTelemetryProcessor.cs @@ -0,0 +1,142 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Telemetry +{ + using System; + using System.Collections.Concurrent; + using System.Net.Http; + using System.Text; + using System.Threading; + using System.Threading.Tasks; + using HdrHistogram; + using Microsoft.Azure.Cosmos.Core.Trace; + using Microsoft.Azure.Cosmos.Telemetry.Models; + using Microsoft.Azure.Documents; + using Microsoft.Azure.Documents.Collections; + + internal class ClientTelemetryProcessor + { + private static readonly Uri endpointUrl = ClientTelemetryOptions.GetClientTelemetryEndpoint(); + + private readonly AuthorizationTokenProvider tokenProvider; + private readonly CosmosHttpClient httpClient; + + internal ClientTelemetryProcessor(CosmosHttpClient httpClient, AuthorizationTokenProvider tokenProvider) + { + this.httpClient = httpClient ?? throw new ArgumentNullException(nameof(httpClient)); + this.tokenProvider = tokenProvider ?? throw new ArgumentNullException(nameof(tokenProvider)); + } + + /// + /// It will create Task to process and send client telemetry payload to Client Telemetry Service. + /// + /// + /// + /// + /// + /// + /// Task + internal async Task ProcessAndSendAsync( + ClientTelemetryProperties clientTelemetryInfo, + ConcurrentDictionary operationInfoSnapshot, + ConcurrentDictionary cacheRefreshInfoSnapshot, + ConcurrentDictionary requestInfoSnapshot, + CancellationToken cancellationToken) + { + try + { + await ClientTelemetryPayloadWriter.SerializedPayloadChunksAsync( + properties: clientTelemetryInfo, + operationInfoSnapshot: operationInfoSnapshot, + cacheRefreshInfoSnapshot: cacheRefreshInfoSnapshot, + requestInfoSnapshot: requestInfoSnapshot, + callback: async (payload) => await this.SendAsync(clientTelemetryInfo.GlobalDatabaseAccountName, payload, cancellationToken)); + } + catch (Exception ex) + { + DefaultTrace.TraceError($"Exception while serializing telemetry payload: {ex}"); + throw; + } + + } + + /// + /// Task to send telemetry information to configured Juno endpoint. + /// If endpoint is not configured then it won't even try to send information. It will just trace an error message. + /// In any case it resets the telemetry information to collect the latest one. + /// + /// Async Task + private async Task SendAsync( + string globalDatabaseAccountName, + string jsonPayload, + CancellationToken cancellationToken) + { + if (endpointUrl == null) + { + DefaultTrace.TraceError("Telemetry is enabled but endpoint is not configured"); + return; + } + + try + { + DefaultTrace.TraceInformation("Sending Telemetry Data to {0}", endpointUrl.AbsoluteUri); + + using HttpRequestMessage request = new HttpRequestMessage + { + Method = HttpMethod.Post, + RequestUri = endpointUrl, + Content = new StringContent(jsonPayload, Encoding.UTF8, "application/json") + }; + + async ValueTask CreateRequestMessage() + { + INameValueCollection headersCollection = new StoreResponseNameValueCollection(); + await this.tokenProvider.AddAuthorizationHeaderAsync( + headersCollection, + endpointUrl, + "POST", + AuthorizationTokenType.PrimaryMasterKey); + + foreach (string key in headersCollection.AllKeys()) + { + request.Headers.Add(key, headersCollection[key]); + } + + request.Headers.Add(HttpConstants.HttpHeaders.DatabaseAccountName, globalDatabaseAccountName); + String envName = ClientTelemetryOptions.GetEnvironmentName(); + if (!String.IsNullOrEmpty(envName)) + { + request.Headers.Add(HttpConstants.HttpHeaders.EnvironmentName, envName); + } + + return request; + } + + using HttpResponseMessage response = await this.httpClient.SendHttpAsync(CreateRequestMessage, + ResourceType.Telemetry, + HttpTimeoutPolicyNoRetry.Instance, + null, + cancellationToken); + + if (!response.IsSuccessStatusCode) + { + DefaultTrace.TraceError("Telemetry Service API response not successful. Status Code : {0}, Message : {1}", response.StatusCode, response.ReasonPhrase); + throw new Exception(string.Format("Telemetry Service API response not successful. Status Code : {0}, Message : {1}", response.StatusCode, response.ReasonPhrase)); + } + else + { + DefaultTrace.TraceInformation("Telemetry data sent successfully."); + } + + } + catch (Exception ex) + { + DefaultTrace.TraceError("Exception while sending telemetry data : {0}", ex.Message); + throw; + } + } + + } +} diff --git a/Microsoft.Azure.Cosmos/src/Telemetry/Models/ClientTelemetryProperties.cs b/Microsoft.Azure.Cosmos/src/Telemetry/Models/ClientTelemetryProperties.cs index 87418ac8d7..22089191fd 100644 --- a/Microsoft.Azure.Cosmos/src/Telemetry/Models/ClientTelemetryProperties.cs +++ b/Microsoft.Azure.Cosmos/src/Telemetry/Models/ClientTelemetryProperties.cs @@ -60,6 +60,9 @@ internal sealed class ClientTelemetryProperties [JsonProperty(PropertyName = "operationInfo")] internal List OperationInfo { get; set; } + [JsonProperty(PropertyName = "requestInfo")] + internal List RequestInfo { get; set; } + [JsonIgnore] internal bool IsDirectConnectionMode { get; } @@ -97,6 +100,7 @@ public ClientTelemetryProperties(string dateTimeUtc, List systemInfo, List cacheRefreshInfo, List operationInfo, + List requestInfo, string machineId) { this.DateTimeUtc = dateTimeUtc; @@ -111,8 +115,81 @@ public ClientTelemetryProperties(string dateTimeUtc, this.SystemInfo = systemInfo; this.CacheRefreshInfo = cacheRefreshInfo; this.OperationInfo = operationInfo; + this.RequestInfo = requestInfo; this.PreferredRegions = preferredRegions; this.MachineId = machineId; } + + public void Write(JsonWriter writer) + { + writer.WritePropertyName("timeStamp"); + writer.WriteValue(this.DateTimeUtc); + + writer.WritePropertyName("clientId"); + writer.WriteValue(this.ClientId); + + writer.WritePropertyName("machineId"); + writer.WriteValue(this.MachineId); + + writer.WritePropertyName("processId"); + writer.WriteValue(this.ProcessId); + + writer.WritePropertyName("userAgent"); + writer.WriteValue(this.UserAgent); + + writer.WritePropertyName("connectionMode"); + writer.WriteValue(this.ConnectionMode); + + writer.WritePropertyName("globalDatabaseAccountName"); + writer.WriteValue(this.GlobalDatabaseAccountName); + + writer.WritePropertyName("applicationRegion"); + if (this.ApplicationRegion != null) + { + writer.WriteValue(this.ApplicationRegion); + } + else + { + writer.WriteNull(); + } + + writer.WritePropertyName("hostEnvInfo"); + writer.WriteValue(this.HostEnvInfo); + + writer.WritePropertyName("acceleratedNetworking"); + if (this.AcceleratedNetworking.HasValue) + { + writer.WriteValue(this.AcceleratedNetworking.Value); + } + else + { + writer.WriteNull(); + } + + writer.WritePropertyName("preferredRegions"); + + if (this.PreferredRegions != null) + { + writer.WriteStartArray(); + foreach (string region in this.PreferredRegions) + { + writer.WriteValue(region); + } + writer.WriteEndArray(); + } + else + { + writer.WriteNull(); + } + + writer.WritePropertyName("aggregationIntervalInSec"); + writer.WriteValue(this.AggregationIntervalInSec); + + if (this.SystemInfo != null && this.SystemInfo.Count > 0) + { + writer.WritePropertyName("systemInfo"); + writer.WriteRawValue(JsonConvert.SerializeObject(this.SystemInfo)); + } + } } } diff --git a/Microsoft.Azure.Cosmos/src/Telemetry/Models/RequestInfo.cs b/Microsoft.Azure.Cosmos/src/Telemetry/Models/RequestInfo.cs new file mode 100644 index 0000000000..d71f0fa446 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Telemetry/Models/RequestInfo.cs @@ -0,0 +1,66 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Telemetry.Models +{ + using System; + using System.Collections.Generic; + using Newtonsoft.Json; + + [Serializable] + internal sealed class RequestInfo + { + [JsonProperty("uri")] + public string Uri { get; set; } + + [JsonProperty("databaseName")] + public string DatabaseName { get; set; } + + [JsonProperty("containerName")] + public string ContainerName { get; set; } + + [JsonProperty("operation")] + public string Operation { get; set; } + + [JsonProperty("resource")] + public string Resource { get; set; } + + [JsonProperty("statusCode")] + public int? StatusCode { get; set; } + + [JsonProperty("subStatusCode")] + public int SubStatusCode { get; set; } + + [JsonProperty("metricInfo")] + public List Metrics { get; set; } = new List(); + + public override int GetHashCode() + { + int hash = 3; + hash = (hash * 7) ^ (this.Uri == null ? 0 : this.Uri.GetHashCode()); + hash = (hash * 7) ^ (this.DatabaseName == null ? 0 : this.DatabaseName.GetHashCode()); + hash = (hash * 7) ^ (this.ContainerName == null ? 0 : this.ContainerName.GetHashCode()); + hash = (hash * 7) ^ (this.Operation == null ? 0 : this.Operation.GetHashCode()); + hash = (hash * 7) ^ (this.Resource == null ? 0 : this.Resource.GetHashCode()); + hash = (hash * 7) ^ (this.StatusCode == null ? 0 : this.StatusCode.GetHashCode()); + hash = (hash * 7) ^ (this.SubStatusCode.GetHashCode()); + return hash; + } + + public override bool Equals(object obj) + { + bool isequal = obj is RequestInfo payload && + ((this.Uri == null && payload.Uri == null) || (this.Uri != null && payload.Uri != null && this.Uri.Equals(payload.Uri))) && + ((this.DatabaseName == null && payload.DatabaseName == null) || (this.DatabaseName != null && payload.DatabaseName != null && this.DatabaseName.Equals(payload.DatabaseName))) && + ((this.ContainerName == null && payload.ContainerName == null) || (this.ContainerName != null && payload.ContainerName != null && this.ContainerName.Equals(payload.ContainerName))) && + ((this.Operation == null && payload.Operation == null) || (this.Operation != null && payload.Operation != null && this.Operation.Equals(payload.Operation))) && + ((this.Resource == null && payload.Resource == null) || (this.Resource != null && payload.Resource != null && this.Resource.Equals(payload.Resource))) && + ((this.StatusCode == null && payload.StatusCode == null) || (this.StatusCode != null && payload.StatusCode != null && this.StatusCode.Equals(payload.StatusCode))) && + this.SubStatusCode.Equals(payload.SubStatusCode); + + return isequal; + } + + } +} diff --git a/Microsoft.Azure.Cosmos/src/Tracing/TraceData/ClientSideRequestStatisticsTraceDatum.cs b/Microsoft.Azure.Cosmos/src/Tracing/TraceData/ClientSideRequestStatisticsTraceDatum.cs index e4e160c13a..10845f133f 100644 --- a/Microsoft.Azure.Cosmos/src/Tracing/TraceData/ClientSideRequestStatisticsTraceDatum.cs +++ b/Microsoft.Azure.Cosmos/src/Tracing/TraceData/ClientSideRequestStatisticsTraceDatum.cs @@ -477,6 +477,7 @@ public StoreResponseStatistics( public string RequestSessionToken { get; } public Uri LocationEndpoint { get; } public bool IsSupplementalResponse { get; } + public TimeSpan RequestLatency => this.RequestResponseTime - this.RequestStartTime.GetValueOrDefault(); } public readonly struct HttpResponseStatistics diff --git a/Microsoft.Azure.Cosmos/src/Tracing/TraceData/SummaryDiagnostics.cs b/Microsoft.Azure.Cosmos/src/Tracing/TraceData/SummaryDiagnostics.cs index b01ddcfb77..1838cb72c5 100644 --- a/Microsoft.Azure.Cosmos/src/Tracing/TraceData/SummaryDiagnostics.cs +++ b/Microsoft.Azure.Cosmos/src/Tracing/TraceData/SummaryDiagnostics.cs @@ -8,25 +8,31 @@ namespace Microsoft.Azure.Cosmos.Tracing.TraceData using System.Collections.Generic; using System.Globalization; using Microsoft.Azure.Cosmos.Json; + using static Microsoft.Azure.Cosmos.Tracing.TraceData.ClientSideRequestStatisticsTraceDatum; internal struct SummaryDiagnostics { public SummaryDiagnostics(ITrace trace) : this() { - this.DirectRequestsSummary = new Lazy>(() => - new Dictionary<(int, int), int>()); - this.GatewayRequestsSummary = new Lazy>(() => - new Dictionary<(int, int), int>()); - this.AllRegionsContacted = new Lazy>(() => new HashSet()); + this.DirectRequestsSummary + = new Lazy>(() => new Dictionary<(int, int), int>()); + this.GatewayRequestsSummary + = new Lazy>(() => new Dictionary<(int, int), int>()); + this.AllRegionsContacted + = new Lazy>(() => new HashSet()); + this.CollectSummaryFromTraceTree(trace); } + public Lazy> AllRegionsNameContacted { get; private set; } = new Lazy>(() => new HashSet()); public Lazy> AllRegionsContacted { get; private set; } + public Lazy> StoreResponseStatistics { get; private set; } = new Lazy>(() => new List()); // Count of (StatusCode, SubStatusCode) tuples public Lazy> DirectRequestsSummary { get; private set; } + public Lazy> HttpResponseStatistics { get; private set; } = new Lazy>(() => new List()); public Lazy> GatewayRequestsSummary { get; private set; } private void CollectSummaryFromTraceTree(ITrace currentTrace) @@ -49,9 +55,10 @@ private void CollectSummaryFromTraceTree(ITrace currentTrace) private void AggregateRegionsContacted(HashSet<(string, Uri)> regionsContacted) { - foreach ((string _, Uri uri) in regionsContacted) + foreach ((string name, Uri uri) in regionsContacted) { this.AllRegionsContacted.Value.Add(uri); + this.AllRegionsNameContacted.Value.Add(name); } } @@ -59,6 +66,8 @@ private void AggregateGatewayStatistics(IReadOnlyList /// Condition to check Quorum(i.e. Strong) read with either an eventual consistency account or a consistent prefix account. /// - /// /// /// /// /// true/false - private static bool IsLocalQuorumConsistency(Documents.ConsistencyLevel backendConsistency, + private static bool IsLocalQuorumConsistency( Documents.ConsistencyLevel desiredConsistency, OperationType? operationType, ResourceType? resourceType) { - if (backendConsistency != Documents.ConsistencyLevel.Eventual && backendConsistency != Documents.ConsistencyLevel.ConsistentPrefix) - { - return false; - } - if (desiredConsistency != Documents.ConsistencyLevel.Strong) { return false; diff --git a/Microsoft.Azure.Cosmos/src/direct/BytesDeserializer.cs b/Microsoft.Azure.Cosmos/src/direct/BytesDeserializer.cs index d31f593a21..0ca1fe1975 100644 --- a/Microsoft.Azure.Cosmos/src/direct/BytesDeserializer.cs +++ b/Microsoft.Azure.Cosmos/src/direct/BytesDeserializer.cs @@ -15,12 +15,11 @@ public BytesDeserializer(byte[] metadata, int length) : this() { this.metadata = new Memory(metadata, 0, length); this.Position = 0; - this.Length = length; } public int Position { get; private set; } - public int Length { get; } + public int Length => this.metadata.Length; public ushort ReadUInt16() { @@ -29,6 +28,8 @@ public ushort ReadUInt16() return value; } + public void AdvancePositionByUInt16() => this.Position += 2; + public byte ReadByte() { byte value = this.metadata.Span[this.Position]; @@ -43,6 +44,8 @@ public uint ReadUInt32() return value; } + public void AdvancePositionByUInt32() => this.Position += 4; + public int ReadInt32() { int value = MemoryMarshal.Read(this.metadata.Span.Slice(this.Position)); @@ -50,6 +53,8 @@ public int ReadInt32() return value; } + public void AdvancePositionByInt32() => this.Position += 4; + public ulong ReadUInt64() { ulong value = MemoryMarshal.Read(this.metadata.Span.Slice(this.Position)); @@ -57,6 +62,8 @@ public ulong ReadUInt64() return value; } + public void AdvancePositionByUInt64() => this.Position += 8; + public long ReadInt64() { long value = MemoryMarshal.Read(this.metadata.Span.Slice(this.Position)); @@ -64,6 +71,8 @@ public long ReadInt64() return value; } + public void AdvancePositionByInt64() => this.Position += 8; + public float ReadSingle() { float value = MemoryMarshal.Read(this.metadata.Span.Slice(this.Position)); @@ -71,6 +80,8 @@ public float ReadSingle() return value; } + public void AdvancePositionBySingle() => this.Position += 4; + public double ReadDouble() { double value = MemoryMarshal.Read(this.metadata.Span.Slice(this.Position)); @@ -78,6 +89,8 @@ public double ReadDouble() return value; } + public void AdvancePositionByDouble() => this.Position += 8; + public Guid ReadGuid() { Guid value = MemoryMarshal.Read(this.metadata.Span.Slice(this.Position)); @@ -85,11 +98,15 @@ public Guid ReadGuid() return value; } + public void AdvancePositionByGuid() => this.Position += 16; + public ReadOnlyMemory ReadBytes(int length) { ReadOnlyMemory value = this.metadata.Slice(this.Position, length); this.Position += length; return value; } + + public void AdvancePositionByBytes(int count) => this.Position += count; } } diff --git a/Microsoft.Azure.Cosmos/src/direct/BytesSerializer.cs b/Microsoft.Azure.Cosmos/src/direct/BytesSerializer.cs index 56cf19abfa..7211ba6b58 100644 --- a/Microsoft.Azure.Cosmos/src/direct/BytesSerializer.cs +++ b/Microsoft.Azure.Cosmos/src/direct/BytesSerializer.cs @@ -53,6 +53,8 @@ public static ReadOnlyMemory GetBytesForString(string toConvert, RntbdCons return new ReadOnlyMemory(stringBuffer, 0, length); } + internal int GetPosition() => this.position; + /// /// Separate out getting the size of GUID into a separate method to keep unsafe contexts isolated. /// diff --git a/Microsoft.Azure.Cosmos/src/direct/Channel.cs b/Microsoft.Azure.Cosmos/src/direct/Channel.cs index 0e78100538..cf602bf8fe 100644 --- a/Microsoft.Azure.Cosmos/src/direct/Channel.cs +++ b/Microsoft.Azure.Cosmos/src/direct/Channel.cs @@ -46,7 +46,8 @@ public Channel(Guid activityId, Uri serverUri, ChannelProperties channelProperti channelProperties.IdleTimeout, channelProperties.EnableChannelMultiplexing, channelProperties.MemoryStreamPool, - channelProperties.RemoteCertificateValidationCallback); + channelProperties.RemoteCertificateValidationCallback, + channelProperties.DnsResolutionFunction); this.timerPool = channelProperties.RequestTimerPool; this.requestTimeoutSeconds = (int) channelProperties.RequestTimeout.TotalSeconds; this.serverUri = serverUri; diff --git a/Microsoft.Azure.Cosmos/src/direct/ChannelProperties.cs b/Microsoft.Azure.Cosmos/src/direct/ChannelProperties.cs index dc6974d8f2..cf9a2a2072 100644 --- a/Microsoft.Azure.Cosmos/src/direct/ChannelProperties.cs +++ b/Microsoft.Azure.Cosmos/src/direct/ChannelProperties.cs @@ -5,7 +5,9 @@ namespace Microsoft.Azure.Documents.Rntbd { using System; using System.Diagnostics; + using System.Net; using System.Net.Security; + using System.Threading.Tasks; internal sealed class ChannelProperties { @@ -19,7 +21,8 @@ public ChannelProperties(UserAgentContainer userAgent, TimeSpan idleTimeout, TimerPool idleTimerPool, RntbdConstants.CallerId callerId, bool enableChannelMultiplexing, MemoryStreamPool memoryStreamPool, - RemoteCertificateValidationCallback remoteCertificateValidationCallback = null) + RemoteCertificateValidationCallback remoteCertificateValidationCallback, + Func> dnsResolutionFunction) { Debug.Assert(userAgent != null); this.UserAgent = userAgent; @@ -53,6 +56,7 @@ public ChannelProperties(UserAgentContainer userAgent, this.MaxConcurrentOpeningConnectionCount = maxConcurrentOpeningConnectionCount; this.MemoryStreamPool = memoryStreamPool; this.RemoteCertificateValidationCallback = remoteCertificateValidationCallback; + this.DnsResolutionFunction = dnsResolutionFunction; } public UserAgentContainer UserAgent { get; private set; } @@ -102,5 +106,7 @@ public ChannelProperties(UserAgentContainer userAgent, public MemoryStreamPool MemoryStreamPool { get; private set; } public RemoteCertificateValidationCallback RemoteCertificateValidationCallback { get; private set; } + + public Func> DnsResolutionFunction { get; private set; } } } diff --git a/Microsoft.Azure.Cosmos/src/direct/CloneableStream.cs b/Microsoft.Azure.Cosmos/src/direct/CloneableStream.cs index aac270dba0..426c7cc6fa 100644 --- a/Microsoft.Azure.Cosmos/src/direct/CloneableStream.cs +++ b/Microsoft.Azure.Cosmos/src/direct/CloneableStream.cs @@ -7,6 +7,7 @@ namespace Microsoft.Azure.Documents using System.IO; using System.Threading; using System.Threading.Tasks; + using Microsoft.Azure.Cosmos.Core.Trace; internal sealed class CloneableStream : Stream, ICloneable { @@ -42,7 +43,7 @@ private MemoryStream CloneStream() public CloneableStream(MemoryStream internalStream, bool allowUnsafeDataAccess = true) { - this.internalStream = internalStream; + this.internalStream = CloneableStream.ConvertToExportableMemoryStream(internalStream); this.allowUnsafeDataAccess = allowUnsafeDataAccess; } @@ -212,6 +213,8 @@ public override void WriteByte(byte value) protected override void Dispose(bool disposing) { this.internalStream.Dispose(); + + base.Dispose(disposing); } public void WriteTo(Stream target) @@ -241,5 +244,36 @@ public override Task CopyToAsync(Stream destination, int bufferSize, Cancellatio { return this.internalStream.CopyToAsync(destination, bufferSize, cancellationToken); } + +#if NETFX45 || NETSTANDARD15 || NETSTANDARD16 + private static MemoryStream ConvertToExportableMemoryStream(MemoryStream mediaStream) + { + // This code path does not change now so we can assume that we always get exportable MemoryStream from existing clients + return mediaStream; + } +#else + private static MemoryStream ConvertToExportableMemoryStream(MemoryStream mediaStream) + { + if (mediaStream != null) + { + if (!(mediaStream is ICloneable || mediaStream.TryGetBuffer(out _))) + { + MemoryStream exportableMemoryStream; + int length = (int)mediaStream.Length; + long mediaStreamPosition = mediaStream.Position; + byte[] buffer = new byte[length]; + mediaStream.Read(buffer, offset: 0, count: length); + exportableMemoryStream = new(buffer, index: 0, count: length, writable: false, publiclyVisible: true); + mediaStream.Position = mediaStreamPosition; + mediaStream = exportableMemoryStream; + + // We could not dispose original stream as the application might still be using it + DefaultTrace.TraceWarning("Change the code to prevent the need for convertion into exportable MemoryStream by using streams with publicly visible buffers"); + } + } + + return mediaStream; + } +#endif } } diff --git a/Microsoft.Azure.Cosmos/src/direct/Connection.cs b/Microsoft.Azure.Cosmos/src/direct/Connection.cs index 5afa065988..ed4ff2dff0 100644 --- a/Microsoft.Azure.Cosmos/src/direct/Connection.cs +++ b/Microsoft.Azure.Cosmos/src/direct/Connection.cs @@ -116,6 +116,8 @@ internal sealed class Connection : IDisposable /// private readonly TimeSpan idleConnectionClosureTimeout; + private readonly Func> dnsResolutionFunction; + // Only one task may write to the stream at once. Reads don't need // mutual exclusion because only one thread consumes from the stream. private readonly SemaphoreSlim writeSemaphore = new SemaphoreSlim(1); @@ -141,13 +143,15 @@ public Connection( TimeSpan sendHangDetectionTime, TimeSpan idleTimeout, MemoryStreamPool memoryStreamPool, - RemoteCertificateValidationCallback remoteCertificateValidationCallback = null) + RemoteCertificateValidationCallback remoteCertificateValidationCallback, + Func> dnsResolutionFunction) { - Debug.Assert(serverUri.PathAndQuery.Equals("/"), serverUri.AbsoluteUri, + Debug.Assert(serverUri.PathAndQuery.Equals("/", StringComparison.Ordinal), serverUri.AbsoluteUri, "The server URI must not specify a path and query"); this.serverUri = serverUri; this.hostNameCertificateOverride = hostNameCertificateOverride; this.BufferProvider = new BufferProvider(); + this.dnsResolutionFunction = dnsResolutionFunction ?? Connection.ResolveHostAsync; if (receiveHangDetectionTime <= Connection.receiveHangGracePeriod) { @@ -631,7 +635,7 @@ private async Task OpenSocketAsync(ChannelOpenArguments args) errorCode = TransportErrorCode.DnsResolutionFailed; args.CommonArguments.SetTimeoutCode( TransportErrorCode.DnsResolutionTimeout); - IPAddress address = await Connection.ResolveHostAsync(this.serverUri.DnsSafeHost); + IPAddress address = await this.dnsResolutionFunction(this.serverUri.DnsSafeHost); errorCode = TransportErrorCode.ConnectFailed; args.CommonArguments.SetTimeoutCode(TransportErrorCode.ConnectTimeout); @@ -1078,7 +1082,7 @@ await Connection.ConnectReuseAddrAsync( return Tuple.Create(await Connection.ConnectUnicastPortAsync(serverUri, address), false); } - private static async Task ResolveHostAsync(string hostName) + internal static async Task ResolveHostAsync(string hostName) { IPAddress[] serverAddresses = await Dns.GetHostAddressesAsync(hostName); int addressIndex = 0; diff --git a/Microsoft.Azure.Cosmos/src/direct/Constants.cs b/Microsoft.Azure.Cosmos/src/direct/Constants.cs index d4c8955705..f8d0555866 100644 --- a/Microsoft.Azure.Cosmos/src/direct/Constants.cs +++ b/Microsoft.Azure.Cosmos/src/direct/Constants.cs @@ -273,8 +273,11 @@ public static class Properties public const string SupportedCapabilities = "supportedCapabilities"; public const string PlacementHints = "placementHints"; public const string IsMasterService = "isMasterService"; + public const string CapUncapMetadata = "capUncapMetadata"; public const string IsCappedForServer = "isCappedForServer"; + public const string CapUncapMetadataForServer = "capUncapMetadataForServer"; public const string IsCappedForMaster = "isCappedForMaster"; + public const string CapUncapMetadataForMaster = "capUncapMetadataForMaster"; public const string CapabilityResource = "capabilityResource"; public const string DocumentType = "documentType"; public const string SystemDatabaseAccountStoreType = "systemDatabaseAccountStoreType"; @@ -437,6 +440,11 @@ public static class Properties public const string EnableIndexingSchemeV2 = "enableIndexingSchemeV2"; + // CapUncapMetadata + public const string Source = "source"; + public const string Reason = "reason"; + public const string IncidentId = "incidentId"; + // GeospatialConfig public const string GeospatialType = "type"; public const string GeospatialConfig = "geospatialConfig"; @@ -449,6 +457,9 @@ public static class Properties public const string LastDocumentGLSN = "lastDocumentGLSN"; public const string UniqueIndexNameEncodingMode = "uniqueIndexNameEncodingMode"; + // ReIndexer + public const string EnableReIndexerProgressCalc = "enableReIndexerProgressCalc"; + // ChangeFeed policy public const string ChangeFeedPolicy = "changeFeedPolicy"; public const string LogRetentionDuration = "retentionDuration"; @@ -593,6 +604,8 @@ public static class Properties public const string RestoreTimestampInUtc = "restoreTimestampInUtc"; public const string RestoreSource = "restoreSource"; public const string IsInAccountRestoreCapabilityEnabled = "isInAccountRestoreCapabilityEnabled"; + public const string CanUndelete = "CanUndelete"; + public const string CanUndeleteReason = "CanUndeleteReason"; // Backup Hold public const string BackupHoldTimeInDays = "backupHoldTimeInDays"; @@ -623,6 +636,9 @@ public static class Properties public const string Message = "message"; public const string ErrorDetails = "errorDetails"; public const string AdditionalErrorInfo = "additionalErrorInfo"; + + //CassandraErrorResource. + public const string Target = "target"; // AddressResource public const string IsPrimary = "isPrimary"; @@ -680,7 +696,12 @@ public static class Properties public const string IsInBitLockerRotation = "IsInBitLockerRotation"; public const string PrimaryBitLockerKeyVersion = "PrimaryBitLockerKeyVersion"; public const string SecondaryBitLockerKeyVersion = "SecondaryBitLockerKeyVersion"; + public const string BitLockerKeysSettingType = "BitLockerKeysSettingType"; public const string BitLockerKeysRotationState = "BitLockerKeysRotationState"; + public const string InfrastructureServices = "InfrastructureServices"; + + // Federation settings + public const string AllowReutilizationOfComputeResources = "AllowReutilizationOfComputeResources"; //Deployment Constants public const string FabricApplicationName = "fabricApplicationName"; @@ -731,6 +752,7 @@ public static class Properties public const string ManagedServiceIdentityInfo = "managedServiceIdentityInfo"; public const string IdentityName = "identity"; public const string MsiSystemAssignedType = "SystemAssigned"; + public const string MsiFirstPartyType = "FirstParty"; public const string MsiNoneType = "None"; public const string MsiUserAssignedType = "UserAssigned"; public const string MsiSystemAndUserAssignedType = "SystemAssigned,UserAssigned"; @@ -823,6 +845,7 @@ public static class Properties public const string MaxCountOfSharedThroughputCollectionsEverCreated = "maxCountOfSharedThroughputCollectionsEverCreated"; public const string OfferLastReplaceTimestamp = "offerLastReplaceTimestamp"; public const string AutopilotSettings = "offerAutopilotSettings"; + public const string IsOfferRestorePending = "isOfferRestorePending"; public const string AutopilotTier = "tier"; public const string AutopilotTargetTier = "targetTier"; @@ -955,6 +978,13 @@ public static class Properties public const string SupportedTimeGrainTypes = "supportedTimeGrainTypes"; public const string SupportedAggregationTypes = "supportedAggregationTypes"; + // Metric ID Mapping Dimension names (Multi-Resource Metrics) + public const string MicrosoftSubscriptionId = "Microsoft.subscriptionId"; + public const string MicrosoftResourceGroupName = "Microsoft.resourceGroupName"; + public const string MicrosoftResourceType = "Microsoft.resourceType"; + public const string MicrosoftResourceName = "Microsoft.resourceName"; + public const string MicrosoftResourceId = "Microsoft.resourceId"; + // IP Range resource public const string IpRangeFilter = "ipRangeFilter"; public const string IpRules = "ipRules"; @@ -963,6 +993,7 @@ public static class Properties // Property to check if point in time restore is enabled for a global database account public const string PitrEnabled = "pitrEnabled"; public const string PitrSku = "pitrSku"; + public const string ReservedInstanceType = "reservedInstanceType"; public const string ContinuousBackupTier = "tier"; public const string EnablePitrMigration = "enablePITRMigration"; public const string EnableLogstoreHeadStartSequenceVector = "enableLogStoreHeadStartSequenceVector"; @@ -980,6 +1011,7 @@ public static class Properties // property to enable full fidelity change feed (change feed with retention from remote+local storage). public const string EnableFullFidelityChangeFeed = "enableFullFidelityChangeFeed"; + public const string EnableFFCFWithPITR = "enableFFCFWithPITR"; // Enable API type check public const string EnableApiTypeCheck = "enableApiTypeCheck"; @@ -995,6 +1027,8 @@ public static class Properties public const string FabricUri = "fabricUri"; public const string ResourcePartitionKey = "resourcePartitionKey"; public const string CanaryLocationSurffix = "euap"; + public const string IsSubscriptionRegionAccessAllowedForRegular = "isSubscriptionRegionAccessAllowedForRegular"; + public const string IsSubscriptionRegionAccessAllowedForAz = "isSubscriptionRegionAccessAllowedForAz"; // Topology Resource public const string Topology = "topology"; @@ -1069,7 +1103,9 @@ public static class Properties public const string QueryRanges = "queryRanges"; // Arm resource type - public const string DatabaseAccounts = "databaseAccounts"; + public const string CosmosResourceProvider = "microsoft.documentdb"; + public const string DatabaseAccounts = "databaseaccounts"; + public const string CosmosArmResouceType = CosmosResourceProvider + "/" + DatabaseAccounts; // SchemaDiscoveryPolicy public const string SchemaDiscoveryPolicy = "schemaDiscoveryPolicy"; @@ -1151,7 +1187,6 @@ public static class Properties public const string NspProfileProxyResources = "nspProfileProxyResources"; public const string NspAssociationProxyResource = "nspAssociationProxyResource"; public const string EnableNetworkSecurityPerimeter = "enableNetworkSecurityPerimeter"; - public const string PrototypeAdditionalEndpointsForPrivateEndpoint = "prototypeAdditionalEndpointsForPrivateEndpoint"; // VNET/Subnet Resource(Network Resource Provider) public const string IgnoreMissingVNetServiceEndpoint = "ignoreMissingVNetServiceEndpoint"; @@ -1366,6 +1401,7 @@ public static class Properties public const string IsOwnedByExternalProvider = "isOwnedByExternalProvider"; public const string ConnectionInformation = "connectionInformation"; public const string CrossSubRegionMigrationInProgress = "CrossSubRegionMigrationInProgress"; + public const string AzMigrationInProgress = "AzMigrationInProgress"; // Data Plane Operation Policy public const string DisableKeyBasedMetadataWriteAccess = "disableKeyBasedMetadataWriteAccess"; @@ -1577,6 +1613,20 @@ public static class FederationCapActions public const string Cap = "Cap"; public const string Uncap = "Uncap"; } + + public static class InAccountUnDeleteNotAllowedReasons + { + // Database UnDelete Failure + public const string DatabaseLive = "Database already exists. Only deleted resources can be restored within same account."; + public const string DatabaseWithSameNameLive = "Database with same name already exist as live database."; + + // Collection UnDelete Failure + public const string DatabaseDoesNotExist = "Could not find the database associated with the collection. Please restore the database before restoring the collection."; + public const string DatabaseWithSameNameExist = "Could not find the database associated with the collection. Another database with same name exist"; + public const string CollectionLive = "Collection already exists. Only deleted resources can be restored within same account."; + public const string CollectionWithSamenNameLive = "Collection with same name already exist as live collection."; + public const string SharedCollectionNotAllowed = "Individual shared database collections restore is not supported. Please restore shared database to restore its collections that share the throughput."; + } public static class DocumentResourceExtendedProperties { @@ -1608,6 +1658,7 @@ public static class SnapshotProperties public const string Table = "table"; public const string Keyspace = "keyspace"; public const string LSN = "lsn"; + public const string IsMasterResourcesDeletionPending = "isMasterResourcesDeletionPending"; } public static class RestoreMetadataResourceProperties @@ -1931,6 +1982,7 @@ public static class LogStoreConstants public const string CollectionGLSN = "CollectionGLSN"; public const string IsValidTimeStamp = "IsValidTimeStamp"; public const string CollectionTS = "CollectionTS"; + public const string CollectionInstanceId = "CollectionInstanceId"; } public static class RestoreConstants @@ -1979,6 +2031,7 @@ public static class SystemStoreConstants public const int SMSDefaultBackupIntervalInMinute = 30; public const int DefaultBackupRetentionInHour = 720; public const string ResourceGroupSuffix = "-rg"; + public const string IsDataTransferStateStoreAccount = "IsDataTransferStateStoreAccount"; } public static class TransportControlCommandOperations @@ -2058,6 +2111,7 @@ public static class MigratePartitionCallerSource public static string ACIS_MitigateMasterMigrationFailure = "ACIS_MitigateMasterMigrationFailure"; public static string ACIS_MitigateServerMigrationFailure = "ACIS_MitigateServerMigrationFailure"; public static string FederationBuildout_CanaryAccountMigration = "FederationBuildout_CanaryAccountMigration"; + public static string USER_InPlaceAZMigration = "FederationBuildout_CanaryAccountMigration"; } public static class EnvironmentVariables diff --git a/Microsoft.Azure.Cosmos/src/direct/CpuMonitor.cs b/Microsoft.Azure.Cosmos/src/direct/CpuMonitor.cs index 45c90e5ae4..d077813a92 100644 --- a/Microsoft.Azure.Cosmos/src/direct/CpuMonitor.cs +++ b/Microsoft.Azure.Cosmos/src/direct/CpuMonitor.cs @@ -46,6 +46,7 @@ public void Start() this.rwLock.EnterWriteLock(); try { + this.ThrowIfDisposed(); if (this.periodicTask != null) { throw new InvalidOperationException("CpuMonitor already started"); @@ -80,6 +81,33 @@ public void Start() DefaultTrace.TraceInformation("CpuMonitor started"); } + private void StopCoreUnderWriteLock(ref CancellationTokenSource cancel, ref Task backgroundTask) + { + if (this.periodicTask == null) + { + throw new InvalidOperationException("CpuMonitor not started or has been stopped or disposed already."); + } + + cancel = this.cancellation; + backgroundTask = this.periodicTask; + + this.cancellation = null; + this.currentReading = null; + this.periodicTask = null; + } + + private static void StopCoreAfterReleasingWriteLock(CancellationTokenSource cancel, Task backgroundTask) + { + cancel.Cancel(); + try + { + backgroundTask.Wait(); + } + catch (AggregateException) + { } + cancel.Dispose(); + } + public void Stop() { this.ThrowIfDisposed(); @@ -88,31 +116,15 @@ public void Stop() this.rwLock.EnterWriteLock(); try { - if (this.periodicTask == null) - { - throw new InvalidOperationException("CpuMonitor not started"); - } - - cancel = this.cancellation; - backgroundTask = this.periodicTask; - - this.cancellation = null; - this.currentReading = null; - this.periodicTask = null; + this.ThrowIfDisposed(); + this.StopCoreUnderWriteLock(ref cancel, ref backgroundTask); } finally { this.rwLock.ExitWriteLock(); } - cancel.Cancel(); - try - { - backgroundTask.Wait(); - } - catch (AggregateException) - { } - cancel.Dispose(); + StopCoreAfterReleasingWriteLock(cancel, backgroundTask); DefaultTrace.TraceInformation("CpuMonitor stopped"); } @@ -127,7 +139,7 @@ public CpuLoadHistory GetCpuLoad() { if (this.periodicTask == null) { - throw new InvalidOperationException("CpuMonitor was not started"); + throw new InvalidOperationException("CpuMonitor was not started or has been stopped or disposed already."); } return this.currentReading; } @@ -139,22 +151,40 @@ public CpuLoadHistory GetCpuLoad() public void Dispose() { - this.ThrowIfDisposed(); - this.rwLock.EnterReadLock(); + Interlocked.MemoryBarrier(); + if (this.disposed) + { + return; + } + + CancellationTokenSource cancel = null; + Task backgroundTask = null; + this.rwLock.EnterWriteLock(); try { + Interlocked.MemoryBarrier(); + if (this.disposed) + { + return; + } + if (this.periodicTask != null) { - throw new InvalidOperationException( - "CpuMonitor must be stopped before Dispose"); + this.StopCoreUnderWriteLock(ref cancel, ref backgroundTask); } } finally { - this.rwLock.ExitReadLock(); + this.MarkDisposed(); + this.rwLock.ExitWriteLock(); + } + + if (backgroundTask != null) + { + StopCoreAfterReleasingWriteLock(cancel, backgroundTask); } + this.rwLock.Dispose(); - this.MarkDisposed(); } private void MarkDisposed() diff --git a/Microsoft.Azure.Cosmos/src/direct/CustomTypeExtensions.cs b/Microsoft.Azure.Cosmos/src/direct/CustomTypeExtensions.cs index 47594e21ad..78c9ec74ec 100644 --- a/Microsoft.Azure.Cosmos/src/direct/CustomTypeExtensions.cs +++ b/Microsoft.Azure.Cosmos/src/direct/CustomTypeExtensions.cs @@ -6,15 +6,14 @@ namespace Microsoft.Azure.Documents { using System; using System.Collections.Generic; - using System.Diagnostics; using System.Diagnostics.Tracing; using System.Globalization; + using System.IO; using System.Net.Sockets; using System.Reflection; using System.Runtime.InteropServices; using System.Security; using System.Security.Cryptography; - using System.Text; using Microsoft.Azure.Cosmos.Core.Trace; /// @@ -32,215 +31,262 @@ namespace Microsoft.Azure.Documents /// internal static class CustomTypeExtensions { - public const int UnicodeEncodingCharSize = UnicodeEncoding.CharSize; + public const int UnicodeEncodingCharSize = 2; + #if COSMOSCLIENT public const string SDKName = "cosmos-netstandard-sdk"; - public const string SDKVersion = "3.30.3"; - public const string SDKAssemblyName = "Microsoft.Azure.Cosmos.Client"; + public const string SDKVersion = "3.18.0"; #else - public const string SDKName = "documentdb-dotnet-sdk"; + public const string SDKName = "documentdb-netcore-sdk"; public const string SDKVersion = "2.14.0"; - public const string SDKAssemblyName = "Microsoft.Azure.Documents.Client"; #endif - public const string hostProcess32Bit = "32-bit"; - public const string hostProcess64Bit = "64-bit"; + #region Type Extension Methods +#if (NETSTANDARD15 || NETSTANDARD16) + public static bool IsAssignableFrom(this Type type, Type c) + { + return type.GetTypeInfo().IsAssignableFrom(c); + } - // Example: Microsoft.Azure.Documents.Common/1.10.23.2 - private static readonly string InternalRequestBaseUserAgentString = - Assembly.GetExecutingAssembly().GetName().Name + "/" + - Assembly.GetExecutingAssembly().GetCustomAttribute().Version; + public static bool IsSubclassOf(this Type type, Type c) + { + return type.GetTypeInfo().IsSubclassOf(c); + } - public static bool IsGenericType(this Type type) + public static MethodInfo GetMethod(this Type type, string name, BindingFlags bindingAttr) { - return type.IsGenericType; + return type.GetTypeInfo().GetMethod(name, bindingAttr); } - public static bool IsEnum(this Type type) + public static MethodInfo GetMethod(this Type type, string name) + { + return type.GetTypeInfo().GetMethod(name); + } + public static MethodInfo GetMethod(this Type type, string name, Type[] types) { - return type.IsEnum; + return type.GetTypeInfo().GetMethod(name, types); } - public static bool IsValueType(this Type type) + public static Type[] GetGenericArguments(this Type type) { - return type.IsValueType; + return type.GetTypeInfo().GetGenericArguments(); } - public static bool IsInterface(this Type type) + public static PropertyInfo GetProperty(this Type type, string name) { - return type.IsInterface; + return type.GetTypeInfo().GetProperty(name); } - public static Type GetBaseType(this Type type) + public static PropertyInfo[] GetProperties(this Type type) { - return type.BaseType; + return type.GetTypeInfo().GetProperties(); } - public static Type GeUnderlyingSystemType(this Type type) + public static PropertyInfo[] GetProperties(this Type type, BindingFlags bindingAttr) { - return type.UnderlyingSystemType; + return type.GetTypeInfo().GetProperties(bindingAttr); } - public static Assembly GetAssembly(this Type type) + public static Type[] GetInterfaces(this Type type) { - return type.Assembly; + return type.GetTypeInfo().GetInterfaces(); } public static ConstructorInfo GetConstructor(this Type type, Type[] types) { - return type.GetConstructor(types); + return type.GetTypeInfo().GetConstructor(types); + } + + public static T GetCustomAttribute(this Type type, bool inherit) where T : Attribute + { + return type.GetTypeInfo().GetCustomAttribute(inherit); } +#endif + +#if NETSTANDARD16 + public static IEnumerable GetCustomAttributes(this Type type, Type attributeType, bool inherit) + { + return type.GetTypeInfo().GetCustomAttributes(attributeType, inherit); + } +#endif + +#endregion - public static IEnumerable GetsCustomAttributes(this MemberInfo memberInfo) + #region Misc Extension Methods +#if (NETSTANDARD15 || NETSTANDARD16) + public static byte[] GetBuffer(this MemoryStream stream) { - return memberInfo.CustomAttributes; + ArraySegment buffer; + stream.TryGetBuffer(out buffer); + return buffer.Array; } + public static void Close(this Stream stream) + { + stream.Dispose(); + } + + public static void Close(this TcpClient tcpClient) + { + tcpClient.Dispose(); + } +#endif +#endregion + + #region Helper Methods +#if (NETSTANDARD15 || NETSTANDARD16) + public static string GetLeftPart(this Uri uri, UriPartial part) + { + const UriComponents NonPathPart = (UriComponents.Scheme | UriComponents.UserInfo | UriComponents.Host | UriComponents.Port); + + switch (part) + { + case UriPartial.Authority: + return uri.GetComponents(NonPathPart, UriFormat.UriEscaped); + + case UriPartial.Path: + return uri.GetComponents(NonPathPart | UriComponents.Path, UriFormat.UriEscaped); + + case UriPartial.Query: + return uri.GetComponents(NonPathPart | UriComponents.Path | UriComponents.Query, UriFormat.UriEscaped); + + case UriPartial.Scheme: + return uri.GetComponents(UriComponents.Scheme | UriComponents.KeepDelimiter, UriFormat.UriEscaped); + } + + throw new ArgumentException("Invalid part", nameof(part)); + } +#endif + public static Delegate CreateDelegate(Type delegateType, object target, MethodInfo methodInfo) { - return Delegate.CreateDelegate(delegateType, target, methodInfo); + return methodInfo.CreateDelegate(delegateType, target); } public static IntPtr SecureStringToCoTaskMemAnsi(SecureString secureString) { - return System.Runtime.InteropServices.Marshal.SecureStringToCoTaskMemAnsi(secureString); + return SecureStringMarshal.SecureStringToCoTaskMemAnsi(secureString); } public static void SetActivityId(ref Guid id) { - Trace.CorrelationManager.ActivityId = id; -#if NETFX45 - System.Diagnostics.Eventing.EventProvider.SetActivityId(ref id); -#else EventSource.SetCurrentThreadActivityId(id); -#endif } public static Random GetRandomNumber() { - using (RNGCryptoServiceProvider cryptoProvider = new RNGCryptoServiceProvider()) + using (RandomNumberGenerator randomNumberGenerator = RandomNumberGenerator.Create()) { - byte[] seedArray = new byte[sizeof (int)]; - cryptoProvider.GetBytes(seedArray); + byte[] seedArray = new byte[sizeof(int)]; + randomNumberGenerator.GetBytes(seedArray); return new Random(BitConverter.ToInt32(seedArray, 0)); } } public static QueryRequestPerformanceActivity StartActivity(DocumentServiceRequest request) { - QueryRequestPerformanceActivity activity = null; - - bool isQuery = !string.IsNullOrEmpty(request.Headers[HttpConstants.HttpHeaders.Query]); - if (isQuery || request.OperationType == OperationType.Query) - { - activity = new QueryRequestPerformanceActivity(); - activity.ActivityStart(); - } - - return activity; + return null; } public static string GenerateBaseUserAgentString() { - // For all requests that are initiated by Client SDK, we want a more meaningful user agent, to be used for telemetry purposes - if (string.CompareOrdinal(Assembly.GetExecutingAssembly().GetName().Name, SDKAssemblyName) == 0) - { - string osVersion = Environment.OSVersion.VersionString; // Microsoft Windows NT 6.2.9200.0 - string trimmedOsVersion = osVersion.Replace(" ", string.Empty); // MicrosoftWindowsNT6.2.9200.0 - // This format is required for user agents in HTTP requests(no space, name and version separated with /) - string formattedOsVersion = trimmedOsVersion.Replace(Environment.OSVersion.Version.ToString(), - "/" + Environment.OSVersion.Version); // MicrosoftWindowsNT/6.2.9200.0 - - string hostProcess = ServiceInteropWrapper.Is64BitProcess ? hostProcess64Bit : hostProcess32Bit; - - // Example: documentdb-dotnet-sdk/1.10.0 Host/64-bit MicrosoftWindowsNT/6.2.9200.0 - return string.Format(CultureInfo.InvariantCulture, "{0}/{1} Host/{2} {3}", - SDKName, - SDKVersion, - hostProcess, - formattedOsVersion); - } - // For all other internal requests, we will continue using the earlier format - else - { - // Example: Microsoft.Azure.Documents.Common/1.10.23.2 - return CustomTypeExtensions.InternalRequestBaseUserAgentString; - } + string version = PlatformApis.GetOSVersion(); + + // Example: Windows/10.0.14393 documentdb-netcore-sdk/0.0.1 + return string.Format(CultureInfo.InvariantCulture, "{0}/{1} {2}/{3}", + PlatformApis.GetOSPlatform(), + String.IsNullOrEmpty(version) ? "Unknown" : version.Trim(), + SDKName, + SDKVersion); } + // This is how you can determine whether a socket is still connected. public static bool ConfirmOpen(Socket socket) - { - NativeMethods.WSAPOLLFD[] poll = new NativeMethods.WSAPOLLFD[1]; - - poll[0].fd = socket.Handle; - poll[0].events = NativeMethods.POLLWRNORM; - poll[0].revents = 0; + { + bool blockingState = socket.Blocking; - GCHandle handlePoll = GCHandle.Alloc(poll, GCHandleType.Pinned); try { - Int32 result = NativeMethods.WSAPoll(handlePoll.AddrOfPinnedObject(), 1, 0); - if (NativeMethods.SOCKET_ERROR == result) - { - return false; - } - else if ((poll[0].revents & (NativeMethods.POLLERR | NativeMethods.POLLHUP | NativeMethods.POLLNVAL)) != - 0) - { - return false; - } - else - { - return true; - } + byte[] tmp = new byte[1]; + + // Make a nonblocking, zero-byte Send call + socket.Blocking = false; + socket.Send(tmp, 0, 0); + return true; } + + catch (SocketException ex) + { + // If the Send call throws a WAEWOULDBLOCK error code (10035), then the socket is still connected; otherwise, the socket is no longer connected + return (ex.SocketErrorCode == SocketError.WouldBlock); + } + + catch (ObjectDisposedException) + { + // Send with throw ObjectDisposedException if the Socket has been closed + return false; + } + finally { - handlePoll.Free(); + socket.Blocking = blockingState; } } - // By pass query parsing on 32 bit processes or if interop assemblies don't exist + // Bypass query parsing on 32 bit process on Windows and always on non-Windows(Linux/OSX) platforms or if interop assemblies don't exist. public static bool ByPassQueryParsing() - { - if(!ServiceInteropWrapper.Is64BitProcess || !ServiceInteropWrapper.AssembliesExist.Value){ - DefaultTrace.TraceVerbose($"Bypass query parsing. IntPtr.Size is {IntPtr.Size} ServiceInteropWrapper.AssembliesExist {ServiceInteropWrapper.AssembliesExist.Value}"); + { + if(!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) || !ServiceInteropWrapper.Is64BitProcess || !ServiceInteropWrapper.AssembliesExist.Value) + { + DefaultTrace.TraceVerbose($"Bypass query parsing. IsWindowsOSPlatform {RuntimeInformation.IsOSPlatform(OSPlatform.Windows)} IntPtr.Size is {IntPtr.Size} ServiceInteropWrapper.AssembliesExist {ServiceInteropWrapper.AssembliesExist.Value}"); return true; } return false; } - private static class NativeMethods +#endregion + +#region Properties converted to Methods + public static bool IsGenericType(this Type type) { - public const Int32 SOCKET_ERROR = -1; + return type.GetTypeInfo().IsGenericType; + } - public const Int16 POLLRDNORM = 0x0100; - public const Int16 POLLRDBAND = 0x0200; - public const Int16 POLLIN = POLLRDNORM | POLLRDBAND; - public const Int16 POLLPRI = 0x0400; + public static bool IsEnum(this Type type) + { + return type.GetTypeInfo().IsEnum; + } - public const Int16 POLLWRNORM = 0x0010; - public const Int16 POLLOUT = POLLWRNORM; - public const Int16 POLLWRBAND = 0x0020; + public static bool IsValueType(this Type type) + { + return type.GetTypeInfo().IsValueType; + } - public const Int16 POLLERR = 0x0001; - public const Int16 POLLHUP = 0x0002; - public const Int16 POLLNVAL = 0x0004; + public static bool IsInterface(this Type type) + { + return type.GetTypeInfo().IsInterface; + } - [StructLayout(LayoutKind.Sequential)] - public struct WSAPOLLFD - { - public IntPtr fd; - public Int16 events; - public Int16 revents; - } + public static Type GetBaseType(this Type type) + { + return type.GetTypeInfo().BaseType; + } + + public static Type GeUnderlyingSystemType(this Type type) + { + return type.GetTypeInfo().UnderlyingSystemType; + } - [DllImport("ws2_32.dll", SetLastError = true)] - public static extern Int32 WSAPoll( - IntPtr fds, - UInt32 fdCount, - Int32 timeout); + public static Assembly GetAssembly(this Type type) + { + return type.GetTypeInfo().Assembly; + } + + public static IEnumerable GetsCustomAttributes(this Type type) + { + return type.GetTypeInfo().CustomAttributes; } +#endregion } } diff --git a/Microsoft.Azure.Cosmos/src/direct/DefaultTrace.cs b/Microsoft.Azure.Cosmos/src/direct/DefaultTrace.cs index daf0dce468..81aca07371 100644 --- a/Microsoft.Azure.Cosmos/src/direct/DefaultTrace.cs +++ b/Microsoft.Azure.Cosmos/src/direct/DefaultTrace.cs @@ -14,7 +14,7 @@ internal static class DefaultTrace { public static readonly Guid ProviderId = new Guid("{B30ABF1C-6A50-4F2B-85C4-61823ED6CF24}"); - private static readonly TraceSource TraceSourceInternal; + private static TraceSource TraceSourceInternal; private static bool IsListenerAdded; @@ -38,6 +38,7 @@ static DefaultTrace() public static TraceSource TraceSource { get { return DefaultTrace.TraceSourceInternal; } + set { DefaultTrace.TraceSourceInternal = value; } } /// diff --git a/Microsoft.Azure.Cosmos/src/direct/DictionaryNameValueCollectionFactory.cs b/Microsoft.Azure.Cosmos/src/direct/DictionaryNameValueCollectionFactory.cs deleted file mode 100644 index b892539aba..0000000000 --- a/Microsoft.Azure.Cosmos/src/direct/DictionaryNameValueCollectionFactory.cs +++ /dev/null @@ -1,49 +0,0 @@ -//------------------------------------------------------------ -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------ - -namespace Microsoft.Azure.Documents.Collections -{ - using System; - using System.Collections.Specialized; - - /// - /// - /// - internal class DictionaryNameValueCollectionFactory : INameValueCollectionFactory - { - /// - /// - /// - /// - public INameValueCollection CreateNewNameValueCollection() - { - return new DictionaryNameValueCollection(); - } - - public INameValueCollection CreateNewNameValueCollection(int capacity) - { - return new DictionaryNameValueCollection(capacity); - } - - public INameValueCollection CreateNewNameValueCollection(INameValueCollection collection) - { - return new DictionaryNameValueCollection(collection); - } - - public INameValueCollection CreateNewNameValueCollection(NameValueCollection collection) - { - return new DictionaryNameValueCollection(collection); - } - - /// - /// - /// - /// - /// - public INameValueCollection CreateNewNameValueCollection(StringComparer comparer) - { - return new DictionaryNameValueCollection(comparer); - } - } -} diff --git a/Microsoft.Azure.Cosmos/src/direct/Dispatcher.cs b/Microsoft.Azure.Cosmos/src/direct/Dispatcher.cs index 13f6088d0e..5167dba6b9 100644 --- a/Microsoft.Azure.Cosmos/src/direct/Dispatcher.cs +++ b/Microsoft.Azure.Cosmos/src/direct/Dispatcher.cs @@ -21,8 +21,6 @@ namespace Microsoft.Azure.Documents.Rntbd using Trace = Microsoft.Azure.Documents.Trace; #endif - using ResponsePool = RntbdConstants.RntbdEntityPool; - // Dispatcher encapsulates the state and logic needed to dispatch multiple requests through // a single connection. internal sealed class Dispatcher : IDisposable @@ -77,14 +75,16 @@ public Dispatcher( TimeSpan idleTimeout, bool enableChannelMultiplexing, MemoryStreamPool memoryStreamPool, - RemoteCertificateValidationCallback remoteCertificateValidationCallback = null) + RemoteCertificateValidationCallback remoteCertificateValidationCallback, + Func> dnsResolutionFunction) { this.connection = new Connection( serverUri, hostNameCertificateOverride, receiveHangDetectionTime, sendHangDetectionTime, idleTimeout, memoryStreamPool, - remoteCertificateValidationCallback); + remoteCertificateValidationCallback, + dnsResolutionFunction); this.userAgent = userAgent; this.connectionStateListener = connectionStateListener; this.serverUri = serverUri; @@ -694,14 +694,13 @@ private async Task ReceiveLoopAsync() CancellationToken cancellationToken = this.cancellation.Token; ChannelCommonArguments args = new ChannelCommonArguments( Guid.Empty, TransportErrorCode.ReceiveTimeout, true); - ResponsePool.EntityOwner response = default; Connection.ResponseMetadata responseMd = null; try { - while (!cancellationToken.IsCancellationRequested) + bool hasTransportErrors = false; + while (!hasTransportErrors && !cancellationToken.IsCancellationRequested) { args.ActivityId = Guid.Empty; - response = ResponsePool.Instance.Get(); responseMd = await this.connection.ReadResponseMetadataAsync(args); ArraySegment metadata = responseMd.Metadata; @@ -710,35 +709,38 @@ private async Task ReceiveLoopAsync() args.ActivityId = header.ActivityId; BytesDeserializer deserializer = new BytesDeserializer(metadata.Array, metadata.Count); - Debug.Assert(response.Entity != null); - response.Entity.ParseFrom(ref deserializer); MemoryStream bodyStream = null; - if (response.Entity.payloadPresent.value.valueByte != (byte) 0x00) + if (HeadersTransportSerialization.TryParseMandatoryResponseHeaders(ref deserializer, out bool payloadPresent, out uint transportRequestId)) + { + if (payloadPresent) + { + bodyStream = await this.connection.ReadResponseBodyAsync(args); + } + this.DispatchRntbdResponse(responseMd, header, bodyStream, metadata.Array, metadata.Count, transportRequestId); + } + else { - bodyStream = await this.connection.ReadResponseBodyAsync(args); + hasTransportErrors = true; + this.DispatchChannelFailureException(TransportExceptions.GetInternalServerErrorException(this.serverUri, RMResources.MissingRequiredHeader)); } - this.DispatchRntbdResponse(responseMd, response, header, bodyStream); responseMd = null; } this.DispatchCancellation(); } catch (OperationCanceledException) { - response.Dispose(); responseMd?.Dispose(); this.DispatchCancellation(); } catch (ObjectDisposedException) { - response.Dispose(); responseMd?.Dispose(); this.DispatchCancellation(); } catch (Exception e) { - response.Dispose(); responseMd?.Dispose(); this.DispatchChannelFailureException(e); } @@ -767,22 +769,13 @@ private Dictionary StopCalls() private void DispatchRntbdResponse( Connection.ResponseMetadata responseMd, - ResponsePool.EntityOwner rntbdResponse, TransportSerialization.RntbdHeader responseHeader, - MemoryStream responseBody) + MemoryStream responseBody, + byte[] metadata, + int metadataLength, + uint transportRequestId) { - if (!rntbdResponse.Entity.transportRequestID.isPresent || - (rntbdResponse.Entity.transportRequestID.GetTokenType() != RntbdTokenTypes.ULong)) - { - responseBody?.Dispose(); - rntbdResponse.Dispose(); - responseMd.Dispose(); - throw TransportExceptions.GetInternalServerErrorException( - this.serverUri, - RMResources.ServerResponseTransportRequestIdMissingError); - } - - CallInfo call = this.RemoveCall(rntbdResponse.Entity.transportRequestID.value.valueULong); + CallInfo call = this.RemoveCall(transportRequestId); if (call != null) { Debug.Assert(this.serverProperties != null); @@ -790,13 +783,12 @@ private void DispatchRntbdResponse( call.TransportRequestStats.RecordState(TransportRequestStats.RequestStage.Received); call.TransportRequestStats.ResponseMetadataSizeInBytes = responseMd.Metadata.Count; call.TransportRequestStats.ResponseBodySizeInBytes = responseBody?.Length; - call.SetResponse(responseMd, rntbdResponse, responseHeader, responseBody, this.serverProperties.Version); + call.SetResponse(responseMd, responseHeader, responseBody, this.serverProperties.Version, metadata, metadataLength); } else { responseBody?.Dispose(); responseMd.Dispose(); - rntbdResponse.Dispose(); } } @@ -957,10 +949,11 @@ public void SendFailed() public void SetResponse( Connection.ResponseMetadata responseMd, - ResponsePool.EntityOwner rntbdResponse, TransportSerialization.RntbdHeader responseHeader, MemoryStream responseBody, - string serverVersion) + string serverVersion, + byte[] metadata, + int metadataLength) { this.ThrowIfDisposed(); // Call SetResult asynchronously. Otherwise, the tasks awaiting on @@ -979,12 +972,13 @@ public void SetResponse( Trace.CorrelationManager.ActivityId = this.activityId; try { + BytesDeserializer bytesDeserializer = new BytesDeserializer(metadata, metadataLength); StoreResponse storeResponse = TransportSerialization.MakeStoreResponse( responseHeader.Status, responseHeader.ActivityId, - rntbdResponse.Entity, responseBody, - serverVersion); + serverVersion, + ref bytesDeserializer); this.completion.SetResult(storeResponse); } catch (Exception e) @@ -994,7 +988,6 @@ public void SetResponse( } finally { - rntbdResponse.Dispose(); responseMd.Dispose(); } }); @@ -1119,4 +1112,4 @@ private enum State } } } -} +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/direct/DocumentServiceRequest.cs b/Microsoft.Azure.Cosmos/src/direct/DocumentServiceRequest.cs index cfd2188512..86a4ab53b4 100644 --- a/Microsoft.Azure.Cosmos/src/direct/DocumentServiceRequest.cs +++ b/Microsoft.Azure.Cosmos/src/direct/DocumentServiceRequest.cs @@ -541,10 +541,14 @@ public string HttpMethod case OperationType.MasterInitiatedProgressCoordination: case OperationType.MetadataCheckAccess: case OperationType.CreateSystemSnapshot: + case OperationType.CreateRidRangeResources: case OperationType.GetAadGroups: case OperationType.UpdateFailoverPriorityList: case OperationType.GetStorageAccountSas: case OperationType.GetBatchCustomerManagedKeyStatus: + case OperationType.UpdatePartitionThroughput: + case OperationType.XPDatabaseAccountMetaData: + case OperationType.Truncate: return HttpConstants.HttpMethods.Post; case OperationType.EnsureSnapshotOperation: diff --git a/Microsoft.Azure.Cosmos/src/direct/GoneAndRetryWithRetryPolicy.cs b/Microsoft.Azure.Cosmos/src/direct/GoneAndRetryWithRetryPolicy.cs index 6661d64d5a..f85a722255 100644 --- a/Microsoft.Azure.Cosmos/src/direct/GoneAndRetryWithRetryPolicy.cs +++ b/Microsoft.Azure.Cosmos/src/direct/GoneAndRetryWithRetryPolicy.cs @@ -15,9 +15,9 @@ namespace Microsoft.Azure.Documents /// TArg1: Perform force refresh. /// TArg2: TimeSpan for completing the work in the callback /// - internal sealed class GoneAndRetryWithRetryPolicy : - IRetryPolicy, - IRetryPolicy>, + internal sealed class GoneAndRetryWithRetryPolicy : + IRetryPolicy, + IRetryPolicy>, IRetryPolicy> { private const int defaultWaitTimeInSeconds = 30; @@ -47,9 +47,9 @@ internal sealed class GoneAndRetryWithRetryPolicy : private DocumentServiceRequest request; public GoneAndRetryWithRetryPolicy( - DocumentServiceRequest request = null, - int? waitTimeInSecondsOverride = null, - TimeSpan minBackoffForRegionReroute = default(TimeSpan), + DocumentServiceRequest request = null, + int? waitTimeInSecondsOverride = null, + TimeSpan minBackoffForRegionReroute = default(TimeSpan), bool detectConnectivityIssues = false) { if (waitTimeInSecondsOverride.HasValue) @@ -60,7 +60,7 @@ public GoneAndRetryWithRetryPolicy( { this.waitTimeInSeconds = GoneAndRetryWithRetryPolicy.defaultWaitTimeInSeconds; } - + this.request = request; this.detectConnectivityIssues = detectConnectivityIssues; this.minBackoffForRegionReroute = minBackoffForRegionReroute; @@ -134,8 +134,9 @@ async Task>> IRetryPolicyException thrown by callback /// /// Is the retry helper should retry + [System.Diagnostics.CodeAnalysis.SuppressMessage("Globalization", "CA1305:Specify IFormatProvider", Justification = "Roslyn Baseline 12/12/2022 16:40")] Task>> IRetryPolicy>.ShouldRetryAsync( - Exception exception, + Exception exception, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); @@ -221,10 +222,10 @@ exception is PartitionKeyRangeGoneException || exceptionToThrow = new ServiceUnavailableException( string.Format( - RMResources.ClientUnavailable, - this.request.RequestContext.ClientRequestStatistics.FailedReplicas.Count, + RMResources.ClientUnavailable, + this.request.RequestContext.ClientRequestStatistics.FailedReplicas.Count, this.request.RequestContext.ClientRequestStatistics.RegionsContacted.Count == 0 ? - 1 : this.request.RequestContext.ClientRequestStatistics.RegionsContacted.Count), + 1 : this.request.RequestContext.ClientRequestStatistics.RegionsContacted.Count), exception, exceptionSubStatus); } @@ -288,7 +289,7 @@ exception is PartitionKeyRangeGoneException || } else { - DefaultTrace.TraceCritical("Received unexpected invalid collection exception, request should be non-null.", exception.ToStringWithData()); + DefaultTrace.TraceCritical("Received unexpected invalid collection exception, request should be non-null. {0}", exception.ToStringWithData()); return Task.FromResult(ShouldRetryResult>.NoRetry(new InternalServerErrorException(exception))); } // prevent the caller from refreshing fabric caches. @@ -308,14 +309,14 @@ exception is PartitionKeyRangeGoneException || } DefaultTrace.TraceWarning( - "GoneAndRetryWithRetryPolicy Received exception, will retry, attempt: {0}, regionRerouteAttempt: {1}, backoffTime: {2}, Timeout: {3}, Exception: {4}", - this.attemptCount, - this.regionRerouteAttemptCount, - backoffTime, + "GoneAndRetryWithRetryPolicy Received exception, will retry, attempt: {0}, regionRerouteAttempt: {1}, backoffTime: {2}, Timeout: {3}, Exception: {4}", + this.attemptCount, + this.regionRerouteAttemptCount, + backoffTime, timeout, exception.ToStringWithData()); return Task.FromResult(ShouldRetryResult>.RetryAfter( - backoffTime, + backoffTime, Tuple.Create(forceRefreshAddressCache, true, timeout, currentAttemptCount, this.regionRerouteAttemptCount, backoffTime))); } diff --git a/Microsoft.Azure.Cosmos/src/direct/HttpConstants.cs b/Microsoft.Azure.Cosmos/src/direct/HttpConstants.cs index 6e367a3bb447a96144132be54804e4b94735a6c1..f995a6cf51f53d3a4a43a53415316e24d536bafc 100644 GIT binary patch delta 1759 zcmb7FT}+!*7(Pe4GN5Y!-PxnVhXT$+r%CwSk&yy{^Ya zR3wnnizlwE0M0N<0@&{rN6;o921uSNq?S*t+`2mQA5|S0Rl&6?W7aB~-r-KZ|I`=7 zbkO6au^ajHQ@oOH9o$Uwf7)sFM!t;GwRjOdnXuBtN~J#SmY(EfqGlT%-R-5OlU8b8 zx{C(i&ZpB$R{F=+;Aj^S(TB+n;OPL!KCFKFY;t?y%c+Q_2ua8KfApzN^C!&ISZB9A zAzlKCplAl8y&_1%Ee?vFu#>lLOP&VgMpQ#*#A$TJbz$gES|)3*Uxe|CfD}JSsme<2 zNj|WD;`P34eYshB$*Eh)8qhtAPJZzyEKW;^E-?CnvIn?)wwQW!Ygxy7riP4kt_E9W z)3x?C?&)a5%poB218-352lAj8(8sN^kixo!PMx%8@tw01BB@TkdamIf`fa*m6BET3 z9AR3>HWSKaeWW}zy6_CWF_M$KI`h|Ns%ba5>e0jq_Cj}iu#2g^Q`F<^D4qcB8!XXC zYuiwbDL2#QTXJmzJLxp4{neqDl*$qa!87rL#YWFA*t0XoDWgwEEHw9vDJ$hojxOA; zrsXdyrmpA7NvZ$*rfi&AERdM*@=7HQ-ZD)&U9#&A8hg%DJBwN0nHiesT+7jGEnx5B^^Nr1%@Tk&A7hdsC&1$uuN7-T_^{{Ef*``+GNMQc zz=O9AYgpxVEBUp+W=VEq4WUOTqJCwu$EhyQ$mbIh>O%X_hiOebj51btT!kW7522g| zcNq3#h-fM?03Rzq0dK}->itLL-Sp0|=f3|rHB?bo5LYNPyb|kpX?&mnel25aH6V>I z6wwF!%8wcHWhI60i_eZ7ZKytpBk5SXyE2+38gCi@O2^*160072F{Ee2F$3c zXUTQJ>O$X;vZ5lEulR~#<+t`;gzNPyF}bbn5Vm{@f36~m!jSTCH=Zx1sAHotPj3K6no$81&9pxHV&h7PMhH*3NHKwgF&IdVIPvxhpF*HobPfpqLey zhN@*krQz>=`e3s(6|&+C&RQ`Ae?o!+>ZF;b0(!7@E6rarZBOTDn0hTsQ=DmQ9~=G} zRMGQ0+#4bclD_@WMNNxN>Y1?6&QTAoezcM17E6XqTc*xc%S*i!eWhGKdPcf+_ZgXE zGyZ;RMGb!Ui(PuHE}xz{eO88ZY3#N=`w^gLEk^ax^U|Roe^*-4zNzu|`-}nxb&WH-LjPIB$lMFx@lTu_Nm*5=%8n<8@0h|E=Ad?{_N0$^F0Y ResolveAsync( bool forceRefreshPartitionAddresses, CancellationToken cancellationToken); - Task UpdateAsync( - IReadOnlyList addressCacheTokens, - CancellationToken cancellationToken = default(CancellationToken)); - Task UpdateAsync( ServerKey serverKey, CancellationToken cancellationToken = default(CancellationToken)); diff --git a/Microsoft.Azure.Cosmos/src/direct/InAccountRestoreParameters.cs b/Microsoft.Azure.Cosmos/src/direct/InAccountRestoreParameters.cs index 4a06d15be9..cee6bb8c83 100644 --- a/Microsoft.Azure.Cosmos/src/direct/InAccountRestoreParameters.cs +++ b/Microsoft.Azure.Cosmos/src/direct/InAccountRestoreParameters.cs @@ -14,6 +14,19 @@ public InAccountRestoreParameters() { } + /// + /// Gets or sets the after triggering the InAccount Restore as part of RestoreParameters + /// + /// + /// A valid value should have unique InstanceId in restore parameters. + /// + [JsonProperty(PropertyName = Constants.Properties.InstanceId)] + public string InstanceId + { + get { return base.GetValue(Constants.Properties.InstanceId); } + set { base.SetValue(Constants.Properties.InstanceId, value); } + } + /// /// Gets or sets the for triggering the InAccount Restore as part of RestoreParameters /// @@ -57,7 +70,8 @@ public string SourceBackupLocation internal override void Validate() { base.Validate(); - if (this.RestoreTimestampInUtc == null) + + if (this.RestoreTimestampInUtc == default) { throw new BadRequestException($"{Constants.Properties.RestoreTimestampInUtc} is a required input for in account restore request"); } diff --git a/Microsoft.Azure.Cosmos/src/direct/LoadBalancingChannel.cs b/Microsoft.Azure.Cosmos/src/direct/LoadBalancingChannel.cs index 518ad09396..08279df7c8 100644 --- a/Microsoft.Azure.Cosmos/src/direct/LoadBalancingChannel.cs +++ b/Microsoft.Azure.Cosmos/src/direct/LoadBalancingChannel.cs @@ -59,7 +59,9 @@ public LoadBalancingChannel(Uri serverUri, ChannelProperties channelProperties, channelProperties.IdleTimerPool, channelProperties.CallerId, channelProperties.EnableChannelMultiplexing, - channelProperties.MemoryStreamPool); + channelProperties.MemoryStreamPool, + channelProperties.RemoteCertificateValidationCallback, + channelProperties.DnsResolutionFunction); this.partitions = new LoadBalancingPartition[channelProperties.PartitionCount]; for (int i = 0; i < this.partitions.Length; i++) { diff --git a/Microsoft.Azure.Cosmos/src/direct/LocationNames.cs b/Microsoft.Azure.Cosmos/src/direct/LocationNames.cs index 40e4495b82..4190b1095b 100644 --- a/Microsoft.Azure.Cosmos/src/direct/LocationNames.cs +++ b/Microsoft.Azure.Cosmos/src/direct/LocationNames.cs @@ -369,5 +369,4 @@ static class LocationNames /// internal const string ItalyNorth = "Italy North"; } -} - +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/direct/NameValueCollectionWrapperFactory.cs b/Microsoft.Azure.Cosmos/src/direct/NameValueCollectionWrapperFactory.cs deleted file mode 100644 index 24633075ea..0000000000 --- a/Microsoft.Azure.Cosmos/src/direct/NameValueCollectionWrapperFactory.cs +++ /dev/null @@ -1,49 +0,0 @@ -//------------------------------------------------------------ -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------ - -namespace Microsoft.Azure.Documents.Collections -{ - using System; - using System.Collections.Specialized; - - /// - /// - /// - internal class NameValueCollectionWrapperFactory : INameValueCollectionFactory - { - /// - /// - /// - /// - public INameValueCollection CreateNewNameValueCollection() - { - return new NameValueCollectionWrapper(); - } - - public INameValueCollection CreateNewNameValueCollection(int capacity) - { - return new NameValueCollectionWrapper(capacity); - } - - public INameValueCollection CreateNewNameValueCollection(INameValueCollection collection) - { - return new NameValueCollectionWrapper(collection); - } - - public INameValueCollection CreateNewNameValueCollection(NameValueCollection collection) - { - return NameValueCollectionWrapper.Create(collection); - } - - /// - /// - /// - /// - /// - public INameValueCollection CreateNewNameValueCollection(StringComparer comparer) - { - return new NameValueCollectionWrapper(comparer); - } - } -} diff --git a/Microsoft.Azure.Cosmos/src/direct/OperationType.cs b/Microsoft.Azure.Cosmos/src/direct/OperationType.cs index c5eb03192e..fb4fedfff4 100644 --- a/Microsoft.Azure.Cosmos/src/direct/OperationType.cs +++ b/Microsoft.Azure.Cosmos/src/direct/OperationType.cs @@ -105,6 +105,11 @@ internal enum OperationType GetStorageAuthToken = 59, CreateClientEncryptionKey = 60, ReplaceClientEncryptionKey = 61, + UpdatePartitionThroughput = 62, + + // Operation type for recreating RidRange resources during the pitr restore of a multi master partition + CreateRidRangeResources = 64, + Truncate = 65, #endif // These names make it unclear what they map to in RequestOperationType. @@ -129,6 +134,7 @@ internal enum OperationType GetGraphDatabaseAccountConfiguration = -19, GetCustomerManagedKeyStatus = -20, GetBatchCustomerManagedKeyStatus = -21, + XPDatabaseAccountMetaData = -22, #endif } @@ -184,9 +190,12 @@ public static bool IsWriteOperation(this OperationType type) type == OperationType.GetSplitPoints || type == OperationType.ForcePartitionBackup || type == OperationType.CreateSystemSnapshot || + type == OperationType.CreateRidRangeResources || type == OperationType.UpdateFailoverPriorityList || type == OperationType.Pause || - type == OperationType.Resume + type == OperationType.Resume || + type == OperationType.UpdatePartitionThroughput || + type == OperationType.Truncate #endif ; } diff --git a/Microsoft.Azure.Cosmos/src/direct/PartitionKeyInternalJsonConverter.cs b/Microsoft.Azure.Cosmos/src/direct/PartitionKeyInternalJsonConverter.cs index db63575fcd..9985e6177f 100644 --- a/Microsoft.Azure.Cosmos/src/direct/PartitionKeyInternalJsonConverter.cs +++ b/Microsoft.Azure.Cosmos/src/direct/PartitionKeyInternalJsonConverter.cs @@ -32,7 +32,8 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s writer.WriteStartArray(); - foreach (IPartitionKeyComponent componentValue in partitionKey.Components) + IEnumerable components = partitionKey.Components ?? Enumerable.Empty(); + foreach (IPartitionKeyComponent componentValue in components) { componentValue.JsonEncode(writer); } diff --git a/Microsoft.Azure.Cosmos/src/direct/Paths.cs b/Microsoft.Azure.Cosmos/src/direct/Paths.cs index b89a92861e..f42c54bfcd 100644 --- a/Microsoft.Azure.Cosmos/src/direct/Paths.cs +++ b/Microsoft.Azure.Cosmos/src/direct/Paths.cs @@ -31,6 +31,7 @@ internal static class Paths public const string Operations_ReadReplicaFromServerPartition = "readreplicafromserverpartition"; public const string Operations_MasterInitiatedProgressCoordination = "masterinitiatedprogresscoordination"; public const string Operations_GetAadGroups = "getaadgroups"; + public const string Operations_XPDatabaseAccountMetaData = "xpmetadata"; public const string Operations_MetadataCheckAccess = "metadatacheckaccess"; //databases namespace off of root------------------- @@ -71,6 +72,11 @@ internal static class Paths public const string DatabaseId = "dbId"; public const string Database_Root = Databases_Root + "{" + DatabaseId + "}"; + // FedURL/accounts/{id}/dbs + public const string FederationEndpoint_Databases_Root = FederationEndpoint_Root + "/" + Databases_Root; + // FedURL/accounts/{id}/dbs/{id} + public const string FederationEndpoint_Database_Root = FederationEndpoint_Databases_Root + "{" + DatabaseId + "}"; + // /dbs/{id}/users public const string UsersPathSegment = "users"; public const string Users_Root = Database_Root + "/" + UsersPathSegment + "/"; @@ -111,6 +117,11 @@ internal static class Paths public const string CollectionId = "collId"; public const string Collection_Root = Collections_Root + "{" + CollectionId + "}"; + // FedURL/accounts/{id}/dbs/{id}/colls + public const string FederationEndpoint_Collections_Root = FederationEndpoint_Root + "/" + Collections_Root; + // FedURL/accounts/{id}/dbs/{id}/colls/{id} + public const string FederationEndpoint_Collection_Root = FederationEndpoint_Collections_Root + "{" + CollectionId + "}"; + // /dbs/{id}/colls/{id}/sprocs public const string StoredProceduresPathSegment = "sprocs"; public const string StoredProcedures_Root = Collection_Root + "/" + StoredProceduresPathSegment + "/"; @@ -119,6 +130,11 @@ internal static class Paths public const string StoredProcedureId = "sprocId"; public const string StoredProcedure_Root = StoredProcedures_Root + "{" + StoredProcedureId + "}"; + // FedURL/accounts/{id}/dbs/{id}/colls/{id}/sprocs + public const string FederationEndpoint_StoredProcedures_Root = FederationEndpoint_Root + "/" + StoredProcedures_Root; + // FedURL/accounts/{id}/dbs/{id}/colls/{id}/sprocs/{id} + public const string FederationEndpoint_StoredProcedure_Root = FederationEndpoint_StoredProcedures_Root + "{" + StoredProcedureId + "}"; + // /dbs/{id}/colls/{id}/triggers public const string TriggersPathSegment = "triggers"; public const string Triggers_Root = Collection_Root + "/" + TriggersPathSegment + "/"; @@ -175,6 +191,11 @@ internal static class Paths public const string AttachmentId = "attachmentId"; public const string Attachment_Root = Attachments_Root + "{" + AttachmentId + "}"; + // FedURL/accounts/{id}/dbs/{id}/colls/{id}/docs/{id}/attachments + public const string FederationEndpoint_Attachments_Root = FederationEndpoint_Root + "/" + Attachments_Root; + // FedURL/accounts/{id}/dbs/{id}/colls/{id}/docs/{id}/attachments/{id} + public const string FederationEndpoint_Attachment_Root = FederationEndpoint_Attachments_Root + "{" + AttachmentId + "}"; + // /dbs/{id}/colls/{id}/pkranges public const string PartitionKeyRangesPathSegment = "pkranges"; public const string PartitionKeyRanges_Root = Collection_Root + "/" + PartitionKeyRangesPathSegment + "/"; @@ -183,6 +204,9 @@ internal static class Paths public const string PartitionKeyRangeId = "pkrangeId"; public const string PartitionKeyRange_Root = PartitionKeyRanges_Root + "{" + PartitionKeyRangeId + "}"; + // FedURL/accounts/{id}/dbs/{id}/colls/{id}/pkranges + public const string FederationEndpoint_PartitionKeyRanges_Root = FederationEndpoint_Root + "/" + PartitionKeyRanges_Root; + // /dbs/{id}/colls/{id}/pkranges/{id}/presplitaction public const string PartitionKeyRangePreSplitSegment = "presplitaction"; public const string PartitionKeyRangePreSplit_Root = PartitionKeyRange_Root + "/" + PartitionKeyRangePreSplitSegment + "/"; @@ -236,6 +260,11 @@ internal static class Paths public const string OfferId = "offerId"; public const string Offer_Root = Offers_Root + "{" + OfferId + "}"; + // FedURL/accounts/{id}/offers + public const string FederationEndpoint_Offers_Root = FederationEndpoint_Root + "/" + Offers_Root; + // FedURL/accounts/{id}/offers/{id} + public const string FederationEndpoint_Offer_Root = FederationEndpoint_Offers_Root + "{" + OfferId + "}"; + // /topology public const string TopologyPathSegment = "topology"; public const string Topology_Root = Root + "/" + TopologyPathSegment + "/"; @@ -350,7 +379,7 @@ internal static class Paths // /accounts/{id}/ public const string AccountsPathSegment = "accounts"; public const string AccountId = "accountId"; - public const string FederationEndpoint_Root = Root + "/" + AccountsPathSegment + "/{" + AccountId + "}/"; + public const string FederationEndpoint_Root = Root + "/" + AccountsPathSegment + "/{" + AccountId + "}"; // /accounts/{id}/address public const string FederationEndpoint_Address_Root = FederationEndpoint_Root + "/" + AddressPathSegment + "/"; @@ -362,6 +391,8 @@ internal static class Paths // /clientconfigs public const string ClientConfigPathSegment = "clientconfigs"; public const string ClientConfig_Root = Root + ClientConfigPathSegment; + public const string FederationEndpoint_ClientConfig_Root = FederationEndpoint_Root + ClientConfig_Root; + // /encryptionscopes/{id} public const string EncryptionScopeId = "encryptionscopeid"; diff --git a/Microsoft.Azure.Cosmos/src/direct/PathsHelper.cs b/Microsoft.Azure.Cosmos/src/direct/PathsHelper.cs index 551bcccb24..02c3c758c5 100644 --- a/Microsoft.Azure.Cosmos/src/direct/PathsHelper.cs +++ b/Microsoft.Azure.Cosmos/src/direct/PathsHelper.cs @@ -41,6 +41,8 @@ public static bool TryParsePathSegments( string databaseName = string.Empty; string collectionName = string.Empty; + resourceUrl = PathsHelper.RemoveAccountsSegment(resourceUrl); + if (!string.IsNullOrEmpty(resourceUrl) && resourceUrl.Contains(Paths.OperationsPathSegment) && (resourceUrl.Contains(Paths.PartitionKeyDeletePathSegment) || resourceUrl.Contains(Paths.CollectionTruncatePathsegment))) { @@ -141,6 +143,8 @@ public static bool TryParsePathSegmentsWithDatabaseAndCollectionAndDocumentNames return false; } + resourceUrl = PathsHelper.RemoveAccountsSegment(resourceUrl); + string[] segments = resourceUrl.Split(PathsHelper.PathSeparatorArray, StringSplitOptions.RemoveEmptyEntries); if (segments == null || segments.Length < 1) @@ -364,6 +368,8 @@ public static bool TryParsePathSegmentsWithDatabaseAndCollectionAndOperationName return false; } + resourceUrl = PathsHelper.RemoveAccountsSegment(resourceUrl); + string[] segments = resourceUrl.Split(PathsHelper.PathSeparatorArray, StringSplitOptions.RemoveEmptyEntries); if (segments == null || segments.Length != 6) @@ -1447,6 +1453,8 @@ public static string GenerateRootOperationPath(OperationType operationType) return Paths.OperationsPathSegment + "/" + Paths.Operations_GetFederationConfigurations; case OperationType.GetDatabaseAccountConfigurations: return Paths.OperationsPathSegment + "/" + Paths.Operations_GetDatabaseAccountConfigurations; + case OperationType.XPDatabaseAccountMetaData: + return Paths.OperationsPathSegment + "/" + Paths.Operations_XPDatabaseAccountMetaData; case OperationType.GetGraphDatabaseAccountConfiguration: return Paths.OperationsPathSegment + "/" + Paths.Operations_GetGraphDatabaseAccountConfiguration; case OperationType.GetStorageServiceConfigurations: @@ -1554,6 +1562,7 @@ private static bool IsRootOperation(in StringSegment operationSegment, in String operationTypeSegment.Equals(Paths.Operations_GetStorageAccountKey, StringComparison.OrdinalIgnoreCase) || operationTypeSegment.Equals(Paths.Operations_GetStorageAccountSas, StringComparison.OrdinalIgnoreCase) || operationTypeSegment.Equals(Paths.Operations_GetDatabaseAccountConfigurations, StringComparison.OrdinalIgnoreCase) || + operationTypeSegment.Equals(Paths.Operations_XPDatabaseAccountMetaData, StringComparison.OrdinalIgnoreCase) || operationTypeSegment.Equals(Paths.Operations_GetUnwrappedDek, StringComparison.OrdinalIgnoreCase) || operationTypeSegment.Equals(Paths.Operations_GetCustomerManagedKeyStatus, StringComparison.OrdinalIgnoreCase) || operationTypeSegment.Equals(Paths.Operations_ReadReplicaFromMasterPartition, StringComparison.OrdinalIgnoreCase) || @@ -1575,6 +1584,17 @@ private static bool IsTopLevelOperationOperation(in StringSegment replicaSegment return false; } + public static string RemoveAccountsSegment(string resourceUrl) + { + if (!string.IsNullOrEmpty(resourceUrl) && resourceUrl.StartsWith("/accounts/", StringComparison.OrdinalIgnoreCase)) + { + int index = resourceUrl.IndexOfNth('/', 3); + resourceUrl = resourceUrl.Substring(index, resourceUrl.Length - index); + } + + return resourceUrl; + } + internal static bool IsNameBased(string resourceIdOrFullName) { // quick way to tell whether it is resourceId nor not, non conclusively. diff --git a/Microsoft.Azure.Cosmos/src/direct/PerfCounters.cs b/Microsoft.Azure.Cosmos/src/direct/PerfCounters.cs index bddf45a278..d2f409bc3b 100644 --- a/Microsoft.Azure.Cosmos/src/direct/PerfCounters.cs +++ b/Microsoft.Azure.Cosmos/src/direct/PerfCounters.cs @@ -5,14 +5,13 @@ namespace Microsoft.Azure.Documents { using System; using System.Diagnostics; + using Microsoft.Azure.Cosmos.ServiceFramework.Core; internal sealed class PerfCounters : IDisposable { - public static PerfCounters Counters = new PerfCounters("DocDB Gateway", "Counters for DocDB Gateway"); + private readonly string performanceCategory; - private string performanceCategory; - - private string performanceCategoryHelp; + private readonly string performanceCategoryHelp; private PerformanceCounter frontendRequestsPerSec; @@ -58,10 +57,12 @@ internal sealed class PerfCounters : IDisposable private PerfCounters(string category, string categoryHelp) { - performanceCategory = category; - performanceCategoryHelp = categoryHelp; + this.performanceCategory = category; + this.performanceCategoryHelp = categoryHelp; } + public static PerfCounters Counters { get; } = new PerfCounters("DocDB Gateway", "Counters for DocDB Gateway"); + public PerformanceCounter FrontendRequestsPerSec { get @@ -77,6 +78,7 @@ public PerformanceCounter FrontendActiveRequests return this.frontendActiveRequests; } } + public PerformanceCounter BackendRequestsPerSec { get @@ -229,6 +231,68 @@ public PerformanceCounter BackendConnectionOpenFailuresDueToSynRetransmitPerSeco } } + /// + /// Creates the given performance counter category. + /// + /// Name of the category. + /// Help description. + /// Category type. + /// Counters in the category. + /// + /// Indicates whether machine-wide synchronization should be used to avoid races between different entry-points attempting to create the same category. + /// + /// If the category already exists then it is checked to ensure that the given counters are present. If not, the category is recreated. + internal static void CreatePerfCounterCategory(string category, + string categoryHelp, + PerformanceCounterCategoryType categoryType, + CounterCreationDataCollection counters, + bool useSystemMutex = true) + { + SystemSynchronizationScope syncScope = useSystemMutex ? SystemSynchronizationScope.CreateSynchronizationScope($"CDBPerfCategory-{category}") : default; + + try + { + // If the performance counter category already exists, check if any counters have changed. + if (PerformanceCounterCategory.Exists(category)) + { + PerformanceCounterCategory perfCategory = new PerformanceCounterCategory(category); + bool shouldReturn = true; + foreach (CounterCreationData counter in counters) + { + try + { + if (!perfCategory.CounterExists(counter.CounterName)) + { + shouldReturn = false; + break; + } + } + catch + { + shouldReturn = false; + break; + } + } + + if (shouldReturn) + { + return; + } + else + { + PerformanceCounterCategory.Delete(category); + } + } + + // Create the category. + PerformanceCounterCategory.Create(category, categoryHelp, categoryType, counters); + } + finally + { + syncScope?.Dispose(); + } + } + /// /// Creating performance counter category is a privileged operation and /// hence done in the WinFab service setup entrypoint that is invoked before @@ -280,127 +344,80 @@ public void InstallCounters() counters.Add(new CounterCreationData("Backend Connection Open Failures Due To Syn Retransmit Timeout/sec", "Number of failures per second when connecting to a backend node which failed with WSAETIMEDOUT", PerformanceCounterType.RateOfCountsPerSecond32)); - CreatePerfCounterCategory(performanceCategory, performanceCategoryHelp, PerformanceCounterCategoryType.SingleInstance, counters); - } - - /// - /// Create a perf counter category with the provided name and creates the provided list of perf counters inside - /// the category. - /// - public static void CreatePerfCounterCategory(string category, string categoryHelp, - PerformanceCounterCategoryType categoryType, - CounterCreationDataCollection counters) - { - // If the performance counter category already exists, check if any counters have changed. - if (PerformanceCounterCategory.Exists(category)) - { - PerformanceCounterCategory perfCategory = new PerformanceCounterCategory(category); - bool shouldReturn = true; - foreach (CounterCreationData counter in counters) - { - try - { - if (!perfCategory.CounterExists(counter.CounterName)) - { - shouldReturn = false; - break; - } - } - catch - { - shouldReturn = false; - break; - } - } - - if (shouldReturn) - { - return; - } - else - { - PerformanceCounterCategory.Delete(category); - } - } - - // Create the category. - PerformanceCounterCategory.Create(category, categoryHelp, categoryType, counters); + PerfCounters.CreatePerfCounterCategory(this.performanceCategory, this.performanceCategoryHelp, PerformanceCounterCategoryType.SingleInstance, counters); } public void InitializePerfCounters() { - this.frontendRequestsPerSec = new PerformanceCounter(performanceCategory, "Frontend Requests/sec", false); + this.frontendRequestsPerSec = new PerformanceCounter(this.performanceCategory, "Frontend Requests/sec", false); this.frontendRequestsPerSec.RawValue = 0; - this.frontendActiveRequests = new PerformanceCounter(performanceCategory, "Frontend Active Requests", false); + this.frontendActiveRequests = new PerformanceCounter(this.performanceCategory, "Frontend Active Requests", false); this.frontendActiveRequests.RawValue = 0; - this.admissionControlledRequestsPerSec = new PerformanceCounter(performanceCategory, "Admission Controlled Requests/sec", false); + this.admissionControlledRequestsPerSec = new PerformanceCounter(this.performanceCategory, "Admission Controlled Requests/sec", false); this.admissionControlledRequestsPerSec.RawValue = 0; - this.admissionControlledRequests = new PerformanceCounter(performanceCategory, "Admission Controlled Requests", false); + this.admissionControlledRequests = new PerformanceCounter(this.performanceCategory, "Admission Controlled Requests", false); this.admissionControlledRequests.RawValue = 0; - this.backendRequestsPerSec = new PerformanceCounter(performanceCategory, "Backend Requests/sec", false); + this.backendRequestsPerSec = new PerformanceCounter(this.performanceCategory, "Backend Requests/sec", false); this.backendRequestsPerSec.RawValue = 0; - this.backendActiveRequests = new PerformanceCounter(performanceCategory, "Backend Active Requests", false); + this.backendActiveRequests = new PerformanceCounter(this.performanceCategory, "Backend Active Requests", false); this.backendActiveRequests.RawValue = 0; - this.currentFrontendConnections = new PerformanceCounter(performanceCategory, "Current Frontend Connections", false); + this.currentFrontendConnections = new PerformanceCounter(this.performanceCategory, "Current Frontend Connections", false); this.currentFrontendConnections.RawValue = 0; - this.fabricResolveServiceFailures = new PerformanceCounter(performanceCategory, "Fabric Resolve Service Failures", false); + this.fabricResolveServiceFailures = new PerformanceCounter(this.performanceCategory, "Fabric Resolve Service Failures", false); this.fabricResolveServiceFailures.RawValue = 0; - this.queryRequestsPerSec = new PerformanceCounter(performanceCategory, "Query Requests/sec", false); + this.queryRequestsPerSec = new PerformanceCounter(this.performanceCategory, "Query Requests/sec", false); this.queryRequestsPerSec.RawValue = 0; - this.triggerRequestsPerSec = new PerformanceCounter(performanceCategory, "Trigger Requests/sec", false); + this.triggerRequestsPerSec = new PerformanceCounter(this.performanceCategory, "Trigger Requests/sec", false); this.triggerRequestsPerSec.RawValue = 0; - this.procedureRequestsPerSec = new PerformanceCounter(performanceCategory, "Procedure Requests/sec", false); + this.procedureRequestsPerSec = new PerformanceCounter(this.performanceCategory, "Procedure Requests/sec", false); this.procedureRequestsPerSec.RawValue = 0; - this.averageProcedureRequestsDuration = new PerformanceCounter(performanceCategory, "Average Procedure Requests Duration", false); + this.averageProcedureRequestsDuration = new PerformanceCounter(this.performanceCategory, "Average Procedure Requests Duration", false); this.averageProcedureRequestsDuration.RawValue = 0; - this.averageProcedureRequestsDurationBase = new PerformanceCounter(performanceCategory, "Average Procedure Requests Duration Base", false); + this.averageProcedureRequestsDurationBase = new PerformanceCounter(this.performanceCategory, "Average Procedure Requests Duration Base", false); this.averageProcedureRequestsDurationBase.RawValue = 0; - this.averageQueryRequestsDuration = new PerformanceCounter(performanceCategory, "Average Query Requests Duration", false); + this.averageQueryRequestsDuration = new PerformanceCounter(this.performanceCategory, "Average Query Requests Duration", false); this.averageQueryRequestsDuration.RawValue = 0; - this.averageQueryRequestsDurationBase = new PerformanceCounter(performanceCategory, "Average Query Requests Duration Base", false); + this.averageQueryRequestsDurationBase = new PerformanceCounter(this.performanceCategory, "Average Query Requests Duration Base", false); this.averageQueryRequestsDurationBase.RawValue = 0; - this.backendConnectionOpenAverageLatency = new PerformanceCounter(performanceCategory, "Backend Connection Open Average Latency", false); + this.backendConnectionOpenAverageLatency = new PerformanceCounter(this.performanceCategory, "Backend Connection Open Average Latency", false); this.backendConnectionOpenAverageLatency.RawValue = 0; - this.backendConnectionOpenAverageLatencyBase = new PerformanceCounter(performanceCategory, "Backend Connection Open Average Latency Base", false); + this.backendConnectionOpenAverageLatencyBase = new PerformanceCounter(this.performanceCategory, "Backend Connection Open Average Latency Base", false); this.backendConnectionOpenAverageLatencyBase.RawValue = 0; - this.fabricResolveServiceAverageLatency = new PerformanceCounter(performanceCategory, "Fabric Resolve Service Average Latency", false); + this.fabricResolveServiceAverageLatency = new PerformanceCounter(this.performanceCategory, "Fabric Resolve Service Average Latency", false); this.fabricResolveServiceAverageLatency.RawValue = 0; - this.fabricResolveServiceAverageLatencyBase = new PerformanceCounter(performanceCategory, "Fabric Resolve Service Average Latency Base", false); + this.fabricResolveServiceAverageLatencyBase = new PerformanceCounter(this.performanceCategory, "Fabric Resolve Service Average Latency Base", false); this.fabricResolveServiceAverageLatencyBase.RawValue = 0; - this.routingFailures = new PerformanceCounter(performanceCategory, "Routing Failures", false); + this.routingFailures = new PerformanceCounter(this.performanceCategory, "Routing Failures", false); this.routingFailures.RawValue = 0; - this.backendConnectionOpenFailuresDueToSynRetransmitPerSecond = new PerformanceCounter(performanceCategory, "Backend Connection Open Failures Due To Syn Retransmit Timeout/sec", false); + this.backendConnectionOpenFailuresDueToSynRetransmitPerSecond = new PerformanceCounter(this.performanceCategory, "Backend Connection Open Failures Due To Syn Retransmit Timeout/sec", false); this.backendConnectionOpenFailuresDueToSynRetransmitPerSecond.RawValue = 0; } #region IDisposable Members - // Implement the dispose pattern. The pattern is detailed at: - // - // http://www.bluebytesoftware.com/blog/CategoryView,category,DesignGuideline.aspx - // public void Dispose() { +#pragma warning disable SA1501 using (this.frontendActiveRequests) { } using (this.frontendRequestsPerSec) { } @@ -442,6 +459,7 @@ public void Dispose() using (this.routingFailures) { } using (this.backendConnectionOpenFailuresDueToSynRetransmitPerSecond) { } +#pragma warning restore SA1501 } #endregion diff --git a/Microsoft.Azure.Cosmos/src/direct/PriorityLevel.cs b/Microsoft.Azure.Cosmos/src/direct/PriorityLevel.cs index 811679e214..e0a7967cf3 100644 --- a/Microsoft.Azure.Cosmos/src/direct/PriorityLevel.cs +++ b/Microsoft.Azure.Cosmos/src/direct/PriorityLevel.cs @@ -4,12 +4,7 @@ namespace Microsoft.Azure.Documents { -#if COSMOSCLIENT - internal -#else - public -#endif - enum PriorityLevel + internal enum PriorityLevel { High = 1, Low = 2, diff --git a/Microsoft.Azure.Cosmos/src/direct/RegionProximityUtil.cs b/Microsoft.Azure.Cosmos/src/direct/RegionProximityUtil.cs index 78fd02ceac..f96a560b1d 100644 --- a/Microsoft.Azure.Cosmos/src/direct/RegionProximityUtil.cs +++ b/Microsoft.Azure.Cosmos/src/direct/RegionProximityUtil.cs @@ -2341,7 +2341,7 @@ public static List GeneratePreferredRegionList(string sourceRegion) { LocationNames.BrazilSoutheast, 302 }, { LocationNames.CanadaCentral, 208 }, { LocationNames.CanadaEast, 218 }, - { LocationNames.CentralIndia, 100 }, + { LocationNames.CentralIndia, 30 }, { LocationNames.CentralUS, 222 }, { LocationNames.ChinaEast, long.MaxValue }, { LocationNames.ChinaEast2, long.MaxValue }, @@ -2372,7 +2372,7 @@ public static List GeneratePreferredRegionList(string sourceRegion) { LocationNames.NorwayEast, 146 }, { LocationNames.NorwayWest, 136 }, { LocationNames.PolandCentral, 126 }, - { LocationNames.QatarCentral, 30 }, + { LocationNames.QatarCentral, 100 }, { LocationNames.SouthAfricaNorth, 264 }, { LocationNames.SouthAfricaWest, 267 }, { LocationNames.SouthCentralUS, 224 }, @@ -5580,4 +5580,4 @@ private static long GetLinkTypeThresholdInMs(GeoLinkTypes geoLinkType) } } } -} \ No newline at end of file +} diff --git a/Microsoft.Azure.Cosmos/src/direct/RequestNameValueCollection.cs b/Microsoft.Azure.Cosmos/src/direct/RequestNameValueCollection.cs index 73cd7b7a5b..933cc95553 100644 --- a/Microsoft.Azure.Cosmos/src/direct/RequestNameValueCollection.cs +++ b/Microsoft.Azure.Cosmos/src/direct/RequestNameValueCollection.cs @@ -81,6 +81,7 @@ internal class RequestNameValueCollection : INameValueCollection public string ForceSideBySideIndexMigration { get; set; } public string GatewaySignature { get; set; } public string GetAllPartitionKeyStatistics { get; set; } + public string HighPriorityForcedBackup { get; set; } public string HttpDate { get; set; } public string IfMatch { get; set; } public string IfModifiedSince { get; set; } @@ -99,6 +100,7 @@ internal class RequestNameValueCollection : INameValueCollection public string IsInternalServerlessRequest { get; set; } public string IsMaterializedViewBuild { get; set; } public string IsMaterializedViewSourceSchemaReplaceBatchRequest { get; set; } + public string IsMigratedFixedCollection { get; set; } public string IsOfferStorageRefreshRequest { get; set; } public string IsReadOnlyScript { get; set; } public string IsRetriedWriteRequest { get; set; } @@ -112,7 +114,9 @@ internal class RequestNameValueCollection : INameValueCollection public string MigrateCollectionDirective { get; set; } public string MigrateOfferToAutopilot { get; set; } public string MigrateOfferToManualThroughput { get; set; } + public string NoRetryOn449StatusCode { get; set; } public string OfferReplaceRURedistribution { get; set; } + public string OptimisticDirectExecute { get; set; } public string PageSize { get; set; } public string PartitionCount { get; set; } public string PartitionKey { get; set; } @@ -124,6 +128,7 @@ internal class RequestNameValueCollection : INameValueCollection public string PopulateIndexMetrics { get; set; } public string PopulateIndexMetricsText { get; set; } public string PopulateLogStoreInfo { get; set; } + public string PopulateMinGLSNForDocumentOperations { get; set; } public string PopulateOldestActiveSchemaId { get; set; } public string PopulatePartitionStatistics { get; set; } public string PopulateQueryMetrics { get; set; } @@ -165,13 +170,16 @@ internal class RequestNameValueCollection : INameValueCollection public string SecondaryMasterKey { get; set; } public string SecondaryReadonlyKey { get; set; } public string SessionToken { get; set; } + public string SetMasterResourcesDeletionPending { get; set; } public string ShareThroughput { get; set; } public string ShouldBatchContinueOnError { get; set; } public string ShouldReturnCurrentServerDateTime { get; set; } + public string SkipAdjustThroughputFractionsForOfferReplace { get; set; } public string SkipRefreshDatabaseAccountConfigs { get; set; } public string SourceCollectionIfMatch { get; set; } public string StartEpk { get; set; } public string StartId { get; set; } + public string SupportedSerializationFormats { get; set; } public string SupportSpatialLegacyCoordinates { get; set; } public string SystemDocumentType { get; set; } public string SystemRestoreOperation { get; set; } @@ -187,6 +195,7 @@ internal class RequestNameValueCollection : INameValueCollection public string UniqueIndexReIndexingState { get; set; } public string UpdateMaxThroughputEverProvisioned { get; set; } public string UpdateOfferStateToPending { get; set; } + public string UpdateOfferStateToRestorePending { get; set; } public string UseArchivalPartition { get; set; } public string UsePolygonsSmallerThanAHemisphere { get; set; } public string UseSystemBudget { get; set; } @@ -206,6 +215,14 @@ public RequestNameValueCollection(INameValueCollection nameValueCollection) } } + public RequestNameValueCollection(IDictionary requestHeaders) + { + foreach (KeyValuePair keyValuePair in requestHeaders) + { + this.UpdateHelper(key: keyValuePair.Key, value: keyValuePair.Value, throwIfAlreadyExists: false, ignoreNotCommonHeaders: false); + } + } + /// /// Only process known headers. Ignores nameValueCollection changes by switching to per field assignment if InvalidOperationException happens while iterating over the keys. /// @@ -381,7 +398,16 @@ public static RequestNameValueCollection BuildRequestNameValueCollectionWithKnow requestNameValueCollection.AllowRestoreParamsUpdate = nameValueCollection[HttpConstants.HttpHeaders.AllowRestoreParamsUpdate]; requestNameValueCollection.PruneCollectionSchemas = nameValueCollection[HttpConstants.HttpHeaders.PruneCollectionSchemas]; requestNameValueCollection.PopulateIndexMetricsText = nameValueCollection[HttpConstants.HttpHeaders.PopulateIndexMetricsText]; + requestNameValueCollection.IsMigratedFixedCollection = nameValueCollection[HttpConstants.HttpHeaders.IsMigratedFixedCollection]; + requestNameValueCollection.SupportedSerializationFormats = nameValueCollection[HttpConstants.HttpHeaders.SupportedSerializationFormats]; + requestNameValueCollection.UpdateOfferStateToRestorePending = nameValueCollection[HttpConstants.HttpHeaders.UpdateOfferStateToRestorePending]; + requestNameValueCollection.SetMasterResourcesDeletionPending = nameValueCollection[HttpConstants.HttpHeaders.SetMasterResourcesDeletionPending]; + requestNameValueCollection.HighPriorityForcedBackup = nameValueCollection[HttpConstants.HttpHeaders.HighPriorityForcedBackup]; + requestNameValueCollection.OptimisticDirectExecute = nameValueCollection[HttpConstants.HttpHeaders.OptimisticDirectExecute]; + requestNameValueCollection.PopulateMinGLSNForDocumentOperations = nameValueCollection[WFConstants.BackendHeaders.PopulateMinGLSNForDocumentOperations]; requestNameValueCollection.IfMatch = nameValueCollection[HttpConstants.HttpHeaders.IfMatch]; + requestNameValueCollection.NoRetryOn449StatusCode = nameValueCollection[HttpConstants.HttpHeaders.NoRetryOn449StatusCode]; + requestNameValueCollection.SkipAdjustThroughputFractionsForOfferReplace = nameValueCollection[HttpConstants.HttpHeaders.SkipAdjustThroughputFractionsForOfferReplace]; } return requestNameValueCollection; @@ -463,6 +489,7 @@ public void Clear() this.ForceSideBySideIndexMigration = null; this.GatewaySignature = null; this.GetAllPartitionKeyStatistics = null; + this.HighPriorityForcedBackup = null; this.HttpDate = null; this.IfMatch = null; this.IfModifiedSince = null; @@ -481,6 +508,7 @@ public void Clear() this.IsInternalServerlessRequest = null; this.IsMaterializedViewBuild = null; this.IsMaterializedViewSourceSchemaReplaceBatchRequest = null; + this.IsMigratedFixedCollection = null; this.IsOfferStorageRefreshRequest = null; this.IsReadOnlyScript = null; this.IsRetriedWriteRequest = null; @@ -494,7 +522,9 @@ public void Clear() this.MigrateCollectionDirective = null; this.MigrateOfferToAutopilot = null; this.MigrateOfferToManualThroughput = null; + this.NoRetryOn449StatusCode = null; this.OfferReplaceRURedistribution = null; + this.OptimisticDirectExecute = null; this.PageSize = null; this.PartitionCount = null; this.PartitionKey = null; @@ -506,6 +536,7 @@ public void Clear() this.PopulateIndexMetrics = null; this.PopulateIndexMetricsText = null; this.PopulateLogStoreInfo = null; + this.PopulateMinGLSNForDocumentOperations = null; this.PopulateOldestActiveSchemaId = null; this.PopulatePartitionStatistics = null; this.PopulateQueryMetrics = null; @@ -547,13 +578,16 @@ public void Clear() this.SecondaryMasterKey = null; this.SecondaryReadonlyKey = null; this.SessionToken = null; + this.SetMasterResourcesDeletionPending = null; this.ShareThroughput = null; this.ShouldBatchContinueOnError = null; this.ShouldReturnCurrentServerDateTime = null; + this.SkipAdjustThroughputFractionsForOfferReplace = null; this.SkipRefreshDatabaseAccountConfigs = null; this.SourceCollectionIfMatch = null; this.StartEpk = null; this.StartId = null; + this.SupportedSerializationFormats = null; this.SupportSpatialLegacyCoordinates = null; this.SystemDocumentType = null; this.SystemRestoreOperation = null; @@ -569,6 +603,7 @@ public void Clear() this.UniqueIndexReIndexingState = null; this.UpdateMaxThroughputEverProvisioned = null; this.UpdateOfferStateToPending = null; + this.UpdateOfferStateToRestorePending = null; this.UseArchivalPartition = null; this.UsePolygonsSmallerThanAHemisphere = null; this.UseSystemBudget = null; @@ -627,6 +662,7 @@ public INameValueCollection Clone() ForceSideBySideIndexMigration = this.ForceSideBySideIndexMigration, GatewaySignature = this.GatewaySignature, GetAllPartitionKeyStatistics = this.GetAllPartitionKeyStatistics, + HighPriorityForcedBackup = this.HighPriorityForcedBackup, HttpDate = this.HttpDate, IfMatch = this.IfMatch, IfModifiedSince = this.IfModifiedSince, @@ -645,6 +681,7 @@ public INameValueCollection Clone() IsInternalServerlessRequest = this.IsInternalServerlessRequest, IsMaterializedViewBuild = this.IsMaterializedViewBuild, IsMaterializedViewSourceSchemaReplaceBatchRequest = this.IsMaterializedViewSourceSchemaReplaceBatchRequest, + IsMigratedFixedCollection = this.IsMigratedFixedCollection, IsOfferStorageRefreshRequest = this.IsOfferStorageRefreshRequest, IsReadOnlyScript = this.IsReadOnlyScript, IsRetriedWriteRequest = this.IsRetriedWriteRequest, @@ -658,7 +695,9 @@ public INameValueCollection Clone() MigrateCollectionDirective = this.MigrateCollectionDirective, MigrateOfferToAutopilot = this.MigrateOfferToAutopilot, MigrateOfferToManualThroughput = this.MigrateOfferToManualThroughput, + NoRetryOn449StatusCode = this.NoRetryOn449StatusCode, OfferReplaceRURedistribution = this.OfferReplaceRURedistribution, + OptimisticDirectExecute = this.OptimisticDirectExecute, PageSize = this.PageSize, PartitionCount = this.PartitionCount, PartitionKey = this.PartitionKey, @@ -670,6 +709,7 @@ public INameValueCollection Clone() PopulateIndexMetrics = this.PopulateIndexMetrics, PopulateIndexMetricsText = this.PopulateIndexMetricsText, PopulateLogStoreInfo = this.PopulateLogStoreInfo, + PopulateMinGLSNForDocumentOperations = this.PopulateMinGLSNForDocumentOperations, PopulateOldestActiveSchemaId = this.PopulateOldestActiveSchemaId, PopulatePartitionStatistics = this.PopulatePartitionStatistics, PopulateQueryMetrics = this.PopulateQueryMetrics, @@ -711,13 +751,16 @@ public INameValueCollection Clone() SecondaryMasterKey = this.SecondaryMasterKey, SecondaryReadonlyKey = this.SecondaryReadonlyKey, SessionToken = this.SessionToken, + SetMasterResourcesDeletionPending = this.SetMasterResourcesDeletionPending, ShareThroughput = this.ShareThroughput, ShouldBatchContinueOnError = this.ShouldBatchContinueOnError, ShouldReturnCurrentServerDateTime = this.ShouldReturnCurrentServerDateTime, + SkipAdjustThroughputFractionsForOfferReplace = this.SkipAdjustThroughputFractionsForOfferReplace, SkipRefreshDatabaseAccountConfigs = this.SkipRefreshDatabaseAccountConfigs, SourceCollectionIfMatch = this.SourceCollectionIfMatch, StartEpk = this.StartEpk, StartId = this.StartId, + SupportedSerializationFormats = this.SupportedSerializationFormats, SupportSpatialLegacyCoordinates = this.SupportSpatialLegacyCoordinates, SystemDocumentType = this.SystemDocumentType, SystemRestoreOperation = this.SystemRestoreOperation, @@ -733,6 +776,7 @@ public INameValueCollection Clone() UniqueIndexReIndexingState = this.UniqueIndexReIndexingState, UpdateMaxThroughputEverProvisioned = this.UpdateMaxThroughputEverProvisioned, UpdateOfferStateToPending = this.UpdateOfferStateToPending, + UpdateOfferStateToRestorePending = this.UpdateOfferStateToRestorePending, UseArchivalPartition = this.UseArchivalPartition, UsePolygonsSmallerThanAHemisphere = this.UsePolygonsSmallerThanAHemisphere, UseSystemBudget = this.UseSystemBudget, @@ -1396,12 +1440,48 @@ public IEnumerable Keys() { yield return HttpConstants.HttpHeaders.PopulateIndexMetricsText; } + if (this.IsMigratedFixedCollection != null) + { + yield return HttpConstants.HttpHeaders.IsMigratedFixedCollection; + } + if (this.SupportedSerializationFormats != null) + { + yield return HttpConstants.HttpHeaders.SupportedSerializationFormats; + } + if (this.UpdateOfferStateToRestorePending != null) + { + yield return HttpConstants.HttpHeaders.UpdateOfferStateToRestorePending; + } + if (this.SetMasterResourcesDeletionPending != null) + { + yield return HttpConstants.HttpHeaders.SetMasterResourcesDeletionPending; + } + if (this.HighPriorityForcedBackup != null) + { + yield return HttpConstants.HttpHeaders.HighPriorityForcedBackup; + } + if (this.OptimisticDirectExecute != null) + { + yield return HttpConstants.HttpHeaders.OptimisticDirectExecute; + } + if (this.PopulateMinGLSNForDocumentOperations != null) + { + yield return WFConstants.BackendHeaders.PopulateMinGLSNForDocumentOperations; + } if (this.IfMatch != null) { yield return HttpConstants.HttpHeaders.IfMatch; } + if (this.NoRetryOn449StatusCode != null) + { + yield return HttpConstants.HttpHeaders.NoRetryOn449StatusCode; + } + if (this.SkipAdjustThroughputFractionsForOfferReplace != null) + { + yield return HttpConstants.HttpHeaders.SkipAdjustThroughputFractionsForOfferReplace; + } - if(this.notCommonHeaders != null) + if (this.notCommonHeaders != null) { foreach (string key in this.notCommonHeaders.Keys) { @@ -2046,11 +2126,47 @@ public NameValueCollection ToNameValueCollection() { this.nameValueCollection.Add(HttpConstants.HttpHeaders.PopulateIndexMetricsText, this.PopulateIndexMetricsText); } + if (this.IsMigratedFixedCollection != null) + { + this.nameValueCollection.Add(HttpConstants.HttpHeaders.IsMigratedFixedCollection, this.IsMigratedFixedCollection); + } + if (this.SupportedSerializationFormats != null) + { + this.nameValueCollection.Add(HttpConstants.HttpHeaders.SupportedSerializationFormats, this.SupportedSerializationFormats); + } + if (this.UpdateOfferStateToRestorePending != null) + { + this.nameValueCollection.Add(HttpConstants.HttpHeaders.UpdateOfferStateToRestorePending, this.UpdateOfferStateToRestorePending); + } + if (this.SetMasterResourcesDeletionPending != null) + { + this.nameValueCollection.Add(HttpConstants.HttpHeaders.SetMasterResourcesDeletionPending, this.SetMasterResourcesDeletionPending); + } + if (this.HighPriorityForcedBackup != null) + { + this.nameValueCollection.Add(HttpConstants.HttpHeaders.HighPriorityForcedBackup, this.HighPriorityForcedBackup); + } + if (this.OptimisticDirectExecute != null) + { + this.nameValueCollection.Add(HttpConstants.HttpHeaders.OptimisticDirectExecute, this.OptimisticDirectExecute); + } + if (this.PopulateMinGLSNForDocumentOperations != null) + { + this.nameValueCollection.Add(WFConstants.BackendHeaders.PopulateMinGLSNForDocumentOperations, this.PopulateMinGLSNForDocumentOperations); + } if (this.IfMatch != null) { this.nameValueCollection.Add(HttpConstants.HttpHeaders.IfMatch, this.IfMatch); } - if(this.notCommonHeaders != null) + if (this.NoRetryOn449StatusCode != null) + { + this.nameValueCollection.Add(HttpConstants.HttpHeaders.NoRetryOn449StatusCode, this.NoRetryOn449StatusCode); + } + if (this.SkipAdjustThroughputFractionsForOfferReplace != null) + { + this.nameValueCollection.Add(HttpConstants.HttpHeaders.SkipAdjustThroughputFractionsForOfferReplace, this.SkipAdjustThroughputFractionsForOfferReplace); + } + if (this.notCommonHeaders != null) { foreach (KeyValuePair keyValuePair in this.notCommonHeaders) { @@ -2242,6 +2358,10 @@ public string Get(string key) { return this.RbacAction; } + if (object.ReferenceEquals(HttpConstants.HttpHeaders.NoRetryOn449StatusCode, key)) + { + return this.NoRetryOn449StatusCode; + } if (string.Equals(HttpConstants.HttpHeaders.CanThrottle, key, StringComparison.OrdinalIgnoreCase)) { return this.CanThrottle; @@ -2257,6 +2377,11 @@ public string Get(string key) return this.RbacAction; } + if (string.Equals(HttpConstants.HttpHeaders.NoRetryOn449StatusCode, key, StringComparison.OrdinalIgnoreCase)) + { + return this.NoRetryOn449StatusCode; + } + break; case 17: if (object.ReferenceEquals(HttpConstants.HttpHeaders.Continuation, key)) @@ -3183,11 +3308,24 @@ public string Get(string key) break; case 41: + if (object.ReferenceEquals(HttpConstants.HttpHeaders.ForceDatabaseAccountUpdate, key)) + { + return this.ForceDatabaseAccountUpdate; + } + if (object.ReferenceEquals(HttpConstants.HttpHeaders.OptimisticDirectExecute, key)) + { + return this.OptimisticDirectExecute; + } if (string.Equals(HttpConstants.HttpHeaders.ForceDatabaseAccountUpdate, key, StringComparison.OrdinalIgnoreCase)) { return this.ForceDatabaseAccountUpdate; } + if (string.Equals(HttpConstants.HttpHeaders.OptimisticDirectExecute, key, StringComparison.OrdinalIgnoreCase)) + { + return this.OptimisticDirectExecute; + } + break; case 42: if (object.ReferenceEquals(WFConstants.BackendHeaders.MergeCheckPointGLSN, key)) @@ -3235,6 +3373,10 @@ public string Get(string key) { return this.UniqueIndexNameEncodingMode; } + if (object.ReferenceEquals(HttpConstants.HttpHeaders.SupportedSerializationFormats, key)) + { + return this.SupportedSerializationFormats; + } if (string.Equals(HttpConstants.HttpHeaders.DisableRUPerMinuteUsage, key, StringComparison.OrdinalIgnoreCase)) { return this.DisableRUPerMinuteUsage; @@ -3255,6 +3397,11 @@ public string Get(string key) return this.UniqueIndexNameEncodingMode; } + if (string.Equals(HttpConstants.HttpHeaders.SupportedSerializationFormats, key, StringComparison.OrdinalIgnoreCase)) + { + return this.SupportedSerializationFormats; + } + break; case 44: if (object.ReferenceEquals(HttpConstants.HttpHeaders.ContentSerializationFormat, key)) @@ -3323,6 +3470,10 @@ public string Get(string key) { return this.SkipRefreshDatabaseAccountConfigs; } + if (object.ReferenceEquals(HttpConstants.HttpHeaders.IsMigratedFixedCollection, key)) + { + return this.IsMigratedFixedCollection; + } if (string.Equals(HttpConstants.HttpHeaders.MigrateOfferToManualThroughput, key, StringComparison.OrdinalIgnoreCase)) { return this.MigrateOfferToManualThroughput; @@ -3333,6 +3484,11 @@ public string Get(string key) return this.SkipRefreshDatabaseAccountConfigs; } + if (string.Equals(HttpConstants.HttpHeaders.IsMigratedFixedCollection, key, StringComparison.OrdinalIgnoreCase)) + { + return this.IsMigratedFixedCollection; + } + break; case 47: if (object.ReferenceEquals(HttpConstants.HttpHeaders.SupportSpatialLegacyCoordinates, key)) @@ -3389,6 +3545,10 @@ public string Get(string key) { return this.AllowRestoreParamsUpdate; } + if (object.ReferenceEquals(HttpConstants.HttpHeaders.HighPriorityForcedBackup, key)) + { + return this.HighPriorityForcedBackup; + } if (string.Equals(HttpConstants.HttpHeaders.PopulateCollectionThroughputInfo, key, StringComparison.OrdinalIgnoreCase)) { return this.PopulateCollectionThroughputInfo; @@ -3409,6 +3569,11 @@ public string Get(string key) return this.AllowRestoreParamsUpdate; } + if (string.Equals(HttpConstants.HttpHeaders.HighPriorityForcedBackup, key, StringComparison.OrdinalIgnoreCase)) + { + return this.HighPriorityForcedBackup; + } + break; case 49: if (string.Equals(HttpConstants.HttpHeaders.UsePolygonsSmallerThanAHemisphere, key, StringComparison.OrdinalIgnoreCase)) @@ -3482,6 +3647,10 @@ public string Get(string key) { return this.IsOfferStorageRefreshRequest; } + if (object.ReferenceEquals(WFConstants.BackendHeaders.PopulateMinGLSNForDocumentOperations, key)) + { + return this.PopulateMinGLSNForDocumentOperations; + } if (string.Equals(HttpConstants.HttpHeaders.IsRUPerGBEnforcementRequest, key, StringComparison.OrdinalIgnoreCase)) { return this.IsRUPerGBEnforcementRequest; @@ -3492,6 +3661,11 @@ public string Get(string key) return this.IsOfferStorageRefreshRequest; } + if (string.Equals(WFConstants.BackendHeaders.PopulateMinGLSNForDocumentOperations, key, StringComparison.OrdinalIgnoreCase)) + { + return this.PopulateMinGLSNForDocumentOperations; + } + break; case 54: if (object.ReferenceEquals(HttpConstants.HttpHeaders.IncludePhysicalPartitionThroughputInfo, key)) @@ -3512,6 +3686,13 @@ public string Get(string key) return this.IsMaterializedViewSourceSchemaReplaceBatchRequest; } + break; + case 55: + if (string.Equals(HttpConstants.HttpHeaders.UpdateOfferStateToRestorePending, key, StringComparison.OrdinalIgnoreCase)) + { + return this.UpdateOfferStateToRestorePending; + } + break; case 56: if (string.Equals(WFConstants.BackendHeaders.CollectionChildResourceContentLimitInKB, key, StringComparison.OrdinalIgnoreCase)) @@ -3528,11 +3709,24 @@ public string Get(string key) break; case 58: + if (object.ReferenceEquals(HttpConstants.HttpHeaders.IgnoreSystemLoweringMaxThroughput, key)) + { + return this.IgnoreSystemLoweringMaxThroughput; + } + if (object.ReferenceEquals(HttpConstants.HttpHeaders.SetMasterResourcesDeletionPending, key)) + { + return this.SetMasterResourcesDeletionPending; + } if (string.Equals(HttpConstants.HttpHeaders.IgnoreSystemLoweringMaxThroughput, key, StringComparison.OrdinalIgnoreCase)) { return this.IgnoreSystemLoweringMaxThroughput; } + if (string.Equals(HttpConstants.HttpHeaders.SetMasterResourcesDeletionPending, key, StringComparison.OrdinalIgnoreCase)) + { + return this.SetMasterResourcesDeletionPending; + } + break; case 59: if (string.Equals(HttpConstants.HttpHeaders.UpdateMaxThroughputEverProvisioned, key, StringComparison.OrdinalIgnoreCase)) @@ -3547,6 +3741,13 @@ public string Get(string key) return this.IsServerlessStorageRefreshRequest; } + break; + case 62: + if (string.Equals(HttpConstants.HttpHeaders.SkipAdjustThroughputFractionsForOfferReplace, key, StringComparison.OrdinalIgnoreCase)) + { + return this.SkipAdjustThroughputFractionsForOfferReplace; + } + break; default: break; @@ -3926,6 +4127,16 @@ public void UpdateHelper( this.RbacAction = value; return; } + if (object.ReferenceEquals(HttpConstants.HttpHeaders.NoRetryOn449StatusCode, key)) + { + if (throwIfAlreadyExists && this.NoRetryOn449StatusCode != null) + { + throw new ArgumentException($"The {key} already exists in the collection"); + } + + this.NoRetryOn449StatusCode = value; + return; + } if (string.Equals(HttpConstants.HttpHeaders.CanThrottle, key, StringComparison.OrdinalIgnoreCase)) { if (throwIfAlreadyExists && this.CanThrottle != null) @@ -3956,6 +4167,16 @@ public void UpdateHelper( this.RbacAction = value; return; } + if (string.Equals(HttpConstants.HttpHeaders.NoRetryOn449StatusCode, key, StringComparison.OrdinalIgnoreCase)) + { + if (throwIfAlreadyExists && this.NoRetryOn449StatusCode != null) + { + throw new ArgumentException($"The {key} already exists in the collection"); + } + + this.NoRetryOn449StatusCode = value; + return; + } break; case 17: if (object.ReferenceEquals(HttpConstants.HttpHeaders.Continuation, key)) @@ -5954,6 +6175,26 @@ public void UpdateHelper( } break; case 41: + if (object.ReferenceEquals(HttpConstants.HttpHeaders.ForceDatabaseAccountUpdate, key)) + { + if (throwIfAlreadyExists && this.ForceDatabaseAccountUpdate != null) + { + throw new ArgumentException($"The {key} already exists in the collection"); + } + + this.ForceDatabaseAccountUpdate = value; + return; + } + if (object.ReferenceEquals(HttpConstants.HttpHeaders.OptimisticDirectExecute, key)) + { + if (throwIfAlreadyExists && this.OptimisticDirectExecute != null) + { + throw new ArgumentException($"The {key} already exists in the collection"); + } + + this.OptimisticDirectExecute = value; + return; + } if (string.Equals(HttpConstants.HttpHeaders.ForceDatabaseAccountUpdate, key, StringComparison.OrdinalIgnoreCase)) { if (throwIfAlreadyExists && this.ForceDatabaseAccountUpdate != null) @@ -5964,6 +6205,16 @@ public void UpdateHelper( this.ForceDatabaseAccountUpdate = value; return; } + if (string.Equals(HttpConstants.HttpHeaders.OptimisticDirectExecute, key, StringComparison.OrdinalIgnoreCase)) + { + if (throwIfAlreadyExists && this.OptimisticDirectExecute != null) + { + throw new ArgumentException($"The {key} already exists in the collection"); + } + + this.OptimisticDirectExecute = value; + return; + } break; case 42: if (object.ReferenceEquals(WFConstants.BackendHeaders.MergeCheckPointGLSN, key)) @@ -6068,6 +6319,16 @@ public void UpdateHelper( this.UniqueIndexNameEncodingMode = value; return; } + if (object.ReferenceEquals(HttpConstants.HttpHeaders.SupportedSerializationFormats, key)) + { + if (throwIfAlreadyExists && this.SupportedSerializationFormats != null) + { + throw new ArgumentException($"The {key} already exists in the collection"); + } + + this.SupportedSerializationFormats = value; + return; + } if (string.Equals(HttpConstants.HttpHeaders.DisableRUPerMinuteUsage, key, StringComparison.OrdinalIgnoreCase)) { if (throwIfAlreadyExists && this.DisableRUPerMinuteUsage != null) @@ -6108,6 +6369,16 @@ public void UpdateHelper( this.UniqueIndexNameEncodingMode = value; return; } + if (string.Equals(HttpConstants.HttpHeaders.SupportedSerializationFormats, key, StringComparison.OrdinalIgnoreCase)) + { + if (throwIfAlreadyExists && this.SupportedSerializationFormats != null) + { + throw new ArgumentException($"The {key} already exists in the collection"); + } + + this.SupportedSerializationFormats = value; + return; + } break; case 44: if (object.ReferenceEquals(HttpConstants.HttpHeaders.ContentSerializationFormat, key)) @@ -6254,6 +6525,16 @@ public void UpdateHelper( this.SkipRefreshDatabaseAccountConfigs = value; return; } + if (object.ReferenceEquals(HttpConstants.HttpHeaders.IsMigratedFixedCollection, key)) + { + if (throwIfAlreadyExists && this.IsMigratedFixedCollection != null) + { + throw new ArgumentException($"The {key} already exists in the collection"); + } + + this.IsMigratedFixedCollection = value; + return; + } if (string.Equals(HttpConstants.HttpHeaders.MigrateOfferToManualThroughput, key, StringComparison.OrdinalIgnoreCase)) { if (throwIfAlreadyExists && this.MigrateOfferToManualThroughput != null) @@ -6274,6 +6555,16 @@ public void UpdateHelper( this.SkipRefreshDatabaseAccountConfigs = value; return; } + if (string.Equals(HttpConstants.HttpHeaders.IsMigratedFixedCollection, key, StringComparison.OrdinalIgnoreCase)) + { + if (throwIfAlreadyExists && this.IsMigratedFixedCollection != null) + { + throw new ArgumentException($"The {key} already exists in the collection"); + } + + this.IsMigratedFixedCollection = value; + return; + } break; case 47: if (object.ReferenceEquals(HttpConstants.HttpHeaders.SupportSpatialLegacyCoordinates, key)) @@ -6398,6 +6689,16 @@ public void UpdateHelper( this.AllowRestoreParamsUpdate = value; return; } + if (object.ReferenceEquals(HttpConstants.HttpHeaders.HighPriorityForcedBackup, key)) + { + if (throwIfAlreadyExists && this.HighPriorityForcedBackup != null) + { + throw new ArgumentException($"The {key} already exists in the collection"); + } + + this.HighPriorityForcedBackup = value; + return; + } if (string.Equals(HttpConstants.HttpHeaders.PopulateCollectionThroughputInfo, key, StringComparison.OrdinalIgnoreCase)) { if (throwIfAlreadyExists && this.PopulateCollectionThroughputInfo != null) @@ -6438,6 +6739,16 @@ public void UpdateHelper( this.AllowRestoreParamsUpdate = value; return; } + if (string.Equals(HttpConstants.HttpHeaders.HighPriorityForcedBackup, key, StringComparison.OrdinalIgnoreCase)) + { + if (throwIfAlreadyExists && this.HighPriorityForcedBackup != null) + { + throw new ArgumentException($"The {key} already exists in the collection"); + } + + this.HighPriorityForcedBackup = value; + return; + } break; case 49: if (string.Equals(HttpConstants.HttpHeaders.UsePolygonsSmallerThanAHemisphere, key, StringComparison.OrdinalIgnoreCase)) @@ -6588,6 +6899,16 @@ public void UpdateHelper( this.IsOfferStorageRefreshRequest = value; return; } + if (object.ReferenceEquals(WFConstants.BackendHeaders.PopulateMinGLSNForDocumentOperations, key)) + { + if (throwIfAlreadyExists && this.PopulateMinGLSNForDocumentOperations != null) + { + throw new ArgumentException($"The {key} already exists in the collection"); + } + + this.PopulateMinGLSNForDocumentOperations = value; + return; + } if (string.Equals(HttpConstants.HttpHeaders.IsRUPerGBEnforcementRequest, key, StringComparison.OrdinalIgnoreCase)) { if (throwIfAlreadyExists && this.IsRUPerGBEnforcementRequest != null) @@ -6608,6 +6929,16 @@ public void UpdateHelper( this.IsOfferStorageRefreshRequest = value; return; } + if (string.Equals(WFConstants.BackendHeaders.PopulateMinGLSNForDocumentOperations, key, StringComparison.OrdinalIgnoreCase)) + { + if (throwIfAlreadyExists && this.PopulateMinGLSNForDocumentOperations != null) + { + throw new ArgumentException($"The {key} already exists in the collection"); + } + + this.PopulateMinGLSNForDocumentOperations = value; + return; + } break; case 54: if (object.ReferenceEquals(HttpConstants.HttpHeaders.IncludePhysicalPartitionThroughputInfo, key)) @@ -6651,6 +6982,18 @@ public void UpdateHelper( return; } break; + case 55: + if (string.Equals(HttpConstants.HttpHeaders.UpdateOfferStateToRestorePending, key, StringComparison.OrdinalIgnoreCase)) + { + if (throwIfAlreadyExists && this.UpdateOfferStateToRestorePending != null) + { + throw new ArgumentException($"The {key} already exists in the collection"); + } + + this.UpdateOfferStateToRestorePending = value; + return; + } + break; case 56: if (string.Equals(WFConstants.BackendHeaders.CollectionChildResourceContentLimitInKB, key, StringComparison.OrdinalIgnoreCase)) { @@ -6676,6 +7019,26 @@ public void UpdateHelper( } break; case 58: + if (object.ReferenceEquals(HttpConstants.HttpHeaders.IgnoreSystemLoweringMaxThroughput, key)) + { + if (throwIfAlreadyExists && this.IgnoreSystemLoweringMaxThroughput != null) + { + throw new ArgumentException($"The {key} already exists in the collection"); + } + + this.IgnoreSystemLoweringMaxThroughput = value; + return; + } + if (object.ReferenceEquals(HttpConstants.HttpHeaders.SetMasterResourcesDeletionPending, key)) + { + if (throwIfAlreadyExists && this.SetMasterResourcesDeletionPending != null) + { + throw new ArgumentException($"The {key} already exists in the collection"); + } + + this.SetMasterResourcesDeletionPending = value; + return; + } if (string.Equals(HttpConstants.HttpHeaders.IgnoreSystemLoweringMaxThroughput, key, StringComparison.OrdinalIgnoreCase)) { if (throwIfAlreadyExists && this.IgnoreSystemLoweringMaxThroughput != null) @@ -6686,6 +7049,16 @@ public void UpdateHelper( this.IgnoreSystemLoweringMaxThroughput = value; return; } + if (string.Equals(HttpConstants.HttpHeaders.SetMasterResourcesDeletionPending, key, StringComparison.OrdinalIgnoreCase)) + { + if (throwIfAlreadyExists && this.SetMasterResourcesDeletionPending != null) + { + throw new ArgumentException($"The {key} already exists in the collection"); + } + + this.SetMasterResourcesDeletionPending = value; + return; + } break; case 59: if (string.Equals(HttpConstants.HttpHeaders.UpdateMaxThroughputEverProvisioned, key, StringComparison.OrdinalIgnoreCase)) @@ -6711,6 +7084,18 @@ public void UpdateHelper( return; } break; + case 62: + if (string.Equals(HttpConstants.HttpHeaders.SkipAdjustThroughputFractionsForOfferReplace, key, StringComparison.OrdinalIgnoreCase)) + { + if (throwIfAlreadyExists && this.SkipAdjustThroughputFractionsForOfferReplace != null) + { + throw new ArgumentException($"The {key} already exists in the collection"); + } + + this.SkipAdjustThroughputFractionsForOfferReplace = value; + return; + } + break; default: break; } diff --git a/Microsoft.Azure.Cosmos/src/direct/RequestOptions.cs b/Microsoft.Azure.Cosmos/src/direct/RequestOptions.cs index fd5b76af0a..7700911c57 100644 --- a/Microsoft.Azure.Cosmos/src/direct/RequestOptions.cs +++ b/Microsoft.Azure.Cosmos/src/direct/RequestOptions.cs @@ -626,7 +626,7 @@ sealed class RequestOptions /// /// /// - public PriorityLevel? PriorityLevel { get; set; } + internal PriorityLevel? PriorityLevel { get; set; } #if !COSMOSCLIENT /// diff --git a/Microsoft.Azure.Cosmos/src/direct/RntbdConstants.cs b/Microsoft.Azure.Cosmos/src/direct/RntbdConstants.cs index 675e81f875..1a4b9e9bec 100644 --- a/Microsoft.Azure.Cosmos/src/direct/RntbdConstants.cs +++ b/Microsoft.Azure.Cosmos/src/direct/RntbdConstants.cs @@ -10,6 +10,7 @@ namespace Microsoft.Azure.Documents { using System; using System.Collections.Concurrent; + using System.Collections.Generic; /// /// THIS IS AN AUTOGENERATED FILE. ALL UPDATES SHOULD BE DONE VIA RntbdConstants.tt @@ -122,6 +123,9 @@ public enum RntbdOperationType : ushort CreateSystemSnapshot = 0x0032, UpdateFailoverPriorityList = 0x0033, GetStorageAuthToken = 0x0034, + UpdatePartitionThroughput = 0x0035, + CreateRidRangeResources = 0x0036, + Truncate = 0x0037, } public enum ConnectionContextRequestTokenIdentifiers : ushort @@ -270,6 +274,15 @@ public enum RntbdContentSerializationFormat : byte Invalid = 0xFF, } + [Flags] + public enum RntbdSupportedSerializationFormats : byte + { + None = 0x00, + JsonText = 0x01, + CosmosBinary = 0x02, + HybridRow = 0x04, + } + public enum RntbdSystemDocumentType : byte { PartitionKey = 0x00, @@ -472,7 +485,14 @@ public enum RequestIdentifiers : ushort PriorityLevel = 0x00BF, AllowRestoreParamsUpdate = 0x00C0, PruneCollectionSchemas = 0x00C1, - PopulateIndexMetricsText = 0x00C2 + PopulateIndexMetricsText = 0x00C2, + IsMigratedFixedCollection = 0x00C3, + SupportedSerializationFormats = 0x00C4, + UpdateOfferStateToRestorePending = 0x00C5, + SetMasterResourcesDeletionPending = 0x00C6, + HighPriorityForcedBackup = 0x00C7, + OptimisticDirectExecute = 0x00C8, + PopulateMinGLSNForDocumentOperations = 0x00C9, } public sealed class Request : RntbdTokenStream @@ -657,6 +677,13 @@ public sealed class Request : RntbdTokenStream public RntbdToken allowRestoreParamsUpdate; public RntbdToken pruneCollectionSchemas; public RntbdToken populateIndexMetricsText; + public RntbdToken isMigratedFixedCollection; + public RntbdToken supportedSerializationFormats; + public RntbdToken updateOfferStateToRestorePending; + public RntbdToken setMasterResourcesDeletionPending; + public RntbdToken highPriorityForcedBackup; + public RntbdToken optimisticDirectExecute; + public RntbdToken populateMinGLSNForDocumentOperations; public Request() { @@ -838,6 +865,13 @@ public Request() this.allowRestoreParamsUpdate = new RntbdToken(false, RntbdTokenTypes.String, (ushort)RequestIdentifiers.AllowRestoreParamsUpdate); this.pruneCollectionSchemas = new RntbdToken(false, RntbdTokenTypes.Byte, (ushort)RequestIdentifiers.PruneCollectionSchemas); this.populateIndexMetricsText = new RntbdToken(false, RntbdTokenTypes.Byte, (ushort)RequestIdentifiers.PopulateIndexMetricsText); + this.isMigratedFixedCollection = new RntbdToken(false, RntbdTokenTypes.Byte, (ushort)RequestIdentifiers.IsMigratedFixedCollection); + this.supportedSerializationFormats = new RntbdToken(false, RntbdTokenTypes.Byte, (ushort)RequestIdentifiers.SupportedSerializationFormats); + this.updateOfferStateToRestorePending = new RntbdToken(false, RntbdTokenTypes.Byte, (ushort)RequestIdentifiers.UpdateOfferStateToRestorePending); + this.setMasterResourcesDeletionPending = new RntbdToken(false, RntbdTokenTypes.Byte, (ushort)RequestIdentifiers.SetMasterResourcesDeletionPending); + this.highPriorityForcedBackup = new RntbdToken(false, RntbdTokenTypes.Byte, (ushort)RequestIdentifiers.HighPriorityForcedBackup); + this.optimisticDirectExecute = new RntbdToken(false, RntbdTokenTypes.Byte, (ushort)RequestIdentifiers.OptimisticDirectExecute); + this.populateMinGLSNForDocumentOperations = new RntbdToken(false, RntbdTokenTypes.Byte, (ushort)RequestIdentifiers.PopulateMinGLSNForDocumentOperations); this.tokens = new RntbdToken[] { @@ -1036,21 +1070,37 @@ public Request() this.allowRestoreParamsUpdate, this.pruneCollectionSchemas, this.populateIndexMetricsText, + this.isMigratedFixedCollection, + this.supportedSerializationFormats, + this.updateOfferStateToRestorePending, + this.setMasterResourcesDeletionPending, + this.highPriorityForcedBackup, + this.optimisticDirectExecute, + this.populateMinGLSNForDocumentOperations, }; } } + // Values are generated from the common source where response headers ordered by the chance headers could apper on response. + // This order helps in constracting more performant switch statements in the loop(s) processing response headers. public enum ResponseIdentifiers : ushort { + TransportRequestID = 0x0035, + ServerDateTimeUtc = 0x0039, + SubStatus = 0x001C, + ETag = 0x0004, + ResourceName = 0x0047, + RequestCharge = 0x0015, + SessionToken = 0x003E, + ContinuationToken = 0x0003, + LSN = 0x0013, + GlobalCommittedLSN = 0x0029, + ItemLSN = 0x0032, + LocalLSN = 0x003A, + QuorumAckedLocalLSN = 0x003B, + ItemLocalLSN = 0x003C, PayloadPresent = 0x0000, LastStateChangeDateTime = 0x0002, - ContinuationToken = 0x0003, - ETag = 0x0004, - ReadsPerformed = 0x0007, - WritesPerformed = 0x0008, - QueriesPerformed = 0x0009, - IndexTermsGenerated = 0x000A, - ScriptsExecuted = 0x000B, RetryAfterMilliseconds = 0x000C, IndexingDirective = 0x000D, StorageMaxResoureQuota = 0x000E, @@ -1058,15 +1108,12 @@ public enum ResponseIdentifiers : ushort SchemaVersion = 0x0010, CollectionPartitionIndex = 0x0011, CollectionServiceIndex = 0x0012, - LSN = 0x0013, ItemCount = 0x0014, - RequestCharge = 0x0015, OwnerFullName = 0x0017, OwnerId = 0x0018, DatabaseAccountId = 0x0019, QuorumAckedLSN = 0x001A, RequestValidationFailure = 0x001B, - SubStatus = 0x001C, CollectionUpdateProgress = 0x001D, CurrentWriteQuorum = 0x001E, CurrentReplicaSetSize = 0x001F, @@ -1076,21 +1123,13 @@ public enum ResponseIdentifiers : ushort XPRole = 0x0026, IsRUPerMinuteUsed = 0x0027, QueryMetrics = 0x0028, - GlobalCommittedLSN = 0x0029, NumberOfReadRegions = 0x0030, OfferReplacePending = 0x0031, - ItemLSN = 0x0032, RestoreState = 0x0033, CollectionSecurityIdentifier = 0x0034, - TransportRequestID = 0x0035, ShareThroughput = 0x0036, DisableRntbdChannel = 0x0038, - ServerDateTimeUtc = 0x0039, - LocalLSN = 0x003A, - QuorumAckedLocalLSN = 0x003B, - ItemLocalLSN = 0x003C, HasTentativeWrites = 0x003D, - SessionToken = 0x003E, ReplicatorLSNToGLSNDelta = 0x003F, ReplicatorLSNToLLSNDelta = 0x0040, VectorClockLocalProgress = 0x0041, @@ -1099,7 +1138,6 @@ public enum ResponseIdentifiers : ushort IndexUtilization = 0x0044, QueryExecutionInfo = 0x0045, UnflushedMergeLogEntryCount = 0x0046, - ResourceName = 0x0047, TimeToLiveInSeconds = 0x0048, ReplicaStatusRevoked = 0x0049, SoftMaxAllowedThroughput = 0x0050, @@ -1122,280 +1160,11 @@ public enum ResponseIdentifiers : ushort MaxContentLength = 0x0061, OldestActiveSchemaId = 0x0062, PhysicalPartitionId = 0x0063, - } - - public sealed class Response : RntbdTokenStream - { - public override int RequiredTokenCount => 1; - - public RntbdToken payloadPresent; - public RntbdToken lastStateChangeDateTime; - public RntbdToken continuationToken; - public RntbdToken eTag; - public RntbdToken readsPerformed; - public RntbdToken writesPerformed; - public RntbdToken queriesPerformed; - public RntbdToken indexTermsGenerated; - public RntbdToken scriptsExecuted; - public RntbdToken retryAfterMilliseconds; - public RntbdToken indexingDirective; - public RntbdToken storageMaxResoureQuota; - public RntbdToken storageResourceQuotaUsage; - public RntbdToken schemaVersion; - public RntbdToken collectionPartitionIndex; - public RntbdToken collectionServiceIndex; - public RntbdToken lSN; - public RntbdToken itemCount; - public RntbdToken requestCharge; - public RntbdToken ownerFullName; - public RntbdToken ownerId; - public RntbdToken databaseAccountId; - public RntbdToken quorumAckedLSN; - public RntbdToken requestValidationFailure; - public RntbdToken subStatus; - public RntbdToken collectionUpdateProgress; - public RntbdToken currentWriteQuorum; - public RntbdToken currentReplicaSetSize; - public RntbdToken collectionLazyIndexProgress; - public RntbdToken partitionKeyRangeId; - public RntbdToken logResults; - public RntbdToken xPRole; - public RntbdToken isRUPerMinuteUsed; - public RntbdToken queryMetrics; - public RntbdToken globalCommittedLSN; - public RntbdToken numberOfReadRegions; - public RntbdToken offerReplacePending; - public RntbdToken itemLSN; - public RntbdToken restoreState; - public RntbdToken collectionSecurityIdentifier; - public RntbdToken transportRequestID; - public RntbdToken shareThroughput; - public RntbdToken disableRntbdChannel; - public RntbdToken serverDateTimeUtc; - public RntbdToken localLSN; - public RntbdToken quorumAckedLocalLSN; - public RntbdToken itemLocalLSN; - public RntbdToken hasTentativeWrites; - public RntbdToken sessionToken; - public RntbdToken replicatorLSNToGLSNDelta; - public RntbdToken replicatorLSNToLLSNDelta; - public RntbdToken vectorClockLocalProgress; - public RntbdToken minimumRUsForOffer; - public RntbdToken xPConfigurationSessionsCount; - public RntbdToken indexUtilization; - public RntbdToken queryExecutionInfo; - public RntbdToken unflushedMergeLogEntryCount; - public RntbdToken resourceName; - public RntbdToken timeToLiveInSeconds; - public RntbdToken replicaStatusRevoked; - public RntbdToken softMaxAllowedThroughput; - public RntbdToken backendRequestDurationMilliseconds; - public RntbdToken correlatedActivityId; - public RntbdToken confirmedStoreChecksum; - public RntbdToken tentativeStoreChecksum; - public RntbdToken pendingPKDelete; - public RntbdToken aadAppliedRoleAssignmentId; - public RntbdToken collectionUniqueIndexReIndexProgress; - public RntbdToken collectionUniqueKeysUnderReIndex; - public RntbdToken analyticalMigrationProgress; - public RntbdToken totalAccountThroughput; - public RntbdToken bYOKEncryptionProgress; - public RntbdToken appliedPolicyElementId; - public RntbdToken mergeProgressBlocked; - public RntbdToken changeFeedInfo; - public RntbdToken reindexerProgress; - public RntbdToken offerReplacePendingForMerge; - public RntbdToken maxContentLength; - public RntbdToken oldestActiveSchemaId; - public RntbdToken physicalPartitionId; - - public Response() - { - this.payloadPresent = new RntbdToken(true, RntbdTokenTypes.Byte, (ushort)ResponseIdentifiers.PayloadPresent); - this.lastStateChangeDateTime = new RntbdToken(false, RntbdTokenTypes.SmallString, (ushort)ResponseIdentifiers.LastStateChangeDateTime); - this.continuationToken = new RntbdToken(false, RntbdTokenTypes.String, (ushort)ResponseIdentifiers.ContinuationToken); - this.eTag = new RntbdToken(false, RntbdTokenTypes.String, (ushort)ResponseIdentifiers.ETag); - this.readsPerformed = new RntbdToken(false, RntbdTokenTypes.ULong, (ushort)ResponseIdentifiers.ReadsPerformed); - this.writesPerformed = new RntbdToken(false, RntbdTokenTypes.ULong, (ushort)ResponseIdentifiers.WritesPerformed); - this.queriesPerformed = new RntbdToken(false, RntbdTokenTypes.ULong, (ushort)ResponseIdentifiers.QueriesPerformed); - this.indexTermsGenerated = new RntbdToken(false, RntbdTokenTypes.ULong, (ushort)ResponseIdentifiers.IndexTermsGenerated); - this.scriptsExecuted = new RntbdToken(false, RntbdTokenTypes.ULong, (ushort)ResponseIdentifiers.ScriptsExecuted); - this.retryAfterMilliseconds = new RntbdToken(false, RntbdTokenTypes.ULong, (ushort)ResponseIdentifiers.RetryAfterMilliseconds); - this.indexingDirective = new RntbdToken(false, RntbdTokenTypes.Byte, (ushort)ResponseIdentifiers.IndexingDirective); - this.storageMaxResoureQuota = new RntbdToken(false, RntbdTokenTypes.String, (ushort)ResponseIdentifiers.StorageMaxResoureQuota); - this.storageResourceQuotaUsage = new RntbdToken(false, RntbdTokenTypes.String, (ushort)ResponseIdentifiers.StorageResourceQuotaUsage); - this.schemaVersion = new RntbdToken(false, RntbdTokenTypes.SmallString, (ushort)ResponseIdentifiers.SchemaVersion); - this.collectionPartitionIndex = new RntbdToken(false, RntbdTokenTypes.ULong, (ushort)ResponseIdentifiers.CollectionPartitionIndex); - this.collectionServiceIndex = new RntbdToken(false, RntbdTokenTypes.ULong, (ushort)ResponseIdentifiers.CollectionServiceIndex); - this.lSN = new RntbdToken(false, RntbdTokenTypes.LongLong, (ushort)ResponseIdentifiers.LSN); - this.itemCount = new RntbdToken(false, RntbdTokenTypes.ULong, (ushort)ResponseIdentifiers.ItemCount); - this.requestCharge = new RntbdToken(false, RntbdTokenTypes.Double, (ushort)ResponseIdentifiers.RequestCharge); - this.ownerFullName = new RntbdToken(false, RntbdTokenTypes.String, (ushort)ResponseIdentifiers.OwnerFullName); - this.ownerId = new RntbdToken(false, RntbdTokenTypes.String, (ushort)ResponseIdentifiers.OwnerId); - this.databaseAccountId = new RntbdToken(false, RntbdTokenTypes.String, (ushort)ResponseIdentifiers.DatabaseAccountId); - this.quorumAckedLSN = new RntbdToken(false, RntbdTokenTypes.LongLong, (ushort)ResponseIdentifiers.QuorumAckedLSN); - this.requestValidationFailure = new RntbdToken(false, RntbdTokenTypes.Byte, (ushort)ResponseIdentifiers.RequestValidationFailure); - this.subStatus = new RntbdToken(false, RntbdTokenTypes.ULong, (ushort)ResponseIdentifiers.SubStatus); - this.collectionUpdateProgress = new RntbdToken(false, RntbdTokenTypes.ULong, (ushort)ResponseIdentifiers.CollectionUpdateProgress); - this.currentWriteQuorum = new RntbdToken(false, RntbdTokenTypes.ULong, (ushort)ResponseIdentifiers.CurrentWriteQuorum); - this.currentReplicaSetSize = new RntbdToken(false, RntbdTokenTypes.ULong, (ushort)ResponseIdentifiers.CurrentReplicaSetSize); - this.collectionLazyIndexProgress = new RntbdToken(false, RntbdTokenTypes.ULong, (ushort)ResponseIdentifiers.CollectionLazyIndexProgress); - this.partitionKeyRangeId = new RntbdToken(false, RntbdTokenTypes.String, (ushort)ResponseIdentifiers.PartitionKeyRangeId); - this.logResults = new RntbdToken(false, RntbdTokenTypes.String, (ushort)ResponseIdentifiers.LogResults); - this.xPRole = new RntbdToken(false, RntbdTokenTypes.ULong, (ushort)ResponseIdentifiers.XPRole); - this.isRUPerMinuteUsed = new RntbdToken(false, RntbdTokenTypes.Byte, (ushort)ResponseIdentifiers.IsRUPerMinuteUsed); - this.queryMetrics = new RntbdToken(false, RntbdTokenTypes.String, (ushort)ResponseIdentifiers.QueryMetrics); - this.globalCommittedLSN = new RntbdToken(false, RntbdTokenTypes.LongLong, (ushort)ResponseIdentifiers.GlobalCommittedLSN); - this.numberOfReadRegions = new RntbdToken(false, RntbdTokenTypes.ULong, (ushort)ResponseIdentifiers.NumberOfReadRegions); - this.offerReplacePending = new RntbdToken(false, RntbdTokenTypes.Byte, (ushort)ResponseIdentifiers.OfferReplacePending); - this.itemLSN = new RntbdToken(false, RntbdTokenTypes.LongLong, (ushort)ResponseIdentifiers.ItemLSN); - this.restoreState = new RntbdToken(false, RntbdTokenTypes.String, (ushort)ResponseIdentifiers.RestoreState); - this.collectionSecurityIdentifier = new RntbdToken(false, RntbdTokenTypes.String, (ushort)ResponseIdentifiers.CollectionSecurityIdentifier); - this.transportRequestID = new RntbdToken(false, RntbdTokenTypes.ULong, (ushort)ResponseIdentifiers.TransportRequestID); - this.shareThroughput = new RntbdToken(false, RntbdTokenTypes.Byte, (ushort)ResponseIdentifiers.ShareThroughput); - this.disableRntbdChannel = new RntbdToken(false, RntbdTokenTypes.Byte, (ushort)ResponseIdentifiers.DisableRntbdChannel); - this.serverDateTimeUtc = new RntbdToken(false, RntbdTokenTypes.SmallString, (ushort)ResponseIdentifiers.ServerDateTimeUtc); - this.localLSN = new RntbdToken(false, RntbdTokenTypes.LongLong, (ushort)ResponseIdentifiers.LocalLSN); - this.quorumAckedLocalLSN = new RntbdToken(false, RntbdTokenTypes.LongLong, (ushort)ResponseIdentifiers.QuorumAckedLocalLSN); - this.itemLocalLSN = new RntbdToken(false, RntbdTokenTypes.LongLong, (ushort)ResponseIdentifiers.ItemLocalLSN); - this.hasTentativeWrites = new RntbdToken(false, RntbdTokenTypes.Byte, (ushort)ResponseIdentifiers.HasTentativeWrites); - this.sessionToken = new RntbdToken(false, RntbdTokenTypes.String, (ushort)ResponseIdentifiers.SessionToken); - this.replicatorLSNToGLSNDelta = new RntbdToken(false, RntbdTokenTypes.LongLong, (ushort)ResponseIdentifiers.ReplicatorLSNToGLSNDelta); - this.replicatorLSNToLLSNDelta = new RntbdToken(false, RntbdTokenTypes.LongLong, (ushort)ResponseIdentifiers.ReplicatorLSNToLLSNDelta); - this.vectorClockLocalProgress = new RntbdToken(false, RntbdTokenTypes.LongLong, (ushort)ResponseIdentifiers.VectorClockLocalProgress); - this.minimumRUsForOffer = new RntbdToken(false, RntbdTokenTypes.ULong, (ushort)ResponseIdentifiers.MinimumRUsForOffer); - this.xPConfigurationSessionsCount = new RntbdToken(false, RntbdTokenTypes.ULong, (ushort)ResponseIdentifiers.XPConfigurationSessionsCount); - this.indexUtilization = new RntbdToken(false, RntbdTokenTypes.String, (ushort)ResponseIdentifiers.IndexUtilization); - this.queryExecutionInfo = new RntbdToken(false, RntbdTokenTypes.String, (ushort)ResponseIdentifiers.QueryExecutionInfo); - this.unflushedMergeLogEntryCount = new RntbdToken(false, RntbdTokenTypes.LongLong, (ushort)ResponseIdentifiers.UnflushedMergeLogEntryCount); - this.resourceName = new RntbdToken(false, RntbdTokenTypes.String, (ushort)ResponseIdentifiers.ResourceName); - this.timeToLiveInSeconds = new RntbdToken(false, RntbdTokenTypes.LongLong, (ushort)ResponseIdentifiers.TimeToLiveInSeconds); - this.replicaStatusRevoked = new RntbdToken(false, RntbdTokenTypes.Byte, (ushort)ResponseIdentifiers.ReplicaStatusRevoked); - this.softMaxAllowedThroughput = new RntbdToken(false, RntbdTokenTypes.ULong, (ushort)ResponseIdentifiers.SoftMaxAllowedThroughput); - this.backendRequestDurationMilliseconds = new RntbdToken(false, RntbdTokenTypes.Double, (ushort)ResponseIdentifiers.BackendRequestDurationMilliseconds); - this.correlatedActivityId = new RntbdToken(false, RntbdTokenTypes.Guid, (ushort)ResponseIdentifiers.CorrelatedActivityId); - this.confirmedStoreChecksum = new RntbdToken(false, RntbdTokenTypes.ULongLong, (ushort)ResponseIdentifiers.ConfirmedStoreChecksum); - this.tentativeStoreChecksum = new RntbdToken(false, RntbdTokenTypes.ULongLong, (ushort)ResponseIdentifiers.TentativeStoreChecksum); - this.pendingPKDelete = new RntbdToken(false, RntbdTokenTypes.Byte, (ushort)ResponseIdentifiers.PendingPKDelete); - this.aadAppliedRoleAssignmentId = new RntbdToken(false, RntbdTokenTypes.String, (ushort)ResponseIdentifiers.AadAppliedRoleAssignmentId); - this.collectionUniqueIndexReIndexProgress = new RntbdToken(false, RntbdTokenTypes.ULong, (ushort)ResponseIdentifiers.CollectionUniqueIndexReIndexProgress); - this.collectionUniqueKeysUnderReIndex = new RntbdToken(false, RntbdTokenTypes.String, (ushort)ResponseIdentifiers.CollectionUniqueKeysUnderReIndex); - this.analyticalMigrationProgress = new RntbdToken(false, RntbdTokenTypes.ULong, (ushort)ResponseIdentifiers.AnalyticalMigrationProgress); - this.totalAccountThroughput = new RntbdToken(false, RntbdTokenTypes.LongLong, (ushort)ResponseIdentifiers.TotalAccountThroughput); - this.bYOKEncryptionProgress = new RntbdToken(false, RntbdTokenTypes.Long, (ushort)ResponseIdentifiers.BYOKEncryptionProgress); - this.appliedPolicyElementId = new RntbdToken(false, RntbdTokenTypes.String, (ushort)ResponseIdentifiers.AppliedPolicyElementId); - this.mergeProgressBlocked = new RntbdToken(false, RntbdTokenTypes.Byte, (ushort)ResponseIdentifiers.MergeProgressBlocked); - this.changeFeedInfo = new RntbdToken(false, RntbdTokenTypes.String, (ushort)ResponseIdentifiers.ChangeFeedInfo); - this.reindexerProgress = new RntbdToken(false, RntbdTokenTypes.String, (ushort)ResponseIdentifiers.ReindexerProgress); - this.offerReplacePendingForMerge = new RntbdToken(false, RntbdTokenTypes.Byte, (ushort)ResponseIdentifiers.OfferReplacePendingForMerge); - this.maxContentLength = new RntbdToken(false, RntbdTokenTypes.ULong, (ushort)ResponseIdentifiers.MaxContentLength); - this.oldestActiveSchemaId = new RntbdToken(false, RntbdTokenTypes.Long, (ushort)ResponseIdentifiers.OldestActiveSchemaId); - this.physicalPartitionId = new RntbdToken(false, RntbdTokenTypes.String, (ushort)ResponseIdentifiers.PhysicalPartitionId); - - this.tokens = new RntbdToken[] - { - this.payloadPresent, - null, // 0x0001 - this.lastStateChangeDateTime, - this.continuationToken, - this.eTag, - null, // 0x0005 - null, // 0x0006 - this.readsPerformed, - this.writesPerformed, - this.queriesPerformed, - this.indexTermsGenerated, - this.scriptsExecuted, - this.retryAfterMilliseconds, - this.indexingDirective, - this.storageMaxResoureQuota, - this.storageResourceQuotaUsage, - this.schemaVersion, - this.collectionPartitionIndex, - this.collectionServiceIndex, - this.lSN, - this.itemCount, - this.requestCharge, - null, // 0x0016 - this.ownerFullName, - this.ownerId, - this.databaseAccountId, - this.quorumAckedLSN, - this.requestValidationFailure, - this.subStatus, - this.collectionUpdateProgress, - this.currentWriteQuorum, - this.currentReplicaSetSize, - this.collectionLazyIndexProgress, - this.partitionKeyRangeId, - null, // 0x0022 - null, // 0x0023 - null, // 0x0024 - this.logResults, - this.xPRole, - this.isRUPerMinuteUsed, - this.queryMetrics, - this.globalCommittedLSN, - null, // 0x002A - null, // 0x002B - null, // 0x002C - null, // 0x002D - null, // 0x002E - null, // 0x002F - this.numberOfReadRegions, - this.offerReplacePending, - this.itemLSN, - this.restoreState, - this.collectionSecurityIdentifier, - this.transportRequestID, - this.shareThroughput, - null, // 0x0037 - this.disableRntbdChannel, - this.serverDateTimeUtc, - this.localLSN, - this.quorumAckedLocalLSN, - this.itemLocalLSN, - this.hasTentativeWrites, - this.sessionToken, - this.replicatorLSNToGLSNDelta, - this.replicatorLSNToLLSNDelta, - this.vectorClockLocalProgress, - this.minimumRUsForOffer, - this.xPConfigurationSessionsCount, - this.indexUtilization, - this.queryExecutionInfo, - this.unflushedMergeLogEntryCount, - this.resourceName, - this.timeToLiveInSeconds, - this.replicaStatusRevoked, - null, // 0x004A - null, // 0x004B - null, // 0x004C - null, // 0x004D - null, // 0x004E - null, // 0x004F - this.softMaxAllowedThroughput, - this.backendRequestDurationMilliseconds, - this.correlatedActivityId, - this.confirmedStoreChecksum, - this.tentativeStoreChecksum, - this.pendingPKDelete, - this.aadAppliedRoleAssignmentId, - this.collectionUniqueIndexReIndexProgress, - this.collectionUniqueKeysUnderReIndex, - this.analyticalMigrationProgress, - this.totalAccountThroughput, - this.bYOKEncryptionProgress, - this.appliedPolicyElementId, - this.mergeProgressBlocked, - this.changeFeedInfo, - this.reindexerProgress, - this.offerReplacePendingForMerge, - this.maxContentLength, - this.oldestActiveSchemaId, - this.physicalPartitionId - }; - } + OfferRestorePending = 0x0064, + InstantScaleUpValue = 0x0065, + RequiresDistribution = 0x0066, + CapacityType = 0x0067, + MinGLSNForDocumentOperations = 0x0068, } // diff --git a/Microsoft.Azure.Cosmos/src/direct/RntbdStreamReader.cs b/Microsoft.Azure.Cosmos/src/direct/RntbdStreamReader.cs index f96f01b3c7..7be205cda1 100644 --- a/Microsoft.Azure.Cosmos/src/direct/RntbdStreamReader.cs +++ b/Microsoft.Azure.Cosmos/src/direct/RntbdStreamReader.cs @@ -80,12 +80,12 @@ private async ValueTask PopulateBytesAndReadAsync(byte[] payload, int offse // if the count requested is bigger than the buffer just read directly into the target payload. if (count >= this.buffer.Length) { - return await this.stream.ReadAsync(payload, offset, count); + return await this.ReadStreamAsync(payload, offset, count); } else { this.offset = 0; - this.length = await this.stream.ReadAsync(this.buffer, offset: 0, this.buffer.Length); + this.length = await this.ReadStreamAsync(this.buffer, offset: 0, this.buffer.Length); if (this.length == 0) { // graceful closure. @@ -100,7 +100,7 @@ private async ValueTask PopulateBytesAndReadAsync(MemoryStream payload, int { Debug.Assert(this.length == 0); this.offset = 0; - this.length = await this.stream.ReadAsync(this.buffer, offset: 0, this.buffer.Length); + this.length = await this.ReadStreamAsync(this.buffer, offset: 0, this.buffer.Length); if (this.length == 0) { // graceful closure. @@ -167,5 +167,23 @@ private int CopyFromAvailableBytes(MemoryStream payload, int count) throw new IOException("Error copying buffered bytes", e); } } + + /// + /// Helper, used to ensure we always issue a zero-byte read before a real one. + /// + /// We do this because, as of .NET 6, all built-in streams will avoid pinning + /// memory for long periods of time if we follow this pattern. + /// + /// See: https://github.com/dotnet/runtime/issues/76029 + /// For the precipitating issue. + /// + private async Task ReadStreamAsync(byte[] buffer, int offset, int count) + { + // this should not complete until we have data to read + await this.stream.ReadAsync(Array.Empty(), 0, 0); + + // this should complete almost immediately + return await this.stream.ReadAsync(buffer, offset, count); + } } } diff --git a/Microsoft.Azure.Cosmos/src/direct/SDKSupportedCapabilities.cs b/Microsoft.Azure.Cosmos/src/direct/SDKSupportedCapabilities.cs index a178abb10f..f5cd68a0ac 100644 --- a/Microsoft.Azure.Cosmos/src/direct/SDKSupportedCapabilities.cs +++ b/Microsoft.Azure.Cosmos/src/direct/SDKSupportedCapabilities.cs @@ -10,5 +10,6 @@ internal enum SDKSupportedCapabilities : ulong { None = 0, PartitionMerge = 1 << 0, + ChangeFeedWithStartTimePostMerge = 1 << 1 } } diff --git a/Microsoft.Azure.Cosmos/src/direct/SnapshotContent.cs b/Microsoft.Azure.Cosmos/src/direct/SnapshotContent.cs index e79a9978d7..e019a29ba8 100644 --- a/Microsoft.Azure.Cosmos/src/direct/SnapshotContent.cs +++ b/Microsoft.Azure.Cosmos/src/direct/SnapshotContent.cs @@ -329,6 +329,19 @@ internal set } } + [JsonProperty(PropertyName = Constants.SnapshotProperties.IsMasterResourcesDeletionPending)] + public bool? IsMasterResourcesDeletionPending + { + get + { + return base.GetValue(Constants.SnapshotProperties.IsMasterResourcesDeletionPending, null); + } + internal set + { + base.SetValue(Constants.SnapshotProperties.IsMasterResourcesDeletionPending, value); + } + } + /// /// Gets the list of PartitionKeyRanges. /// diff --git a/Microsoft.Azure.Cosmos/src/direct/StatusCodes.cs b/Microsoft.Azure.Cosmos/src/direct/StatusCodes.cs index 3fa2250dda..85d541664f 100644 --- a/Microsoft.Azure.Cosmos/src/direct/StatusCodes.cs +++ b/Microsoft.Azure.Cosmos/src/direct/StatusCodes.cs @@ -97,11 +97,16 @@ internal enum SubStatusCodes ConfigurationNameAlreadyExists = 3207, PartitionkeyHashCollisionForId = 3302, + // 409: Partition migration Count mismatch conflict sub status codes + PartitionMigrationDocumentCountMismatchBetweenSourceAndTargetPartition = 3050, + PartitionMigrationDocumentCountMismatchBetweenTargetPartitionReplicas = 3051, + // 503: Service Unavailable due to region being out of capacity for bindable partitions InsufficientBindablePartitions = 1007, ComputeFederationNotFound = 1012, OperationPaused = 9001, ServiceIsOffline = 9002, + InsufficientCapacity = 9003, //412: PreCondition Failed SplitIsDisabled = 2001, @@ -119,6 +124,7 @@ internal enum SubStatusCodes OfferValidationFailed = 2017, CanNotAquireMasterPartitionAccessLock = 2018, CanNotAcquireInAccountRestoreInProgressLock = 2019, + CollectionStateChanged = 2020, //412: PreConditionFailed migration substatus codes PartitionMigrationCancelledForPendingUserOperation = 2006, @@ -133,15 +139,14 @@ internal enum SubStatusCodes PartitionMigrationFailedToResolvePartitionInformation = 2026, PartitionMigrationTopologyHasWriteRegionEmpty = 2027, PartitionMigrationIsDisableOnTheGlobalDatabaseAccount = 2028, - - // 500: InternalServerError migration sub status codes - PartitionMigrationDocumentCountMismatchBetweenSourceAndTargetPartition = 3050, - PartitionMigrationDocumentCountMismatchBetweenTargetPartitionReplicas = 3051, + PartitionMigrationIsDisableOnTheRunnerAccount = 2029, + PartitionMigrationCanNotProceedForInactiveRegionalDatabaseAccount = 2030, // 500: InternalServerError ConfigurationNameNotEmpty = 3001, ConfigurationOperationCancelled = 3002, InvalidAccountConfiguration = 3003, + FederationDoesnotExistOrIsLocked = 3004, // 429: Request Rate Too Large PrepareTimeLimitExceeded = 3207, @@ -166,7 +171,8 @@ internal enum SubStatusCodes InvalidKeyVaultKeyAndCertURI = 4011, // Indicate the Key Vault Key and Cert URI is invalid. CustomerKeyRotated = 4012, // Indicates the rewrapped key doesn't match with existing key. MissingRequestParameter = 4013, // Indicates that the incoming request has missing parameters. - InvalidKeyVaultSecretURI = 4014, // Indicate the Key Vault secret URI is invalid. + InvalidKeyVaultSecretURI = 4014, // Indicates the Key Vault secret URI is invalid. + UndefinedDefaultIdentity = 4015, // Indicates that the account has an undefined default identity. // Keep in sync with Microsoft.Azure.Cosmos.ServiceFramework.Security.AadAuthentication.AadSubStatusCodes // 401 : Unauthorized Exception (User-side errors start with 50) @@ -211,7 +217,6 @@ internal enum SubStatusCodes NspNotInitiated = 5312, NspOperationNotSupported = 5313, - // 200 OK. List feed throttled response. ListResourceFeedThrottled = 5500, diff --git a/Microsoft.Azure.Cosmos/src/direct/StoreClientFactory.cs b/Microsoft.Azure.Cosmos/src/direct/StoreClientFactory.cs index c5ea4f4421..a6fcc8727f 100644 --- a/Microsoft.Azure.Cosmos/src/direct/StoreClientFactory.cs +++ b/Microsoft.Azure.Cosmos/src/direct/StoreClientFactory.cs @@ -7,6 +7,7 @@ namespace Microsoft.Azure.Documents using System; using System.Diagnostics; using System.Net.Security; + using System.Threading.Tasks; using Microsoft.Azure.Cosmos.Core.Trace; using Microsoft.Azure.Documents.Client; @@ -47,7 +48,8 @@ public StoreClientFactory( bool enableChannelMultiplexing = false, int rntbdMaxConcurrentOpeningConnectionCount = ushort.MaxValue, // Optional for Rntbd MemoryStreamPool memoryStreamPool = null, - RemoteCertificateValidationCallback remoteCertificateValidationCallback = null) + RemoteCertificateValidationCallback remoteCertificateValidationCallback = null, + Func> dnsResolutionFunction = null) // optional override { // <=0 means idle timeout is disabled. // valid value: >= 10 minutes @@ -218,6 +220,7 @@ public StoreClientFactory( MaxConcurrentOpeningConnectionCount = rntbdMaxConcurrentOpeningConnectionCount, MemoryStreamPool = memoryStreamPool, RemoteCertificateValidationCallback = remoteCertificateValidationCallback, + DnsResolutionFunction = dnsResolutionFunction }); this.fallbackTransportClient = new Rntbd.TransportClient( @@ -243,6 +246,7 @@ public StoreClientFactory( MaxConcurrentOpeningConnectionCount = rntbdMaxConcurrentOpeningConnectionCount, MemoryStreamPool = memoryStreamPool, RemoteCertificateValidationCallback = remoteCertificateValidationCallback, + DnsResolutionFunction = dnsResolutionFunction }); } else diff --git a/Microsoft.Azure.Cosmos/src/direct/StoreReader.cs b/Microsoft.Azure.Cosmos/src/direct/StoreReader.cs index c04c48fd10..27060d0dcb 100644 --- a/Microsoft.Azure.Cosmos/src/direct/StoreReader.cs +++ b/Microsoft.Azure.Cosmos/src/direct/StoreReader.cs @@ -181,14 +181,6 @@ private async Task ReadMultipleReplicasInternalAsync(Document includePrimary, entity.RequestContext.ForceRefreshAddressCache); - if (!string.IsNullOrEmpty(requestedCollectionRid) && !string.IsNullOrEmpty(entity.RequestContext.ResolvedCollectionRid)) - { - if (!requestedCollectionRid.Equals(entity.RequestContext.ResolvedCollectionRid)) - { - this.sessionContainer.ClearTokenByResourceId(requestedCollectionRid); - } - } - ISessionToken requestSessionToken = null; if (useSessionToken) { @@ -430,7 +422,7 @@ private async Task ReadPrimaryInternalAsync( DateTime startTimeUtc = DateTime.UtcNow; StrongBox endTimeUtc = new (); - using ReferenceCountedDisposable storeResult = await this.GetResult(entity, requiresValidLsn, primaryUri, endTimeUtc); + using ReferenceCountedDisposable storeResult = await GetResult(entity, requiresValidLsn, primaryUri, endTimeUtc); entity.RequestContext.ClientRequestStatistics.RecordResponse( entity, storeResult.Target, diff --git a/Microsoft.Azure.Cosmos/src/direct/StoreResponseNameValueCollection.cs b/Microsoft.Azure.Cosmos/src/direct/StoreResponseNameValueCollection.cs index 6023fb724c..36122f41c7 100644 --- a/Microsoft.Azure.Cosmos/src/direct/StoreResponseNameValueCollection.cs +++ b/Microsoft.Azure.Cosmos/src/direct/StoreResponseNameValueCollection.cs @@ -11,6 +11,7 @@ namespace Microsoft.Azure.Documents.Collections using System.Collections.Generic; using System.Collections.Specialized; using System.Linq; + using System.Threading; using Microsoft.Azure.Documents; /// @@ -22,7 +23,9 @@ namespace Microsoft.Azure.Documents.Collections internal class StoreResponseNameValueCollection : INameValueCollection, IEnumerable> { private static readonly StringComparer DefaultStringComparer = StringComparer.OrdinalIgnoreCase; - private readonly Lazy> lazyNotCommonHeaders; + + // this is null if it's never been added to, and is created in a thread safe manner via GetOrCreateLazyHeaders() + private Dictionary lazyNotCommonHeaders; // The INameValueCollection interface is expected to be a replacement for NameValueCollection across the projects. // However, there are a few public API with NameValueCollection as return type, e.g. DocumentServiceResponse.ResponseHeaders and @@ -42,6 +45,7 @@ internal class StoreResponseNameValueCollection : INameValueCollection, IEnumera public string AppliedPolicyElementId { get; set; } public string BackendRequestDurationMilliseconds { get; set; } public string ByokEncryptionProgress { get; set; } + public string CapacityType { get; set; } public string ChangeFeedInfo { get; set; } public string CollectionIndexTransformationProgress { get; set; } public string CollectionLazyIndexingProgress { get; set; } @@ -63,6 +67,8 @@ internal class StoreResponseNameValueCollection : INameValueCollection, IEnumera public string HasTentativeWrites { get; set; } public string IndexingDirective { get; set; } public string IndexUtilization { get; set; } + public string InstantScaleUpValue { get; set; } + public string IsOfferRestorePending { get; set; } public string IsRUPerMinuteUsed { get; set; } public string ItemCount { get; set; } public string ItemLocalLSN { get; set; } @@ -74,6 +80,7 @@ internal class StoreResponseNameValueCollection : INameValueCollection, IEnumera public string MaxContentLength { get; set; } public string MaxResourceQuota { get; set; } public string MergeProgressBlocked { get; set; } + public string MinGLSNForDocumentOperations { get; set; } public string MinimumRUsForOffer { get; set; } public string NumberOfReadRegions { get; set; } public string OfferReplacePending { get; set; } @@ -94,6 +101,7 @@ internal class StoreResponseNameValueCollection : INameValueCollection, IEnumera public string ReplicatorLSNToLLSNDelta { get; set; } public string RequestCharge { get; set; } public string RequestValidationFailure { get; set; } + public string RequiresDistribution { get; set; } public string ResourceId { get; set; } public string RestoreState { get; set; } public string RetryAfterInMilliseconds { get; set; } @@ -114,13 +122,12 @@ internal class StoreResponseNameValueCollection : INameValueCollection, IEnumera public string XPRole { get; set; } public StoreResponseNameValueCollection() - : this(new Lazy>(() => new Dictionary(StoreResponseNameValueCollection.DefaultStringComparer))) { } - private StoreResponseNameValueCollection(Lazy> notCommonHeaders) + private StoreResponseNameValueCollection(Dictionary lazyNotCommonHeaders) { - this.lazyNotCommonHeaders = notCommonHeaders ?? throw new ArgumentNullException(nameof(notCommonHeaders)); + this.lazyNotCommonHeaders = lazyNotCommonHeaders; } public string this[string key] @@ -149,9 +156,9 @@ public string[] AllKeys() public void Clear() { - if (this.lazyNotCommonHeaders.IsValueCreated) + if (this.lazyNotCommonHeaders != null) { - this.lazyNotCommonHeaders.Value.Clear(); + this.lazyNotCommonHeaders.Clear(); } this.AadAppliedRoleAssignmentId = null; @@ -160,6 +167,7 @@ public void Clear() this.AppliedPolicyElementId = null; this.BackendRequestDurationMilliseconds = null; this.ByokEncryptionProgress = null; + this.CapacityType = null; this.ChangeFeedInfo = null; this.CollectionIndexTransformationProgress = null; this.CollectionLazyIndexingProgress = null; @@ -181,6 +189,8 @@ public void Clear() this.HasTentativeWrites = null; this.IndexingDirective = null; this.IndexUtilization = null; + this.InstantScaleUpValue = null; + this.IsOfferRestorePending = null; this.IsRUPerMinuteUsed = null; this.ItemCount = null; this.ItemLocalLSN = null; @@ -192,6 +202,7 @@ public void Clear() this.MaxContentLength = null; this.MaxResourceQuota = null; this.MergeProgressBlocked = null; + this.MinGLSNForDocumentOperations = null; this.MinimumRUsForOffer = null; this.NumberOfReadRegions = null; this.OfferReplacePending = null; @@ -212,6 +223,7 @@ public void Clear() this.ReplicatorLSNToLLSNDelta = null; this.RequestCharge = null; this.RequestValidationFailure = null; + this.RequiresDistribution = null; this.ResourceId = null; this.RestoreState = null; this.RetryAfterInMilliseconds = null; @@ -235,13 +247,10 @@ public void Clear() public INameValueCollection Clone() { - Lazy> cloneNotCommonHeaders = new Lazy>(() => new Dictionary(StoreResponseNameValueCollection.DefaultStringComparer)); - if (this.lazyNotCommonHeaders.IsValueCreated) + Dictionary cloneNotCommonHeaders = null; + if (this.lazyNotCommonHeaders != null) { - foreach (KeyValuePair notCommonHeader in this.lazyNotCommonHeaders.Value) - { - cloneNotCommonHeaders.Value[notCommonHeader.Key] = notCommonHeader.Value; - } + cloneNotCommonHeaders = new Dictionary(this.lazyNotCommonHeaders, StoreResponseNameValueCollection.DefaultStringComparer); } StoreResponseNameValueCollection cloneHeaders = new StoreResponseNameValueCollection(cloneNotCommonHeaders) @@ -252,6 +261,7 @@ public INameValueCollection Clone() AppliedPolicyElementId = this.AppliedPolicyElementId, BackendRequestDurationMilliseconds = this.BackendRequestDurationMilliseconds, ByokEncryptionProgress = this.ByokEncryptionProgress, + CapacityType = this.CapacityType, ChangeFeedInfo = this.ChangeFeedInfo, CollectionIndexTransformationProgress = this.CollectionIndexTransformationProgress, CollectionLazyIndexingProgress = this.CollectionLazyIndexingProgress, @@ -273,6 +283,8 @@ public INameValueCollection Clone() HasTentativeWrites = this.HasTentativeWrites, IndexingDirective = this.IndexingDirective, IndexUtilization = this.IndexUtilization, + InstantScaleUpValue = this.InstantScaleUpValue, + IsOfferRestorePending = this.IsOfferRestorePending, IsRUPerMinuteUsed = this.IsRUPerMinuteUsed, ItemCount = this.ItemCount, ItemLocalLSN = this.ItemLocalLSN, @@ -284,6 +296,7 @@ public INameValueCollection Clone() MaxContentLength = this.MaxContentLength, MaxResourceQuota = this.MaxResourceQuota, MergeProgressBlocked = this.MergeProgressBlocked, + MinGLSNForDocumentOperations = this.MinGLSNForDocumentOperations, MinimumRUsForOffer = this.MinimumRUsForOffer, NumberOfReadRegions = this.NumberOfReadRegions, OfferReplacePending = this.OfferReplacePending, @@ -304,6 +317,7 @@ public INameValueCollection Clone() ReplicatorLSNToLLSNDelta = this.ReplicatorLSNToLLSNDelta, RequestCharge = this.RequestCharge, RequestValidationFailure = this.RequestValidationFailure, + RequiresDistribution = this.RequiresDistribution, ResourceId = this.ResourceId, RestoreState = this.RestoreState, RetryAfterInMilliseconds = this.RetryAfterInMilliseconds, @@ -643,10 +657,30 @@ IEnumerator> IEnumerable(HttpConstants.HttpHeaders.MaxContentLength, this.MaxContentLength); } + if (this.IsOfferRestorePending != null) + { + yield return new KeyValuePair(HttpConstants.HttpHeaders.IsOfferRestorePending, this.IsOfferRestorePending); + } + if (this.InstantScaleUpValue != null) + { + yield return new KeyValuePair(HttpConstants.HttpHeaders.InstantScaleUpValue, this.InstantScaleUpValue); + } + if (this.RequiresDistribution != null) + { + yield return new KeyValuePair(WFConstants.BackendHeaders.RequiresDistribution, this.RequiresDistribution); + } + if (this.CapacityType != null) + { + yield return new KeyValuePair(HttpConstants.HttpHeaders.CapacityType, this.CapacityType); + } + if (this.MinGLSNForDocumentOperations != null) + { + yield return new KeyValuePair(WFConstants.BackendHeaders.MinGLSNForDocumentOperations, this.MinGLSNForDocumentOperations); + } - if (this.lazyNotCommonHeaders.IsValueCreated) + if (this.lazyNotCommonHeaders != null) { - foreach (KeyValuePair kvp in this.lazyNotCommonHeaders.Value) + foreach (KeyValuePair kvp in this.lazyNotCommonHeaders) { yield return kvp; } @@ -970,10 +1004,30 @@ public IEnumerable Keys() { yield return HttpConstants.HttpHeaders.MaxContentLength; } + if (this.IsOfferRestorePending != null) + { + yield return HttpConstants.HttpHeaders.IsOfferRestorePending; + } + if (this.InstantScaleUpValue != null) + { + yield return HttpConstants.HttpHeaders.InstantScaleUpValue; + } + if (this.RequiresDistribution != null) + { + yield return WFConstants.BackendHeaders.RequiresDistribution; + } + if (this.CapacityType != null) + { + yield return HttpConstants.HttpHeaders.CapacityType; + } + if (this.MinGLSNForDocumentOperations != null) + { + yield return WFConstants.BackendHeaders.MinGLSNForDocumentOperations; + } - if(this.lazyNotCommonHeaders.IsValueCreated) + if (this.lazyNotCommonHeaders != null) { - foreach (string key in this.lazyNotCommonHeaders.Value.Keys) + foreach (string key in this.lazyNotCommonHeaders.Keys) { yield return key; } @@ -1296,9 +1350,29 @@ public NameValueCollection ToNameValueCollection() { this.nameValueCollection.Add(HttpConstants.HttpHeaders.MaxContentLength, this.MaxContentLength); } - if(this.lazyNotCommonHeaders.IsValueCreated) + if (this.IsOfferRestorePending != null) + { + this.nameValueCollection.Add(HttpConstants.HttpHeaders.IsOfferRestorePending, this.IsOfferRestorePending); + } + if (this.InstantScaleUpValue != null) { - foreach (KeyValuePair keyValuePair in this.lazyNotCommonHeaders.Value) + this.nameValueCollection.Add(HttpConstants.HttpHeaders.InstantScaleUpValue, this.InstantScaleUpValue); + } + if (this.RequiresDistribution != null) + { + this.nameValueCollection.Add(WFConstants.BackendHeaders.RequiresDistribution, this.RequiresDistribution); + } + if (this.CapacityType != null) + { + this.nameValueCollection.Add(HttpConstants.HttpHeaders.CapacityType, this.CapacityType); + } + if (this.MinGLSNForDocumentOperations != null) + { + this.nameValueCollection.Add(WFConstants.BackendHeaders.MinGLSNForDocumentOperations, this.MinGLSNForDocumentOperations); + } + if(this.lazyNotCommonHeaders != null) + { + foreach (KeyValuePair keyValuePair in this.lazyNotCommonHeaders) { this.nameValueCollection.Add(keyValuePair.Key, keyValuePair.Value); } @@ -1593,6 +1667,10 @@ public string Get(string key) { return this.TransportRequestID; } + if (object.ReferenceEquals(HttpConstants.HttpHeaders.CapacityType, key)) + { + return this.CapacityType; + } if (string.Equals(WFConstants.BackendHeaders.CurrentWriteQuorum, key, StringComparison.OrdinalIgnoreCase)) { return this.CurrentWriteQuorum; @@ -1608,6 +1686,11 @@ public string Get(string key) return this.TransportRequestID; } + if (string.Equals(HttpConstants.HttpHeaders.CapacityType, key, StringComparison.OrdinalIgnoreCase)) + { + return this.CapacityType; + } + break; case 26: if (object.ReferenceEquals(HttpConstants.HttpHeaders.LastStateChangeUtc, key)) @@ -1630,6 +1713,10 @@ public string Get(string key) { return this.MinimumRUsForOffer; } + if (object.ReferenceEquals(HttpConstants.HttpHeaders.IsOfferRestorePending, key)) + { + return this.IsOfferRestorePending; + } if (string.Equals(HttpConstants.HttpHeaders.LastStateChangeUtc, key, StringComparison.OrdinalIgnoreCase)) { return this.LastStateChangeUtc; @@ -1655,6 +1742,11 @@ public string Get(string key) return this.MinimumRUsForOffer; } + if (string.Equals(HttpConstants.HttpHeaders.IsOfferRestorePending, key, StringComparison.OrdinalIgnoreCase)) + { + return this.IsOfferRestorePending; + } + break; case 27: if (object.ReferenceEquals(WFConstants.BackendHeaders.NumberOfReadRegions, key)) @@ -1709,6 +1801,10 @@ public string Get(string key) { return this.QuorumAckedLocalLSN; } + if (object.ReferenceEquals(WFConstants.BackendHeaders.MinGLSNForDocumentOperations, key)) + { + return this.MinGLSNForDocumentOperations; + } if (string.Equals(WFConstants.BackendHeaders.CurrentReplicaSetSize, key, StringComparison.OrdinalIgnoreCase)) { return this.CurrentReplicaSetSize; @@ -1729,6 +1825,11 @@ public string Get(string key) return this.QuorumAckedLocalLSN; } + if (string.Equals(WFConstants.BackendHeaders.MinGLSNForDocumentOperations, key, StringComparison.OrdinalIgnoreCase)) + { + return this.MinGLSNForDocumentOperations; + } + break; case 30: if (object.ReferenceEquals(WFConstants.BackendHeaders.ReIndexerProgress, key)) @@ -1824,6 +1925,10 @@ public string Get(string key) { return this.HasTentativeWrites; } + if (object.ReferenceEquals(HttpConstants.HttpHeaders.InstantScaleUpValue, key)) + { + return this.InstantScaleUpValue; + } if (string.Equals(HttpConstants.HttpHeaders.LogResults, key, StringComparison.OrdinalIgnoreCase)) { return this.LogResults; @@ -1834,6 +1939,11 @@ public string Get(string key) return this.HasTentativeWrites; } + if (string.Equals(HttpConstants.HttpHeaders.InstantScaleUpValue, key, StringComparison.OrdinalIgnoreCase)) + { + return this.InstantScaleUpValue; + } + break; case 35: if (object.ReferenceEquals(WFConstants.BackendHeaders.PartitionKeyRangeId, key)) @@ -1935,6 +2045,10 @@ public string Get(string key) { return this.TentativeStoreChecksum; } + if (object.ReferenceEquals(WFConstants.BackendHeaders.RequiresDistribution, key)) + { + return this.RequiresDistribution; + } if (string.Equals(WFConstants.BackendHeaders.VectorClockLocalProgress, key, StringComparison.OrdinalIgnoreCase)) { return this.VectorClockLocalProgress; @@ -1950,6 +2064,11 @@ public string Get(string key) return this.TentativeStoreChecksum; } + if (string.Equals(WFConstants.BackendHeaders.RequiresDistribution, key, StringComparison.OrdinalIgnoreCase)) + { + return this.RequiresDistribution; + } + break; case 40: if (string.Equals(WFConstants.BackendHeaders.SoftMaxAllowedThroughput, key, StringComparison.OrdinalIgnoreCase)) @@ -2024,8 +2143,7 @@ public string Get(string key) break; } - if (this.lazyNotCommonHeaders.IsValueCreated - && this.lazyNotCommonHeaders.Value.TryGetValue(key, out string value)) + if (this.lazyNotCommonHeaders?.TryGetValue(key, out string value) ?? false) { return value; } @@ -2620,6 +2738,16 @@ public void UpdateHelper( this.TransportRequestID = value; return; } + if (object.ReferenceEquals(HttpConstants.HttpHeaders.CapacityType, key)) + { + if (throwIfAlreadyExists && this.CapacityType != null) + { + throw new ArgumentException($"The {key} already exists in the collection"); + } + + this.CapacityType = value; + return; + } if (string.Equals(WFConstants.BackendHeaders.CurrentWriteQuorum, key, StringComparison.OrdinalIgnoreCase)) { if (throwIfAlreadyExists && this.CurrentWriteQuorum != null) @@ -2650,6 +2778,16 @@ public void UpdateHelper( this.TransportRequestID = value; return; } + if (string.Equals(HttpConstants.HttpHeaders.CapacityType, key, StringComparison.OrdinalIgnoreCase)) + { + if (throwIfAlreadyExists && this.CapacityType != null) + { + throw new ArgumentException($"The {key} already exists in the collection"); + } + + this.CapacityType = value; + return; + } break; case 26: if (object.ReferenceEquals(HttpConstants.HttpHeaders.LastStateChangeUtc, key)) @@ -2702,6 +2840,16 @@ public void UpdateHelper( this.MinimumRUsForOffer = value; return; } + if (object.ReferenceEquals(HttpConstants.HttpHeaders.IsOfferRestorePending, key)) + { + if (throwIfAlreadyExists && this.IsOfferRestorePending != null) + { + throw new ArgumentException($"The {key} already exists in the collection"); + } + + this.IsOfferRestorePending = value; + return; + } if (string.Equals(HttpConstants.HttpHeaders.LastStateChangeUtc, key, StringComparison.OrdinalIgnoreCase)) { if (throwIfAlreadyExists && this.LastStateChangeUtc != null) @@ -2752,6 +2900,16 @@ public void UpdateHelper( this.MinimumRUsForOffer = value; return; } + if (string.Equals(HttpConstants.HttpHeaders.IsOfferRestorePending, key, StringComparison.OrdinalIgnoreCase)) + { + if (throwIfAlreadyExists && this.IsOfferRestorePending != null) + { + throw new ArgumentException($"The {key} already exists in the collection"); + } + + this.IsOfferRestorePending = value; + return; + } break; case 27: if (object.ReferenceEquals(WFConstants.BackendHeaders.NumberOfReadRegions, key)) @@ -2868,6 +3026,16 @@ public void UpdateHelper( this.QuorumAckedLocalLSN = value; return; } + if (object.ReferenceEquals(WFConstants.BackendHeaders.MinGLSNForDocumentOperations, key)) + { + if (throwIfAlreadyExists && this.MinGLSNForDocumentOperations != null) + { + throw new ArgumentException($"The {key} already exists in the collection"); + } + + this.MinGLSNForDocumentOperations = value; + return; + } if (string.Equals(WFConstants.BackendHeaders.CurrentReplicaSetSize, key, StringComparison.OrdinalIgnoreCase)) { if (throwIfAlreadyExists && this.CurrentReplicaSetSize != null) @@ -2908,6 +3076,16 @@ public void UpdateHelper( this.QuorumAckedLocalLSN = value; return; } + if (string.Equals(WFConstants.BackendHeaders.MinGLSNForDocumentOperations, key, StringComparison.OrdinalIgnoreCase)) + { + if (throwIfAlreadyExists && this.MinGLSNForDocumentOperations != null) + { + throw new ArgumentException($"The {key} already exists in the collection"); + } + + this.MinGLSNForDocumentOperations = value; + return; + } break; case 30: if (object.ReferenceEquals(WFConstants.BackendHeaders.ReIndexerProgress, key)) @@ -3108,6 +3286,16 @@ public void UpdateHelper( this.HasTentativeWrites = value; return; } + if (object.ReferenceEquals(HttpConstants.HttpHeaders.InstantScaleUpValue, key)) + { + if (throwIfAlreadyExists && this.InstantScaleUpValue != null) + { + throw new ArgumentException($"The {key} already exists in the collection"); + } + + this.InstantScaleUpValue = value; + return; + } if (string.Equals(HttpConstants.HttpHeaders.LogResults, key, StringComparison.OrdinalIgnoreCase)) { if (throwIfAlreadyExists && this.LogResults != null) @@ -3128,6 +3316,16 @@ public void UpdateHelper( this.HasTentativeWrites = value; return; } + if (string.Equals(HttpConstants.HttpHeaders.InstantScaleUpValue, key, StringComparison.OrdinalIgnoreCase)) + { + if (throwIfAlreadyExists && this.InstantScaleUpValue != null) + { + throw new ArgumentException($"The {key} already exists in the collection"); + } + + this.InstantScaleUpValue = value; + return; + } break; case 35: if (object.ReferenceEquals(WFConstants.BackendHeaders.PartitionKeyRangeId, key)) @@ -3346,6 +3544,16 @@ public void UpdateHelper( this.TentativeStoreChecksum = value; return; } + if (object.ReferenceEquals(WFConstants.BackendHeaders.RequiresDistribution, key)) + { + if (throwIfAlreadyExists && this.RequiresDistribution != null) + { + throw new ArgumentException($"The {key} already exists in the collection"); + } + + this.RequiresDistribution = value; + return; + } if (string.Equals(WFConstants.BackendHeaders.VectorClockLocalProgress, key, StringComparison.OrdinalIgnoreCase)) { if (throwIfAlreadyExists && this.VectorClockLocalProgress != null) @@ -3376,6 +3584,16 @@ public void UpdateHelper( this.TentativeStoreChecksum = value; return; } + if (string.Equals(WFConstants.BackendHeaders.RequiresDistribution, key, StringComparison.OrdinalIgnoreCase)) + { + if (throwIfAlreadyExists && this.RequiresDistribution != null) + { + throw new ArgumentException($"The {key} already exists in the collection"); + } + + this.RequiresDistribution = value; + return; + } break; case 40: if (string.Equals(WFConstants.BackendHeaders.SoftMaxAllowedThroughput, key, StringComparison.OrdinalIgnoreCase)) @@ -3509,22 +3727,41 @@ public void UpdateHelper( if (throwIfAlreadyExists) { - this.lazyNotCommonHeaders.Value.Add(key, value); + this.GetOrCreateLazyHeaders().Add(key, value); } else { if (value == null) { - if (this.lazyNotCommonHeaders.IsValueCreated) + // don't create lazyNotCommonHeaders if it doesn't already exist + + if (this.lazyNotCommonHeaders != null) { - this.lazyNotCommonHeaders.Value.Remove(key); + this.lazyNotCommonHeaders.Remove(key); } } else { - this.lazyNotCommonHeaders.Value[key] = value; + this.GetOrCreateLazyHeaders()[key] = value; } } } + + private Dictionary GetOrCreateLazyHeaders() + { + Dictionary lazyHeaders = this.lazyNotCommonHeaders; + + if (lazyHeaders == null) + { + // risk over allocating, but everyone will get the same dictionary in the end + Dictionary newDict = new Dictionary(StoreResponseNameValueCollection.DefaultStringComparer); + + // Either swap newDict in (getting back the old null) or obtain the Dictionary some other thread swapped in + // (and then we drop newDict on the floor). + lazyHeaders = Interlocked.CompareExchange(ref this.lazyNotCommonHeaders, newDict, null) ?? newDict; + } + + return lazyHeaders; + } } } \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/direct/SupportedSerializationFormats.cs b/Microsoft.Azure.Cosmos/src/direct/SupportedSerializationFormats.cs new file mode 100644 index 0000000000..c472e29e30 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/direct/SupportedSerializationFormats.cs @@ -0,0 +1,29 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +using System; + +namespace Microsoft.Azure.Documents +{ + [Flags] + internal enum SupportedSerializationFormats + { + None = 0, + + /// + /// Standard JSON RFC UTF-8 text. + /// + JsonText = 1 << 0, + + /// + /// Custom binary for Cosmos DB that encodes a superset of JSON values. + /// + CosmosBinary = 1 << 1, + + /// + /// HybridRow format. + /// + HybridRow = 1 << 2, + } +} diff --git a/Microsoft.Azure.Cosmos/src/direct/SystemSynchronizationScope.cs b/Microsoft.Azure.Cosmos/src/direct/SystemSynchronizationScope.cs new file mode 100644 index 0000000000..1d3363cb8b --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/direct/SystemSynchronizationScope.cs @@ -0,0 +1,158 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.ServiceFramework.Core +{ + using System; + using System.Threading; + using Microsoft.Azure.Cosmos.Core.Trace; + + /// + /// Encapsulates a system mutex that can be used for inter-process synchronization of operations. + /// + internal sealed class SystemSynchronizationScope : IDisposable + { + private readonly Mutex mutex; + private readonly bool isOwned; + + /// + /// Initializes a new instance of the class. + /// + /// Name of the mutex. + /// Time to wait to acquire the mutex. + public SystemSynchronizationScope(string name, TimeSpan timeout = default) + { + if (string.IsNullOrWhiteSpace(name)) + { + throw new ArgumentException("Name should not be null or empty", nameof(name)); + } + + this.MutexName = name; + Mutex tempMutex = default; + try + { + tempMutex = new Mutex(initiallyOwned: true, this.MutexName, out bool createdNew); + if (!createdNew) + { + DefaultTrace.TraceInformation($"{this.TraceId}: Acquiring existing system mutex '{this.MutexName}'"); + try + { + timeout = timeout == default ? Timeout.InfiniteTimeSpan : timeout; + this.isOwned = tempMutex.WaitOne(timeout); + if (!this.isOwned) + { + throw new TimeoutException($"Timed out waiting for system mutex '{this.MutexName}'"); + } + + DefaultTrace.TraceInformation($"{this.TraceId}: Acquired existing system mutex '{this.MutexName}'"); + } + catch (AbandonedMutexException amEx) + { + DefaultTrace.TraceWarning($"{this.TraceId}: {nameof(AbandonedMutexException)} waiting for mutex '{this.MutexName}': {amEx}"); + this.isOwned = true; + } + } + else + { + this.isOwned = true; + DefaultTrace.TraceInformation($"{this.TraceId}: Created system mutex '{this.MutexName}'"); + } + + this.mutex = tempMutex; + tempMutex = default; + } + finally + { + this.ReleaseAndDisposeMutexSave(tempMutex); + } + } + + /// + /// Gets the name of the system mutex. + /// + public string MutexName { get; } + + private string TraceId => $"{nameof(SystemSynchronizationScope)}[{Environment.CurrentManagedThreadId}]"; + + /// + /// Creates a synchronization object based on a mutex of the given name to guarantee that the code within the scope executes synchronously + /// across processes. + /// + /// Name of the scope mutex. + /// Time to wait to acquire the mutex. + /// Object which releases the scope mutex when disposed. + public static SystemSynchronizationScope CreateSynchronizationScope(string name, TimeSpan timeout = default) + => new SystemSynchronizationScope(name, timeout); + + /// + /// Executes an operation within a system mutex synchronization scope. + /// + /// Name of the scope mutex. + /// Operation to be executed. + /// Time to wait to acquire the mutex. + /// Result of the . + /// Thrown if the is null. + public static TResult ExecuteWithSynchronization(string name, Func function, TimeSpan timeout = default) + { + if (function == null) + { + throw new ArgumentNullException(nameof(name)); + } + + using (SystemSynchronizationScope.CreateSynchronizationScope(name, timeout)) + { + return function.Invoke(); + } + } + + /// + /// Executes an operation within a system mutex synchronization scope. + /// + /// Name of the scope mutex. + /// Operation to be executed. + /// Time to wait to acquire the mutex. + /// Thrown if the is null. + public static void ExecuteWithSynchronization(string name, Action action, TimeSpan timeout = default) + { + SystemSynchronizationScope.ExecuteWithSynchronization(name, + function: () => + { + action.Invoke(); + return true; + }, + timeout); + } + + public void Dispose() + { + this.ReleaseAndDisposeMutexSave(this.mutex); + } + + private void ReleaseAndDisposeMutexSave(Mutex mutex) + { + if (mutex != null) + { + try + { + // If we already have the mutex then release it. + if (this.isOwned) + { + DefaultTrace.TraceInformation($"{this.TraceId}: Releasing system mutex '{this.MutexName}'"); + mutex.ReleaseMutex(); + } + } + catch (AbandonedMutexException amEx) + { + DefaultTrace.TraceWarning($"{this.TraceId}: {nameof(AbandonedMutexException)} waiting for mutex '{this.MutexName}': {amEx}"); + } + catch (ApplicationException appEx) + { + DefaultTrace.TraceWarning($"{this.TraceId}: Exception releasing system mutex '{this.MutexName}': {appEx}"); + } + + mutex.Dispose(); + } + } + } +} diff --git a/Microsoft.Azure.Cosmos/src/direct/TransportAddressUri.cs b/Microsoft.Azure.Cosmos/src/direct/TransportAddressUri.cs index 4d7fd62bf2..d3fe82650c 100644 --- a/Microsoft.Azure.Cosmos/src/direct/TransportAddressUri.cs +++ b/Microsoft.Azure.Cosmos/src/direct/TransportAddressUri.cs @@ -48,6 +48,7 @@ internal sealed class TransportAddressUri : IEquatable public TransportAddressUri(Uri addressUri) { this.Uri = addressUri ?? throw new ArgumentNullException(paramName: nameof(addressUri)); + this.ReplicaServerKey = new (uri: addressUri); this.uriToString = addressUri.ToString(); this.PathAndQuery = addressUri.PathAndQuery.TrimEnd(TransportSerialization.UrlTrim); this.healthState = new ( @@ -69,6 +70,11 @@ public TransportAddressUri(Uri addressUri) /// public string PathAndQuery { get; } + /// + /// An instance of containing the replica host and port details. + /// + public ServerKey ReplicaServerKey { get; } + /// /// Is a flag to determine if the replica the URI is pointing to is unhealthy. /// The unhealthy status is reset after 1 minutes to prevent a replica from diff --git a/Microsoft.Azure.Cosmos/src/direct/TransportSerialization.cs b/Microsoft.Azure.Cosmos/src/direct/TransportSerialization.cs index 7df69fd775..edc303ccf4 100644 --- a/Microsoft.Azure.Cosmos/src/direct/TransportSerialization.cs +++ b/Microsoft.Azure.Cosmos/src/direct/TransportSerialization.cs @@ -156,6 +156,7 @@ internal static SerializedRequest BuildRequest( TransportSerialization.AddPopulateQueryMetrics(requestHeaders, rntbdRequest); TransportSerialization.AddPopulateQueryMetricsIndexUtilization(requestHeaders, rntbdRequest); TransportSerialization.AddPopulateIndexMetricsText(requestHeaders, rntbdRequest); + TransportSerialization.AddOptimisticDirectExecute(requestHeaders, rntbdRequest); TransportSerialization.AddQueryForceScan(requestHeaders, rntbdRequest); TransportSerialization.AddResponseContinuationTokenLimitInKb(requestHeaders, rntbdRequest); TransportSerialization.AddPopulatePartitionStatistics(requestHeaders, rntbdRequest); @@ -180,6 +181,7 @@ internal static SerializedRequest BuildRequest( TransportSerialization.AddFanoutOperationStateHeader(requestHeaders, rntbdRequest); TransportSerialization.AddStartAndEndKeys(request, requestHeaders, rntbdRequest); TransportSerialization.AddContentSerializationFormat(requestHeaders, rntbdRequest); + TransportSerialization.AddSupportedSerializationFormats(requestHeaders, rntbdRequest); TransportSerialization.AddIsUserRequest(requestHeaders, rntbdRequest); TransportSerialization.AddPreserveFullContent(requestHeaders, rntbdRequest); TransportSerialization.AddIsRUPerGBEnforcementRequest(requestHeaders, rntbdRequest); @@ -199,10 +201,13 @@ internal static SerializedRequest BuildRequest( TransportSerialization.AddRequestedCollectionType(requestHeaders, rntbdRequest); TransportSerialization.AddIsThroughputCapRequest(requestHeaders, rntbdRequest); TransportSerialization.AddUpdateOfferStateToPending(requestHeaders, rntbdRequest); + TransportSerialization.AddUpdateOfferStateToRestorePending(requestHeaders, rntbdRequest); + TransportSerialization.AddMasterResourcesDeletionPending(requestHeaders, rntbdRequest); TransportSerialization.AddIsInternalServerlessRequest(requestHeaders, rntbdRequest); TransportSerialization.AddOfferReplaceRURedistribution(requestHeaders, rntbdRequest); TransportSerialization.AddIsMaterializedViewSourceSchemaReplaceBatchRequest(requestHeaders, rntbdRequest); TransportSerialization.AddIsCassandraAlterTypeRequest(request, rntbdRequest); + TransportSerialization.AddHighPriorityForcedBackup(requestHeaders, rntbdRequest); TransportSerialization.FillTokenFromHeader(request, HttpConstants.HttpHeaders.Authorization, requestHeaders.Authorization, rntbdRequest.authorizationToken, rntbdRequest); TransportSerialization.FillTokenFromHeader(request, HttpConstants.HttpHeaders.SessionToken, requestHeaders.SessionToken, rntbdRequest.sessionToken, rntbdRequest); @@ -283,7 +288,10 @@ internal static SerializedRequest BuildRequest( TransportSerialization.FillTokenFromHeader(request, HttpConstants.HttpHeaders.ForceDatabaseAccountUpdate, requestHeaders.ForceDatabaseAccountUpdate, rntbdRequest.forceDatabaseAccountUpdate, rntbdRequest); TransportSerialization.AddPriorityLevelHeader(request, HttpConstants.HttpHeaders.PriorityLevel, requestHeaders.PriorityLevel, requestHeaders, rntbdRequest); TransportSerialization.FillTokenFromHeader(request, HttpConstants.HttpHeaders.AllowRestoreParamsUpdate, requestHeaders.AllowRestoreParamsUpdate, rntbdRequest.allowRestoreParamsUpdate, rntbdRequest); - + TransportSerialization.FillTokenFromHeader(request, HttpConstants.HttpHeaders.PruneCollectionSchemas, requestHeaders.PruneCollectionSchemas, rntbdRequest.pruneCollectionSchemas, rntbdRequest); + TransportSerialization.FillTokenFromHeader(request, HttpConstants.HttpHeaders.IsMigratedFixedCollection, requestHeaders.IsMigratedFixedCollection, rntbdRequest.isMigratedFixedCollection, rntbdRequest); + TransportSerialization.FillTokenFromHeader(request, WFConstants.BackendHeaders.PopulateMinGLSNForDocumentOperations, requestHeaders.PopulateMinGLSNForDocumentOperations, rntbdRequest.populateMinGLSNForDocumentOperations, rntbdRequest); + // will be null in case of direct, which is fine - BE will use the value from the connection context message. // When this is used in Gateway, the header value will be populated with the proxied HTTP request's header, and // BE will respect the per-request value. @@ -420,128 +428,19 @@ internal static byte[] BuildContextRequest(Guid activityId, UserAgentContainer u } internal static StoreResponse MakeStoreResponse( - StatusCodes status, - Guid activityId, - RntbdConstants.Response response, - Stream body, - string serverVersion) - { - StoreResponseNameValueCollection responseHeaders = new StoreResponseNameValueCollection(); - StoreResponse storeResponse = new StoreResponse() - { - Headers = responseHeaders - }; - - // When adding new RntbdResponseTokens please add the constant name and constant value to the - // list at the top of the StoreResponseNameValueCollection.tt file. - // This will add the new property matching the constant name to the StoreResponseNameValueCollection which avoids the dictionary overhead - responseHeaders.LastStateChangeUtc = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.lastStateChangeDateTime); - responseHeaders.Continuation = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.continuationToken); - responseHeaders.ETag = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.eTag); - responseHeaders.RetryAfterInMilliseconds = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.retryAfterMilliseconds); - responseHeaders.MaxResourceQuota = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.storageMaxResoureQuota); - responseHeaders.CurrentResourceQuotaUsage = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.storageResourceQuotaUsage); - responseHeaders.CollectionPartitionIndex = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.collectionPartitionIndex); - responseHeaders.CollectionServiceIndex = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.collectionServiceIndex); - responseHeaders.LSN = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.lSN); - responseHeaders.ItemCount = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.itemCount); - responseHeaders.SchemaVersion = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.schemaVersion); - responseHeaders.OwnerFullName = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.ownerFullName); - responseHeaders.OwnerId = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.ownerId); - responseHeaders.DatabaseAccountId = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.databaseAccountId); - responseHeaders.QuorumAckedLSN = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.quorumAckedLSN); - responseHeaders.RequestValidationFailure = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.requestValidationFailure); - responseHeaders.SubStatus = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.subStatus); - responseHeaders.CollectionIndexTransformationProgress = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.collectionUpdateProgress); - responseHeaders.CurrentWriteQuorum = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.currentWriteQuorum); - responseHeaders.CurrentReplicaSetSize = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.currentReplicaSetSize); - responseHeaders.CollectionLazyIndexingProgress = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.collectionLazyIndexProgress); - responseHeaders.PartitionKeyRangeId = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.partitionKeyRangeId); - responseHeaders.LogResults = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.logResults); - responseHeaders.XPRole = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.xPRole); - responseHeaders.IsRUPerMinuteUsed = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.isRUPerMinuteUsed); - responseHeaders.QueryMetrics = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.queryMetrics); - responseHeaders.QueryExecutionInfo = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.queryExecutionInfo); - responseHeaders.IndexUtilization = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.indexUtilization); - responseHeaders.GlobalCommittedLSN = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.globalCommittedLSN); - responseHeaders.NumberOfReadRegions = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.numberOfReadRegions); - responseHeaders.OfferReplacePending = TransportSerialization.GetResponseBoolHeaderIfPresent(response.offerReplacePending); - responseHeaders.ItemLSN = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.itemLSN); - responseHeaders.RestoreState = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.restoreState); - responseHeaders.CollectionSecurityIdentifier = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.collectionSecurityIdentifier); - responseHeaders.TransportRequestID = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.transportRequestID); - responseHeaders.ShareThroughput = TransportSerialization.GetResponseBoolHeaderIfPresent(response.shareThroughput); - responseHeaders.DisableRntbdChannel = TransportSerialization.GetResponseBoolHeaderIfPresent(response.disableRntbdChannel); - responseHeaders.XDate = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.serverDateTimeUtc); - responseHeaders.LocalLSN = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.localLSN); - responseHeaders.QuorumAckedLocalLSN = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.quorumAckedLocalLSN); - responseHeaders.ItemLocalLSN = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.itemLocalLSN); - responseHeaders.HasTentativeWrites = TransportSerialization.GetResponseBoolHeaderIfPresent(response.hasTentativeWrites); - responseHeaders.SessionToken = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.sessionToken); - responseHeaders.ReplicatorLSNToGLSNDelta = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.replicatorLSNToGLSNDelta); - responseHeaders.ReplicatorLSNToLLSNDelta = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.replicatorLSNToLLSNDelta); - responseHeaders.VectorClockLocalProgress = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.vectorClockLocalProgress); - responseHeaders.MinimumRUsForOffer = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.minimumRUsForOffer); - responseHeaders.XPConfigurationSessionsCount = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.xPConfigurationSessionsCount); - responseHeaders.UnflushedMergLogEntryCount = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.unflushedMergeLogEntryCount); - responseHeaders.ResourceId = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.resourceName); - responseHeaders.TimeToLiveInSeconds = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.timeToLiveInSeconds); - responseHeaders.ReplicaStatusRevoked = TransportSerialization.GetResponseBoolHeaderIfPresent(response.replicaStatusRevoked); - responseHeaders.SoftMaxAllowedThroughput = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.softMaxAllowedThroughput); - responseHeaders.BackendRequestDurationMilliseconds = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.backendRequestDurationMilliseconds); - responseHeaders.CorrelatedActivityId = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.correlatedActivityId); - responseHeaders.ConfirmedStoreChecksum = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.confirmedStoreChecksum); - responseHeaders.TentativeStoreChecksum = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.tentativeStoreChecksum); - responseHeaders.PendingPKDelete = TransportSerialization.GetResponseBoolHeaderIfPresent(response.pendingPKDelete); - responseHeaders.AadAppliedRoleAssignmentId = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.aadAppliedRoleAssignmentId); - responseHeaders.CollectionUniqueIndexReIndexProgress = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.collectionUniqueIndexReIndexProgress); - responseHeaders.CollectionUniqueKeysUnderReIndex = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.collectionUniqueKeysUnderReIndex); - responseHeaders.AnalyticalMigrationProgress = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.analyticalMigrationProgress); - responseHeaders.TotalAccountThroughput = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.totalAccountThroughput); - responseHeaders.ByokEncryptionProgress = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.bYOKEncryptionProgress); - responseHeaders.AppliedPolicyElementId = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.appliedPolicyElementId); - responseHeaders.MergeProgressBlocked = TransportSerialization.GetResponseBoolHeaderIfPresent(response.mergeProgressBlocked); - responseHeaders.ChangeFeedInfo = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.changeFeedInfo); - responseHeaders.ReIndexerProgress = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.reindexerProgress); - responseHeaders.OfferReplacePendingForMerge = TransportSerialization.GetResponseBoolHeaderIfPresent(response.offerReplacePendingForMerge); - responseHeaders.OldestActiveSchemaId = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.oldestActiveSchemaId); - responseHeaders.PhysicalPartitionId = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.physicalPartitionId); - responseHeaders.MaxContentLength = TransportSerialization.GetStringFromRntbdTokenIfPresent(response.maxContentLength); - if (response.requestCharge.isPresent) - { - responseHeaders.RequestCharge = string.Format(CultureInfo.InvariantCulture, "{0:0.##}", response.requestCharge.value.valueDouble); - } - - if (response.indexingDirective.isPresent) - { - string indexingDirective; - switch (response.indexingDirective.value.valueByte) - { - case (byte) RntbdConstants.RntbdIndexingDirective.Default: - indexingDirective = IndexingDirectiveStrings.Default; - break; - case (byte) RntbdConstants.RntbdIndexingDirective.Exclude: - indexingDirective = IndexingDirectiveStrings.Exclude; - break; - case (byte) RntbdConstants.RntbdIndexingDirective.Include: - indexingDirective = IndexingDirectiveStrings.Include; - break; - default: - throw new Exception(); - } - - responseHeaders.IndexingDirective = indexingDirective; - } - - responseHeaders.ServerVersion = serverVersion; - - responseHeaders.ActivityId = activityId.ToString(); - - storeResponse.ResponseBody = body; - storeResponse.Status = (int)status; - - return storeResponse; - } + StatusCodes status, + Guid activityId, + Stream body, + string serverVersion, + ref BytesDeserializer rntbdHeaderReader) => new() + { + Headers = HeadersTransportSerialization.BuildStoreResponseNameValueCollection( + activityId, + serverVersion, + ref rntbdHeaderReader), + ResponseBody = body, + Status = (int)status + }; internal static RntbdHeader DecodeRntbdHeader(byte[] header) { @@ -550,47 +449,6 @@ internal static RntbdHeader DecodeRntbdHeader(byte[] header) return new RntbdHeader(status, activityId); } - private static string GetStringFromRntbdTokenIfPresent(RntbdToken token) - { - if (token.isPresent) - { - switch (token.GetTokenType()) - { - case RntbdTokenTypes.Guid: - return token.value.valueGuid.ToString(); - case RntbdTokenTypes.LongLong: - return token.value.valueLongLong.ToString(CultureInfo.InvariantCulture); - case RntbdTokenTypes.Double: - return token.value.valueDouble.ToString(CultureInfo.InvariantCulture); - case RntbdTokenTypes.ULong: - return token.value.valueULong.ToString(CultureInfo.InvariantCulture); - case RntbdTokenTypes.ULongLong: - return token.value.valueULongLong.ToString(CultureInfo.InvariantCulture); - case RntbdTokenTypes.Byte: - return token.value.valueByte.ToString(CultureInfo.InvariantCulture); - case RntbdTokenTypes.String: - case RntbdTokenTypes.SmallString: - return BytesSerializer.GetStringFromBytes(token.value.valueBytes); - case RntbdTokenTypes.Long: - return token.value.valueLong.ToString(CultureInfo.InvariantCulture); - default: - throw new Exception($"Unsupported token type {token.GetTokenType()}"); - } - } - - return null; - } - - private static string GetResponseBoolHeaderIfPresent(RntbdToken token) - { - if (token.isPresent) - { - return (token.value.valueByte != 0).ToString().ToLowerInvariant(); - } - - return null; - } - private static RntbdConstants.RntbdOperationType GetRntbdOperationType(OperationType operationType) { switch (operationType) @@ -688,10 +546,16 @@ private static RntbdConstants.RntbdOperationType GetRntbdOperationType(Operation return RntbdConstants.RntbdOperationType.MetadataCheckAccess; case OperationType.CreateSystemSnapshot: return RntbdConstants.RntbdOperationType.CreateSystemSnapshot; + case OperationType.CreateRidRangeResources: + return RntbdConstants.RntbdOperationType.CreateRidRangeResources; case OperationType.UpdateFailoverPriorityList: return RntbdConstants.RntbdOperationType.UpdateFailoverPriorityList; case OperationType.GetStorageAuthToken: return RntbdConstants.RntbdOperationType.GetStorageAuthToken; + case OperationType.UpdatePartitionThroughput: + return RntbdConstants.RntbdOperationType.UpdatePartitionThroughput; + case OperationType.Truncate: + return RntbdConstants.RntbdOperationType.Truncate; #endif case OperationType.AddComputeGatewayRequestCharges: return RntbdConstants.RntbdOperationType.AddComputeGatewayRequestCharges; @@ -1503,6 +1367,18 @@ private static void AddPopulateIndexMetricsText(RequestNameValueCollection reque } } + private static void AddOptimisticDirectExecute(RequestNameValueCollection requestHeaders, RntbdConstants.Request rntbdRequest) + { + if (!string.IsNullOrEmpty(requestHeaders.OptimisticDirectExecute)) + { + rntbdRequest.optimisticDirectExecute.value.valueByte = (requestHeaders.OptimisticDirectExecute. + Equals(bool.TrueString, StringComparison.OrdinalIgnoreCase)) + ? (byte)0x01 + : (byte)0x00; + rntbdRequest.optimisticDirectExecute.isPresent = true; + } + } + private static void AddQueryForceScan(RequestNameValueCollection requestHeaders, RntbdConstants.Request rntbdRequest) { if (!string.IsNullOrEmpty(requestHeaders.ForceQueryScan)) @@ -2115,6 +1991,47 @@ private static void AddContentSerializationFormat(RequestNameValueCollection req } } + [System.Diagnostics.CodeAnalysis.SuppressMessage("Globalization", "CA1305:Specify IFormatProvider", Justification = "Roslyn Baseline 12/12/2022 16:40")] + private static void AddSupportedSerializationFormats(RequestNameValueCollection requestHeaders, RntbdConstants.Request rntbdRequest) + { + if (requestHeaders.SupportedSerializationFormats != null) + { + RntbdConstants.RntbdSupportedSerializationFormats rntbdSupportedSerializationFormats = RntbdConstants.RntbdSupportedSerializationFormats.None; + + // Making empty header value check consistent with http request. If header value is empty throw exception. + if (requestHeaders.SupportedSerializationFormats.Length == 0 || !Enum.TryParse(requestHeaders.SupportedSerializationFormats, true, out SupportedSerializationFormats supportedSerializationFormats)) + { + throw new BadRequestException(String.Format(CultureInfo.CurrentUICulture, RMResources.InvalidEnumValue, + requestHeaders.SupportedSerializationFormats, nameof(SupportedSerializationFormats))); + } + + if(supportedSerializationFormats.HasFlag(SupportedSerializationFormats.JsonText)) + { + rntbdSupportedSerializationFormats |= RntbdConstants.RntbdSupportedSerializationFormats.JsonText; + } + + if(supportedSerializationFormats.HasFlag(SupportedSerializationFormats.CosmosBinary)) + { + rntbdSupportedSerializationFormats |= RntbdConstants.RntbdSupportedSerializationFormats.CosmosBinary; + } + + if (supportedSerializationFormats.HasFlag(SupportedSerializationFormats.HybridRow)) + { + rntbdSupportedSerializationFormats |= RntbdConstants.RntbdSupportedSerializationFormats.HybridRow; + } + + if((supportedSerializationFormats & + ~(SupportedSerializationFormats.JsonText | SupportedSerializationFormats.CosmosBinary | SupportedSerializationFormats.HybridRow)) != SupportedSerializationFormats.None) + { + throw new BadRequestException(String.Format(CultureInfo.CurrentUICulture, RMResources.InvalidEnumValue, + requestHeaders.SupportedSerializationFormats, nameof(SupportedSerializationFormats))); + } + + rntbdRequest.supportedSerializationFormats.value.valueByte = (byte)rntbdSupportedSerializationFormats; + rntbdRequest.supportedSerializationFormats.isPresent = true; + } + } + private static void FillTokenFromHeader(DocumentServiceRequest request, string headerName, string headerStringValue, RntbdToken token, RntbdConstants.Request rntbdRequest) { object headerValue = null; @@ -2532,6 +2449,30 @@ private static void AddUpdateOfferStateToPending(RequestNameValueCollection requ } } + private static void AddUpdateOfferStateToRestorePending(RequestNameValueCollection requestHeaders, RntbdConstants.Request rntbdRequest) + { + if (!string.IsNullOrEmpty(requestHeaders.UpdateOfferStateToRestorePending)) + { + rntbdRequest.updateOfferStateToRestorePending.value.valueByte = (requestHeaders.UpdateOfferStateToRestorePending. + Equals(bool.TrueString, StringComparison.OrdinalIgnoreCase)) + ? (byte)0x01 + : (byte)0x00; + rntbdRequest.updateOfferStateToRestorePending.isPresent = true; + } + } + + private static void AddMasterResourcesDeletionPending(RequestNameValueCollection requestHeaders, RntbdConstants.Request rntbdRequest) + { + if (!string.IsNullOrEmpty(requestHeaders.SetMasterResourcesDeletionPending)) + { + rntbdRequest.setMasterResourcesDeletionPending.value.valueByte = (requestHeaders.SetMasterResourcesDeletionPending. + Equals(bool.TrueString, StringComparison.OrdinalIgnoreCase)) + ? (byte)0x01 + : (byte)0x00; + rntbdRequest.setMasterResourcesDeletionPending.isPresent = true; + } + } + private static void AddOfferReplaceRURedistribution(RequestNameValueCollection requestHeaders, RntbdConstants.Request rntbdRequest) { if(!string.IsNullOrEmpty(requestHeaders.OfferReplaceRURedistribution)) @@ -2568,6 +2509,18 @@ private static void AddIsCassandraAlterTypeRequest(DocumentServiceRequest reques } } + private static void AddHighPriorityForcedBackup(RequestNameValueCollection requestHeaders, RntbdConstants.Request rntbdRequest) + { + if (!string.IsNullOrEmpty(requestHeaders.HighPriorityForcedBackup)) + { + rntbdRequest.highPriorityForcedBackup.value.valueByte = (requestHeaders.HighPriorityForcedBackup. + Equals(bool.TrueString, StringComparison.OrdinalIgnoreCase)) + ? (byte)0x01 + : (byte)0x00; + rntbdRequest.highPriorityForcedBackup.isPresent = true; + } + } + private static void AddPriorityLevelHeader(DocumentServiceRequest request, string headerName, string headerStringValue, RequestNameValueCollection requestHeaders, RntbdConstants.Request rntbdRequest) { PriorityLevel priorityLevel = PriorityLevel.High; diff --git a/Microsoft.Azure.Cosmos/src/direct/WFConstants.cs b/Microsoft.Azure.Cosmos/src/direct/WFConstants.cs index e12f8eff723bb9a2fc70650df3b9e54e57a18270..ed18a83d4200c80a3750deb325c9b1f678c0fee4 100644 GIT binary patch delta 680 zcmbV}%SwV#5XZ+*+K6Zo5~z6#D>xQ>xe&y{#4cu8rW7se^HNIsc@NsQ30j4-X{k?8 zV6-ae0a`?>o}fk0D^zoiUtliV9Oj(!oB#Z0=I%!G{-C*?vEkFIwq@3u3s8d`)FBK7 zIvaE=KpL9Z@lT`Cs-NJ$RcO*{kIN2l-~MFRYr8h#vu;sJ5Zr(m$U-VdDceH4Oae8? zsD*M+6kGwypkU1Iz^jlEcNdKQx_D<$>Qi89;eHJUSt9#YF6{dbMO2kRArA?vCJQ17 z6-bG=i6*yak~i6781cUpBZn1WaH^7>r6^mWR*xYMadN=D^0NVF5D_u&CJQ0rGjKu! zlOrx{2S$8(HH(qn-#i9KeVL5LtmZ + /// THIS IS AN AUTOGENERATED FILE. ALL UPDATES SHOULD BE DONE VIA RntbdConstants.tt + /// This allows the RntbdTokenStreams to be correctly ordered and optimized. + /// If you need to add a new RntbdToken to any of the existing types, do it on the RntbdConstants.tt file + /// + internal static class HeadersTransportSerialization + { + public static StoreResponseNameValueCollection BuildStoreResponseNameValueCollection( + Guid activityId, + string serverVersion, + ref BytesDeserializer rntbdHeaderReader) + { + StoreResponseNameValueCollection responseHeaders = new() + { + ActivityId = activityId.ToString(), + ServerVersion = serverVersion + }; + + while(rntbdHeaderReader.Position < rntbdHeaderReader.Length) + { + ResponseIdentifiers identifier = (ResponseIdentifiers)rntbdHeaderReader.ReadUInt16(); + switch (identifier) + { + case ResponseIdentifiers.TransportRequestID: + { + responseHeaders.TransportRequestID = HeadersTransportSerialization.ReadUIntHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.ServerDateTimeUtc: + { + responseHeaders.XDate = HeadersTransportSerialization.ReadSmallStringHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.SubStatus: + { + responseHeaders.SubStatus = HeadersTransportSerialization.ReadUIntHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.ETag: + { + responseHeaders.ETag = HeadersTransportSerialization.ReadStringHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.ResourceName: + { + responseHeaders.ResourceId = HeadersTransportSerialization.ReadStringHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.RequestCharge: + { + RntbdTokenTypes type = (RntbdTokenTypes)rntbdHeaderReader.ReadByte(); + Debug.Assert(type == RntbdTokenTypes.Double); + double value = rntbdHeaderReader.ReadDouble(); + responseHeaders.RequestCharge = string.Format(CultureInfo.InvariantCulture, "{0:0.##}", value); + break; + } + + case ResponseIdentifiers.SessionToken: + { + responseHeaders.SessionToken = HeadersTransportSerialization.ReadStringHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.ContinuationToken: + { + responseHeaders.Continuation = HeadersTransportSerialization.ReadStringHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.LSN: + { + responseHeaders.LSN = HeadersTransportSerialization.ReadLongHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.GlobalCommittedLSN: + { + responseHeaders.GlobalCommittedLSN = HeadersTransportSerialization.ReadLongHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.ItemLSN: + { + responseHeaders.ItemLSN = HeadersTransportSerialization.ReadLongHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.LocalLSN: + { + responseHeaders.LocalLSN = HeadersTransportSerialization.ReadLongHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.QuorumAckedLocalLSN: + { + responseHeaders.QuorumAckedLocalLSN = HeadersTransportSerialization.ReadLongHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.ItemLocalLSN: + { + responseHeaders.ItemLocalLSN = HeadersTransportSerialization.ReadLongHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.LastStateChangeDateTime: + { + responseHeaders.LastStateChangeUtc = HeadersTransportSerialization.ReadSmallStringHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.RetryAfterMilliseconds: + { + responseHeaders.RetryAfterInMilliseconds = HeadersTransportSerialization.ReadUIntHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.IndexingDirective: + { + RntbdTokenTypes type = (RntbdTokenTypes)rntbdHeaderReader.ReadByte(); + Debug.Assert(type == RntbdTokenTypes.Byte); + byte value = rntbdHeaderReader.ReadByte(); + string indexingDirective = value switch + { + (byte)RntbdConstants.RntbdIndexingDirective.Default => IndexingDirectiveStrings.Default, + (byte)RntbdConstants.RntbdIndexingDirective.Exclude => IndexingDirectiveStrings.Exclude, + (byte)RntbdConstants.RntbdIndexingDirective.Include => IndexingDirectiveStrings.Include, + _ => throw new Exception(), + }; + responseHeaders.IndexingDirective = indexingDirective; + break; + } + + case ResponseIdentifiers.StorageMaxResoureQuota: + { + responseHeaders.MaxResourceQuota = HeadersTransportSerialization.ReadStringHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.StorageResourceQuotaUsage: + { + responseHeaders.CurrentResourceQuotaUsage = HeadersTransportSerialization.ReadStringHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.SchemaVersion: + { + responseHeaders.SchemaVersion = HeadersTransportSerialization.ReadSmallStringHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.CollectionPartitionIndex: + { + responseHeaders.CollectionPartitionIndex = HeadersTransportSerialization.ReadUIntHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.CollectionServiceIndex: + { + responseHeaders.CollectionServiceIndex = HeadersTransportSerialization.ReadUIntHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.ItemCount: + { + responseHeaders.ItemCount = HeadersTransportSerialization.ReadUIntHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.OwnerFullName: + { + responseHeaders.OwnerFullName = HeadersTransportSerialization.ReadStringHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.OwnerId: + { + responseHeaders.OwnerId = HeadersTransportSerialization.ReadStringHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.DatabaseAccountId: + { + responseHeaders.DatabaseAccountId = HeadersTransportSerialization.ReadStringHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.QuorumAckedLSN: + { + responseHeaders.QuorumAckedLSN = HeadersTransportSerialization.ReadLongHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.RequestValidationFailure: + { + responseHeaders.RequestValidationFailure = HeadersTransportSerialization.ReadIntBoolHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.CollectionUpdateProgress: + { + responseHeaders.CollectionIndexTransformationProgress = HeadersTransportSerialization.ReadUIntHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.CurrentWriteQuorum: + { + responseHeaders.CurrentWriteQuorum = HeadersTransportSerialization.ReadUIntHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.CurrentReplicaSetSize: + { + responseHeaders.CurrentReplicaSetSize = HeadersTransportSerialization.ReadUIntHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.CollectionLazyIndexProgress: + { + responseHeaders.CollectionLazyIndexingProgress = HeadersTransportSerialization.ReadUIntHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.PartitionKeyRangeId: + { + responseHeaders.PartitionKeyRangeId = HeadersTransportSerialization.ReadStringHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.LogResults: + { + responseHeaders.LogResults = HeadersTransportSerialization.ReadStringHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.XPRole: + { + responseHeaders.XPRole = HeadersTransportSerialization.ReadUIntHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.IsRUPerMinuteUsed: + { + responseHeaders.IsRUPerMinuteUsed = HeadersTransportSerialization.ReadIntBoolHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.QueryMetrics: + { + responseHeaders.QueryMetrics = HeadersTransportSerialization.ReadStringHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.NumberOfReadRegions: + { + responseHeaders.NumberOfReadRegions = HeadersTransportSerialization.ReadUIntHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.OfferReplacePending: + { + responseHeaders.OfferReplacePending = HeadersTransportSerialization.ReadBoolHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.RestoreState: + { + responseHeaders.RestoreState = HeadersTransportSerialization.ReadStringHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.CollectionSecurityIdentifier: + { + responseHeaders.CollectionSecurityIdentifier = HeadersTransportSerialization.ReadStringHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.ShareThroughput: + { + responseHeaders.ShareThroughput = HeadersTransportSerialization.ReadBoolHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.DisableRntbdChannel: + { + responseHeaders.DisableRntbdChannel = HeadersTransportSerialization.ReadBoolHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.HasTentativeWrites: + { + responseHeaders.HasTentativeWrites = HeadersTransportSerialization.ReadBoolHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.ReplicatorLSNToGLSNDelta: + { + responseHeaders.ReplicatorLSNToGLSNDelta = HeadersTransportSerialization.ReadLongHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.ReplicatorLSNToLLSNDelta: + { + responseHeaders.ReplicatorLSNToLLSNDelta = HeadersTransportSerialization.ReadLongHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.VectorClockLocalProgress: + { + responseHeaders.VectorClockLocalProgress = HeadersTransportSerialization.ReadLongHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.MinimumRUsForOffer: + { + responseHeaders.MinimumRUsForOffer = HeadersTransportSerialization.ReadUIntHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.XPConfigurationSessionsCount: + { + responseHeaders.XPConfigurationSessionsCount = HeadersTransportSerialization.ReadUIntHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.IndexUtilization: + { + responseHeaders.IndexUtilization = HeadersTransportSerialization.ReadStringHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.QueryExecutionInfo: + { + responseHeaders.QueryExecutionInfo = HeadersTransportSerialization.ReadStringHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.UnflushedMergeLogEntryCount: + { + responseHeaders.UnflushedMergLogEntryCount = HeadersTransportSerialization.ReadLongHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.TimeToLiveInSeconds: + { + responseHeaders.TimeToLiveInSeconds = HeadersTransportSerialization.ReadLongHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.ReplicaStatusRevoked: + { + responseHeaders.ReplicaStatusRevoked = HeadersTransportSerialization.ReadBoolHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.SoftMaxAllowedThroughput: + { + responseHeaders.SoftMaxAllowedThroughput = HeadersTransportSerialization.ReadUIntHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.BackendRequestDurationMilliseconds: + { + responseHeaders.BackendRequestDurationMilliseconds = HeadersTransportSerialization.ReadDoubleHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.CorrelatedActivityId: + { + responseHeaders.CorrelatedActivityId = HeadersTransportSerialization.ReadGuidHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.ConfirmedStoreChecksum: + { + responseHeaders.ConfirmedStoreChecksum = HeadersTransportSerialization.ReadULongHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.TentativeStoreChecksum: + { + responseHeaders.TentativeStoreChecksum = HeadersTransportSerialization.ReadULongHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.PendingPKDelete: + { + responseHeaders.PendingPKDelete = HeadersTransportSerialization.ReadBoolHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.AadAppliedRoleAssignmentId: + { + responseHeaders.AadAppliedRoleAssignmentId = HeadersTransportSerialization.ReadStringHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.CollectionUniqueIndexReIndexProgress: + { + responseHeaders.CollectionUniqueIndexReIndexProgress = HeadersTransportSerialization.ReadUIntHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.CollectionUniqueKeysUnderReIndex: + { + responseHeaders.CollectionUniqueKeysUnderReIndex = HeadersTransportSerialization.ReadStringHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.AnalyticalMigrationProgress: + { + responseHeaders.AnalyticalMigrationProgress = HeadersTransportSerialization.ReadUIntHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.TotalAccountThroughput: + { + responseHeaders.TotalAccountThroughput = HeadersTransportSerialization.ReadLongHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.BYOKEncryptionProgress: + { + responseHeaders.ByokEncryptionProgress = HeadersTransportSerialization.ReadIntHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.AppliedPolicyElementId: + { + responseHeaders.AppliedPolicyElementId = HeadersTransportSerialization.ReadStringHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.MergeProgressBlocked: + { + responseHeaders.MergeProgressBlocked = HeadersTransportSerialization.ReadBoolHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.ChangeFeedInfo: + { + responseHeaders.ChangeFeedInfo = HeadersTransportSerialization.ReadStringHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.ReindexerProgress: + { + responseHeaders.ReIndexerProgress = HeadersTransportSerialization.ReadStringHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.OfferReplacePendingForMerge: + { + responseHeaders.OfferReplacePendingForMerge = HeadersTransportSerialization.ReadBoolHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.MaxContentLength: + { + responseHeaders.MaxContentLength = HeadersTransportSerialization.ReadUIntHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.OldestActiveSchemaId: + { + responseHeaders.OldestActiveSchemaId = HeadersTransportSerialization.ReadIntHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.PhysicalPartitionId: + { + responseHeaders.PhysicalPartitionId = HeadersTransportSerialization.ReadStringHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.OfferRestorePending: + { + responseHeaders.IsOfferRestorePending = HeadersTransportSerialization.ReadBoolHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.InstantScaleUpValue: + { + responseHeaders.InstantScaleUpValue = HeadersTransportSerialization.ReadUIntHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.RequiresDistribution: + { + responseHeaders.RequiresDistribution = HeadersTransportSerialization.ReadBoolHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.CapacityType: + { + responseHeaders.CapacityType = HeadersTransportSerialization.ReadUShortHeader(ref rntbdHeaderReader); + break; + } + + case ResponseIdentifiers.MinGLSNForDocumentOperations: + { + responseHeaders.MinGLSNForDocumentOperations = HeadersTransportSerialization.ReadLongHeader(ref rntbdHeaderReader); + break; + } + + default: + { + // We have to read all headers if those are in the middle of the payload + // For example ReadsPerformed, WritesPerformed,QueriesPerformed, IndexTermsGenerated and ScriptsExecuted + HeadersTransportSerialization.AdvanceByRntbdHeader(ref rntbdHeaderReader, identifier); + break; + } + } + } + + return responseHeaders; + } + + /// + /// Reads PayloadPresent RNTBD header to tell if payload is present. Resets the Position back on + /// if PayloadPresent was not the first header to make sure no other data is lost before the final headers processing + /// in . + /// + /// + /// TODO: https://msdata.visualstudio.com/CosmosDB/_workitems/edit/2105986 consider initializing + /// StoreResponseNameValueCollection on the main "receive" thread and reuse headers processing. + /// + internal static bool TryParseMandatoryResponseHeaders(ref BytesDeserializer rntbdHeaderReader, out bool payloadPresent, out uint transportRequestId) + { + payloadPresent = default; + transportRequestId = default; + + bool hasPayloadPresent = false; + bool hasTransportRequestId = false; + + while((!hasPayloadPresent || !hasTransportRequestId) && rntbdHeaderReader.Position < rntbdHeaderReader.Length) + { + ResponseIdentifiers identifier = (ResponseIdentifiers)rntbdHeaderReader.ReadUInt16(); + if (identifier == ResponseIdentifiers.PayloadPresent) + { + RntbdTokenTypes type = (RntbdTokenTypes)rntbdHeaderReader.ReadByte(); + Debug.Assert(type == RntbdTokenTypes.Byte); + + hasPayloadPresent = true; + payloadPresent = rntbdHeaderReader.ReadByte() != 0x0; + } + else if (identifier == ResponseIdentifiers.TransportRequestID) + { + RntbdTokenTypes type = (RntbdTokenTypes)rntbdHeaderReader.ReadByte(); + Debug.Assert(type == RntbdTokenTypes.ULong); + + hasTransportRequestId = true; + transportRequestId = rntbdHeaderReader.ReadUInt32(); + } + else + { + HeadersTransportSerialization.AdvanceByRntbdHeader(ref rntbdHeaderReader, identifier); + } + } + + return hasPayloadPresent && hasTransportRequestId; + } + + /// + /// Offsetting by current header. Used to skip unused RNTBD headers. + /// + private static void AdvanceByRntbdHeader(ref BytesDeserializer rntbdHeaderReader, ResponseIdentifiers identifier) + { + RntbdTokenTypes tokenType = (RntbdTokenTypes)rntbdHeaderReader.ReadByte(); + switch (tokenType) + { + case RntbdTokenTypes.Byte: + { + rntbdHeaderReader.ReadByte(); + return; + } + + case RntbdTokenTypes.UShort: + { + rntbdHeaderReader.AdvancePositionByUInt16(); + return; + } + + case RntbdTokenTypes.ULong: + { + rntbdHeaderReader.AdvancePositionByUInt32(); + return; + } + + case RntbdTokenTypes.Long: + { + rntbdHeaderReader.AdvancePositionByInt32(); + return; + } + + case RntbdTokenTypes.ULongLong: + { + rntbdHeaderReader.AdvancePositionByUInt64(); + return; + } + + case RntbdTokenTypes.LongLong: + { + rntbdHeaderReader.AdvancePositionByInt64(); + return; + } + + case RntbdTokenTypes.Float: + { + rntbdHeaderReader.AdvancePositionBySingle(); + return; + } + + case RntbdTokenTypes.Double: + { + rntbdHeaderReader.AdvancePositionByDouble(); + return; + } + + case RntbdTokenTypes.Guid: + { + rntbdHeaderReader.AdvancePositionByGuid(); + return; + } + + case RntbdTokenTypes.SmallBytes: + case RntbdTokenTypes.SmallString: + { + byte length = rntbdHeaderReader.ReadByte(); + rntbdHeaderReader.AdvancePositionByBytes(length); + return; + } + case RntbdTokenTypes.Bytes: + case RntbdTokenTypes.String: + { + ushort length = rntbdHeaderReader.ReadUInt16(); + rntbdHeaderReader.AdvancePositionByBytes(length); + return; + } + case RntbdTokenTypes.ULongBytes: + case RntbdTokenTypes.ULongString: + { + uint length = rntbdHeaderReader.ReadUInt32(); + rntbdHeaderReader.AdvancePositionByBytes((int)length); + return; + } + default: + { + INameValueCollection validationFailureResponseHeader = new DictionaryNameValueCollection(); + validationFailureResponseHeader.Add(HttpConstants.HttpHeaders.RequestValidationFailure, "1"); + throw new InternalServerErrorException($"Unrecognized token type {tokenType} with identifier {identifier} found in RNTBD token stream", validationFailureResponseHeader); + } + } + } + + private static string ReadStringHeader(ref BytesDeserializer rntbdHeaderReader) + { + RntbdTokenTypes type = (RntbdTokenTypes)rntbdHeaderReader.ReadByte(); + Debug.Assert(type == RntbdTokenTypes.String); + ushort length = rntbdHeaderReader.ReadUInt16(); + return BytesSerializer.GetStringFromBytes(rntbdHeaderReader.ReadBytes(length)); + } + + private static string ReadSmallStringHeader(ref BytesDeserializer rntbdHeaderReader) + { + RntbdTokenTypes type = (RntbdTokenTypes)rntbdHeaderReader.ReadByte(); + Debug.Assert(type == RntbdTokenTypes.SmallString); + byte length = rntbdHeaderReader.ReadByte(); + return BytesSerializer.GetStringFromBytes(rntbdHeaderReader.ReadBytes(length)); + } + + private static string ReadDoubleHeader(ref BytesDeserializer rntbdHeaderReader) + { + RntbdTokenTypes type = (RntbdTokenTypes)rntbdHeaderReader.ReadByte(); + Debug.Assert(type == RntbdTokenTypes.Double); + return rntbdHeaderReader.ReadDouble().ToString(CultureInfo.InvariantCulture); + } + + private static string ReadIntHeader(ref BytesDeserializer rntbdHeaderReader) + { + RntbdTokenTypes type = (RntbdTokenTypes)rntbdHeaderReader.ReadByte(); + Debug.Assert(type == RntbdTokenTypes.Long); + return rntbdHeaderReader.ReadInt32().ToString(CultureInfo.InvariantCulture); + } + + private static string ReadLongHeader(ref BytesDeserializer rntbdHeaderReader) + { + RntbdTokenTypes type = (RntbdTokenTypes)rntbdHeaderReader.ReadByte(); + Debug.Assert(type == RntbdTokenTypes.LongLong); + return rntbdHeaderReader.ReadInt64().ToString(CultureInfo.InvariantCulture); + } + + private static string ReadIntBoolHeader(ref BytesDeserializer rntbdHeaderReader) + { + RntbdTokenTypes type = (RntbdTokenTypes)rntbdHeaderReader.ReadByte(); + Debug.Assert(type == RntbdTokenTypes.Byte); + return rntbdHeaderReader.ReadByte() != 0x0 ? "1" : "0"; + } + + private static string ReadBoolHeader(ref BytesDeserializer rntbdHeaderReader) + { + RntbdTokenTypes type = (RntbdTokenTypes)rntbdHeaderReader.ReadByte(); + Debug.Assert(type == RntbdTokenTypes.Byte); + return rntbdHeaderReader.ReadByte() != 0x0 ? "true" : "false"; + } + + private static string ReadGuidHeader(ref BytesDeserializer rntbdHeaderReader) + { + RntbdTokenTypes type = (RntbdTokenTypes)rntbdHeaderReader.ReadByte(); + Debug.Assert(type == RntbdTokenTypes.Guid); + return rntbdHeaderReader.ReadGuid().ToString(); + } + + private static string ReadUIntHeader(ref BytesDeserializer rntbdHeaderReader) + { + RntbdTokenTypes type = (RntbdTokenTypes)rntbdHeaderReader.ReadByte(); + Debug.Assert(type == RntbdTokenTypes.ULong); + return rntbdHeaderReader.ReadUInt32().ToString(); + } + + private static string ReadUShortHeader(ref BytesDeserializer rntbdHeaderReader) + { + RntbdTokenTypes type = (RntbdTokenTypes)rntbdHeaderReader.ReadByte(); + Debug.Assert(type == RntbdTokenTypes.UShort); + return rntbdHeaderReader.ReadUInt16().ToString(CultureInfo.InvariantCulture); + } + + private static string ReadULongHeader(ref BytesDeserializer rntbdHeaderReader) + { + RntbdTokenTypes type = (RntbdTokenTypes)rntbdHeaderReader.ReadByte(); + Debug.Assert(type == RntbdTokenTypes.ULongLong); + return rntbdHeaderReader.ReadUInt64().ToString(); + } + } +} diff --git a/Microsoft.Azure.Cosmos/src/direct/rntbd2/HeadersTransportSerialization.tt b/Microsoft.Azure.Cosmos/src/direct/rntbd2/HeadersTransportSerialization.tt new file mode 100644 index 0000000000..63b5bb8c44 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/direct/rntbd2/HeadersTransportSerialization.tt @@ -0,0 +1,341 @@ +<#@ template language="C#" hostspecific="true" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ include file="..\Rntbd\RntbdConstantsDefinition.ttinclude"#><##> +<#@ include file="..\Rntbd\RntbdConstantsResponseTokens.ttinclude"#><##> +<#@ output extension=".cs" #> +<# +Dictionary tokenNameOverride = new Dictionary() +{ + {"LastStateChangeDateTime", "LastStateChangeUtc"}, + {"ContinuationToken", "Continuation"}, + {"RetryAfterMilliseconds", "RetryAfterInMilliseconds"}, + {"StorageMaxResoureQuota", "MaxResourceQuota"}, + {"StorageResourceQuotaUsage", "CurrentResourceQuotaUsage"}, + {"CollectionUpdateProgress", "CollectionIndexTransformationProgress"}, + {"CollectionLazyIndexProgress", "CollectionLazyIndexingProgress"}, + {"ServerDateTimeUtc", "XDate"}, + {"UnflushedMergeLogEntryCount", "UnflushedMergLogEntryCount"}, + {"ResourceName", "ResourceId"}, + {"BYOKEncryptionProgress", "ByokEncryptionProgress"}, + {"ReindexerProgress", "ReIndexerProgress"}, + {"OfferRestorePending", "IsOfferRestorePending"} +}; +#> +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +// THIS IS AN AUTOGENERATED FILE. ALL UPDATES SHOULD BE DONE VIA HeadersTransportSerialization.tt +namespace Microsoft.Azure.Documents.Rntbd +{ + using System; + using System.Diagnostics; + using System.Globalization; +#if COSMOSCLIENT + using Microsoft.Azure.Cosmos.Rntbd; +#endif + using Microsoft.Azure.Documents.Collections; + using static Microsoft.Azure.Documents.RntbdConstants; + + /// + /// THIS IS AN AUTOGENERATED FILE. ALL UPDATES SHOULD BE DONE VIA RntbdConstants.tt + /// This allows the RntbdTokenStreams to be correctly ordered and optimized. + /// If you need to add a new RntbdToken to any of the existing types, do it on the RntbdConstants.tt file + /// + internal static class HeadersTransportSerialization + { + public static StoreResponseNameValueCollection BuildStoreResponseNameValueCollection( + Guid activityId, + string serverVersion, + ref BytesDeserializer rntbdHeaderReader) + { + StoreResponseNameValueCollection responseHeaders = new() + { + ActivityId = activityId.ToString(), + ServerVersion = serverVersion + }; + + while(rntbdHeaderReader.Position < rntbdHeaderReader.Length) + { + ResponseIdentifiers identifier = (ResponseIdentifiers)rntbdHeaderReader.ReadUInt16(); + switch (identifier) + { +<# foreach(RntbdTokenDefinition token in responseTokens) { #> +<# if (token.Name == "PayloadPresent") continue; #> +<# string responseHeadersFieldName = tokenNameOverride.ContainsKey(token.Name) ? tokenNameOverride[token.Name] : token.Name; #> + case ResponseIdentifiers.<#= token.Name #>: + { + <# if (token.Name == "RequestCharge") {#> + RntbdTokenTypes type = (RntbdTokenTypes)rntbdHeaderReader.ReadByte(); + Debug.Assert(type == RntbdTokenTypes.Double); + double value = rntbdHeaderReader.ReadDouble(); + responseHeaders.RequestCharge = string.Format(CultureInfo.InvariantCulture, "{0:0.##}", value); + <#} else if (token.Name == "IndexingDirective") {#> + RntbdTokenTypes type = (RntbdTokenTypes)rntbdHeaderReader.ReadByte(); + Debug.Assert(type == RntbdTokenTypes.Byte); + byte value = rntbdHeaderReader.ReadByte(); + string indexingDirective = value switch + { + (byte)RntbdConstants.RntbdIndexingDirective.Default => IndexingDirectiveStrings.Default, + (byte)RntbdConstants.RntbdIndexingDirective.Exclude => IndexingDirectiveStrings.Exclude, + (byte)RntbdConstants.RntbdIndexingDirective.Include => IndexingDirectiveStrings.Include, + _ => throw new Exception(), + }; + responseHeaders.IndexingDirective = indexingDirective; + <#} else if (token.TokenType == "RntbdTokenTypes.UShort") {#> + responseHeaders.<#= responseHeadersFieldName #> = HeadersTransportSerialization.ReadUShortHeader(ref rntbdHeaderReader); + <#} else if (token.TokenType == "RntbdTokenTypes.ULong") {#> + responseHeaders.<#= responseHeadersFieldName #> = HeadersTransportSerialization.ReadUIntHeader(ref rntbdHeaderReader); + <#} else if (token.TokenType == "RntbdTokenTypes.ULongLong") {#> + responseHeaders.<#= responseHeadersFieldName #> = HeadersTransportSerialization.ReadULongHeader(ref rntbdHeaderReader); + <#} else if (token.TokenType == "RntbdTokenTypes.Long") {#> + responseHeaders.<#= responseHeadersFieldName #> = HeadersTransportSerialization.ReadIntHeader(ref rntbdHeaderReader); + <#} else if (token.TokenType == "RntbdTokenTypes.LongLong") {#> + responseHeaders.<#= responseHeadersFieldName #> = HeadersTransportSerialization.ReadLongHeader(ref rntbdHeaderReader); + <#} else if (token.TokenType == "RntbdTokenTypes.Double") {#> + responseHeaders.<#= responseHeadersFieldName #> = HeadersTransportSerialization.ReadDoubleHeader(ref rntbdHeaderReader); + <#} else if (token.TokenType == "RntbdTokenTypes.Guid") {#> + responseHeaders.<#= responseHeadersFieldName #> = HeadersTransportSerialization.ReadGuidHeader(ref rntbdHeaderReader); + <#} else if (token.TokenType == "RntbdTokenTypes.String") {#> + responseHeaders.<#= responseHeadersFieldName #> = HeadersTransportSerialization.ReadStringHeader(ref rntbdHeaderReader); + <#} else if (token.TokenType == "RntbdTokenTypes.SmallString") {#> + responseHeaders.<#= responseHeadersFieldName #> = HeadersTransportSerialization.ReadSmallStringHeader(ref rntbdHeaderReader); + <#} else if (token.TokenType == "RntbdTokenTypes.Byte" && (token.Name == "RequestValidationFailure" || token.Name == "IsRUPerMinuteUsed")) {#> + responseHeaders.<#= responseHeadersFieldName #> = HeadersTransportSerialization.ReadIntBoolHeader(ref rntbdHeaderReader); + <#} else if (token.TokenType == "RntbdTokenTypes.Byte") {#> + responseHeaders.<#= responseHeadersFieldName #> = HeadersTransportSerialization.ReadBoolHeader(ref rntbdHeaderReader); + <#} else { throw new Exception("Unsupported TokenTypr for response header"); } #> + break; + } + +<# } #> + default: + { + // We have to read all headers if those are in the middle of the payload + // For example ReadsPerformed, WritesPerformed,QueriesPerformed, IndexTermsGenerated and ScriptsExecuted + HeadersTransportSerialization.AdvanceByRntbdHeader(ref rntbdHeaderReader, identifier); + break; + } + } + } + + return responseHeaders; + } + + /// + /// Reads PayloadPresent RNTBD header to tell if payload is present. Resets the Position back on + /// if PayloadPresent was not the first header to make sure no other data is lost before the final headers processing + /// in . + /// + /// + /// TODO: https://msdata.visualstudio.com/CosmosDB/_workitems/edit/2105986 consider initializing + /// StoreResponseNameValueCollection on the main "receive" thread and reuse headers processing. + /// + internal static bool TryParseMandatoryResponseHeaders(ref BytesDeserializer rntbdHeaderReader, out bool payloadPresent, out uint transportRequestId) + { + payloadPresent = default; + transportRequestId = default; + + bool hasPayloadPresent = false; + bool hasTransportRequestId = false; + + while((!hasPayloadPresent || !hasTransportRequestId) && rntbdHeaderReader.Position < rntbdHeaderReader.Length) + { + ResponseIdentifiers identifier = (ResponseIdentifiers)rntbdHeaderReader.ReadUInt16(); + if (identifier == ResponseIdentifiers.PayloadPresent) + { + RntbdTokenTypes type = (RntbdTokenTypes)rntbdHeaderReader.ReadByte(); + Debug.Assert(type == RntbdTokenTypes.Byte); + + hasPayloadPresent = true; + payloadPresent = rntbdHeaderReader.ReadByte() != 0x0; + } + else if (identifier == ResponseIdentifiers.TransportRequestID) + { + RntbdTokenTypes type = (RntbdTokenTypes)rntbdHeaderReader.ReadByte(); + Debug.Assert(type == RntbdTokenTypes.ULong); + + hasTransportRequestId = true; + transportRequestId = rntbdHeaderReader.ReadUInt32(); + } + else + { + HeadersTransportSerialization.AdvanceByRntbdHeader(ref rntbdHeaderReader, identifier); + } + } + + return hasPayloadPresent && hasTransportRequestId; + } + + /// + /// Offsetting by current header. Used to skip unused RNTBD headers. + /// + private static void AdvanceByRntbdHeader(ref BytesDeserializer rntbdHeaderReader, ResponseIdentifiers identifier) + { + RntbdTokenTypes tokenType = (RntbdTokenTypes)rntbdHeaderReader.ReadByte(); + switch (tokenType) + { + case RntbdTokenTypes.Byte: + { + rntbdHeaderReader.ReadByte(); + return; + } + + case RntbdTokenTypes.UShort: + { + rntbdHeaderReader.AdvancePositionByUInt16(); + return; + } + + case RntbdTokenTypes.ULong: + { + rntbdHeaderReader.AdvancePositionByUInt32(); + return; + } + + case RntbdTokenTypes.Long: + { + rntbdHeaderReader.AdvancePositionByInt32(); + return; + } + + case RntbdTokenTypes.ULongLong: + { + rntbdHeaderReader.AdvancePositionByUInt64(); + return; + } + + case RntbdTokenTypes.LongLong: + { + rntbdHeaderReader.AdvancePositionByInt64(); + return; + } + + case RntbdTokenTypes.Float: + { + rntbdHeaderReader.AdvancePositionBySingle(); + return; + } + + case RntbdTokenTypes.Double: + { + rntbdHeaderReader.AdvancePositionByDouble(); + return; + } + + case RntbdTokenTypes.Guid: + { + rntbdHeaderReader.AdvancePositionByGuid(); + return; + } + + case RntbdTokenTypes.SmallBytes: + case RntbdTokenTypes.SmallString: + { + byte length = rntbdHeaderReader.ReadByte(); + rntbdHeaderReader.AdvancePositionByBytes(length); + return; + } + case RntbdTokenTypes.Bytes: + case RntbdTokenTypes.String: + { + ushort length = rntbdHeaderReader.ReadUInt16(); + rntbdHeaderReader.AdvancePositionByBytes(length); + return; + } + case RntbdTokenTypes.ULongBytes: + case RntbdTokenTypes.ULongString: + { + uint length = rntbdHeaderReader.ReadUInt32(); + rntbdHeaderReader.AdvancePositionByBytes((int)length); + return; + } + default: + { + INameValueCollection validationFailureResponseHeader = new DictionaryNameValueCollection(); + validationFailureResponseHeader.Add(HttpConstants.HttpHeaders.RequestValidationFailure, "1"); + throw new InternalServerErrorException($"Unrecognized token type {tokenType} with identifier {identifier} found in RNTBD token stream", validationFailureResponseHeader); + } + } + } + + private static string ReadStringHeader(ref BytesDeserializer rntbdHeaderReader) + { + RntbdTokenTypes type = (RntbdTokenTypes)rntbdHeaderReader.ReadByte(); + Debug.Assert(type == RntbdTokenTypes.String); + ushort length = rntbdHeaderReader.ReadUInt16(); + return BytesSerializer.GetStringFromBytes(rntbdHeaderReader.ReadBytes(length)); + } + + private static string ReadSmallStringHeader(ref BytesDeserializer rntbdHeaderReader) + { + RntbdTokenTypes type = (RntbdTokenTypes)rntbdHeaderReader.ReadByte(); + Debug.Assert(type == RntbdTokenTypes.SmallString); + byte length = rntbdHeaderReader.ReadByte(); + return BytesSerializer.GetStringFromBytes(rntbdHeaderReader.ReadBytes(length)); + } + + private static string ReadDoubleHeader(ref BytesDeserializer rntbdHeaderReader) + { + RntbdTokenTypes type = (RntbdTokenTypes)rntbdHeaderReader.ReadByte(); + Debug.Assert(type == RntbdTokenTypes.Double); + return rntbdHeaderReader.ReadDouble().ToString(CultureInfo.InvariantCulture); + } + + private static string ReadIntHeader(ref BytesDeserializer rntbdHeaderReader) + { + RntbdTokenTypes type = (RntbdTokenTypes)rntbdHeaderReader.ReadByte(); + Debug.Assert(type == RntbdTokenTypes.Long); + return rntbdHeaderReader.ReadInt32().ToString(CultureInfo.InvariantCulture); + } + + private static string ReadLongHeader(ref BytesDeserializer rntbdHeaderReader) + { + RntbdTokenTypes type = (RntbdTokenTypes)rntbdHeaderReader.ReadByte(); + Debug.Assert(type == RntbdTokenTypes.LongLong); + return rntbdHeaderReader.ReadInt64().ToString(CultureInfo.InvariantCulture); + } + + private static string ReadIntBoolHeader(ref BytesDeserializer rntbdHeaderReader) + { + RntbdTokenTypes type = (RntbdTokenTypes)rntbdHeaderReader.ReadByte(); + Debug.Assert(type == RntbdTokenTypes.Byte); + return rntbdHeaderReader.ReadByte() != 0x0 ? "1" : "0"; + } + + private static string ReadBoolHeader(ref BytesDeserializer rntbdHeaderReader) + { + RntbdTokenTypes type = (RntbdTokenTypes)rntbdHeaderReader.ReadByte(); + Debug.Assert(type == RntbdTokenTypes.Byte); + return rntbdHeaderReader.ReadByte() != 0x0 ? "true" : "false"; + } + + private static string ReadGuidHeader(ref BytesDeserializer rntbdHeaderReader) + { + RntbdTokenTypes type = (RntbdTokenTypes)rntbdHeaderReader.ReadByte(); + Debug.Assert(type == RntbdTokenTypes.Guid); + return rntbdHeaderReader.ReadGuid().ToString(); + } + + private static string ReadUIntHeader(ref BytesDeserializer rntbdHeaderReader) + { + RntbdTokenTypes type = (RntbdTokenTypes)rntbdHeaderReader.ReadByte(); + Debug.Assert(type == RntbdTokenTypes.ULong); + return rntbdHeaderReader.ReadUInt32().ToString(); + } + + private static string ReadUShortHeader(ref BytesDeserializer rntbdHeaderReader) + { + RntbdTokenTypes type = (RntbdTokenTypes)rntbdHeaderReader.ReadByte(); + Debug.Assert(type == RntbdTokenTypes.UShort); + return rntbdHeaderReader.ReadUInt16().ToString(CultureInfo.InvariantCulture); + } + + private static string ReadULongHeader(ref BytesDeserializer rntbdHeaderReader) + { + RntbdTokenTypes type = (RntbdTokenTypes)rntbdHeaderReader.ReadByte(); + Debug.Assert(type == RntbdTokenTypes.ULongLong); + return rntbdHeaderReader.ReadUInt64().ToString(); + } + } +} diff --git a/Microsoft.Azure.Cosmos/src/direct/rntbd2/TransportClient.cs b/Microsoft.Azure.Cosmos/src/direct/rntbd2/TransportClient.cs index 0c23958c68..1c1a315289 100644 --- a/Microsoft.Azure.Cosmos/src/direct/rntbd2/TransportClient.cs +++ b/Microsoft.Azure.Cosmos/src/direct/rntbd2/TransportClient.cs @@ -91,7 +91,8 @@ public TransportClient(Options clientOptions) clientOptions.CallerId, clientOptions.EnableChannelMultiplexing, clientOptions.MemoryStreamPool, - clientOptions.RemoteCertificateValidationCallback)); + clientOptions.RemoteCertificateValidationCallback, + clientOptions.DnsResolutionFunction)); } internal override Task InvokeStoreAsync( @@ -379,6 +380,7 @@ public Options(TimeSpan requestTimeout) this.CallerId = RntbdConstants.CallerId.Anonymous; this.EnableChannelMultiplexing = false; this.MaxConcurrentOpeningConnectionCount = ushort.MaxValue; + this.DnsResolutionFunction = null; } public TimeSpan RequestTimeout { get; private set; } @@ -457,6 +459,11 @@ public TimeSpan TimerPoolResolution public RemoteCertificateValidationCallback RemoteCertificateValidationCallback { get; internal set; } + /// + /// Override for DNS resolution callbacks for RNTBD connections. + /// + public Func> DnsResolutionFunction { get; internal set; } + public override string ToString() { StringBuilder s = new StringBuilder(); @@ -493,6 +500,8 @@ public override string ToString() s.AppendLine(this.MaxConcurrentOpeningConnectionCount.ToString(CultureInfo.InvariantCulture)); s.Append(" Use_RecyclableMemoryStream: "); s.AppendLine(this.MemoryStreamPool != null ? bool.TrueString : bool.FalseString); + s.Append(" Use_CustomDnsResolution: "); + s.AppendLine(this.DnsResolutionFunction != null ? bool.TrueString : bool.FalseString); return s.ToString(); } 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 59a5eabf76..d468fe87f5 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 @@ -61,7 +61,7 @@ - - - Change Feed Estimator - feedIterator = estimator.GetCurrentStateIterator(); - - List traces = new List(); - - while (feedIterator.HasMoreResults) - { - FeedResponse responseMessage = await feedIterator.ReadNextAsync(cancellationToken: default); - ITrace trace = ((CosmosTraceDiagnostics)responseMessage.Diagnostics).Value; - traces.Add(trace); - } - - ITrace traceForest = TraceJoiner.JoinTraces(traces); -]]> - - - - - - \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/BaselineTest/TestBaseline/EndToEndTraceWriterBaselineTests.MiscellanousAsync.xml b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/BaselineTest/TestBaseline/EndToEndTraceWriterBaselineTests.MiscellanousAsync.xml index a6a935fe01..832dfee446 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/BaselineTest/TestBaseline/EndToEndTraceWriterBaselineTests.MiscellanousAsync.xml +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/BaselineTest/TestBaseline/EndToEndTraceWriterBaselineTests.MiscellanousAsync.xml @@ -44,7 +44,7 @@ diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/BaselineTest/TestBaseline/LinqTranslationWithCustomSerializerBaseline.TestMemberInitializer.xml b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/BaselineTest/TestBaseline/LinqTranslationWithCustomSerializerBaseline.TestMemberInitializer.xml deleted file mode 100644 index 8763ef6866..0000000000 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/BaselineTest/TestBaseline/LinqTranslationWithCustomSerializerBaseline.TestMemberInitializer.xml +++ /dev/null @@ -1,48 +0,0 @@ - - - - - (doc == new DataObject() {NumericField = 12, StringField = "12"}))]]> - - - - - - - - - new DataObject() {NumericField = 12, StringField = "12"})]]> - - - - - - - - - IIF((doc.NumericField > 12), new DataObject() {NumericField = 12, StringField = "12"}, new DataObject() {NumericField = 12, StringField = "12"}))]]> - - - 12) ? {"number": 12, "String_value": "12", "id": null, "Pk": null} : {"number": 12, "String_value": "12", "id": null, "Pk": null}) -FROM root]]> - - - - - - (doc == new DataObject() {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/ClientTelemetryTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/ClientTelemetryTests.cs index 54c4bd2bd2..08028cec69 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/ClientTelemetryTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/ClientTelemetryTests.cs @@ -24,8 +24,6 @@ namespace Microsoft.Azure.Cosmos.SDK.EmulatorTests using System.Linq; using Cosmos.Util; using Microsoft.Azure.Cosmos.Telemetry.Models; - using Microsoft.Azure.Cosmos.Routing; - using Microsoft.Azure.Cosmos.Common; [TestClass] public class ClientTelemetryTests : BaseCosmosClientHelper @@ -302,7 +300,8 @@ await container.ReadItemAsync( await this.WaitAndAssert(expectedOperationCount: 2, expectedConsistencyLevel: Microsoft.Azure.Cosmos.ConsistencyLevel.Eventual, expectedOperationRecordCountMap: expectedRecordCountInOperation, - expectedCacheSource: null); + expectedCacheSource: null, + isExpectedNetworkTelemetry: false); } [TestMethod] @@ -337,7 +336,8 @@ await container.ReadItemStreamAsync( await this.WaitAndAssert(expectedOperationCount: 2, expectedConsistencyLevel: Microsoft.Azure.Cosmos.ConsistencyLevel.ConsistentPrefix, expectedOperationRecordCountMap: expectedRecordCountInOperation, - expectedCacheSource: null); + expectedCacheSource: null, + isExpectedNetworkTelemetry: false); } [TestMethod] @@ -792,10 +792,11 @@ public async Task CreateItemWithSubStatusCodeTest(ConnectionMode mode) { { Documents.OperationType.Create.ToString(), 1} }; - + await this.WaitAndAssert(expectedOperationCount: 2, expectedOperationRecordCountMap: expectedRecordCountInOperation, - expectedSubstatuscode: 999999); + expectedSubstatuscode: 999999, + isExpectedNetworkTelemetry: false); } @@ -812,19 +813,23 @@ private async Task WaitAndAssert( IDictionary expectedOperationRecordCountMap = null, int expectedSubstatuscode = 0, bool? isAzureInstance = null, - string expectedCacheSource = "ClientCollectionCache") + 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. @@ -864,7 +869,8 @@ private async Task WaitAndAssert( 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); @@ -874,6 +880,7 @@ private async Task WaitAndAssert( localCopyOfActualInfo: localCopyOfActualInfo, actualOperationList: actualOperationList, actualSystemInformation: actualSystemInformation, + actualRequestInformation: actualRequestInformation, isAzureInstance: isAzureInstance); ClientTelemetryTests.AssertOperationLevelInformation( @@ -892,8 +899,37 @@ private async Task WaitAndAssert( } 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(); @@ -937,12 +973,12 @@ private static void AssertOperationLevelInformation( 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}"); @@ -978,6 +1014,7 @@ private static void AssertAccountLevelInformation( List localCopyOfActualInfo, List actualOperationList, List actualSystemInformation, + List actualRequestInformation, bool? isAzureInstance) { ISet machineId = new HashSet(); @@ -985,8 +1022,23 @@ private static void AssertAccountLevelInformation( // Asserting If basic client telemetry object is as expected foreach (ClientTelemetryProperties telemetryInfo in localCopyOfActualInfo) { - actualOperationList.AddRange(telemetryInfo.OperationInfo); - actualSystemInformation.AddRange(telemetryInfo.SystemInfo); + 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()) { @@ -1079,20 +1131,8 @@ public async Task CheckMisconfiguredTelemetryEndpoint_should_stop_the_job() mode: ConnectionMode.Direct, customHttpHandler: customHttpHandler); - // Create an item - ToDoActivity testItem = ToDoActivity.CreateRandomToDoActivity("MyTestPkValue"); - ItemResponse createResponse = await container.CreateItemAsync(testItem); - ToDoActivity testItemCreated = createResponse.Resource; - - // Read an Item - ItemResponse response = await container.ReadItemAsync(testItem.id, new Cosmos.PartitionKey(testItem.id)); - - await Task.Delay(1500); - - response = await container.ReadItemAsync(testItem.id, new Cosmos.PartitionKey(testItem.id)); - - await Task.Delay(3500); - + await Task.Delay(TimeSpan.FromMilliseconds(5000)); // wait for 5 sec, ideally telemetry would be sent 5 times but client telemetry endpoint is not functional (in this test), it should try 3 times maximum and after that client telemetry job should be stopped. + Assert.AreEqual(3, retryCounter); } diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosContainerTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosContainerTests.cs index 82501a5bfa..5615f1dc34 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosContainerTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosContainerTests.cs @@ -11,6 +11,7 @@ namespace Microsoft.Azure.Cosmos.SDK.EmulatorTests using System.Linq; using System.Net; using System.Threading.Tasks; + using HttpConstants = Microsoft.Azure.Documents.HttpConstants; using Microsoft.Azure.Cosmos.Resource.CosmosExceptions; using Microsoft.Azure.Cosmos.Tracing; using Microsoft.Azure.Documents; @@ -23,6 +24,7 @@ public class CosmosContainerTests { private CosmosClient cosmosClient = null; private Cosmos.Database cosmosDatabase = null; + private static long ToEpoch(DateTime dateTime) { return (long)(dateTime - new DateTime(1970, 1, 1)).TotalSeconds; @@ -714,7 +716,6 @@ public async Task GetFeedRangeOnContainerRecreateScenariosTestAsync() } } -#if PREVIEW //MultiHash container checks. [TestMethod] public async Task CreateContainerIfNotExistsAsyncForMultiHashCollectionsTest() @@ -799,7 +800,6 @@ public async Task CreateContainerIfNotExistsAsyncForMultiHashCollectionsTest() } -#endif [TestMethod] public async Task StreamPartitionedCreateWithPathDelete() { diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosMultiHashTest.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosMultiHashTest.cs index c77352d07f..5307145dfc 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosMultiHashTest.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosMultiHashTest.cs @@ -1,5 +1,4 @@ -#if PREVIEW -namespace Microsoft.Azure.Cosmos.SDK.EmulatorTests +namespace Microsoft.Azure.Cosmos.SDK.EmulatorTests { using System; using System.Collections.Generic; @@ -13,23 +12,19 @@ namespace Microsoft.Azure.Cosmos.SDK.EmulatorTests [TestClass] public class CosmosMultiHashTest { + private CosmosClient client = null; private Cosmos.Database database = null; - private CosmosClient client = null; private Container container = null; private ContainerProperties containerProperties = null; - private readonly string currentVersion = HttpConstants.Versions.CurrentVersion; - - [TestInitialize] public async Task TestInitialize() { - HttpConstants.Versions.CurrentVersion = "2020-07-15"; this.client = TestCommon.CreateCosmosClient(true); this.database = await this.client.CreateDatabaseIfNotExistsAsync("mydb"); - this.containerProperties = new ContainerProperties("mycoll", new List { "/ZipCode", "/Address" }); + this.containerProperties = new ContainerProperties("mycoll", new List { "/ZipCode", "/City" }); this.container = await this.database.CreateContainerAsync(this.containerProperties); } @@ -37,32 +32,44 @@ public async Task TestInitialize() public async Task Cleanup() { await this.database.DeleteAsync(); - HttpConstants.Versions.CurrentVersion = this.currentVersion; this.client.Dispose(); } [TestMethod] public async Task MultiHashCreateDocumentTest() { + Cosmos.PartitionKey pKey; //Document create test ItemResponse[] documents = new ItemResponse[3]; - Document doc1 = new Document { Id = "document1" }; - doc1.SetValue("ZipCode", "500026"); - doc1.SetValue("Address", "Secunderabad"); - doc1.SetValue("Type", "Residence"); - documents[0] = await this.container.CreateItemAsync(doc1); - - doc1 = new Document { Id = "document2" }; - doc1.SetValue("ZipCode", "15232"); - doc1.SetValue("Address", "Pittsburgh"); - doc1.SetValue("Type", "Business"); - documents[1] = await this.container.CreateItemAsync(doc1); - - doc1 = new Document { Id = "document3" }; - doc1.SetValue("ZipCode", "11790"); - doc1.SetValue("Address", "Stonybrook"); - doc1.SetValue("Type", "Goverment"); - documents[2] = await this.container.CreateItemAsync(doc1); + Document doc = new Document { Id = "document1" }; + doc.SetValue("ZipCode", "500026"); + doc.SetValue("City", "Secunderabad"); + doc.SetValue("Type", "Residence"); + pKey= new PartitionKeyBuilder() + .Add(doc.GetPropertyValue("ZipCode")) + .Add(doc.GetPropertyValue("City")) + .Build(); + documents[0] = await this.container.CreateItemAsync(doc, pKey); + + doc = new Document { Id = "document2" }; + doc.SetValue("ZipCode", "15232"); + doc.SetValue("City", "Pittsburgh"); + doc.SetValue("Type", "Business"); + pKey = new PartitionKeyBuilder() + .Add(doc.GetPropertyValue("ZipCode")) + .Add(doc.GetPropertyValue("City")) + .Build(); + documents[1] = await this.container.CreateItemAsync(doc); + + doc = new Document { Id = "document3" }; + doc.SetValue("ZipCode", "11790"); + doc.SetValue("City", "Stonybrook"); + doc.SetValue("Type", "Goverment"); + pKey = new PartitionKeyBuilder() + .Add(doc.GetPropertyValue("ZipCode")) + .Add(doc.GetPropertyValue("City")) + .Build(); + documents[2] = await this.container.CreateItemAsync(doc); Assert.AreEqual(3, documents.Select(document => ((Document)document).SelfLink).Distinct().Count()); @@ -72,14 +79,16 @@ public async Task MultiHashCreateDocumentTest() foreach (Document document in documents) { badPKey = new PartitionKeyBuilder() - .Add(document.GetPropertyValue("Address")) + .Add(document.GetPropertyValue("ZipCode")) .Build(); document.Id += "Bad"; - ArgumentException createException = await Assert.ThrowsExceptionAsync(() => + CosmosException createException = await Assert.ThrowsExceptionAsync(() => this.container.CreateItemAsync(document, badPKey) ); + + Assert.AreEqual(createException.StatusCode, HttpStatusCode.BadRequest); } } @@ -91,45 +100,44 @@ public async Task MultiHashDeleteDocumentTest() //Create Items for test ItemResponse[] documents = new ItemResponse[3]; - Document doc1 = new Document { Id = "document1" }; - doc1.SetValue("ZipCode", "500026"); - doc1.SetValue("Address", "Secunderabad"); - doc1.SetValue("Type", "Residence"); - documents[0] = await this.container.CreateItemAsync(doc1); - - doc1 = new Document { Id = "document2" }; - doc1.SetValue("ZipCode", "15232"); - doc1.SetValue("Address", "Pittsburgh"); - doc1.SetValue("Type", "Business"); - documents[1] = await this.container.CreateItemAsync(doc1); - - doc1 = new Document { Id = "document3" }; - doc1.SetValue("ZipCode", "11790"); - doc1.SetValue("Address", "Stonybrook"); - doc1.SetValue("Type", "Goverment"); - documents[2] = await this.container.CreateItemAsync(doc1); + Document doc = new Document { Id = "document1" }; + doc.SetValue("ZipCode", "500026"); + doc.SetValue("City", "Secunderabad"); + doc.SetValue("Type", "Residence"); + documents[0] = await this.container.CreateItemAsync(doc); + + doc = new Document { Id = "document2" }; + doc.SetValue("ZipCode", "15232"); + doc.SetValue("City", "Pittsburgh"); + doc.SetValue("Type", "Business"); + documents[1] = await this.container.CreateItemAsync(doc); + + doc = new Document { Id = "document3" }; + doc.SetValue("ZipCode", "11790"); + doc.SetValue("City", "Stonybrook"); + doc.SetValue("Type", "Goverment"); + documents[2] = await this.container.CreateItemAsync(doc); //Document Delete Test foreach (Document document in documents) { - //Negative test - using incomplete partition key + //Negative test - using incomplete partition key (try one with more values too) badPKey = new PartitionKeyBuilder() - .Add(document.GetPropertyValue("Address")) + .Add(document.GetPropertyValue("ZipCode")) .Build(); CosmosException deleteException = await Assert.ThrowsExceptionAsync(() => this.container.DeleteItemAsync(document.Id, badPKey) ); - Assert.AreEqual(deleteException.StatusCode, HttpStatusCode.BadRequest); //Positive test pKey = new PartitionKeyBuilder() .Add(document.GetPropertyValue("ZipCode")) - .Add(document.GetPropertyValue("Address")) + .Add(document.GetPropertyValue("City")) .Build(); - Document readDocument = (await this.container.DeleteItemAsync(document.Id, pKey)).Resource; + Document deleteDocument = (await this.container.DeleteItemAsync(document.Id, pKey)).Resource; CosmosException clientException = await Assert.ThrowsExceptionAsync(() => this.container.ReadItemAsync(document.Id, pKey) @@ -147,30 +155,30 @@ public async Task MultiHashReadItemTest() //Create Items for test ItemResponse[] documents = new ItemResponse[3]; - Document doc1 = new Document { Id = "document1" }; - doc1.SetValue("ZipCode", "500026"); - doc1.SetValue("Address", "Secunderabad"); - doc1.SetValue("Type", "Residence"); - documents[0] = await this.container.CreateItemAsync(doc1); - - doc1 = new Document { Id = "document2" }; - doc1.SetValue("ZipCode", "15232"); - doc1.SetValue("Address", "Pittsburgh"); - doc1.SetValue("Type", "Business"); - documents[1] = await this.container.CreateItemAsync(doc1); - - doc1 = new Document { Id = "document3" }; - doc1.SetValue("ZipCode", "11790"); - doc1.SetValue("Address", "Stonybrook"); - doc1.SetValue("Type", "Goverment"); - documents[2] = await this.container.CreateItemAsync(doc1); + Document doc = new Document { Id = "document1" }; + doc.SetValue("ZipCode", "500026"); + doc.SetValue("City", "Secunderabad"); + doc.SetValue("Type", "Residence"); + documents[0] = await this.container.CreateItemAsync(doc); + + doc = new Document { Id = "document2" }; + doc.SetValue("ZipCode", "15232"); + doc.SetValue("City", "Pittsburgh"); + doc.SetValue("Type", "Business"); + documents[1] = await this.container.CreateItemAsync(doc); + + doc = new Document { Id = "document3" }; + doc.SetValue("ZipCode", "11790"); + doc.SetValue("City", "Stonybrook"); + doc.SetValue("Type", "Goverment"); + documents[2] = await this.container.CreateItemAsync(doc); //Document Read Test foreach (Document document in documents) { pKey = new PartitionKeyBuilder() .Add(document.GetPropertyValue("ZipCode")) - .Add(document.GetPropertyValue("Address")) + .Add(document.GetPropertyValue("City")) .Build(); Document readDocument = (await this.container.ReadItemAsync(document.Id, pKey)).Resource; @@ -178,7 +186,7 @@ public async Task MultiHashReadItemTest() //Negative test - using incomplete partition key badPKey = new PartitionKeyBuilder() - .Add(document.GetPropertyValue("Address")) + .Add(document.GetPropertyValue("ZipCode")) .Build(); CosmosException clientException = await Assert.ThrowsExceptionAsync(() => @@ -193,40 +201,47 @@ public async Task MultiHashReadItemTest() public async Task MultiHashReadManyTest() { Cosmos.PartitionKey pKey; + Cosmos.PartitionKey badPKey; //Create Items for test ItemResponse[] documents = new ItemResponse[3]; - Document doc1 = new Document { Id = "document1" }; - doc1.SetValue("ZipCode", "500026"); - doc1.SetValue("Address", "Secunderabad"); - doc1.SetValue("Type", "Residence"); - documents[0] = await this.container.CreateItemAsync(doc1); - - doc1 = new Document { Id = "document2" }; - doc1.SetValue("ZipCode", "15232"); - doc1.SetValue("Address", "Pittsburgh"); - doc1.SetValue("Type", "Business"); - documents[1] = await this.container.CreateItemAsync(doc1); - - doc1 = new Document { Id = "document3" }; - doc1.SetValue("ZipCode", "11790"); - doc1.SetValue("Address", "Stonybrook"); - doc1.SetValue("Type", "Goverment"); - documents[2] = await this.container.CreateItemAsync(doc1); + Document doc = new Document { Id = "document1" }; + doc.SetValue("ZipCode", "500026"); + doc.SetValue("City", "Secunderabad"); + doc.SetValue("Type", "Residence"); + documents[0] = await this.container.CreateItemAsync(doc); + + doc = new Document { Id = "document2" }; + doc.SetValue("ZipCode", "15232"); + doc.SetValue("City", "Pittsburgh"); + doc.SetValue("Type", "Business"); + documents[1] = await this.container.CreateItemAsync(doc); + + doc = new Document { Id = "document3" }; + doc.SetValue("ZipCode", "11790"); + doc.SetValue("City", "Stonybrook"); + doc.SetValue("Type", "Goverment"); + documents[2] = await this.container.CreateItemAsync(doc); //Read Many Test List<(string, Cosmos.PartitionKey)> itemList = new List<(string, Cosmos.PartitionKey)>(); + List<(string, Cosmos.PartitionKey)> incompleteList = new List<(string, Cosmos.PartitionKey)>(); foreach (Document document in documents) { pKey = new PartitionKeyBuilder() .Add(document.GetPropertyValue("ZipCode")) - .Add(document.GetPropertyValue("Address")) + .Add(document.GetPropertyValue("City")) + .Build(); + + badPKey = new PartitionKeyBuilder() + .Add(document.GetPropertyValue("ZipCode")) .Build(); itemList.Add((document.Id, pKey)); + incompleteList.Add((document.Id, badPKey)); } - FeedResponse feedResponse = await this.container.ReadManyItemsAsync(itemList); + FeedResponse feedResponse = await this.container.ReadManyItemsAsync(itemList); Assert.IsNotNull(feedResponse); Assert.AreEqual(feedResponse.Count, 3); @@ -234,17 +249,25 @@ public async Task MultiHashReadManyTest() Assert.IsNotNull(feedResponse.Diagnostics); int count = 0; - foreach (ToDoActivity item in feedResponse) + foreach (Document item in feedResponse) { count++; Assert.IsNotNull(item); - Assert.IsNotNull(item.pk); } Assert.AreEqual(count, 3); + + //Negative test - using incomplete partition key + await Assert.ThrowsExceptionAsync(() => + this.container.ReadManyItemsAsync(incompleteList)); } + public record DatabaseItem( + string Id, + string Pk + ); + [TestMethod] - public async Task MultiHashUpsetItemTest() + public async Task MultiHashUpsertItemTest() { Cosmos.PartitionKey pKey; Cosmos.PartitionKey badPKey; @@ -252,90 +275,92 @@ public async Task MultiHashUpsetItemTest() //Create Items for test ItemResponse[] documents = new ItemResponse[3]; - Document doc1 = new Document { Id = "document1" }; - doc1.SetValue("ZipCode", "500026"); - doc1.SetValue("Address", "Secunderabad"); - doc1.SetValue("Type", "Residence"); - documents[0] = await this.container.CreateItemAsync(doc1); - - doc1 = new Document { Id = "document2" }; - doc1.SetValue("ZipCode", "15232"); - doc1.SetValue("Address", "Pittsburgh"); - doc1.SetValue("Type", "Business"); - documents[1] = await this.container.CreateItemAsync(doc1); - - doc1 = new Document { Id = "document3" }; - doc1.SetValue("ZipCode", "11790"); - doc1.SetValue("Address", "Stonybrook"); - doc1.SetValue("Type", "Goverment"); - documents[2] = await this.container.CreateItemAsync(doc1); + Document doc = new Document { Id = "document1" }; + doc.SetValue("ZipCode", "500026"); + doc.SetValue("City", "Secunderabad"); + doc.SetValue("Type", "Residence"); + documents[0] = await this.container.CreateItemAsync(doc); + + doc = new Document { Id = "document2" }; + doc.SetValue("ZipCode", "15232"); + doc.SetValue("City", "Pittsburgh"); + doc.SetValue("Type", "Business"); + documents[1] = await this.container.CreateItemAsync(doc); + + doc = new Document { Id = "document3" }; + doc.SetValue("ZipCode", "11790"); + doc.SetValue("City", "Stonybrook"); + doc.SetValue("Type", "Goverment"); + documents[2] = await this.container.CreateItemAsync(doc); //Document Upsert Test - doc1 = new Document { Id = "document4" }; - doc1.SetValue("ZipCode", "97756"); - doc1.SetValue("Address", "Redmond"); - doc1.SetValue("Type", "Residence"); + doc = new Document { Id = "document4" }; + doc.SetValue("ZipCode", "97756"); + doc.SetValue("City", "Redmond"); + doc.SetValue("Type", "Residence"); pKey = new PartitionKeyBuilder() - .Add(doc1.GetPropertyValue("ZipCode")) - .Add(doc1.GetPropertyValue("Address")) + .Add(doc.GetPropertyValue("ZipCode")) + .Add(doc.GetPropertyValue("City")) .Build(); //insert check - await this.container.UpsertItemAsync(doc1, pKey); + await this.container.UpsertItemAsync(doc, pKey); - Document readCheck = (await this.container.ReadItemAsync(doc1.Id, pKey)).Resource; + Document readCheck = (await this.container.ReadItemAsync(doc.Id, pKey)).Resource; - Assert.AreEqual(doc1.GetPropertyValue("ZipCode"), readCheck.GetPropertyValue("ZipCode")); - Assert.AreEqual(doc1.GetPropertyValue("Address"), readCheck.GetPropertyValue("Address")); - Assert.AreEqual(doc1.GetPropertyValue("Type"), readCheck.GetPropertyValue("Type")); + Assert.AreEqual(doc.GetPropertyValue("ZipCode"), readCheck.GetPropertyValue("ZipCode")); + Assert.AreEqual(doc.GetPropertyValue("City"), readCheck.GetPropertyValue("City")); + Assert.AreEqual(doc.GetPropertyValue("Type"), readCheck.GetPropertyValue("Type")); - doc1 = new Document { Id = "document4" }; - doc1.SetValue("ZipCode", "97756"); - doc1.SetValue("Address", "Redmond"); - doc1.SetValue("Type", "Business"); + doc = new Document { Id = "document4" }; + doc.SetValue("ZipCode", "97756"); + doc.SetValue("City", "Redmond"); + doc.SetValue("Type", "Business"); //update check pKey = new PartitionKeyBuilder() - .Add(doc1.GetPropertyValue("ZipCode")) - .Add(doc1.GetPropertyValue("Address")) + .Add(doc.GetPropertyValue("ZipCode")) + .Add(doc.GetPropertyValue("City")) .Build(); - documents.Append>(await this.container.UpsertItemAsync(doc1, pKey)); + documents.Append>(await this.container.UpsertItemAsync(doc, pKey)); - readCheck = (await this.container.ReadItemAsync(doc1.Id, pKey)).Resource; + readCheck = (await this.container.ReadItemAsync(doc.Id, pKey)).Resource; - Assert.AreEqual(doc1.GetPropertyValue("ZipCode"), readCheck.GetPropertyValue("ZipCode")); - Assert.AreEqual(doc1.GetPropertyValue("Address"), readCheck.GetPropertyValue("Address")); - Assert.AreEqual(doc1.GetPropertyValue("Type"), readCheck.GetPropertyValue("Type")); + Assert.AreEqual(doc.GetPropertyValue("ZipCode"), readCheck.GetPropertyValue("ZipCode")); + Assert.AreEqual(doc.GetPropertyValue("City"), readCheck.GetPropertyValue("City")); + Assert.AreEqual(doc.GetPropertyValue("Type"), readCheck.GetPropertyValue("Type")); count = 0; - foreach (Document doc in this.container.GetItemLinqQueryable(true)) + foreach (Document document in this.container.GetItemLinqQueryable(true)) { count++; } Assert.AreEqual(4, count); //Negative test - using incomplete partition key - doc1 = new Document { Id = "document4" }; - doc1.SetValue("ZipCode", "97756"); - doc1.SetValue("Address", "Redmond"); - doc1.SetValue("Type", "Residence"); + doc = new Document { Id = "document4" }; + doc.SetValue("ZipCode", "97756"); + doc.SetValue("City", "Redmond"); + doc.SetValue("Type", "Residence"); badPKey = new PartitionKeyBuilder() - .Add(doc1.GetPropertyValue("ZipCode")) + .Add(doc.GetPropertyValue("ZipCode")) .Build(); - await Assert.ThrowsExceptionAsync(() => - this.container.UpsertItemAsync(doc1, badPKey) + CosmosException clientException = await Assert.ThrowsExceptionAsync(() => + this.container.UpsertItemAsync(doc, badPKey) ); - readCheck = (await this.container.ReadItemAsync(doc1.Id, pKey)).Resource; + Assert.AreEqual(clientException.StatusCode, HttpStatusCode.BadRequest); + + readCheck = (await this.container.ReadItemAsync(doc.Id, pKey)).Resource; - Assert.AreEqual(doc1.GetPropertyValue("ZipCode"), readCheck.GetPropertyValue("ZipCode")); - Assert.AreEqual(doc1.GetPropertyValue("Address"), readCheck.GetPropertyValue("Address")); - Assert.AreNotEqual(doc1.GetPropertyValue("Type"), readCheck.GetPropertyValue("Type")); + Assert.AreEqual(doc.GetPropertyValue("ZipCode"), readCheck.GetPropertyValue("ZipCode")); + Assert.AreEqual(doc.GetPropertyValue("City"), readCheck.GetPropertyValue("City")); + Assert.AreNotEqual(doc.GetPropertyValue("Type"), readCheck.GetPropertyValue("Type")); } [TestMethod] @@ -346,30 +371,30 @@ public async Task MultiHashReplaceItemTest() //Create items for test ItemResponse[] documents = new ItemResponse[3]; - Document doc1 = new Document { Id = "document1" }; - doc1.SetValue("ZipCode", "500026"); - doc1.SetValue("Address", "Secunderabad"); - doc1.SetValue("Type", "Residence"); - documents[0] = await this.container.CreateItemAsync(doc1); - - doc1 = new Document { Id = "document2" }; - doc1.SetValue("ZipCode", "15232"); - doc1.SetValue("Address", "Pittsburgh"); - doc1.SetValue("Type", "Business"); - documents[1] = await this.container.CreateItemAsync(doc1); - - doc1 = new Document { Id = "document3" }; - doc1.SetValue("ZipCode", "11790"); - doc1.SetValue("Address", "Stonybrook"); - doc1.SetValue("Type", "Goverment"); - documents[2] = await this.container.CreateItemAsync(doc1); + Document doc = new Document { Id = "document1" }; + doc.SetValue("ZipCode", "500026"); + doc.SetValue("City", "Secunderabad"); + doc.SetValue("Type", "Residence"); + documents[0] = await this.container.CreateItemAsync(doc); + + doc = new Document { Id = "document2" }; + doc.SetValue("ZipCode", "15232"); + doc.SetValue("City", "Pittsburgh"); + doc.SetValue("Type", "Business"); + documents[1] = await this.container.CreateItemAsync(doc); + + doc = new Document { Id = "document3" }; + doc.SetValue("ZipCode", "11790"); + doc.SetValue("City", "Stonybrook"); + doc.SetValue("Type", "Goverment"); + documents[2] = await this.container.CreateItemAsync(doc); //Document Replace Test foreach (Document document in documents) { pKey = new PartitionKeyBuilder() .Add(document.GetPropertyValue("ZipCode")) - .Add(document.GetPropertyValue("Address")) + .Add(document.GetPropertyValue("City")) .Build(); @@ -383,14 +408,16 @@ public async Task MultiHashReplaceItemTest() //Negative test - using incomplete partition key badPKey = new PartitionKeyBuilder() - .Add(document.GetPropertyValue("Address")) + .Add(document.GetPropertyValue("ZipCode")) .Build(); readDocument.SetValue("Type", "Goverment"); - await Assert.ThrowsExceptionAsync(() => + CosmosException clientException = await Assert.ThrowsExceptionAsync(() => this.container.ReplaceItemAsync(document, document.Id, partitionKey: badPKey) ); + + Assert.AreEqual(clientException.StatusCode, HttpStatusCode.BadRequest); } } @@ -398,37 +425,59 @@ await Assert.ThrowsExceptionAsync(() => public async Task MultiHashQueryItemTest() { Cosmos.PartitionKey pKey; + Cosmos.PartitionKey badPKey; //Create items for test ItemResponse[] documents = new ItemResponse[3]; - Document doc1 = new Document { Id = "document1" }; - doc1.SetValue("ZipCode", "500026"); - doc1.SetValue("Address", "Secunderabad"); - doc1.SetValue("Type", "Residence"); - documents[0] = await this.container.CreateItemAsync(doc1); - - doc1 = new Document { Id = "document2" }; - doc1.SetValue("ZipCode", "15232"); - doc1.SetValue("Address", "Pittsburgh"); - doc1.SetValue("Type", "Business"); - documents[1] = await this.container.CreateItemAsync(doc1); - - doc1 = new Document { Id = "document3" }; - doc1.SetValue("ZipCode", "11790"); - doc1.SetValue("Address", "Stonybrook"); - doc1.SetValue("Type", "Goverment"); - documents[2] = await this.container.CreateItemAsync(doc1); + Document doc = new Document { Id = "document1" }; + doc.SetValue("ZipCode", "500026"); + doc.SetValue("City", "Secunderabad"); + doc.SetValue("Type", "Residence"); + documents[0] = await this.container.CreateItemAsync(doc); + + doc = new Document { Id = "document2" }; + doc.SetValue("ZipCode", "15232"); + doc.SetValue("City", "Pittsburgh"); + doc.SetValue("Type", "Business"); + documents[1] = await this.container.CreateItemAsync(doc); + + doc = new Document { Id = "document3" }; + doc.SetValue("ZipCode", "11790"); + doc.SetValue("City", "Stonybrook"); + doc.SetValue("Type", "Goverment"); + documents[2] = await this.container.CreateItemAsync(doc); //Query foreach (Document document in documents) { pKey = new PartitionKeyBuilder() .Add(document.GetPropertyValue("ZipCode")) - .Add(document.GetPropertyValue("Address")) + .Add(document.GetPropertyValue("City")) .Build(); - String query = $"SELECT * from c where c.id = {document.GetPropertyValue("Id")}"; + badPKey = new PartitionKeyBuilder() + .Add(document.GetPropertyValue("City")) + .Build(); + + String query = $"SELECT * from c where c.id = \"{document.GetPropertyValue("id")}\""; + + using (FeedIterator feedIterator = this.container.GetItemQueryIterator( + query, + null, + new QueryRequestOptions() { PartitionKey = pKey })) + { + Assert.IsTrue(feedIterator.HasMoreResults); + + FeedResponse queryDoc = await feedIterator.ReadNextAsync(); + queryDoc.First(); + Assert.IsTrue(queryDoc.Count == 1); + feedIterator.Dispose(); + } + //Using an incomplete partition key with prefix of PK path definition + pKey = new PartitionKeyBuilder() + .Add(document.GetPropertyValue("ZipCode")) + .Build(); using (FeedIterator feedIterator = this.container.GetItemQueryIterator( query, null, @@ -437,11 +486,25 @@ public async Task MultiHashQueryItemTest() Assert.IsTrue(feedIterator.HasMoreResults); FeedResponse queryDoc = await feedIterator.ReadNextAsync(); + queryDoc.First(); + Assert.IsTrue(queryDoc.Count == 1); + feedIterator.Dispose(); } + //Negative test - using incomplete partition key + using (FeedIterator badFeedIterator = this.container.GetItemQueryIterator( + query, + null, + new QueryRequestOptions() { PartitionKey = badPKey})) + { + FeedResponse queryDocBad = await badFeedIterator.ReadNextAsync(); + Assert.ThrowsException(() => + queryDocBad.First() + ); + badFeedIterator.Dispose(); + } } } } -} -#endif +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosReadManyItemsTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosReadManyItemsTests.cs index ede534cb9d..d215b6b18b 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosReadManyItemsTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosReadManyItemsTests.cs @@ -5,16 +5,11 @@ namespace Microsoft.Azure.Cosmos.SDK.EmulatorTests { using System; - using System.Collections.Concurrent; using System.Collections.Generic; - using System.Collections.ObjectModel; using System.Net; - using System.Net.Http; - using System.Text; using System.Threading; using System.Threading.Tasks; using Microsoft.Azure.Cosmos.Fluent; - using Microsoft.Azure.Cosmos.Query.Core; using Microsoft.Azure.Cosmos.Tracing; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -22,16 +17,15 @@ namespace Microsoft.Azure.Cosmos.SDK.EmulatorTests public class CosmosReadManyItemsTests : BaseCosmosClientHelper { private Container Container = null; - private ContainerProperties containerSettings = null; [TestInitialize] public async Task TestInitialize() { await base.TestInit(); string PartitionKey = "/pk"; - this.containerSettings = new ContainerProperties(id: Guid.NewGuid().ToString(), partitionKeyPath: PartitionKey); + ContainerProperties containerSettings = new ContainerProperties(id: Guid.NewGuid().ToString(), partitionKeyPath: PartitionKey); ContainerResponse response = await this.database.CreateContainerAsync( - this.containerSettings, + containerSettings, throughput: 20000, cancellationToken: this.cancellationToken); Assert.IsNotNull(response); @@ -122,23 +116,24 @@ public async Task ReadManyDoesNotFetchQueryPlan() [TestMethod] public async Task ReadManyWithIdasPk() { - string PartitionKey = "/id"; - ContainerProperties containerSettings = new ContainerProperties(id: Guid.NewGuid().ToString(), partitionKeyPath: PartitionKey); - Container container = await this.database.CreateContainerAsync(containerSettings); + Container container = await this.database.CreateContainerAsync(Guid.NewGuid().ToString(), "/id"); List<(string, PartitionKey)> itemList = new List<(string, PartitionKey)>(); - for (int i = 0; i < 5; i++) - { - itemList.Add((i.ToString(), new PartitionKey(i.ToString()))); - } // Create items with different pk values for (int i = 0; i < 5; i++) { ToDoActivity item = ToDoActivity.CreateRandomToDoActivity(); - item.id = i.ToString(); ItemResponse itemResponse = await container.CreateItemAsync(item); Assert.AreEqual(HttpStatusCode.Created, itemResponse.StatusCode); + + itemList.Add((item.id, new PartitionKey(item.id))); + + ToDoActivity itemWithSingleQuotes = ToDoActivity.CreateRandomToDoActivity(id: item.id + "'singlequote"); + ItemResponse itemResponseWithSingleQuotes = await container.CreateItemAsync(itemWithSingleQuotes); + Assert.AreEqual(HttpStatusCode.Created, itemResponseWithSingleQuotes.StatusCode); + + itemList.Add((itemWithSingleQuotes.id, new PartitionKey(itemWithSingleQuotes.id))); } using (ResponseMessage responseMessage = await container.ReadManyItemsStreamAsync(itemList)) @@ -149,12 +144,12 @@ public async Task ReadManyWithIdasPk() ToDoActivity[] items = this.GetClient().ClientContext.SerializerCore.FromFeedStream( CosmosFeedResponseSerializer.GetStreamWithoutServiceEnvelope(responseMessage.Content)); - Assert.AreEqual(items.Length, 5); + Assert.AreEqual(items.Length, 10); } FeedResponse feedResponse = await container.ReadManyItemsAsync(itemList); Assert.IsNotNull(feedResponse); - Assert.AreEqual(feedResponse.Count, 5); + Assert.AreEqual(feedResponse.Count, 10); Assert.IsTrue(feedResponse.Headers.RequestCharge > 0); Assert.IsNotNull(feedResponse.Diagnostics); } @@ -515,44 +510,7 @@ await container.CreateItemAsync( await database.DeleteAsync(); client.Dispose(); - } - -#if PREVIEW - [TestMethod] - public async Task ReadManyMultiplePK() - { - IReadOnlyList pkPaths = new List { "/pk", "/description" }; - ContainerProperties containerSettings = new ContainerProperties(id: Guid.NewGuid().ToString(), partitionKeyPaths: pkPaths); - Container container = await this.database.CreateContainerAsync(containerSettings); - - for (int i = 0; i < 5; i++) - { - ToDoActivity item = ToDoActivity.CreateRandomToDoActivity(); - item.pk = "pk" + i.ToString(); - item.id = i.ToString(); - item.description = "description" + i; - ItemResponse itemResponse = await container.CreateItemAsync(item); - Assert.AreEqual(HttpStatusCode.Created, itemResponse.StatusCode); - } - - List<(string, PartitionKey)> itemList = new List<(string, PartitionKey)>(); - for (int i = 0; i < 5; i++) - { - PartitionKey partitionKey = new PartitionKeyBuilder() - .Add("pk" + i) - .Add("description" + i) - .Build(); - - itemList.Add((i.ToString(), partitionKey)); - } - - FeedResponse feedResponse = await container.ReadManyItemsAsync(itemList); - Assert.IsNotNull(feedResponse); - Assert.AreEqual(feedResponse.Count, 5); - Assert.IsTrue(feedResponse.Headers.RequestCharge > 0); - Assert.IsNotNull(feedResponse.Diagnostics); - } -#endif + } private class NestedToDoActivity { diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/FeedRangeCreateFromPartitionKeyAsyncEmulatorTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/FeedRangeCreateFromPartitionKeyAsyncEmulatorTests.cs new file mode 100644 index 0000000000..6df5b0a66f --- /dev/null +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/FeedRangeCreateFromPartitionKeyAsyncEmulatorTests.cs @@ -0,0 +1,344 @@ +namespace Microsoft.Azure.Cosmos.SDK.EmulatorTests +{ + using System; + using System.Collections.Generic; + using System.IO; + using System.Linq; + using System.Threading.Tasks; + using System.Xml; + using Microsoft.Azure.Cosmos; + using Microsoft.Azure.Documents; + using Microsoft.VisualStudio.TestTools.UnitTesting; + using Newtonsoft.Json; + using Newtonsoft.Json.Linq; + using Database = Database; + using PartitionKey = PartitionKey; + using PartitionKeyDefinitionVersion = PartitionKeyDefinitionVersion; + + /// + /// Testing Prefix and Full Partition for , against a with Hierarchical Partition Keys. + /// + /// + [TestClass] + public class FeedRangeCreateFromPartitionKeyAsyncEmulatorTests + { + private CosmosClient client = null; + private Database database = null; + + private readonly string currentVersion = HttpConstants.Versions.CurrentVersion; + + [TestInitialize] + public async Task TestInit() + { + HttpConstants.Versions.CurrentVersion = "2020-07-15"; + this.client = TestCommon.CreateCosmosClient(true); + + string databaseName = Guid.NewGuid().ToString(); + DatabaseResponse databaseResponse = await this.client.CreateDatabaseIfNotExistsAsync(databaseName); + this.database = databaseResponse; + } + + [TestCleanup] + public async Task TestCleanup() + { + await this.database.DeleteAsync(); + this.client.Dispose(); + + HttpConstants.Versions.CurrentVersion = this.currentVersion; + } + + /// + /// Using to create a new with Hierarchical Partition Keys. + /// Using with a Prefix partition on a MultiHash V2 . + /// + /// + /// + [TestMethod] + public async Task GetChangeFeedIteratorWithPrefixPartitionKeyReturnsFeedIterator() + { + Container container = await this.database.CreateContainerIfNotExistsAsync(new(id: @"TestMultiHashedContainer", partitionKeyPaths: new List() { "/city", "/state", "/zipCode" })); + ContainerProperties containerProperties = await container.ReadContainerAsync(); + + Assert.AreEqual(expected: PartitionKeyDefinitionVersion.V2, actual: containerProperties.PartitionKeyDefinitionVersion); + Assert.AreEqual(expected: 3, actual: containerProperties.PartitionKey.Paths.Count); + Assert.IsTrue(containerProperties.PartitionKey.Paths.Contains("/city")); + Assert.IsTrue(containerProperties.PartitionKey.Paths.Contains("/state")); + Assert.IsTrue(containerProperties.PartitionKey.Paths.Contains("/zipCode")); + Assert.AreEqual(expected: Documents.PartitionKind.MultiHash, actual: containerProperties.PartitionKey.Kind); + + dynamic item = new { id = Guid.NewGuid().ToString(), city = "Redmond", state = "WA", zipCode = "98502" }; + PartitionKey partitionKey = new PartitionKeyBuilder() + .Add(item.city) + .Add(item.state) + .Add(item.zipCode) + .Build(); + + _ = await container.CreateItemAsync(item: item, partitionKey: partitionKey); + + partitionKey = new PartitionKeyBuilder() + .Add(item.city) + .Add(item.state) + .Build(); + + FeedRange feedRange = new FeedRangePartitionKey(partitionKey); + FeedIterator iterator = container.GetChangeFeedIterator(ChangeFeedStartFrom.Beginning(feedRange), ChangeFeedMode.Incremental); + FeedResponse response = await iterator.ReadNextAsync(); + + string json = JsonConvert.SerializeObject(response.First()); + JObject @object = JObject.Parse(json); + + Assert.AreEqual(expected: item.id, actual: @object["id"]); + Assert.AreEqual(expected: item.city, actual: @object["city"]); + Assert.AreEqual(expected: item.state, actual: @object["state"]); + Assert.AreEqual(expected: item.zipCode, actual: @object["zipCode"]); + } + + /// + /// Using to create a new with hierarchical partition keys. + /// Using with a Prefix Partition on a MultiHash . + /// + /// + /// + [TestMethod] + public async Task GetChangeFeedStreamIteratorWithPrefixPartitionKeyReturnsFeedIterator() + { + Container container = await this.database.CreateContainerIfNotExistsAsync(new(id: @"TestMultiHashedContainer", partitionKeyPaths: new List() { "/city", "/state", "/zipCode" })); + ContainerProperties containerProperties = await container.ReadContainerAsync(); + + Assert.AreEqual(expected: PartitionKeyDefinitionVersion.V2, actual: containerProperties.PartitionKeyDefinitionVersion); + Assert.AreEqual(expected: 3, actual: containerProperties.PartitionKey.Paths.Count); + Assert.IsTrue(containerProperties.PartitionKey.Paths.Contains("/city")); + Assert.IsTrue(containerProperties.PartitionKey.Paths.Contains("/state")); + Assert.IsTrue(containerProperties.PartitionKey.Paths.Contains("/zipCode")); + Assert.AreEqual(expected: Documents.PartitionKind.MultiHash, actual: containerProperties.PartitionKey.Kind); + + dynamic item = new { id = Guid.NewGuid().ToString(), city = "Redmond", state = "WA", zipCode = "98502" }; + PartitionKey partitionKey = new PartitionKeyBuilder() + .Add(item.city) + .Add(item.state) + .Add(item.zipCode) + .Build(); + + _ = await container.CreateItemAsync(item: item, partitionKey: partitionKey); + + partitionKey = new PartitionKeyBuilder() + .Add(item.city) + .Add(item.state) + .Build(); + + FeedRange feedRange = new FeedRangePartitionKey(partitionKey); + using (FeedIterator iterator = container.GetChangeFeedStreamIterator(ChangeFeedStartFrom.Beginning(feedRange), ChangeFeedMode.Incremental)) + { + ResponseMessage responseMessage = await iterator.ReadNextAsync(); + + using (StreamReader streamReader = new(responseMessage.Content)) + { + string content = await streamReader.ReadToEndAsync(); + + JObject @object = JObject.Parse(content); + JToken token = @object["Documents"].First(); + + Assert.AreEqual(expected: item.id, actual: token["id"]); + Assert.AreEqual(expected: item.city, actual: token["city"]); + Assert.AreEqual(expected: item.state, actual: token["state"]); + Assert.AreEqual(expected: item.zipCode, actual: token["zipCode"]); + } + } + } + + /// + /// Using to create a new with Hierarchical Partition Keys. + /// using with a Prefix partition on a MultiHash V2 . + /// + /// + /// + [TestMethod] + [Ignore("Query is returning 'Partition key provided either doesn't correspond to definition in the collection or doesn't match partition key field values specified in the document.' Investigation.")] + [Owner("naga.naravamakula")] + public async Task GetItemQueryIteratorWithPrefixPartitionKeyReturnsFeedIterator() + { + Container container = await this.database.CreateContainerIfNotExistsAsync(new(id: @"TestMultiHashedContainer", partitionKeyPaths: new List() { "/city", "/state", "/zipCode" })); + ContainerProperties containerProperties = await container.ReadContainerAsync(); + + Assert.AreEqual(expected: PartitionKeyDefinitionVersion.V2, actual: containerProperties.PartitionKeyDefinitionVersion); + Assert.AreEqual(expected: 3, actual: containerProperties.PartitionKey.Paths.Count); + Assert.IsTrue(containerProperties.PartitionKey.Paths.Contains("/city")); + Assert.IsTrue(containerProperties.PartitionKey.Paths.Contains("/state")); + Assert.IsTrue(containerProperties.PartitionKey.Paths.Contains("/zipCode")); + Assert.AreEqual(expected: Documents.PartitionKind.MultiHash, actual: containerProperties.PartitionKey.Kind); + + dynamic item = new { id = Guid.NewGuid().ToString(), city = "Redmond", state = "WA", zipCode = "98052" }; + PartitionKey partitionKey = new PartitionKeyBuilder() + .Add(item.city) + .Add(item.state) + .Add(item.zipCode) + .Build(); + + _ = await container.CreateItemAsync(item: item, partitionKey: partitionKey); + + QueryDefinition queryDefinition = new QueryDefinition(query: "SELECT * FROM c WHERE c.city = @cityInput AND c.state = @stateInput") + .WithParameter("@cityInput", "Redmond") + .WithParameter("@stateInput", "WA"); + + partitionKey = new PartitionKeyBuilder() + .Add(item.city) + .Add(item.state) + .Build(); + + FeedRange feedRange = new FeedRangePartitionKey(partitionKey); + Console.WriteLine(feedRange.ToJsonString()); + using (FeedIterator iterator = container.GetItemQueryIterator(feedRange: feedRange, queryDefinition: queryDefinition, requestOptions: new() { PartitionKey = partitionKey })) + { + FeedResponse feedResponse = await iterator.ReadNextAsync(); + + string content = JsonConvert.SerializeObject(feedResponse.First()); + JObject @object = JObject.Parse(content); + + Assert.AreEqual(expected: item.id, actual: @object["id"]); + Assert.AreEqual(expected: item.city, actual: @object["city"]); + Assert.AreEqual(expected: item.state, actual: @object["state"]); + Assert.AreEqual(expected: item.zipCode, actual: @object["zipCode"]); + } + } + + /// + /// Using to create a new with Hierarchical Partition Keys. + /// Using with a Prefix Partition on a MultiHash V2 . + /// + /// + /// + [TestMethod] + public async Task GetItemQueryStreamIteratorWithPrefixPartitionKeyReturnsFeedIterator() + { + Container container = await this.database.CreateContainerIfNotExistsAsync(new(id: @"TestMultiHashedContainer", partitionKeyPaths: new List() { "/city", "/state", "/zipCode" })); + ContainerProperties containerProperties = await container.ReadContainerAsync(); + + Assert.AreEqual(expected: PartitionKeyDefinitionVersion.V2, actual: containerProperties.PartitionKeyDefinitionVersion); + Assert.AreEqual(expected: 3, actual: containerProperties.PartitionKey.Paths.Count); + Assert.IsTrue(containerProperties.PartitionKey.Paths.Contains("/city")); + Assert.IsTrue(containerProperties.PartitionKey.Paths.Contains("/state")); + Assert.IsTrue(containerProperties.PartitionKey.Paths.Contains("/zipCode")); + Assert.AreEqual(expected: Documents.PartitionKind.MultiHash, actual: containerProperties.PartitionKey.Kind); + + dynamic item = new { id = Guid.NewGuid().ToString(), city = "Redmond", state = "WA", zipCode = "98052" }; + PartitionKey partitionKey = new PartitionKeyBuilder() + .Add(item.city) + .Add(item.state) + .Add(item.zipCode) + .Build(); + + _ = await container.CreateItemAsync(item: item, partitionKey: partitionKey); + + QueryDefinition queryDefinition = new QueryDefinition(query: "SELECT * FROM c WHERE c.city = @cityInput AND c.state = @stateInput") + .WithParameter("@cityInput", "Redmond") + .WithParameter("@stateInput", "WA"); + + using (FeedIterator iterator = container.GetItemQueryStreamIterator(queryDefinition: queryDefinition, requestOptions: new() { PartitionKey = partitionKey })) + { + ResponseMessage responseMessage = await iterator.ReadNextAsync(); + + using (StreamReader streamReader = new(responseMessage.Content)) + { + string content = await streamReader.ReadToEndAsync(); + + JObject @object = JObject.Parse(content); + JToken token = @object["Documents"].First(); + + Assert.AreEqual(expected: item.id, actual: token["id"]); + Assert.AreEqual(expected: item.city, actual: token["city"]); + Assert.AreEqual(expected: item.state, actual: token["state"]); + Assert.AreEqual(expected: item.zipCode, actual: token["zipCode"]); + } + } + } + + /// + /// Using to create a new with Hierarchical Partition Keys. + /// Using with a Full Partition on a MultiHash V2 . + /// + /// + /// + [TestMethod] + public async Task ReadItemWithFullPartitionKeyReturnsFeedIterator() + { + ContainerProperties containerProperties = new(id: @"TestMultiHashedContainer", partitionKeyDefinition: new Documents.PartitionKeyDefinition + { + Kind = Documents.PartitionKind.MultiHash, + Version = Documents.PartitionKeyDefinitionVersion.V2, + Paths = new System.Collections.ObjectModel.Collection(new List() { "/city", "/state", "/zipCode" }) + }); + + Container container = await this.database.CreateContainerIfNotExistsAsync(containerProperties: containerProperties); + + Assert.AreEqual(expected: PartitionKeyDefinitionVersion.V2, actual: containerProperties.PartitionKeyDefinitionVersion); + Assert.AreEqual(expected: 3, actual: containerProperties.PartitionKey.Paths.Count); + Assert.IsTrue(containerProperties.PartitionKey.Paths.Contains("/city")); + Assert.IsTrue(containerProperties.PartitionKey.Paths.Contains("/state")); + Assert.IsTrue(containerProperties.PartitionKey.Paths.Contains("/zipCode")); + Assert.AreEqual(expected: Documents.PartitionKind.MultiHash, actual: containerProperties.PartitionKey.Kind); + + dynamic item = new { id = Guid.NewGuid().ToString(), city = "Redmond", state = "WA", zipCode = "98052" }; + PartitionKey partitionKey = new PartitionKeyBuilder() + .Add(item.city) + .Add(item.state) + .Add(item.zipCode) + .Build(); + + _ = await container.CreateItemAsync(item: item, partitionKey: partitionKey); + + ItemResponse itemResponse = await container.ReadItemAsync(id: item.id, partitionKey: partitionKey); + + string content = JsonConvert.SerializeObject(itemResponse.Resource); + JObject @object = JObject.Parse(content); + + Assert.AreEqual(expected: item.id, actual: @object["id"]); + Assert.AreEqual(expected: item.city, actual: @object["city"]); + Assert.AreEqual(expected: item.state, actual: @object["state"]); + Assert.AreEqual(expected: item.zipCode, actual: @object["zipCode"]); + } + + /// + /// Using to create a new with Hierarchical Partition Keys. + /// Using + /// Using with a Full Partition on a MultiHash V2 . + /// + /// + /// + [TestMethod] + public async Task ReadItemStreamWithFullPartitionKeyReturnsFeedIterator() + { + Container container = await this.database.CreateContainerIfNotExistsAsync(new(id: @"TestMultiHashedContainer", partitionKeyPaths: new List() { "/city", "/state", "/zipCode" })); + ContainerProperties containerProperties = await container.ReadContainerAsync(); + + Assert.AreEqual(expected: PartitionKeyDefinitionVersion.V2, actual: containerProperties.PartitionKeyDefinitionVersion); + Assert.AreEqual(expected: 3, actual: containerProperties.PartitionKey.Paths.Count); + Assert.IsTrue(containerProperties.PartitionKey.Paths.Contains("/city")); + Assert.IsTrue(containerProperties.PartitionKey.Paths.Contains("/state")); + Assert.IsTrue(containerProperties.PartitionKey.Paths.Contains("/zipCode")); + Assert.AreEqual(expected: Documents.PartitionKind.MultiHash, actual: containerProperties.PartitionKey.Kind); + + dynamic item = new { id = Guid.NewGuid().ToString(), city = "Redmond", state = "WA", zipCode = "98052" }; + PartitionKey partitionKey = new PartitionKeyBuilder() + .Add(item.city) + .Add(item.state) + .Add(item.zipCode) + .Build(); + + _ = await container.CreateItemAsync(item: item, partitionKey: partitionKey); + + using (ResponseMessage responseMessage = await container.ReadItemStreamAsync(id: item.id, partitionKey: partitionKey)) + { + using (StreamReader streamReader = new(responseMessage.Content)) + { + string content = await streamReader.ReadToEndAsync(); + JObject @object = JObject.Parse(content); + + Assert.AreEqual(expected: item.id, actual: @object["id"]); + Assert.AreEqual(expected: item.city, actual: @object["city"]); + Assert.AreEqual(expected: item.state, actual: @object["state"]); + Assert.AreEqual(expected: item.zipCode, actual: @object["zipCode"]); + } + } + } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/LinqTestsCommon.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/LinqTestsCommon.cs index 2b8f5c2d4a..5907d861fc 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/LinqTestsCommon.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/LinqTestsCommon.cs @@ -455,7 +455,9 @@ Family createDataObj(Random random) return getQuery; } - public static Func> GenerateSimpleCosmosData(Cosmos.Database cosmosDatabase) + public static Func> GenerateSimpleCosmosData( + Cosmos.Database cosmosDatabase + ) { const int DocumentCount = 10; PartitionKeyDefinition partitionKeyDefinition = new PartitionKeyDefinition { Paths = new System.Collections.ObjectModel.Collection(new[] { "/Pk" }), Kind = PartitionKind.Hash }; diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/LinqTranslationBaselineTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/LinqTranslationBaselineTests.cs index 01b64cd4fd..14aadd354f 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/LinqTranslationBaselineTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/LinqTranslationBaselineTests.cs @@ -1,5 +1,5 @@ //----------------------------------------------------------------------- -// +// // Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------- diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/LinqTranslationWithCustomSerializerBaseline.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/LinqTranslationWithCustomSerializerBaseline.cs deleted file mode 100644 index c81beaaeb8..0000000000 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/LinqTranslationWithCustomSerializerBaseline.cs +++ /dev/null @@ -1,159 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. All rights reserved. -// -//----------------------------------------------------------------------- -namespace Microsoft.Azure.Cosmos.Services.Management.Tests.LinqProviderTests -{ - using BaselineTest; - using Microsoft.Azure.Cosmos.Linq; - using Microsoft.Azure.Cosmos.Spatial; - using Microsoft.VisualStudio.TestTools.UnitTesting; - using System; - using System.Collections.Generic; - using System.Globalization; - using System.Linq; - using System.Linq.Dynamic; - using System.Text; - using System.Text.Json; - using Microsoft.Azure.Documents; - using Microsoft.Azure.Cosmos.SDK.EmulatorTests; - using System.Threading.Tasks; - using global::Azure.Core.Serialization; - using System.IO; - using System.Text.Json.Serialization; - - [Microsoft.Azure.Cosmos.SDK.EmulatorTests.TestClass] - public class LinqTranslationWithCustomSerializerBaseline : BaselineTests - { - private static CosmosClient cosmosClient; - private static Cosmos.Database testDb; - private static Container testContainer; - - [ClassInitialize] - public async static Task Initialize(TestContext textContext) - { - cosmosClient = TestCommon.CreateCosmosClient((cosmosClientBuilder) - => cosmosClientBuilder.WithCustomSerializer(new SystemTextJsonSerializer(new JsonSerializerOptions())).WithConnectionModeGateway()); - - string dbName = $"{nameof(LinqTranslationBaselineTests)}-{Guid.NewGuid().ToString("N")}"; - testDb = await cosmosClient.CreateDatabaseAsync(dbName); - } - - [ClassCleanup] - public async static Task CleanUp() - { - if (testDb != null) - { - await testDb.DeleteStreamAsync(); - } - - cosmosClient?.Dispose(); - } - - [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(); - } - - // Custom serializer that uses System.Text.Json.JsonSerializer instead of NewtonsoftJson.JsonSerializer - 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; - } - } - - internal class DataObject : LinqTestObject - { - [JsonPropertyName("number")] - public double NumericField { get; set; } - - [JsonPropertyName("String_value")] - public string StringField { get; set; } - - [JsonPropertyName("id")] - public string Id { get; set; } - - [JsonPropertyName("Pk")] - public string Pk { get; set; } - } - - [TestMethod] - public void TestMemberInitializer() - { - const int Records = 100; - const int NumAbsMax = 500; - const int MaxStringLength = 100; - DataObject createDataObj(Random random) - { - DataObject obj = new DataObject - { - NumericField = random.Next(NumAbsMax * 2) - NumAbsMax, - StringField = LinqTestsCommon.RandomString(random, random.Next(MaxStringLength)), - Id = Guid.NewGuid().ToString(), - Pk = "Test" - }; - return obj; - } - Func> getQuery = LinqTestsCommon.GenerateTestCosmosData(createDataObj, Records, testContainer); - - List inputs = new List - { - new LinqTestInput("Filter w/ DataObject initializer with constant value", b => getQuery(b).Where(doc => doc == new DataObject() { NumericField = 12, StringField = "12" })), - new LinqTestInput("Select w/ DataObject initializer", b => getQuery(b).Select(doc => new DataObject() { NumericField = 12, StringField = "12" })), - new LinqTestInput("Deeper than top level reference", b => getQuery(b).Select(doc => doc.NumericField > 12 ? new DataObject() { NumericField = 12, StringField = "12" } : new DataObject() { NumericField = 12, StringField = "12" })), - - - // Negative test case: serializing only field name using custom serializer not currently supported - new LinqTestInput("Filter w/ DataObject initializer with member initialization", b => getQuery(b).Where(doc => doc == new DataObject() { NumericField = doc.NumericField, StringField = doc.StringField }).Select(b => "A")) - }; - this.ExecuteTestSuite(inputs); - } - - - public override LinqTestOutput ExecuteTest(LinqTestInput input) - { - return LinqTestsCommon.ExecuteTest(input); - } - } -} \ No newline at end of file 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 17c2891887..710c582448 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 @@ -36,7 +36,6 @@ - @@ -247,9 +246,6 @@ PreserveNewest - - PreserveNewest - PreserveNewest diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Query/BypassQueryParsingTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Query/BypassQueryParsingTests.cs new file mode 100644 index 0000000000..a0c821c72d --- /dev/null +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Query/BypassQueryParsingTests.cs @@ -0,0 +1,64 @@ +namespace Microsoft.Azure.Cosmos.EmulatorTests.Query +{ + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.Azure.Cosmos.CosmosElements; + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + [TestCategory("Query")] + public sealed class BypassQueryParsingTests : QueryTestsBase + { + [TestMethod] + public async Task TestBypassQueryParsingWithNonePartitionKey() + { + int documentCount = 400; + QueryRequestOptions feedOptions = new QueryRequestOptions { PartitionKey = PartitionKey.None }; + string query = "SELECT VALUE r.numberField FROM r"; + IReadOnlyList expected = Enumerable.Range(0, documentCount).ToList(); + + async Task ImplementationAsync(Container container, IReadOnlyList documents) + { + ContainerInternal containerCore = container as ContainerInlineCore; + + MockCosmosQueryClient cosmosQueryClientCore = new MockCosmosQueryClient( + containerCore.ClientContext, + containerCore, + forceQueryPlanGatewayElseServiceInterop: true); + + ContainerInternal containerWithBypassParsing = new ContainerInlineCore( + containerCore.ClientContext, + (DatabaseCore)containerCore.Database, + containerCore.Id, + cosmosQueryClientCore); + + List items = await RunQueryAsync(containerWithBypassParsing, query, feedOptions); + int[] actual = items.Cast().Select(x => (int)Number64.ToLong(x.Value)).ToArray(); + + Assert.IsTrue(expected.SequenceEqual(actual)); + } + + IReadOnlyList documents = CreateDocuments(documentCount); + + await this.CreateIngestQueryDeleteAsync( + ConnectionModes.Direct | ConnectionModes.Gateway, + CollectionTypes.NonPartitioned | CollectionTypes.SinglePartition | CollectionTypes.MultiPartition, + documents, + ImplementationAsync, + "/undefinedPartitionKey"); + } + + private static IReadOnlyList CreateDocuments(int documentCount) + { + List documents = new List(documentCount); + for (int i = 0; i < documentCount; ++i) + { + string document = $@"{{ ""numberField"": {i}, ""nullField"": null }}"; + documents.Add(document); + } + + return documents; + } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Query/OptimisticDirectExecutionQueryTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Query/OptimisticDirectExecutionQueryTests.cs index 751c21b64b..7de38b187a 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Query/OptimisticDirectExecutionQueryTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Query/OptimisticDirectExecutionQueryTests.cs @@ -7,91 +7,270 @@ using System.Threading.Tasks; using Microsoft.Azure.Cosmos.CosmosElements; using Microsoft.Azure.Cosmos.Query.Core; - using Microsoft.Azure.Documents; using Microsoft.VisualStudio.TestTools.UnitTesting; [TestClass] [TestCategory("Query")] public sealed class OptimisticDirectExecutionQueryTests : QueryTestsBase { + private const int NumberOfDocuments = 8; + private const string PartitionKeyField = "key"; + private const string NumberField = "numberField"; + private const string NullField = "nullField"; + private static class PageSizeOptions { public static readonly int[] NonGroupByPageSizeOptions = { -1, 1, 2, 10, 100 }; public static readonly int[] GroupByPageSizeOptions = { -1 }; + public static readonly int[] PageSize100 = { 100 }; } [TestMethod] public async Task TestPassingOptimisticDirectExecutionQueries() { - int numberOfDocuments = 8; - string partitionKey = "key"; - string numberField = "numberField"; - string nullField = "nullField"; - - List documents = CreateDocuments(numberOfDocuments, partitionKey, numberField, nullField); + IReadOnlyList empty = new List(0); + IReadOnlyList first5Integers = Enumerable.Range(0, 5).ToList(); + IReadOnlyList first7Integers = Enumerable.Range(0, NumberOfDocuments).ToList(); + IReadOnlyList first7IntegersReversed = Enumerable.Range(0, NumberOfDocuments).Reverse().ToList(); + PartitionKey partitionKeyValue = new PartitionKey("/value"); List singlePartitionContainerTestCases = new List() { // Tests for bool enableOptimisticDirectExecution - CreateInput( query: $"SELECT TOP 5 VALUE r.numberField FROM r ORDER BY r.{partitionKey}", expectedResult: new List { 0, 1, 2, 3, 4 }, partitionKey: "/value", partition: CollectionTypes.SinglePartition, enableOptimisticDirectExecution: true, pageSizeOptions: PageSizeOptions.NonGroupByPageSizeOptions, expectedPipelineType: TestInjections.PipelineType.OptimisticDirectExecution), - CreateInput( query: $"SELECT TOP 5 VALUE r.numberField FROM r ORDER BY r.{partitionKey}", expectedResult: new List { 0, 1, 2, 3, 4 }, partitionKey: "/value", partition: CollectionTypes.SinglePartition, enableOptimisticDirectExecution: false, pageSizeOptions: PageSizeOptions.NonGroupByPageSizeOptions, expectedPipelineType: TestInjections.PipelineType.Passthrough), + CreateInput( + query: $"SELECT TOP 5 VALUE r.numberField FROM r ORDER BY r.{PartitionKeyField}", + expectedResult: first5Integers, + partitionKey: partitionKeyValue, + enableOptimisticDirectExecution: true, + pageSizeOptions: PageSizeOptions.NonGroupByPageSizeOptions, + expectedPipelineType: TestInjections.PipelineType.OptimisticDirectExecution), + CreateInput( + query: $"SELECT TOP 5 VALUE r.numberField FROM r ORDER BY r.{PartitionKeyField}", + expectedResult: first5Integers, + partitionKey: partitionKeyValue, + enableOptimisticDirectExecution: false, + pageSizeOptions: PageSizeOptions.NonGroupByPageSizeOptions, + expectedPipelineType: TestInjections.PipelineType.Passthrough), // Simple query - CreateInput( query: $"SELECT VALUE r.numberField FROM r", expectedResult: new List { 0, 1, 2, 3, 4, 5, 6, 7 }, partitionKey: "/value", partition: CollectionTypes.SinglePartition, enableOptimisticDirectExecution: true, pageSizeOptions: PageSizeOptions.NonGroupByPageSizeOptions, expectedPipelineType: TestInjections.PipelineType.OptimisticDirectExecution), - CreateInput( query: $"SELECT VALUE r.numberField FROM r", expectedResult: new List { 0, 1, 2, 3, 4, 5, 6, 7 }, partitionKey: null, partition: CollectionTypes.SinglePartition, enableOptimisticDirectExecution: true, pageSizeOptions: PageSizeOptions.NonGroupByPageSizeOptions, expectedPipelineType: TestInjections.PipelineType.OptimisticDirectExecution), + CreateInput( + query: $"SELECT VALUE r.numberField FROM r", + expectedResult: first7Integers, + partitionKey: partitionKeyValue, + enableOptimisticDirectExecution: true, + pageSizeOptions: PageSizeOptions.NonGroupByPageSizeOptions, + expectedPipelineType: TestInjections.PipelineType.OptimisticDirectExecution), + CreateInput( + query: $"SELECT VALUE r.numberField FROM r", + expectedResult: first7Integers, + partitionKey: null, + enableOptimisticDirectExecution: true, + pageSizeOptions: PageSizeOptions.NonGroupByPageSizeOptions, + expectedPipelineType: TestInjections.PipelineType.OptimisticDirectExecution), // DISTINCT with ORDER BY - CreateInput( query: $"SELECT DISTINCT VALUE r.{numberField} FROM r ORDER BY r.{numberField} DESC", expectedResult: new List { 7, 6, 5, 4, 3, 2, 1, 0 }, partitionKey: "/value", partition: CollectionTypes.SinglePartition, enableOptimisticDirectExecution: true, pageSizeOptions: PageSizeOptions.NonGroupByPageSizeOptions, expectedPipelineType: TestInjections.PipelineType.OptimisticDirectExecution), - CreateInput( query: $"SELECT DISTINCT VALUE r.{numberField} FROM r ORDER BY r.{numberField} DESC", expectedResult: new List { 7, 6, 5, 4, 3, 2, 1, 0 }, partitionKey: null, partition: CollectionTypes.SinglePartition, enableOptimisticDirectExecution: true, pageSizeOptions: PageSizeOptions.NonGroupByPageSizeOptions, expectedPipelineType: TestInjections.PipelineType.OptimisticDirectExecution), + CreateInput( + query: $"SELECT DISTINCT VALUE r.{NumberField} FROM r ORDER BY r.{NumberField} DESC", + expectedResult: first7IntegersReversed, + partitionKey: partitionKeyValue, + enableOptimisticDirectExecution: true, + pageSizeOptions: PageSizeOptions.NonGroupByPageSizeOptions, + expectedPipelineType: TestInjections.PipelineType.OptimisticDirectExecution), + CreateInput( + query: $"SELECT DISTINCT VALUE r.{NumberField} FROM r ORDER BY r.{NumberField} DESC", + expectedResult: first7IntegersReversed, + partitionKey: null, + enableOptimisticDirectExecution: true, + pageSizeOptions: PageSizeOptions.NonGroupByPageSizeOptions, + expectedPipelineType: TestInjections.PipelineType.OptimisticDirectExecution), // TOP with GROUP BY - CreateInput( query: $"SELECT TOP 5 VALUE r.{numberField} FROM r GROUP BY r.{numberField}", expectedResult: new List { 0, 1, 2, 3, 4 }, partitionKey: "/value", partition: CollectionTypes.SinglePartition, enableOptimisticDirectExecution: true, pageSizeOptions: PageSizeOptions.GroupByPageSizeOptions, expectedPipelineType: TestInjections.PipelineType.OptimisticDirectExecution), - CreateInput( query: $"SELECT TOP 5 VALUE r.{numberField} FROM r GROUP BY r.{numberField}", expectedResult: new List { 0, 1, 2, 3, 4 }, partitionKey: null, partition: CollectionTypes.SinglePartition, enableOptimisticDirectExecution: true, pageSizeOptions: PageSizeOptions.GroupByPageSizeOptions, expectedPipelineType: TestInjections.PipelineType.OptimisticDirectExecution), + CreateInput( + query: $"SELECT TOP 5 VALUE r.{NumberField} FROM r GROUP BY r.{NumberField}", + expectedResult: first5Integers, + partitionKey: partitionKeyValue, + enableOptimisticDirectExecution: true, + pageSizeOptions: PageSizeOptions.GroupByPageSizeOptions, + expectedPipelineType: TestInjections.PipelineType.OptimisticDirectExecution), + CreateInput( + query: $"SELECT TOP 5 VALUE r.{NumberField} FROM r GROUP BY r.{NumberField}", + expectedResult: first5Integers, + partitionKey: null, + enableOptimisticDirectExecution: true, + pageSizeOptions: PageSizeOptions.GroupByPageSizeOptions, + expectedPipelineType: TestInjections.PipelineType.OptimisticDirectExecution), // OFFSET LIMIT with WHERE and BETWEEN - CreateInput( query: $"SELECT VALUE r.numberField FROM r WHERE r.{numberField} BETWEEN 0 AND {numberOfDocuments} OFFSET 1 LIMIT 1", expectedResult: new List { 1 }, partitionKey: "/value", partition: CollectionTypes.SinglePartition, pageSizeOptions: PageSizeOptions.NonGroupByPageSizeOptions, enableOptimisticDirectExecution: true, expectedPipelineType: TestInjections.PipelineType.OptimisticDirectExecution), - CreateInput( query: $"SELECT VALUE r.numberField FROM r WHERE r.{numberField} BETWEEN 0 AND {numberOfDocuments} OFFSET 1 LIMIT 1", expectedResult: new List { 1 }, partitionKey: null, partition: CollectionTypes.SinglePartition, pageSizeOptions: PageSizeOptions.NonGroupByPageSizeOptions, enableOptimisticDirectExecution: true, expectedPipelineType: TestInjections.PipelineType.OptimisticDirectExecution) + CreateInput( + query: $"SELECT VALUE r.numberField FROM r WHERE r.{NumberField} BETWEEN 0 AND {NumberOfDocuments} OFFSET 1 LIMIT 1", + expectedResult: new List { 1 }, + partitionKey: partitionKeyValue, + pageSizeOptions: PageSizeOptions.NonGroupByPageSizeOptions, + enableOptimisticDirectExecution: true, + expectedPipelineType: TestInjections.PipelineType.OptimisticDirectExecution), + CreateInput( + query: $"SELECT VALUE r.numberField FROM r WHERE r.{NumberField} BETWEEN 0 AND {NumberOfDocuments} OFFSET 1 LIMIT 1", + expectedResult: new List { 1 }, + partitionKey: null, + pageSizeOptions: PageSizeOptions.NonGroupByPageSizeOptions, + enableOptimisticDirectExecution: true, + expectedPipelineType: TestInjections.PipelineType.OptimisticDirectExecution) }; List multiPartitionContainerTestCases = new List() { // Simple query - CreateInput( query: $"SELECT VALUE r.numberField FROM r", expectedResult: new List { 0, 1, 2, 3, 4, 5, 6, 7 }, partitionKey: "/value", partition: CollectionTypes.MultiPartition, enableOptimisticDirectExecution: true, pageSizeOptions: PageSizeOptions.NonGroupByPageSizeOptions, expectedPipelineType: TestInjections.PipelineType.OptimisticDirectExecution), - CreateInput( query: $"SELECT VALUE r.numberField FROM r", expectedResult: new List { 0, 1, 2, 3, 4, 5, 6, 7 }, partitionKey: null, partition: CollectionTypes.MultiPartition, enableOptimisticDirectExecution: true, pageSizeOptions: PageSizeOptions.NonGroupByPageSizeOptions, expectedPipelineType: TestInjections.PipelineType.Passthrough), + CreateInput( + query: $"SELECT VALUE r.numberField FROM r", + expectedResult: first7Integers, + partitionKey: partitionKeyValue, + enableOptimisticDirectExecution: true, + pageSizeOptions: PageSizeOptions.NonGroupByPageSizeOptions, + expectedPipelineType: TestInjections.PipelineType.OptimisticDirectExecution), + CreateInput( + query: $"SELECT VALUE r.numberField FROM r", + expectedResult: first7Integers, + partitionKey: null, + enableOptimisticDirectExecution: true, + pageSizeOptions: PageSizeOptions.NonGroupByPageSizeOptions, + expectedPipelineType: TestInjections.PipelineType.Passthrough), // DISTINCT with ORDER BY - CreateInput( query: $"SELECT DISTINCT VALUE r.{numberField} FROM r ORDER BY r.{numberField} DESC", expectedResult: new List { 7, 6, 5, 4, 3, 2, 1, 0 }, partitionKey: "/value", partition: CollectionTypes.MultiPartition, enableOptimisticDirectExecution: true, pageSizeOptions: PageSizeOptions.NonGroupByPageSizeOptions, expectedPipelineType: TestInjections.PipelineType.OptimisticDirectExecution), - CreateInput( query: $"SELECT DISTINCT VALUE r.{numberField} FROM r ORDER BY r.{numberField} DESC", expectedResult: new List { 7, 6, 5, 4, 3, 2, 1, 0 }, partitionKey: null, partition: CollectionTypes.MultiPartition, enableOptimisticDirectExecution: true, pageSizeOptions: PageSizeOptions.NonGroupByPageSizeOptions, expectedPipelineType: TestInjections.PipelineType.Specialized), + CreateInput( + query: $"SELECT DISTINCT VALUE r.{NumberField} FROM r ORDER BY r.{NumberField} DESC", + expectedResult: first7IntegersReversed, + partitionKey: partitionKeyValue, + enableOptimisticDirectExecution: true, + pageSizeOptions: PageSizeOptions.NonGroupByPageSizeOptions, + expectedPipelineType: TestInjections.PipelineType.OptimisticDirectExecution), + CreateInput( + query: $"SELECT DISTINCT VALUE r.{NumberField} FROM r ORDER BY r.{NumberField} DESC", + expectedResult: first7IntegersReversed, + partitionKey: null, + enableOptimisticDirectExecution: true, + pageSizeOptions: PageSizeOptions.NonGroupByPageSizeOptions, + expectedPipelineType: TestInjections.PipelineType.Specialized), // OFFSET LIMIT with WHERE and BETWEEN - CreateInput( query: $"SELECT VALUE r.numberField FROM r WHERE r.{numberField} BETWEEN 0 AND {numberOfDocuments} OFFSET 1 LIMIT 1", expectedResult: new List { 1 }, partitionKey: "/value", partition: CollectionTypes.MultiPartition, enableOptimisticDirectExecution: true, pageSizeOptions: PageSizeOptions.NonGroupByPageSizeOptions, expectedPipelineType: TestInjections.PipelineType.OptimisticDirectExecution), - CreateInput( query: $"SELECT VALUE r.numberField FROM r WHERE r.{numberField} BETWEEN 0 AND {numberOfDocuments} OFFSET 1 LIMIT 1", expectedResult: new List { 1 }, partitionKey: null, partition: CollectionTypes.MultiPartition, enableOptimisticDirectExecution: true, pageSizeOptions: PageSizeOptions.NonGroupByPageSizeOptions, expectedPipelineType: TestInjections.PipelineType.Specialized) + CreateInput( + query: $"SELECT VALUE r.numberField FROM r WHERE r.{NumberField} BETWEEN 0 AND {NumberOfDocuments} OFFSET 1 LIMIT 1", + expectedResult: new List { 1 }, + partitionKey: partitionKeyValue, + enableOptimisticDirectExecution: true, + pageSizeOptions: PageSizeOptions.NonGroupByPageSizeOptions, + expectedPipelineType: TestInjections.PipelineType.OptimisticDirectExecution), + CreateInput( + query: $"SELECT VALUE r.numberField FROM r WHERE r.{NumberField} BETWEEN 0 AND {NumberOfDocuments} OFFSET 1 LIMIT 1", + expectedResult: new List { 1 }, + partitionKey: null, + enableOptimisticDirectExecution: true, + pageSizeOptions: PageSizeOptions.NonGroupByPageSizeOptions, + expectedPipelineType: TestInjections.PipelineType.Specialized) }; + IReadOnlyList documents = CreateDocuments(NumberOfDocuments, PartitionKeyField, NumberField, NullField); + await this.CreateIngestQueryDeleteAsync( ConnectionModes.Direct | ConnectionModes.Gateway, CollectionTypes.SinglePartition, documents, - (container, documents) => RunPassingTests(singlePartitionContainerTestCases, container), - "/" + partitionKey); + (container, documents) => RunTests(singlePartitionContainerTestCases, container), + "/" + PartitionKeyField); await this.CreateIngestQueryDeleteAsync( ConnectionModes.Direct | ConnectionModes.Gateway, CollectionTypes.MultiPartition, documents, - (container, documents) => RunPassingTests(multiPartitionContainerTestCases, container), - "/" + partitionKey); + (container, documents) => RunTests(multiPartitionContainerTestCases, container), + "/" + PartitionKeyField); } [TestMethod] - public async Task TestFailingOptimisticDirectExecutionOutput() + public async Task TestQueriesWithPartitionKeyNone() { - int numberOfDocuments = 8; - string partitionKey = "key"; - string numberField = "numberField"; - string nullField = "nullField"; + int documentCount = 400; + IReadOnlyList first400Integers = Enumerable.Range(0, documentCount).ToList(); + IReadOnlyList first400IntegersReversed = Enumerable.Range(0, documentCount).Reverse().ToList(); + + IReadOnlyList testCases = new List + { + CreateInput( + query: $"SELECT VALUE r.numberField FROM r", + expectedResult: first400Integers, + partitionKey: PartitionKey.None, + enableOptimisticDirectExecution: false, + pageSizeOptions: PageSizeOptions.PageSize100, + expectedPipelineType: TestInjections.PipelineType.Passthrough), + CreateInput( + query: $"SELECT VALUE r.{NumberField} FROM r ORDER BY r.{NumberField} ASC", + expectedResult: first400Integers, + partitionKey: PartitionKey.None, + enableOptimisticDirectExecution: false, + pageSizeOptions: PageSizeOptions.PageSize100, + expectedPipelineType: TestInjections.PipelineType.Passthrough), + CreateInput( + query: $"SELECT VALUE r.{NumberField} FROM r ORDER BY r.{NumberField} DESC", + expectedResult: first400IntegersReversed, + partitionKey: PartitionKey.None, + enableOptimisticDirectExecution: false, + pageSizeOptions: PageSizeOptions.PageSize100, + expectedPipelineType: TestInjections.PipelineType.Passthrough), + CreateInput( + query: $"SELECT VALUE r.numberField FROM r WHERE r.{NumberField} BETWEEN 0 AND {NumberOfDocuments} OFFSET 1 LIMIT 1", + expectedResult: new List { 1 }, + partitionKey: PartitionKey.None, + enableOptimisticDirectExecution: false, + pageSizeOptions: PageSizeOptions.PageSize100, + expectedPipelineType: TestInjections.PipelineType.Passthrough), + CreateInput( + query: $"SELECT VALUE r.numberField FROM r", + expectedResult: first400Integers, + partitionKey: PartitionKey.None, + enableOptimisticDirectExecution: true, + pageSizeOptions: PageSizeOptions.PageSize100, + expectedPipelineType: TestInjections.PipelineType.OptimisticDirectExecution), + CreateInput( + query: $"SELECT VALUE r.{NumberField} FROM r ORDER BY r.{NumberField} ASC", + expectedResult: first400Integers, + partitionKey: PartitionKey.None, + enableOptimisticDirectExecution: true, + pageSizeOptions: PageSizeOptions.PageSize100, + expectedPipelineType: TestInjections.PipelineType.OptimisticDirectExecution), + CreateInput( + query: $"SELECT VALUE r.{NumberField} FROM r ORDER BY r.{NumberField} DESC", + expectedResult: first400IntegersReversed, + partitionKey: PartitionKey.None, + enableOptimisticDirectExecution: true, + pageSizeOptions: PageSizeOptions.PageSize100, + expectedPipelineType: TestInjections.PipelineType.OptimisticDirectExecution), + CreateInput( + query: $"SELECT VALUE r.numberField FROM r WHERE r.{NumberField} BETWEEN 0 AND {NumberOfDocuments} OFFSET 1 LIMIT 1", + expectedResult: new List { 1 }, + partitionKey: PartitionKey.None, + enableOptimisticDirectExecution: true, + pageSizeOptions: PageSizeOptions.PageSize100, + expectedPipelineType: TestInjections.PipelineType.OptimisticDirectExecution), + }; + + List documents = new List(documentCount); + for (int i = 0; i < documentCount; ++i) + { + string document = $@"{{ {NumberField}: {i}, {NullField}: null }}"; + documents.Add(document); + } + + await this.CreateIngestQueryDeleteAsync( + ConnectionModes.Direct | ConnectionModes.Gateway, + CollectionTypes.NonPartitioned | CollectionTypes.SinglePartition | CollectionTypes.MultiPartition, + documents, + (container, documents) => RunTests(testCases, container), + "/undefinedPartitionKey"); + } - List documents = CreateDocuments(numberOfDocuments, partitionKey, numberField, nullField); + [TestMethod] + public async Task TestFailingOptimisticDirectExecutionOutput() + { + IReadOnlyList documents = CreateDocuments(NumberOfDocuments, PartitionKeyField, NumberField, NullField); // check if bad continuation queries and syntax error queries are handled by pipeline IDictionary invalidQueries = new Dictionary @@ -106,10 +285,10 @@ await this.CreateIngestQueryDeleteAsync( CollectionTypes.SinglePartition | CollectionTypes.MultiPartition, documents, (container, documents) => RunFailingTests(container, invalidQueries), - "/" + partitionKey); + "/" + PartitionKeyField); } - private static async Task RunPassingTests(IEnumerable testCases, Container container) + private static async Task RunTests(IEnumerable testCases, Container container) { foreach (DirectExecutionTestCase testCase in testCases) { @@ -118,9 +297,7 @@ private static async Task RunPassingTests(IEnumerable t QueryRequestOptions feedOptions = new QueryRequestOptions { MaxItemCount = pageSize, - PartitionKey = testCase.PartitionKey == null - ? null - : new Cosmos.PartitionKey(testCase.PartitionKey), + PartitionKey = testCase.PartitionKey, EnableOptimisticDirectExecution = testCase.EnableOptimisticDirectExecution, TestSettings = new TestInjections(simulate429s: false, simulateEmptyPages: false, new TestInjections.ResponseStats()) }; @@ -130,7 +307,7 @@ private static async Task RunPassingTests(IEnumerable t testCase.Query, feedOptions); - long[] actual = items.Cast().Select(x => Number64.ToLong(x.Value)).ToArray(); + int[] actual = items.Cast().Select(x => (int)Number64.ToLong(x.Value)).ToArray(); Assert.IsTrue(testCase.ExpectedResult.SequenceEqual(actual)); Assert.AreEqual(testCase.ExpectedPipelineType, feedOptions.TestSettings.Stats.PipelineType.Value); @@ -151,7 +328,7 @@ private static async Task RunFailingTests(Container container, IDictionary( + await container.GetItemQueryIterator( queryDefinition: new QueryDefinition(queryAndResult.Key), continuationToken: queryAndResult.Value, requestOptions: feedOptions).ReadNextAsync(); @@ -169,16 +346,13 @@ await container.GetItemQueryIterator( } } - private static List CreateDocuments(int documentCount, string partitionKey, string numberField, string nullField) + private static IReadOnlyList CreateDocuments(int documentCount, string partitionKey, string numberField, string nullField) { List documents = new List(documentCount); for (int i = 0; i < documentCount; ++i) { - Document doc = new Document(); - doc.SetPropertyValue(partitionKey, "/value"); - doc.SetPropertyValue(numberField, i % documentCount); - doc.SetPropertyValue(nullField, null); - documents.Add(doc.ToString()); + string document = $@"{{ {partitionKey}: ""/value"", {numberField}: {i}, {nullField}: null }}"; + documents.Add(document); } return documents; @@ -186,31 +360,28 @@ private static List CreateDocuments(int documentCount, string partitionK private static DirectExecutionTestCase CreateInput( string query, - List expectedResult, - string partitionKey, - CollectionTypes partition, + IReadOnlyList expectedResult, + PartitionKey? partitionKey, bool enableOptimisticDirectExecution, int[] pageSizeOptions, TestInjections.PipelineType expectedPipelineType) { - return new DirectExecutionTestCase(query, expectedResult, partitionKey, partition, enableOptimisticDirectExecution, pageSizeOptions, expectedPipelineType); + return new DirectExecutionTestCase(query, expectedResult, partitionKey, enableOptimisticDirectExecution, pageSizeOptions, expectedPipelineType); } - internal readonly struct DirectExecutionTestCase + private readonly struct DirectExecutionTestCase { public string Query { get; } - public List ExpectedResult { get; } - public string PartitionKey { get; } - public CollectionTypes Partition { get; } + public IReadOnlyList ExpectedResult { get; } + public PartitionKey? PartitionKey { get; } public bool EnableOptimisticDirectExecution { get; } public int[] PageSizeOptions { get; } public TestInjections.PipelineType ExpectedPipelineType { get; } public DirectExecutionTestCase( string query, - List expectedResult, - string partitionKey, - CollectionTypes partition, + IReadOnlyList expectedResult, + PartitionKey? partitionKey, bool enableOptimisticDirectExecution, int[] pageSizeOptions, TestInjections.PipelineType expectedPipelineType) @@ -218,7 +389,6 @@ public DirectExecutionTestCase( this.Query = query; this.ExpectedResult = expectedResult; this.PartitionKey = partitionKey; - this.Partition = partition; this.EnableOptimisticDirectExecution = enableOptimisticDirectExecution; this.PageSizeOptions = pageSizeOptions; this.ExpectedPipelineType = expectedPipelineType; 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 91c69a4466..e81eda0d01 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 @@ -442,51 +442,6 @@ public async Task ChangeFeedAsync() } //---------------------------------------------------------------- - //---------------------------------------------------------------- - // ChangeFeed Estimator - //---------------------------------------------------------------- - { - Container leaseContainer = await EndToEndTraceWriterBaselineTests.database.CreateContainerAsync( - id: Guid.NewGuid().ToString(), - partitionKeyPath: "/id"); - - ChangeFeedProcessor processor = container - .GetChangeFeedProcessorBuilder( - processorName: "test", - onChangesDelegate: (IReadOnlyCollection docs, CancellationToken token) => Task.CompletedTask) - .WithInstanceName("random") - .WithLeaseContainer(leaseContainer) - .Build(); - - await processor.StartAsync(); - - // Letting processor initialize - await Task.Delay(2000); - - await processor.StopAsync(); - - startLineNumber = GetLineNumber(); - ChangeFeedEstimator estimator = container.GetChangeFeedEstimator( - "test", - leaseContainer); - using FeedIterator feedIterator = estimator.GetCurrentStateIterator(); - - List traces = new List(); - - while (feedIterator.HasMoreResults) - { - FeedResponse responseMessage = await feedIterator.ReadNextAsync(cancellationToken: default); - ITrace trace = ((CosmosTraceDiagnostics)responseMessage.Diagnostics).Value; - traces.Add(trace); - } - - ITrace traceForest = TraceJoiner.JoinTraces(traces); - endLineNumber = GetLineNumber(); - - inputs.Add(new Input("Change Feed Estimator", traceForest, startLineNumber, endLineNumber)); - } - //---------------------------------------------------------------- - this.ExecuteTestSuite(inputs); } diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/TestBaseline/AggregateSubquerySqlParserBaselineTests.First.xml b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/TestBaseline/AggregateSubquerySqlParserBaselineTests.First.xml new file mode 100644 index 0000000000..ae098baddc --- /dev/null +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/TestBaseline/AggregateSubquerySqlParserBaselineTests.First.xml @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/TestBaseline/AggregateSubquerySqlParserBaselineTests.Last.xml b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/TestBaseline/AggregateSubquerySqlParserBaselineTests.Last.xml new file mode 100644 index 0000000000..68b61ba3f1 --- /dev/null +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/TestBaseline/AggregateSubquerySqlParserBaselineTests.Last.xml @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/TestBaseline/ScalarExpressionSqlParserBaselineTests.First.xml b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/TestBaseline/ScalarExpressionSqlParserBaselineTests.First.xml new file mode 100644 index 0000000000..10b917f519 --- /dev/null +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/TestBaseline/ScalarExpressionSqlParserBaselineTests.First.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/TestBaseline/ScalarExpressionSqlParserBaselineTests.Last.xml b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/TestBaseline/ScalarExpressionSqlParserBaselineTests.Last.xml new file mode 100644 index 0000000000..ba5694ca80 --- /dev/null +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/TestBaseline/ScalarExpressionSqlParserBaselineTests.Last.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/TestBaseline/TraceWriterBaselineTests.ScenariosAsync.xml b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/TestBaseline/TraceWriterBaselineTests.ScenariosAsync.xml index eecc33b72f..27ddc7bc78 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/TestBaseline/TraceWriterBaselineTests.ScenariosAsync.xml +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/TestBaseline/TraceWriterBaselineTests.ScenariosAsync.xml @@ -127,7 +127,7 @@ @@ -71,7 +71,7 @@ + /// Verifies that if the renewed read a different Owner from the captured in memory, throws a LeaseLost + /// + [TestMethod] + public async Task IfOwnerChangedThrowOnRenew() + { + DocumentServiceLeaseStoreManagerOptions options = new DocumentServiceLeaseStoreManagerOptions + { + HostName = Guid.NewGuid().ToString() + }; + + DocumentServiceLeaseCore lease = new DocumentServiceLeaseCore() + { + LeaseToken = "0", + Owner = Guid.NewGuid().ToString(), + FeedRange = new FeedRangePartitionKeyRange("0") + }; + + Mock mockUpdater = new Mock(); + + Func, bool> validateUpdater = (Func updater) => + { + // Simulate dirty read from db + DocumentServiceLeaseCore serverLease = new DocumentServiceLeaseCore() + { + LeaseToken = "0", + Owner = Guid.NewGuid().ToString(), + FeedRange = new FeedRangePartitionKeyRange("0") + }; + DocumentServiceLease afterUpdateLease = updater(serverLease); + return true; + }; + + mockUpdater.Setup(c => c.UpdateLeaseAsync( + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.Is>(f => validateUpdater(f)))) + .ReturnsAsync(lease); + + ResponseMessage leaseResponse = new ResponseMessage(System.Net.HttpStatusCode.OK) + { + Content = new CosmosJsonDotNetSerializer().ToStream(lease) + }; + + Mock leaseContainer = new Mock(); + leaseContainer.Setup(c => c.ReadItemStreamAsync( + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny())).ReturnsAsync(leaseResponse); + + DocumentServiceLeaseManagerCosmos documentServiceLeaseManagerCosmos = new DocumentServiceLeaseManagerCosmos( + Mock.Of(), + leaseContainer.Object, + mockUpdater.Object, + options, + Mock.Of()); + + LeaseLostException leaseLost = await Assert.ThrowsExceptionAsync(() => documentServiceLeaseManagerCosmos.RenewAsync(lease)); + + Assert.IsTrue(leaseLost.InnerException is CosmosException innerCosmosException + && innerCosmosException.StatusCode == HttpStatusCode.PreconditionFailed); + } + + /// + /// Verifies that if the update properties read a different Owner from the captured in memory, throws a LeaseLost + /// + [TestMethod] + public async Task IfOwnerChangedThrowOnUpdateProperties() + { + DocumentServiceLeaseCore lease = new DocumentServiceLeaseCore() + { + LeaseToken = "0", + Owner = Guid.NewGuid().ToString(), + FeedRange = new FeedRangePartitionKeyRange("0") + }; + + DocumentServiceLeaseStoreManagerOptions options = new DocumentServiceLeaseStoreManagerOptions + { + HostName = lease.Owner + }; + + Mock mockUpdater = new Mock(); + + Func, bool> validateUpdater = (Func updater) => + { + // Simulate dirty read from db + DocumentServiceLeaseCore serverLease = new DocumentServiceLeaseCore() + { + LeaseToken = "0", + Owner = Guid.NewGuid().ToString(), + FeedRange = new FeedRangePartitionKeyRange("0") + }; + DocumentServiceLease afterUpdateLease = updater(serverLease); + return true; + }; + + mockUpdater.Setup(c => c.UpdateLeaseAsync( + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.Is>(f => validateUpdater(f)))) + .ReturnsAsync(lease); + + ResponseMessage leaseResponse = new ResponseMessage(System.Net.HttpStatusCode.OK) + { + Content = new CosmosJsonDotNetSerializer().ToStream(lease) + }; + + Mock leaseContainer = new Mock(); + leaseContainer.Setup(c => c.ReadItemStreamAsync( + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny())).ReturnsAsync(leaseResponse); + + DocumentServiceLeaseManagerCosmos documentServiceLeaseManagerCosmos = new DocumentServiceLeaseManagerCosmos( + Mock.Of(), + leaseContainer.Object, + mockUpdater.Object, + options, + Mock.Of()); + + LeaseLostException leaseLost = await Assert.ThrowsExceptionAsync(() => documentServiceLeaseManagerCosmos.UpdatePropertiesAsync(lease)); + + Assert.IsTrue(leaseLost.InnerException is CosmosException innerCosmosException + && innerCosmosException.StatusCode == HttpStatusCode.PreconditionFailed); + } + + /// + /// Verifies that if the update properties read a different Owner from the captured in memory, throws a LeaseLost + /// + [TestMethod] + public async Task IfOwnerChangedThrowOnRelease() + { + DocumentServiceLeaseStoreManagerOptions options = new DocumentServiceLeaseStoreManagerOptions + { + HostName = Guid.NewGuid().ToString() + }; + + DocumentServiceLeaseCore lease = new DocumentServiceLeaseCore() + { + LeaseToken = "0", + Owner = Guid.NewGuid().ToString(), + FeedRange = new FeedRangePartitionKeyRange("0") + }; + + Mock mockUpdater = new Mock(); + + Func, bool> validateUpdater = (Func updater) => + { + // Simulate dirty read from db + DocumentServiceLeaseCore serverLease = new DocumentServiceLeaseCore() + { + LeaseToken = "0", + Owner = Guid.NewGuid().ToString(), + FeedRange = new FeedRangePartitionKeyRange("0") + }; + DocumentServiceLease afterUpdateLease = updater(serverLease); + return true; + }; + + mockUpdater.Setup(c => c.UpdateLeaseAsync( + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.Is>(f => validateUpdater(f)))) + .ReturnsAsync(lease); + + ResponseMessage leaseResponse = new ResponseMessage(System.Net.HttpStatusCode.OK) + { + Content = new CosmosJsonDotNetSerializer().ToStream(lease) + }; + + Mock leaseContainer = new Mock(); + leaseContainer.Setup(c => c.ReadItemStreamAsync( + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny())).ReturnsAsync(leaseResponse); + + DocumentServiceLeaseManagerCosmos documentServiceLeaseManagerCosmos = new DocumentServiceLeaseManagerCosmos( + Mock.Of(), + leaseContainer.Object, + mockUpdater.Object, + options, + Mock.Of()); + + LeaseLostException leaseLost = await Assert.ThrowsExceptionAsync(() => documentServiceLeaseManagerCosmos.ReleaseAsync(lease)); + + Assert.IsTrue(leaseLost.InnerException is CosmosException innerCosmosException + && innerCosmosException.StatusCode == HttpStatusCode.PreconditionFailed); + } + /// /// When a lease is missing the range information, check that we are adding it /// diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/ClientTelemetryTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/ClientTelemetryTests.cs index 3bbbd1d3ac..b7e5d1f08e 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/ClientTelemetryTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/ClientTelemetryTests.cs @@ -30,13 +30,13 @@ public void CheckMetricsAggregationLogic() MetricInfo metrics = new MetricInfo("metricsName", "unitName"); LongConcurrentHistogram histogram = new LongConcurrentHistogram(1, - Int64.MaxValue, + long.MaxValue, 5); - histogram.RecordValue((long)10); - histogram.RecordValue((long)20); - histogram.RecordValue((long)30); - histogram.RecordValue((long)40); + histogram.RecordValue(10); + histogram.RecordValue(20); + histogram.RecordValue(30); + histogram.RecordValue(40); metrics.SetAggregators(histogram); @@ -58,14 +58,14 @@ public void CheckMetricsAggregationLogicWithAdjustment() MetricInfo metrics = new MetricInfo("metricsName", "unitName"); long adjustmentFactor = 1000; - LongConcurrentHistogram histogram = new LongConcurrentHistogram(1, - Int64.MaxValue, - 5); + LongConcurrentHistogram histogram = new LongConcurrentHistogram(1, + long.MaxValue, + 5); - histogram.RecordValue((long)(10 * adjustmentFactor)); - histogram.RecordValue((long)(20 * adjustmentFactor)); - histogram.RecordValue((long)(30 * adjustmentFactor)); - histogram.RecordValue((long)(40 * adjustmentFactor)); + histogram.RecordValue(10 * adjustmentFactor); + histogram.RecordValue(20 * adjustmentFactor); + histogram.RecordValue(30 * adjustmentFactor); + histogram.RecordValue(40 * adjustmentFactor); metrics.SetAggregators(histogram, adjustmentFactor); @@ -85,11 +85,11 @@ public void CheckMetricsAggregationLogicWithAdjustment() [TestMethod] public void CheckJsonSerializerContract() { - string json = JsonConvert.SerializeObject(new ClientTelemetryProperties(clientId: "clientId", - processId: "", - userAgent: null, - connectionMode: ConnectionMode.Direct, - preferredRegions: null, + string json = JsonConvert.SerializeObject(new ClientTelemetryProperties(clientId: "clientId", + processId: "", + userAgent: null, + connectionMode: ConnectionMode.Direct, + preferredRegions: null, aggregationIntervalInSec: 10), ClientTelemetryOptions.JsonSerializerSettings); Assert.AreEqual("{\"clientId\":\"clientId\",\"processId\":\"\",\"connectionMode\":\"DIRECT\",\"aggregationIntervalInSec\":10,\"systemInfo\":[]}", json); } @@ -101,21 +101,34 @@ public void CheckJsonSerializerContractWithPreferredRegions() { "region1" }; - string json = JsonConvert.SerializeObject(new ClientTelemetryProperties(clientId: "clientId", - processId: "", - userAgent: null, - connectionMode: ConnectionMode.Direct, + string json = JsonConvert.SerializeObject(new ClientTelemetryProperties(clientId: "clientId", + processId: "", + userAgent: null, + connectionMode: ConnectionMode.Direct, preferredRegions: preferredRegion, aggregationIntervalInSec: 1), ClientTelemetryOptions.JsonSerializerSettings); Assert.AreEqual("{\"clientId\":\"clientId\",\"processId\":\"\",\"connectionMode\":\"DIRECT\",\"preferredRegions\":[\"region1\"],\"aggregationIntervalInSec\":1,\"systemInfo\":[]}", json); } [TestMethod] - [ExpectedException(typeof(System.FormatException))] + [ExpectedException(typeof(FormatException))] public void CheckMisconfiguredTelemetry_should_fail() { Environment.SetEnvironmentVariable(ClientTelemetryOptions.EnvPropsClientTelemetryEnabled, "non-boolean"); using CosmosClient client = MockCosmosUtil.CreateMockCosmosClient(); } + + [TestMethod] + [DataRow(200, 0 ,1, false)] + [DataRow(404, 0, 1, false)] + [DataRow(404, 1002, 1, true)] + [DataRow(409, 0, 1, false)] + [DataRow(409, 1002, 1, true)] + [DataRow(503, 2001, 1, true)] + [DataRow(200, 0, 6, true)] + public void CheckEligibleStatistics(int statusCode, int subStatusCode, int latencyInMs, bool expectedFlag) + { + Assert.AreEqual(expectedFlag, ClientTelemetryOptions.IsEligible(statusCode, subStatusCode, TimeSpan.FromMilliseconds(latencyInMs))); + } } } diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Contracts/ContractTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Contracts/ContractTests.cs index 9501dee4ce..a4d295a634 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Contracts/ContractTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Contracts/ContractTests.cs @@ -23,13 +23,9 @@ public void ApiVersionTest() } catch(ArgumentNullException) { } -#if PREVIEW + Assert.AreEqual(HttpConstants.Versions.v2020_07_15, HttpConstants.Versions.CurrentVersion); CollectionAssert.AreEqual(Encoding.UTF8.GetBytes(HttpConstants.Versions.v2020_07_15), HttpConstants.Versions.CurrentVersionUTF8); -#else - Assert.AreEqual(HttpConstants.Versions.v2018_12_31, HttpConstants.Versions.CurrentVersion); - CollectionAssert.AreEqual(Encoding.UTF8.GetBytes(HttpConstants.Versions.v2018_12_31), HttpConstants.Versions.CurrentVersionUTF8); -#endif ulong capabilitites = SDKSupportedCapabilitiesHelpers.GetSDKSupportedCapabilities(); Assert.AreEqual(capabilitites & (ulong)SDKSupportedCapabilities.PartitionMerge, (ulong)SDKSupportedCapabilities.PartitionMerge); 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 43801584fe..39ae1d2eca 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 @@ -284,32 +284,10 @@ "Attributes": [], "MethodInfo": "Microsoft.Azure.Cosmos.ChangeFeedPolicy get_ChangeFeedPolicy();IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" }, - "System.Collections.Generic.IReadOnlyList`1[System.String] get_PartitionKeyPaths()": { - "Type": "Method", - "Attributes": [], - "MethodInfo": "System.Collections.Generic.IReadOnlyList`1[System.String] get_PartitionKeyPaths();IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" - }, - "System.Collections.Generic.IReadOnlyList`1[System.String] PartitionKeyPaths[Newtonsoft.Json.JsonIgnoreAttribute()]": { - "Type": "Property", - "Attributes": [ - "JsonIgnoreAttribute" - ], - "MethodInfo": "System.Collections.Generic.IReadOnlyList`1[System.String] PartitionKeyPaths;CanRead:True;CanWrite:True;System.Collections.Generic.IReadOnlyList`1[System.String] get_PartitionKeyPaths();IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;Void set_PartitionKeyPaths(System.Collections.Generic.IReadOnlyList`1[System.String]);IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" - }, - "Void .ctor(System.String, System.Collections.Generic.IReadOnlyList`1[System.String])": { - "Type": "Constructor", - "Attributes": [], - "MethodInfo": "[Void .ctor(System.String, System.Collections.Generic.IReadOnlyList`1[System.String]), Void .ctor(System.String, System.Collections.Generic.IReadOnlyList`1[System.String])]" - }, "Void set_ChangeFeedPolicy(Microsoft.Azure.Cosmos.ChangeFeedPolicy)": { "Type": "Method", "Attributes": [], "MethodInfo": "Void set_ChangeFeedPolicy(Microsoft.Azure.Cosmos.ChangeFeedPolicy);IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" - }, - "Void set_PartitionKeyPaths(System.Collections.Generic.IReadOnlyList`1[System.String])": { - "Type": "Method", - "Attributes": [], - "MethodInfo": "Void set_PartitionKeyPaths(System.Collections.Generic.IReadOnlyList`1[System.String]);IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" } }, "NestedTypes": {} @@ -384,47 +362,6 @@ } }, "NestedTypes": {} - }, - "Microsoft.Azure.Cosmos.PartitionKeyBuilder;System.Object;IsAbstract:False;IsSealed:True;IsInterface:False;IsEnum:False;IsClass:True;IsValueType:False;IsNested:False;IsGenericType:False;IsSerializable:False": { - "Subclasses": {}, - "Members": { - "Microsoft.Azure.Cosmos.PartitionKey Build()": { - "Type": "Method", - "Attributes": [], - "MethodInfo": "Microsoft.Azure.Cosmos.PartitionKey Build();IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" - }, - "Microsoft.Azure.Cosmos.PartitionKeyBuilder Add(Boolean)": { - "Type": "Method", - "Attributes": [], - "MethodInfo": "Microsoft.Azure.Cosmos.PartitionKeyBuilder Add(Boolean);IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" - }, - "Microsoft.Azure.Cosmos.PartitionKeyBuilder Add(Double)": { - "Type": "Method", - "Attributes": [], - "MethodInfo": "Microsoft.Azure.Cosmos.PartitionKeyBuilder Add(Double);IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" - }, - "Microsoft.Azure.Cosmos.PartitionKeyBuilder Add(System.String)": { - "Type": "Method", - "Attributes": [], - "MethodInfo": "Microsoft.Azure.Cosmos.PartitionKeyBuilder Add(System.String);IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" - }, - "Microsoft.Azure.Cosmos.PartitionKeyBuilder AddNoneType()": { - "Type": "Method", - "Attributes": [], - "MethodInfo": "Microsoft.Azure.Cosmos.PartitionKeyBuilder AddNoneType();IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" - }, - "Microsoft.Azure.Cosmos.PartitionKeyBuilder AddNullValue()": { - "Type": "Method", - "Attributes": [], - "MethodInfo": "Microsoft.Azure.Cosmos.PartitionKeyBuilder AddNullValue();IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" - }, - "Void .ctor()": { - "Type": "Constructor", - "Attributes": [], - "MethodInfo": "[Void .ctor(), Void .ctor()]" - } - }, - "NestedTypes": {} } }, "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 9edd8d6de1..3cf5c017c2 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 @@ -2167,6 +2167,18 @@ ], "MethodInfo": "Microsoft.Azure.Cosmos.UniqueKeyPolicy UniqueKeyPolicy;CanRead:True;CanWrite:True;Microsoft.Azure.Cosmos.UniqueKeyPolicy get_UniqueKeyPolicy();IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;Void set_UniqueKeyPolicy(Microsoft.Azure.Cosmos.UniqueKeyPolicy);IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" }, + "System.Collections.Generic.IReadOnlyList`1[System.String] get_PartitionKeyPaths()": { + "Type": "Method", + "Attributes": [], + "MethodInfo": "System.Collections.Generic.IReadOnlyList`1[System.String] get_PartitionKeyPaths();IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "System.Collections.Generic.IReadOnlyList`1[System.String] PartitionKeyPaths[Newtonsoft.Json.JsonIgnoreAttribute()]": { + "Type": "Property", + "Attributes": [ + "JsonIgnoreAttribute" + ], + "MethodInfo": "System.Collections.Generic.IReadOnlyList`1[System.String] PartitionKeyPaths;CanRead:True;CanWrite:True;System.Collections.Generic.IReadOnlyList`1[System.String] get_PartitionKeyPaths();IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;Void set_PartitionKeyPaths(System.Collections.Generic.IReadOnlyList`1[System.String]);IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, "System.Nullable`1[Microsoft.Azure.Cosmos.PartitionKeyDefinitionVersion] get_PartitionKeyDefinitionVersion()": { "Type": "Method", "Attributes": [], @@ -2294,6 +2306,11 @@ "Attributes": [], "MethodInfo": "[Void .ctor(), Void .ctor()]" }, + "Void .ctor(System.String, System.Collections.Generic.IReadOnlyList`1[System.String])": { + "Type": "Constructor", + "Attributes": [], + "MethodInfo": "[Void .ctor(System.String, System.Collections.Generic.IReadOnlyList`1[System.String]), Void .ctor(System.String, System.Collections.Generic.IReadOnlyList`1[System.String])]" + }, "Void .ctor(System.String, System.String)": { "Type": "Constructor", "Attributes": [], @@ -2348,6 +2365,11 @@ "Attributes": [], "MethodInfo": "Void set_PartitionKeyPath(System.String);IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" }, + "Void set_PartitionKeyPaths(System.Collections.Generic.IReadOnlyList`1[System.String])": { + "Type": "Method", + "Attributes": [], + "MethodInfo": "Void set_PartitionKeyPaths(System.Collections.Generic.IReadOnlyList`1[System.String]);IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, "Void set_TimeToLivePropertyPath(System.String)[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]": { "Type": "Method", "Attributes": [ @@ -5589,6 +5611,47 @@ }, "NestedTypes": {} }, + "Microsoft.Azure.Cosmos.PartitionKeyBuilder;System.Object;IsAbstract:False;IsSealed:True;IsInterface:False;IsEnum:False;IsClass:True;IsValueType:False;IsNested:False;IsGenericType:False;IsSerializable:False": { + "Subclasses": {}, + "Members": { + "Microsoft.Azure.Cosmos.PartitionKey Build()": { + "Type": "Method", + "Attributes": [], + "MethodInfo": "Microsoft.Azure.Cosmos.PartitionKey Build();IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "Microsoft.Azure.Cosmos.PartitionKeyBuilder Add(Boolean)": { + "Type": "Method", + "Attributes": [], + "MethodInfo": "Microsoft.Azure.Cosmos.PartitionKeyBuilder Add(Boolean);IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "Microsoft.Azure.Cosmos.PartitionKeyBuilder Add(Double)": { + "Type": "Method", + "Attributes": [], + "MethodInfo": "Microsoft.Azure.Cosmos.PartitionKeyBuilder Add(Double);IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "Microsoft.Azure.Cosmos.PartitionKeyBuilder Add(System.String)": { + "Type": "Method", + "Attributes": [], + "MethodInfo": "Microsoft.Azure.Cosmos.PartitionKeyBuilder Add(System.String);IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "Microsoft.Azure.Cosmos.PartitionKeyBuilder AddNoneType()": { + "Type": "Method", + "Attributes": [], + "MethodInfo": "Microsoft.Azure.Cosmos.PartitionKeyBuilder AddNoneType();IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "Microsoft.Azure.Cosmos.PartitionKeyBuilder AddNullValue()": { + "Type": "Method", + "Attributes": [], + "MethodInfo": "Microsoft.Azure.Cosmos.PartitionKeyBuilder AddNullValue();IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "Void .ctor()": { + "Type": "Constructor", + "Attributes": [], + "MethodInfo": "[Void .ctor(), Void .ctor()]" + } + }, + "NestedTypes": {} + }, "Microsoft.Azure.Cosmos.PartitionKeyDefinitionVersion;System.Enum;IsAbstract:False;IsSealed:True;IsInterface:False;IsEnum:True;IsClass:False;IsValueType:True;IsNested:False;IsGenericType:False;IsSerializable:True": { "Subclasses": {}, "Members": { diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/GatewayAddressCacheTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/GatewayAddressCacheTests.cs index 9e3b87ec83..809814aef1 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/GatewayAddressCacheTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/GatewayAddressCacheTests.cs @@ -18,6 +18,8 @@ namespace Microsoft.Azure.Cosmos using Microsoft.Azure.Cosmos.Tests; using Microsoft.Azure.Cosmos.Tracing; using Microsoft.Azure.Documents; + using Microsoft.Azure.Documents.Client; + using Microsoft.Azure.Documents.Rntbd; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; @@ -108,8 +110,11 @@ public void TestGatewayAddressCacheAutoRefreshOnSuboptimalPartition() public async Task TestGatewayAddressCacheUpdateOnConnectionResetAsync() { FakeMessageHandler messageHandler = new FakeMessageHandler(); - HttpClient httpClient = new HttpClient(messageHandler); - httpClient.Timeout = TimeSpan.FromSeconds(120); + HttpClient httpClient = new HttpClient(messageHandler) + { + Timeout = TimeSpan.FromSeconds(120) + }; + GatewayAddressCache cache = new GatewayAddressCache( new Uri(GatewayAddressCacheTests.DatabaseAccountApiEndpoint), Documents.Client.Protocol.Tcp, @@ -129,8 +134,9 @@ public async Task TestGatewayAddressCacheUpdateOnConnectionResetAsync() Assert.IsNotNull(addresses.AllAddresses.Select(address => address.PhysicalUri == "https://blabla.com")); - // call updateAddress - cache.TryRemoveAddresses(new Documents.Rntbd.ServerKey(new Uri("https://blabla.com"))); + // Mark transport addresses to Unhealthy depcting a connection reset event. + ServerKey faultyServerKey = new (new Uri("https://blabla2.com")); + await cache.MarkAddressesToUnhealthyAsync(faultyServerKey); // check if the addresss is updated addresses = await cache.TryGetAddressesAsync( @@ -140,7 +146,15 @@ public async Task TestGatewayAddressCacheUpdateOnConnectionResetAsync() false, CancellationToken.None); - Assert.IsNotNull(addresses.AllAddresses.Select(address => address.PhysicalUri == "https://blabla5.com")); + // Validate that the above transport uri with host blabla2.com has been marked Unhealthy. + IReadOnlyList transportAddressUris = addresses + .Get(Protocol.Tcp)? + .ReplicaTransportAddressUris; + + TransportAddressUri transportAddressUri = transportAddressUris + .Single(x => x.ReplicaServerKey.Equals(faultyServerKey)); + + Assert.IsTrue(condition: transportAddressUri.GetCurrentHealthState().GetHealthStatus().Equals(TransportAddressHealthState.HealthStatus.Unhealthy)); } [TestMethod] @@ -1458,23 +1472,23 @@ public int GetMethodInvocationCount() } Task IOpenConnectionsHandler.TryOpenRntbdChannelsAsync( - IReadOnlyList addresses) + IEnumerable addresses) { - this.totalReceivedAddressesCounter = addresses.Count; - for (int i = 0; i < addresses.Count; i++) + this.totalReceivedAddressesCounter = addresses.Count(); + for (int i = 0; i < addresses.Count(); i++) { if (this.useAttemptBasedFailingIndexs) { if (this.failIndexesByAttempts.ContainsKey(i) && this.failIndexesByAttempts[i].Contains(this.methodInvocationCounter)) { this.ExecuteFailureCondition( - addresses: addresses, + addresses: addresses.ToList(), index: i); } else { this.ExecuteSuccessCondition( - addresses: addresses, + addresses: addresses.ToList(), index: i); } } @@ -1483,13 +1497,13 @@ Task IOpenConnectionsHandler.TryOpenRntbdChannelsAsync( if (this.failingIndexes.Contains(i)) { this.ExecuteFailureCondition( - addresses: addresses, + addresses: addresses.ToList(), index: i); } else { this.ExecuteSuccessCondition( - addresses: addresses, + addresses: addresses.ToList(), index: i); } } 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 8884e22815..ae5dccd2c8 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/HandlerTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/HandlerTests.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.Globalization; using System.IO; using System.Linq; @@ -438,6 +439,153 @@ public void TestAggregateExceptionConverter() Assert.IsTrue(response.ErrorMessage.Contains(errorMessage)); } + [TestMethod] + public async Task TestResolveFeedRangeBasedOnPrefixWithFeedRangePartitionKeyAndMultiHashContainerAsync() + { + dynamic item = new { id = Guid.NewGuid().ToString(), city = "Redmond", state = "WA", zipCode = "98502" }; + Cosmos.PartitionKey partitionKey = new PartitionKeyBuilder() + .Add(item.city) + .Add(item.state) + .Build(); + + await HandlerTests.TestResolveFeedRangeBasedOnPrefixAsync( + partitionKeyDefinition: new PartitionKeyDefinition() + { + Kind = PartitionKind.MultiHash, + Paths = new Collection(new List() { "/city", "/state", "/zipCode" }) + }, + inputFeedRange: new FeedRangePartitionKey(partitionKey), + expectedFeedRange: new FeedRangeEpk(new Documents.Routing.Range( + min: "01620B162169497AFD85FA66E99F73760845FB119899DE50766A2C4CEFC2FA73", + max: "01620B162169497AFD85FA66E99F73760845FB119899DE50766A2C4CEFC2FA73FF", + isMinInclusive: true, + isMaxInclusive: default)), + getPartitionKeyDefinitionAsyncExecutions: Moq.Times.Once()); + } + + [TestMethod] + public async Task TestResolveFeedRangeBasedOnPrefixWithFeedRangePartitionKeyOnHashContainerAsync() + { + dynamic item = new { id = Guid.NewGuid().ToString(), city = "Redmond" }; + Cosmos.PartitionKey partitionKey = new PartitionKeyBuilder() + .Add(item.city) + .Build(); + + await HandlerTests.TestResolveFeedRangeBasedOnPrefixAsync( + partitionKeyDefinition: new PartitionKeyDefinition() + { + Kind = PartitionKind.Hash, + Paths = new Collection(new List() { "/city" }) + }, + inputFeedRange: new FeedRangePartitionKey(partitionKey), + expectedFeedRange: new FeedRangePartitionKey(partitionKey), + getPartitionKeyDefinitionAsyncExecutions: Moq.Times.Once()); + } + + [TestMethod] + public async Task TestResolveFeedRangeBasedOnPrefixWithFeedRangePartitionKeyOnRangeContainerAsync() + { + dynamic item = new { id = Guid.NewGuid().ToString(), city = "Redmond" }; + Cosmos.PartitionKey partitionKey = new PartitionKeyBuilder() + .Add(item.city) + .Build(); + + await HandlerTests.TestResolveFeedRangeBasedOnPrefixAsync( + partitionKeyDefinition: new PartitionKeyDefinition() + { + Kind = PartitionKind.Range, + Paths = new Collection(new List() { "/city" }) + }, + inputFeedRange: new FeedRangePartitionKey(partitionKey), + expectedFeedRange: new FeedRangePartitionKey(partitionKey), + getPartitionKeyDefinitionAsyncExecutions: Moq.Times.Once()); + } + + [TestMethod] + public async Task TestResolveFeedRangeBasedOnPrefixWithFeedRangeEpkOnMultiHashContainerAsync() + { + await HandlerTests.TestResolveFeedRangeBasedOnPrefixAsync( + partitionKeyDefinition: new PartitionKeyDefinition() + { + Kind = PartitionKind.MultiHash, + Paths = new Collection(new List() { "/city", "/state", "/zipCode" }) + }, + inputFeedRange: FeedRangeEpk.FullRange, + expectedFeedRange: FeedRangeEpk.FullRange, + getPartitionKeyDefinitionAsyncExecutions: Moq.Times.Never()); + } + + [TestMethod] + public async Task TestResolveFeedRangeBasedOnPrefixWithFeedRangeEpkOnHashContainerAsync() + { + await HandlerTests.TestResolveFeedRangeBasedOnPrefixAsync( + partitionKeyDefinition: new PartitionKeyDefinition() + { + Kind = PartitionKind.Hash, + Paths = new Collection(new List() { "/city" }) + }, + inputFeedRange: FeedRangeEpk.FullRange, + expectedFeedRange: FeedRangeEpk.FullRange, + getPartitionKeyDefinitionAsyncExecutions: Moq.Times.Never()); + } + + [TestMethod] + public async Task TestResolveFeedRangeBasedOnPrefixWithFeedRangeEpkOnRangeContainerAsync() + { + await HandlerTests.TestResolveFeedRangeBasedOnPrefixAsync( + partitionKeyDefinition: new PartitionKeyDefinition() + { + Kind = PartitionKind.Range, + Paths = new Collection(new List() { "/city" }) + }, + inputFeedRange: FeedRangeEpk.FullRange, + expectedFeedRange: FeedRangeEpk.FullRange, + getPartitionKeyDefinitionAsyncExecutions: Moq.Times.Never()); + } + + private static async Task TestResolveFeedRangeBasedOnPrefixAsync( + PartitionKeyDefinition partitionKeyDefinition, + FeedRangeInternal inputFeedRange, + FeedRangeInternal expectedFeedRange, + Moq.Times getPartitionKeyDefinitionAsyncExecutions) + where TFeedRange : FeedRangeInternal + { + using CosmosClient client = MockCosmosUtil.CreateMockCosmosClient( + accountConsistencyLevel: Cosmos.ConsistencyLevel.Strong, + customizeClientBuilder: builder => builder.WithConsistencyLevel(Cosmos.ConsistencyLevel.Eventual)); + + Moq.Mock mockContainer = MockCosmosUtil.CreateMockContainer( + dbName: Guid.NewGuid().ToString(), + containerName: Guid.NewGuid().ToString()); + + CancellationToken cancellationToken = CancellationToken.None; + + mockContainer + .Setup(container => container.GetPartitionKeyDefinitionAsync(cancellationToken)) + .Returns(Task.FromResult(partitionKeyDefinition)); + + RequestInvokerHandler invoker = new( + client: client, + requestedClientConsistencyLevel: default); + + Cosmos.FeedRange feedRange = await RequestInvokerHandler.ResolveFeedRangeBasedOnPrefixContainerAsync( + feedRange: inputFeedRange, + cosmosContainerCore: mockContainer.Object, + cancellationToken: cancellationToken); + + mockContainer.Verify(x => x.GetPartitionKeyDefinitionAsync(Moq.It.IsAny()), getPartitionKeyDefinitionAsyncExecutions); + + Assert.IsNotNull(feedRange, "FeedRange did not initialize"); + + Assert.IsInstanceOfType( + value: feedRange, + expectedType: typeof(TFeedRange)); + + Assert.AreEqual( + expected: expectedFeedRange.ToJsonString(), + actual: feedRange.ToJsonString()); + } + private class SomePayload { public string V1 { get; set; } 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 856fcaee04..c867b0f003 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 @@ -9,7 +9,7 @@ false false Microsoft.Azure.Cosmos.Tests - $(LangVersion) + $(LangVersion) @@ -34,6 +34,7 @@ + @@ -68,6 +69,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest @@ -170,12 +174,24 @@ PreserveNewest - - PreserveNewest - - - PreserveNewest - + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + PreserveNewest @@ -194,9 +210,9 @@ PreserveNewest - + PreserveNewest - + PreserveNewest @@ -359,6 +375,9 @@ PreserveNewest + + PreserveNewest + diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/OfflineEngine/AggregateProjectionDector.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/OfflineEngine/AggregateProjectionDector.cs index ca162fc467..18c59fcc49 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/OfflineEngine/AggregateProjectionDector.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/OfflineEngine/AggregateProjectionDector.cs @@ -111,6 +111,12 @@ public override bool Visit(SqlExistsScalarExpression sqlExistsScalarExpression) return false; } + public override bool Visit(SqlFirstScalarExpression sqlFirstScalarExpression) + { + // No need to worry about aggregates within the subquery (they will recursively get rewritten). + return false; + } + public override bool Visit(SqlFunctionCallScalarExpression sqlFunctionCallScalarExpression) { Aggregate aggregate; @@ -129,6 +135,12 @@ public override bool Visit(SqlInScalarExpression sqlInScalarExpression) return hasAggregates; } + public override bool Visit(SqlLastScalarExpression sqlLastScalarExpression) + { + // No need to worry about aggregates within the subquery (they will recursively get rewritten). + return false; + } + public override bool Visit(SqlLikeScalarExpression sqlLikeScalarExpression) { return false; diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/OfflineEngine/AggregateProjectionTransformer.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/OfflineEngine/AggregateProjectionTransformer.cs index 1ce82d3c98..e644eeee43 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/OfflineEngine/AggregateProjectionTransformer.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/OfflineEngine/AggregateProjectionTransformer.cs @@ -140,6 +140,12 @@ public override SqlScalarExpression Visit(SqlExistsScalarExpression sqlExistsSca return sqlExistsScalarExpression; } + public override SqlScalarExpression Visit(SqlFirstScalarExpression sqlFirstScalarExpression) + { + // No need to worry about aggregates within the subquery (they will recursively get rewritten). + return sqlFirstScalarExpression; + } + public override SqlScalarExpression Visit(SqlFunctionCallScalarExpression sqlFunctionCallScalarExpression) { SqlScalarExpression rewrittenExpression; @@ -293,6 +299,12 @@ public override SqlScalarExpression Visit(SqlInScalarExpression sqlInScalarExpre items); } + public override SqlScalarExpression Visit(SqlLastScalarExpression sqlLastScalarExpression) + { + // No need to worry about aggregates within the subquery (they will recursively get rewritten). + return sqlLastScalarExpression; + } + public override SqlScalarExpression Visit(SqlLikeScalarExpression sqlLikeScalarExpression) { return sqlLikeScalarExpression; diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/OfflineEngine/ScalarExpressionEvaluator.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/OfflineEngine/ScalarExpressionEvaluator.cs index 2a671f2568..4c0cda94dc 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/OfflineEngine/ScalarExpressionEvaluator.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/OfflineEngine/ScalarExpressionEvaluator.cs @@ -257,6 +257,16 @@ public override CosmosElement Visit(SqlExistsScalarExpression scalarExpression, return CosmosBoolean.Create(subqueryResults.Any()); } + public override CosmosElement Visit(SqlFirstScalarExpression scalarExpression, CosmosElement document) + { + // Only run on the current document since the subquery is always correlated. + IEnumerable subqueryResults = SqlInterpreter.ExecuteQuery( + new CosmosElement[] { document }, + scalarExpression.Subquery); + + return subqueryResults.FirstOrDefault(CosmosUndefined.Create()); + } + public override CosmosElement Visit(SqlFunctionCallScalarExpression scalarExpression, CosmosElement document) { List arguments = new List(); @@ -304,6 +314,16 @@ public override CosmosElement Visit(SqlInScalarExpression scalarExpression, Cosm return CosmosBoolean.Create(contains); } + public override CosmosElement Visit(SqlLastScalarExpression scalarExpression, CosmosElement document) + { + // Only run on the current document since the subquery is always correlated. + IEnumerable subqueryResults = SqlInterpreter.ExecuteQuery( + new CosmosElement[] { document }, + scalarExpression.Subquery); + + return subqueryResults.LastOrDefault(CosmosUndefined.Create()); + } + public override CosmosElement Visit(SqlLikeScalarExpression scalarExpression, CosmosElement document) { // Consider the necessity of having v3 offline engine. Should we remove this altogether? diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/OfflineEngine/SqlInterpreter.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/OfflineEngine/SqlInterpreter.cs index ba45092faa..c9da37b7c4 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/OfflineEngine/SqlInterpreter.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/OfflineEngine/SqlInterpreter.cs @@ -755,6 +755,11 @@ public override bool Visit(SqlExistsScalarExpression scalarExpression) return false; } + public override bool Visit(SqlFirstScalarExpression scalarExpression) + { + return false; + } + public override bool Visit(SqlFunctionCallScalarExpression scalarExpression) { if (this.MatchesGroupByExpression(scalarExpression)) @@ -805,6 +810,11 @@ public override bool Visit(SqlInScalarExpression scalarExpression) return true; } + public override bool Visit(SqlLastScalarExpression scalarExpression) + { + return false; + } + public override bool Visit(SqlLikeScalarExpression scalarExpression) { return false; diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Parser/AggregateSubquerySqlParserBaselineTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Parser/AggregateSubquerySqlParserBaselineTests.cs index 079fbbba46..92c6d6056b 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Parser/AggregateSubquerySqlParserBaselineTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Parser/AggregateSubquerySqlParserBaselineTests.cs @@ -54,12 +54,109 @@ public void All() " FROM (SELECT udf.ALL(1, 2)) AS ALL " + " WHERE ALL( SELECT VALUE 1) " + ")") - }; this.ExecuteTestSuite(inputs); } + [TestMethod] + public void First() + { + List inputs = new List() + { + CreateInput( + description: "FIRST in an SqlSelectItem as an alias", + query: "SELECT 1 AS FIRST"), + CreateInput( + description: "FIRST in an AliasedCollectionExpression as an alias", + query: "SELECT * " + + "FROM (SELECT VALUE 1) AS FIRST"), + CreateInput( + description: "FIRST in an ArrayIteratorCollectionExpression", + query: "SELECT * " + + "FROM FIRST IN (SELECT VALUE 1)"), + CreateInput( + description: "FIRST in an InputPathCollection and IdentifierPathExpression", + query: "SELECT * " + + "FROM FIRST.FIRST"), + CreateInput( + description: "FIRST in a PropertyRefScalarExpression", + query: "SELECT FIRST"), + CreateInput( + description: "FIRST in a PropertyRefScalarExpression as child", + query: "SELECT c.FIRST"), + CreateInput( + description: "FIRST in a PropertyRefScalarExpression as parent and child", + query: "SELECT FIRST.FIRST"), + CreateInput( + description: "FIRST in a function cFIRST", + query: "SELECT FIRST(1, 2)"), + CreateInput( + description: "FIRST in a UDF function cFIRST", + query: "SELECT udf.FIRST(1, 2)"), + CreateInput( + description: "FIRST in every possible grammar rule at the same time", + query: "SELECT FIRST(1, 2) AS FIRST " + + "FROM FIRST IN (SELECT FIRST.FIRST) " + + "WHERE FIRST( " + + " SELECT FIRST " + + " FROM (SELECT udf.FIRST(1, 2)) AS FIRST " + + " WHERE FIRST( SELECT VALUE 1) " + + ")") + }; + + this.ExecuteTestSuite(inputs); + } + + [TestMethod] + public void Last() + { + List inputs = new List() + { + CreateInput( + description: "LAST in an SqlSelectItem as an alias", + query: "SELECT 1 AS LAST"), + CreateInput( + description: "LAST in an AliasedCollectionExpression as an alias", + query: "SELECT * " + + "FROM (SELECT VALUE 1) AS LAST"), + CreateInput( + description: "LAST in an ArrayIteratorCollectionExpression", + query: "SELECT * " + + "FROM LAST IN (SELECT VALUE 1)"), + CreateInput( + description: "LAST in an InputPathCollection and IdentifierPathExpression", + query: "SELECT * " + + "FROM LAST.LAST"), + CreateInput( + description: "LAST in a PropertyRefScalarExpression", + query: "SELECT LAST"), + CreateInput( + description: "LAST in a PropertyRefScalarExpression as child", + query: "SELECT c.LAST"), + CreateInput( + description: "LAST in a PropertyRefScalarExpression as parent and child", + query: "SELECT LAST.LAST"), + CreateInput( + description: "LAST in a function cLAST", + query: "SELECT LAST(1, 2)"), + CreateInput( + description: "LAST in a UDF function cLAST", + query: "SELECT udf.LAST(1, 2)"), + CreateInput( + description: "LAST in every possible grammar rule at the same time", + query: "SELECT LAST(1, 2) AS LAST " + + "FROM LAST IN (SELECT LAST.LAST) " + + "WHERE LAST( " + + " SELECT LAST " + + " FROM (SELECT udf.LAST(1, 2)) AS LAST " + + " WHERE LAST( SELECT VALUE 1) " + + ")") + }; + + this.ExecuteTestSuite(inputs); + } + public static SqlParserBaselineTestInput CreateInput(string description, string query) { return new SqlParserBaselineTestInput(description, query); 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 2faed74686..43377f0074 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 @@ -246,6 +246,38 @@ public void Exists() this.ExecuteTestSuite(inputs); } + [TestMethod] + public void First() + { + List inputs = new List() + { + // Positive + CreateInput(description: "Basic", scalarExpression: "FIRST(SELECT *)"), + CreateInput(description: "case insensitive", scalarExpression: "FIRST(SELECT *)"), + CreateInput(description: "nested", scalarExpression:"FIRST( SELECT * WHERE FIRST( SELECT *))"), + CreateInput( + description: "multiple nested", + scalarExpression: + "FIRST( " + + " SELECT * " + + " WHERE FIRST( " + + " SELECT *" + + " WHERE FIRST(" + + " SELECT *" + + " WHERE FIRST(" + + " SELECT VALUE 1" + + " )" + + " )" + + " )" + + ")"), + + // Negative + CreateInput(description: "No closing parens", scalarExpression: "FIRST(SELECT *") + }; + + this.ExecuteTestSuite(inputs); + } + [TestMethod] public void FunctionCall() { @@ -291,6 +323,38 @@ public void In() this.ExecuteTestSuite(inputs); } + [TestMethod] + public void Last() + { + List inputs = new List() + { + // Positive + CreateInput(description: "Basic", scalarExpression: "LAST(SELECT *)"), + CreateInput(description: "case insensitive", scalarExpression: "LAST(SELECT *)"), + CreateInput(description: "nested", scalarExpression:"LAST( SELECT * WHERE LAST( SELECT *))"), + CreateInput( + description: "multiple nested", + scalarExpression: + "LAST( " + + " SELECT * " + + " WHERE LAST( " + + " SELECT *" + + " WHERE LAST(" + + " SELECT *" + + " WHERE LAST(" + + " SELECT VALUE 1" + + " )" + + " )" + + " )" + + ")"), + + // Negative + CreateInput(description: "No closing parens", scalarExpression: "LAST(SELECT *") + }; + + this.ExecuteTestSuite(inputs); + } + [TestMethod] public void Literal() { diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Telemetry/ClientTelemetryPayloadWithoutMetrics.json b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Telemetry/ClientTelemetryPayloadWithoutMetrics.json new file mode 100644 index 0000000000..a17f0fd74c --- /dev/null +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Telemetry/ClientTelemetryPayloadWithoutMetrics.json @@ -0,0 +1,135 @@ +{ + "timeStamp": "2022-07-12T10:37:40Z", + "clientId": "1d5a40cf-d1a3-4ac5-ad34-307ad9243985", + "machineId": "vmId:d0cb93eb-214b-4c2b-bd3d-cc93e90d9efd", + "processId": "dotnet", + "userAgent": "cosmos-netstandard-sdk/3.28.0|8|X64|Microsoft Windows 10.0.22000|.NET 6.0.6|L|F 00000010|", + "connectionMode": "DIRECT", + "globalDatabaseAccountName": "localhost", + "applicationRegion": "eastus", + "hostEnvInfo": "Linux|18.04-LTS|Standard_D2s_v3|AzurePublicCloud", + "preferredRegions": [ "region1", "region2" ], + "aggregationIntervalInSec": 1, + "acceleratedNetworking": false, + "systemInfo": [ + { + "resource": "HostMachine", + "metricInfo": { + "metricsName": "CPU", + "unitName": "Percentage", + "mean": 38.55, + "count": 4, + "min": 10.96, + "max": 73.27, + "percentiles": { + "50": 33.11, + "90": 73.27, + "95": 73.27, + "99": 73.27, + "99.9": 73.27 + } + } + }, + { + "resource": "HostMachine", + "metricInfo": { + "metricsName": "MemoryRemaining", + "unitName": "MB", + "mean": 31904.0, + "count": 4, + "min": 31744.0, + "max": 31999.9990234375, + "percentiles": { + "50": 31999.9990234375, + "90": 31999.9990234375, + "95": 31999.9990234375, + "99": 31999.9990234375, + "99.9": 31999.9990234375 + } + } + }, + { + "resource": "HostMachine", + "metricInfo": { + "metricsName": "SystemPool_AvailableThreads", + "unitName": "ThreadCount", + "mean": 32704.0, + "count": 4, + "min": 32640.0, + "max": 32767.0, + "percentiles": { + "50": 32767.0, + "90": 32767.0, + "95": 32767.0, + "99": 32767.0, + "99.9": 32767.0 + } + } + }, + { + "resource": "HostMachine", + "metricInfo": { + "metricsName": "SystemPool_ThreadWaitInterval", + "unitName": "MilliSecond", + "mean": 0.1743, + "count": 3, + "min": 0.0488, + "max": 0.3359, + "percentiles": { + "50": 0.1391, + "90": 0.3359, + "95": 0.3359, + "99": 0.3359, + "99.9": 0.3359 + } + } + }, + { + "resource": "HostMachine", + "metricInfo": { + "metricsName": "SystemPool_IsThreadStarving_True", + "unitName": "Count", + "mean": 0.1, + "count": 2, + "min": 0.1, + "max": 0.1 + } + }, + { + "resource": "HostMachine", + "metricInfo": { + "metricsName": "RntbdOpenConnections", + "unitName": "Count", + "mean": 0.25, + "count": 4, + "min": 0.1, + "max": 1.0, + "percentiles": { + "50": 0.1, + "90": 1.0, + "95": 1.0, + "99": 1.0, + "99.9": 1.0 + } + } + }, + { + "resource": "HostMachine", + "metricInfo": { + "metricsName": "TcpNewChannelOpenLatency", + "unitName": "MilliSecond", + "mean": 0.25, + "count": 4, + "min": 0.1, + "max": 1.0, + "percentiles": { + "50": 0.1, + "90": 1.0, + "95": 1.0, + "99": 1.0, + "99.9": 1.0 + } + } + } + ] +} 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 new file mode 100644 index 0000000000..48cb0d1e42 --- /dev/null +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Telemetry/ClientTelemetryTests.cs @@ -0,0 +1,258 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Tests.Telemetry +{ + using System; + using Microsoft.VisualStudio.TestTools.UnitTesting; + using HdrHistogram; + using Newtonsoft.Json; + using Microsoft.Azure.Cosmos.Telemetry; + using System.Collections.Generic; + using Microsoft.Azure.Cosmos.Telemetry.Models; + using System.Text; + using System.IO; + using System.Net.Http; + using Moq; + using System.Threading.Tasks; + using System.Threading; + using System.Net; + using System.Collections.Concurrent; + + /// + /// Tests for . + /// + [TestClass] + public class ClientTelemetryTests + { + [TestCleanup] + public void Cleanup() + { + Environment.SetEnvironmentVariable(ClientTelemetryOptions.EnvPropsClientTelemetryEnabled, null); + } + + [TestMethod] + public void CheckMetricsAggregationLogic() + { + MetricInfo metrics = new MetricInfo("metricsName", "unitName"); + + LongConcurrentHistogram histogram = new LongConcurrentHistogram(1, + long.MaxValue, + 5); + + histogram.RecordValue(10); + histogram.RecordValue(20); + histogram.RecordValue(30); + histogram.RecordValue(40); + + metrics.SetAggregators(histogram); + + Assert.AreEqual(40, metrics.Max); + Assert.AreEqual(10, metrics.Min); + Assert.AreEqual(4, metrics.Count); + Assert.AreEqual(25, metrics.Mean); + + Assert.AreEqual(20, metrics.Percentiles[ClientTelemetryOptions.Percentile50]); + Assert.AreEqual(40, metrics.Percentiles[ClientTelemetryOptions.Percentile90]); + Assert.AreEqual(40, metrics.Percentiles[ClientTelemetryOptions.Percentile95]); + Assert.AreEqual(40, metrics.Percentiles[ClientTelemetryOptions.Percentile99]); + Assert.AreEqual(40, metrics.Percentiles[ClientTelemetryOptions.Percentile999]); + } + + [TestMethod] + public void CheckMetricsAggregationLogicWithAdjustment() + { + MetricInfo metrics = new MetricInfo("metricsName", "unitName"); + long adjustmentFactor = 1000; + + LongConcurrentHistogram histogram = new LongConcurrentHistogram(1, + long.MaxValue, + 5); + + histogram.RecordValue(10 * adjustmentFactor); + histogram.RecordValue(20 * adjustmentFactor); + histogram.RecordValue(30 * adjustmentFactor); + histogram.RecordValue(40 * adjustmentFactor); + + metrics.SetAggregators(histogram, adjustmentFactor); + + Assert.AreEqual(40, metrics.Max); + Assert.AreEqual(10, metrics.Min); + Assert.AreEqual(4, metrics.Count); + + Assert.AreEqual(25, metrics.Mean); + + Assert.AreEqual(20, metrics.Percentiles[ClientTelemetryOptions.Percentile50]); + Assert.AreEqual(40, metrics.Percentiles[ClientTelemetryOptions.Percentile90]); + Assert.AreEqual(40, metrics.Percentiles[ClientTelemetryOptions.Percentile95]); + Assert.AreEqual(40, metrics.Percentiles[ClientTelemetryOptions.Percentile99]); + Assert.AreEqual(40, metrics.Percentiles[ClientTelemetryOptions.Percentile999]); + } + + [TestMethod] + public void CheckJsonSerializerContract() + { + string json = JsonConvert.SerializeObject(new ClientTelemetryProperties(clientId: "clientId", + processId: "", + userAgent: null, + connectionMode: ConnectionMode.Direct, + preferredRegions: null, + aggregationIntervalInSec: 10), ClientTelemetryOptions.JsonSerializerSettings); + Assert.AreEqual("{\"clientId\":\"clientId\",\"processId\":\"\",\"connectionMode\":\"DIRECT\",\"aggregationIntervalInSec\":10,\"systemInfo\":[]}", json); + } + + [TestMethod] + public void CheckJsonSerializerContractWithPreferredRegions() + { + List preferredRegion = new List + { + "region1" + }; + string json = JsonConvert.SerializeObject(new ClientTelemetryProperties(clientId: "clientId", + processId: "", + userAgent: null, + connectionMode: ConnectionMode.Direct, + preferredRegions: preferredRegion, + aggregationIntervalInSec: 1), ClientTelemetryOptions.JsonSerializerSettings); + Assert.AreEqual("{\"clientId\":\"clientId\",\"processId\":\"\",\"connectionMode\":\"DIRECT\",\"preferredRegions\":[\"region1\"],\"aggregationIntervalInSec\":1,\"systemInfo\":[]}", json); + } + + [TestMethod] + [DataRow(100, 50, 200)] // When operation, cacherefresh and request info is there in payload + [DataRow(0, 50, 0)] // When only cacherefresh info is there in payload + [DataRow(100, 50, 0)] // When only operation and cacherefresh info is there in payload + [DataRow(100, 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); + ClientTelemetryProperties clientTelemetryProperties = JsonConvert.DeserializeObject(data); + + int totalPayloadSizeInBytes = data.Length; + + int actualOperationInfoSize = 0; + int actualCacheRefreshInfoSize = 0; + int actualRequestInfoSize = 0; + + Mock mockHttpHandler = new Mock(); + _ = mockHttpHandler.Setup(x => x.SendAsync( + It.IsAny(), + It.IsAny())) + .Callback( + (request, cancellationToken) => + { + string payloadJson = request.Content.ReadAsStringAsync().Result; + Assert.IsTrue(payloadJson.Length <= ClientTelemetryOptions.PayloadSizeThreshold, "Payload Size is " + payloadJson.Length); + + ClientTelemetryProperties propertiesToSend = JsonConvert.DeserializeObject(payloadJson); + + Assert.AreEqual(7, propertiesToSend.SystemInfo.Count, "System Info is not correct"); + + actualOperationInfoSize += propertiesToSend.OperationInfo?.Count ?? 0; + actualCacheRefreshInfoSize += propertiesToSend.CacheRefreshInfo?.Count ?? 0; + actualRequestInfoSize += propertiesToSend.RequestInfo?.Count ?? 0; + }) + .Returns(Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK))); + + ClientTelemetryProcessor processor = new ClientTelemetryProcessor( + MockCosmosUtil.CreateCosmosHttpClient(() => new HttpClient(new HttpHandlerHelper(mockHttpHandler.Object))), + Mock.Of()); + + ConcurrentDictionary operationInfoSnapshot + = new ConcurrentDictionary(); + + for (int i = 0; i < (expectedOperationInfoSize/2); i++) + { + OperationInfo opeInfo = new OperationInfo(Regions.WestUS, + 0, + Documents.ConsistencyLevel.Session.ToString(), + "databaseName" + i, + "containerName", + Documents.OperationType.Read, + Documents.ResourceType.Document, + 200, + 0); + + LongConcurrentHistogram latency = new LongConcurrentHistogram(ClientTelemetryOptions.RequestLatencyMin, + ClientTelemetryOptions.RequestLatencyMax, + ClientTelemetryOptions.RequestLatencyPrecision); + latency.RecordValue(10l); + + LongConcurrentHistogram requestcharge = new LongConcurrentHistogram(ClientTelemetryOptions.RequestChargeMin, + ClientTelemetryOptions.RequestChargeMax, + ClientTelemetryOptions.RequestChargePrecision); + requestcharge.RecordValue(11l); + + operationInfoSnapshot.TryAdd(opeInfo, (latency, requestcharge)); + } + + ConcurrentDictionary cacheRefreshInfoSnapshot + = new ConcurrentDictionary(); + for (int i = 0; i < expectedCacheRefreshInfoSize; i++) + { + CacheRefreshInfo crInfo = new CacheRefreshInfo(Regions.WestUS, + 10, + Documents.ConsistencyLevel.Session.ToString(), + "databaseName" + i, + "containerName", + Documents.OperationType.Read, + Documents.ResourceType.Document, + 200, + 1002, + "dummycache") ; + + LongConcurrentHistogram latency = new LongConcurrentHistogram(ClientTelemetryOptions.RequestLatencyMin, + ClientTelemetryOptions.RequestLatencyMax, + ClientTelemetryOptions.RequestLatencyPrecision); + latency.RecordValue(10l); + + cacheRefreshInfoSnapshot.TryAdd(crInfo, latency); + } + + ConcurrentDictionary requestInfoInfoSnapshot + = new ConcurrentDictionary(); + for (int i = 0; i < expectedRequestInfoSize; i++) + { + RequestInfo reqInfo = new RequestInfo + { + Uri = "https://dummyuri.com", + DatabaseName = "databaseName" + i, + ContainerName = "containerName" + i, + Operation = Documents.OperationType.Read.ToString(), + Resource = Documents.ResourceType.Document.ToString(), + StatusCode = 200, + SubStatusCode = 0 + }; + + LongConcurrentHistogram latency = new LongConcurrentHistogram(ClientTelemetryOptions.RequestLatencyMin, + ClientTelemetryOptions.RequestLatencyMax, + ClientTelemetryOptions.RequestLatencyPrecision); + latency.RecordValue(10l); + + requestInfoInfoSnapshot.TryAdd(reqInfo, latency); + } + + await processor.ProcessAndSendAsync( + clientTelemetryProperties, + operationInfoSnapshot, + cacheRefreshInfoSnapshot, + requestInfoInfoSnapshot, + new CancellationToken()); + + Assert.AreEqual(expectedOperationInfoSize, actualOperationInfoSize, "Operation Info is not correct"); + Assert.AreEqual(expectedCacheRefreshInfoSize, actualCacheRefreshInfoSize, "Cache Refresh Info is not correct"); + Assert.AreEqual(expectedRequestInfoSize, actualRequestInfoSize, "Request Info is not correct"); + } + + [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/Tracing/TraceTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Tracing/TraceTests.cs index f747d35d22..ff27842308 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Tracing/TraceTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Tracing/TraceTests.cs @@ -125,6 +125,8 @@ public void ValidateStoreResultSerialization() storeResultProperties.Remove(nameof(storeResult.Target.Exception)); storeResultProperties.Add("transportRequestTimeline"); storeResultProperties.Remove(nameof(storeResult.Target.TransportRequestStats)); + storeResultProperties.Add("ReplicaHealthStatuses"); + storeResultProperties.Remove(nameof(storeResult.Target.ReplicaHealthStatuses)); foreach (string key in jsonPropertyNames) { diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/ValidationHelpersTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/ValidationHelpersTests.cs index 2c9db33cec..dbfc45eb36 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/ValidationHelpersTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/ValidationHelpersTests.cs @@ -4,6 +4,8 @@ namespace Microsoft.Azure.Cosmos.Tests { + using System; + using System.Collections.Generic; using System.Data; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -11,62 +13,72 @@ namespace Microsoft.Azure.Cosmos.Tests public class ValidationHelpersTest { [TestMethod] - [DataRow(true, ConsistencyLevel.Eventual, ConsistencyLevel.Strong)] - [DataRow(true, ConsistencyLevel.ConsistentPrefix, ConsistencyLevel.Strong)] - [DataRow(false, ConsistencyLevel.Eventual, ConsistencyLevel.BoundedStaleness)] - [DataRow(false, ConsistencyLevel.ConsistentPrefix, ConsistencyLevel.BoundedStaleness)] - [DataRow(false, ConsistencyLevel.Session, ConsistencyLevel.Strong)] - [DataRow(false, ConsistencyLevel.BoundedStaleness, ConsistencyLevel.Strong)] - public void TestIsValidConsistencyLevelOverwrite(bool isValidConsistencyLevelOverwrite, - ConsistencyLevel backendConsistencyLevel, - ConsistencyLevel desiredConsistencyLevel) + [DataRow(true)] + [DataRow(false)] + public void TestIsValidConsistencyLevelOverwrite_AllCombinations( + bool isValidConsistencyLevelOverwrite) { - bool result = ValidationHelpers.IsValidConsistencyLevelOverwrite(backendConsistencyLevel, - desiredConsistencyLevel, - true, - Documents.OperationType.Read, - Documents.ResourceType.Document); + ConsistencyLevel[] allConsistencies = Enum.GetValues(); + + // All overrides when target is 'Strong' are VALID + ConsistencyLevel desiredConsistencyLevel = ConsistencyLevel.Strong; + foreach (ConsistencyLevel backendConsistencyLevel in allConsistencies) + { + if (backendConsistencyLevel == desiredConsistencyLevel) + { + continue; + } + + foreach (KeyValuePair entry in ValidationHelpersTest.GetPerOperationExpectations()) + { + bool result = ValidationHelpers.IsValidConsistencyLevelOverwrite(backendConsistencyLevel, + desiredConsistencyLevel, + isValidConsistencyLevelOverwrite, + (Documents.OperationType)entry.Key, + Documents.ResourceType.Document); - Assert.AreEqual(isValidConsistencyLevelOverwrite, result); + Assert.AreEqual(isValidConsistencyLevelOverwrite && entry.Value, result, + $"({isValidConsistencyLevelOverwrite}, {backendConsistencyLevel}, {desiredConsistencyLevel}) ({entry.Key}, {entry.Value})"); + } + } } [TestMethod] - [DataRow(false, ConsistencyLevel.Eventual, ConsistencyLevel.Strong)] - [DataRow(false, ConsistencyLevel.ConsistentPrefix, ConsistencyLevel.Strong)] - public void TestIsValidConsistencyLevelOverwrite_OnlyWhenSpecifyingExplicitOverwrite(bool isValidConsistencyLevelOverwrite, + [DataRow(ConsistencyLevel.Eventual, ConsistencyLevel.BoundedStaleness)] + [DataRow(ConsistencyLevel.ConsistentPrefix, ConsistencyLevel.BoundedStaleness)] + [DataRow(ConsistencyLevel.Session, ConsistencyLevel.BoundedStaleness)] + public void TestIsValidConsistencyLevelOverwrite_BoundedPromotionsRejected( ConsistencyLevel backendConsistencyLevel, ConsistencyLevel desiredConsistencyLevel) { - bool result = ValidationHelpers.IsValidConsistencyLevelOverwrite(backendConsistencyLevel, - desiredConsistencyLevel, - false, - Documents.OperationType.Read, - Documents.ResourceType.Document); + foreach (KeyValuePair entry in ValidationHelpersTest.GetPerOperationExpectations()) + { + bool result = ValidationHelpers.IsValidConsistencyLevelOverwrite(backendConsistencyLevel, + desiredConsistencyLevel, + true, + (Documents.OperationType)entry.Key, + Documents.ResourceType.Document); - Assert.AreEqual(isValidConsistencyLevelOverwrite, result); + Assert.AreEqual(false, result, + $"({backendConsistencyLevel}, {desiredConsistencyLevel}) ({entry.Key}, {entry.Value})"); + } } - [TestMethod] - [DataRow(true, ConsistencyLevel.Eventual, ConsistencyLevel.Strong, Documents.OperationType.Read)] - [DataRow(true, ConsistencyLevel.Eventual, ConsistencyLevel.Strong, Documents.OperationType.ReadFeed)] - [DataRow(true, ConsistencyLevel.ConsistentPrefix, ConsistencyLevel.Strong, Documents.OperationType.Query)] - [DataRow(true, ConsistencyLevel.ConsistentPrefix, ConsistencyLevel.Strong, Documents.OperationType.SqlQuery)] - [DataRow(false, ConsistencyLevel.Eventual, ConsistencyLevel.Strong, Documents.OperationType.QueryPlan)] - [DataRow(false, ConsistencyLevel.ConsistentPrefix, ConsistencyLevel.Strong, Documents.OperationType.Create)] - [DataRow(false, ConsistencyLevel.ConsistentPrefix, ConsistencyLevel.Strong, Documents.OperationType.Batch)] - public void TestIsValidConsistencyLevelOverwrite_OnlyAllowedForCertainOperationTypes( - bool isValidConsistencyLevelOverwrite, - ConsistencyLevel backendConsistencyLevel, - ConsistencyLevel desiredConsistencyLevel, - dynamic operationType) + private static Dictionary GetPerOperationExpectations() { - bool result = ValidationHelpers.IsValidConsistencyLevelOverwrite(backendConsistencyLevel, - desiredConsistencyLevel, - true, - (Documents.OperationType) operationType, - Documents.ResourceType.Document); + Dictionary perOperationOverride = new Dictionary(); + + foreach (Documents.OperationType operationType in Enum.GetValues()) + { + perOperationOverride.Add( + operationType, + Documents.OperationTypeExtensions.IsReadOperation(operationType) + && operationType != Documents.OperationType.Head + && operationType != Documents.OperationType.HeadFeed + && operationType != Documents.OperationType.QueryPlan); + } - Assert.AreEqual(isValidConsistencyLevelOverwrite, result); + return perOperationOverride; } } } \ No newline at end of file diff --git a/changelog.md b/changelog.md index aa2aaad67d..a8a156b922 100644 --- a/changelog.md +++ b/changelog.md @@ -13,6 +13,19 @@ 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.32.2](https://www.nuget.org/packages/Microsoft.Azure.Cosmos/3.32.2) - 2023-03-10 +### [3.32.2-preview](https://www.nuget.org/packages/Microsoft.Azure.Cosmos/3.32.2-preview) - 2023-03-10 + +#### Fixed +- [#3713](https://github.com/Azure/azure-cosmos-dotnet-v3/pull/3713) CosmosNullReferenceException: Refactors CosmosNullReferenceException to pass along InnerException property on parent NullReferenceException. +- [#3749](https://github.com/Azure/azure-cosmos-dotnet-v3/pull/3749) Query: Fixes regression from LINQ custom serializer fix. Introduced in 3.32.0 PR [3749](https://github.com/Azure/azure-cosmos-dotnet-v3/pull/3749) + +### [3.32.1](https://www.nuget.org/packages/Microsoft.Azure.Cosmos/3.32.1) - 2023-03-01 +### [3.32.1-preview](https://www.nuget.org/packages/Microsoft.Azure.Cosmos/3.32.1-preview) - 2023-03-01 + +#### Fixed +- [#3732](https://github.com/Azure/azure-cosmos-dotnet-v3/pull/3732) ReadMany: Fixes BadRequest when using Ids with single quotes + ### [3.32.0](https://www.nuget.org/packages/Microsoft.Azure.Cosmos/3.32.0) - 2023-02-03 #### Fixed - [#3466](https://github.com/Azure/azure-cosmos-dotnet-v3/pull/3466) ClientRetryPolicy: Fixes behavior to Meta-data write operations in multimaster accounts diff --git a/templates/static-tools.yml b/templates/static-tools.yml index b3ce2b11de..fb7b375586 100644 --- a/templates/static-tools.yml +++ b/templates/static-tools.yml @@ -23,30 +23,16 @@ jobs: arguments: '-p:Optimize=true -p:IsPreview=true --configuration Release' versioningScheme: OFF - - task: securedevelopmentteam.vss-secure-development-tools.build-task-binskim.BinSkim@3 + - task: securedevelopmentteam.vss-secure-development-tools.build-task-binskim.BinSkim@4 displayName: 'BinSkim' inputs: - toolVersion: Latest - InputType: Basic - Function: analyze - AnalyzeTarget: $(Build.SourcesDirectory)\Microsoft.Azure.Cosmos\src\bin\Release\netstandard2.0\Microsoft.Azure.Cosmos.Client.dll - AnalyzeConfigPath: default + AnalyzeTargetGlob: $(Build.SourcesDirectory)\Microsoft.Azure.Cosmos\src\bin\Release\netstandard2.0\Microsoft.Azure.Cosmos.Client.dll AnalyzeRecurse: true AnalyzeVerbose: true AnalyzeHashes: false AnalyzeStatistics: false AnalyzeEnvironment: false - #Analyze source code for type of content and target types to help determine which tools to run - - task: securedevelopmentteam.vss-secure-development-tools.build-task-autoapplicability.AutoApplicability@1 - displayName: 'AutoApplicability' - inputs: - VerboseWriter: true - ExternalRelease: true - InternalRelease: true - IsService: true - IsSoftware: true - # Analyze source and build output text files for credentials - task: securedevelopmentteam.vss-secure-development-tools.build-task-credscan.CredScan@3 displayName: 'CredScan' @@ -58,22 +44,19 @@ jobs: verboseOutput: false # Scan text elements including code, code comments, and content/web pages, for sensitive terms based on legal, cultural, or geopolitical reasons - - task: securedevelopmentteam.vss-secure-development-tools.build-task-policheck.PoliCheck@1 + - task: securedevelopmentteam.vss-secure-development-tools.build-task-policheck.PoliCheck@2 displayName: 'PoliCheck' inputs: targetType: F + optionsFC: 0 # AntiMalware scan - - task: securedevelopmentteam.vss-secure-development-tools.build-task-antimalware.AntiMalware@3 + - task: securedevelopmentteam.vss-secure-development-tools.build-task-antimalware.AntiMalware@4 displayName: 'AntiMalware' continueOnError: true # signature refresh failing resulting in tasks failures inputs: EnableServices: true - # Run checks for recently discovered vulnerabilities which are not yet incorporated to another tool - - task: securedevelopmentteam.vss-secure-development-tools.build-task-vulnerabilityassessment.VulnerabilityAssessment@0 - displayName: 'Vulnerability Assessment' - - task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0 displayName: 'Component Governance Detection' #https://docs.opensource.microsoft.com/tools/cg.html inputs: @@ -81,11 +64,16 @@ jobs: failOnAlert: true # Publish Analysis Results (position after all tools ran) - - task: securedevelopmentteam.vss-secure-development-tools.build-task-publishsecurityanalysislogs.PublishSecurityAnalysisLogs@2 + - task: securedevelopmentteam.vss-secure-development-tools.build-task-publishsecurityanalysislogs.PublishSecurityAnalysisLogs@3 displayName: 'Publish Security Analysis Logs' # The Post-Analysis build task will analyze the log files produced by the tools, and introduce a build break - - task: securedevelopmentteam.vss-secure-development-tools.build-task-postanalysis.PostAnalysis@1 + - task: securedevelopmentteam.vss-secure-development-tools.build-task-postanalysis.PostAnalysis@2 displayName: 'Post Analysis' inputs: - AllTools: true + GdnBreakFast: true + GdnBreakAllTools: false + GdnBreakGdnToolCredScan: true + GdnBreakGdnToolBinSkim: true + GdnBreakGdnToolPoliCheck: true + GdnBreakGdnToolPoliCheckSeverity: Error