public override Task <CosmosResponseMessage> SendAsync( CosmosRequestMessage request, CancellationToken cancellationToken) { if (request == null) { throw new ArgumentNullException(nameof(request)); } RequestOptions promotedRequestOptions = request.RequestOptions; if (promotedRequestOptions != null) { // Fill request options promotedRequestOptions.FillRequestOptions(request); // Validate the request consistency compatibility with account consistency // Type based access context for requested consistency preferred for performance Cosmos.ConsistencyLevel?consistencyLevel = null; if (promotedRequestOptions is ItemRequestOptions) { consistencyLevel = (promotedRequestOptions as ItemRequestOptions).ConsistencyLevel; } else if (promotedRequestOptions is QueryRequestOptions) { consistencyLevel = (promotedRequestOptions as QueryRequestOptions).ConsistencyLevel; } else if (promotedRequestOptions is StoredProcedureRequestOptions) { consistencyLevel = (promotedRequestOptions as StoredProcedureRequestOptions).ConsistencyLevel; } if (consistencyLevel.HasValue) { if (!ValidationHelpers.ValidateConsistencyLevel(this.client.AccountConsistencyLevel, consistencyLevel.Value)) { throw new ArgumentException(string.Format( CultureInfo.CurrentUICulture, RMResources.InvalidConsistencyLevel, consistencyLevel.Value.ToString(), this.client.AccountConsistencyLevel)); } } } return(this.client.DocumentClient.EnsureValidClientAsync() .ContinueWith(task => request.AssertPartitioningDetailsAsync(this.client, cancellationToken)) .ContinueWith(task => { if (task.IsFaulted) { throw task.Exception; } this.FillMultiMasterContext(request); return base.SendAsync(request, cancellationToken); }) .Unwrap()); }
public static CosmosClient CreateMockCosmosClient( Action <CosmosClientBuilder> customizeClientBuilder = null, Cosmos.ConsistencyLevel?accountConsistencyLevel = null) { DocumentClient documentClient = accountConsistencyLevel.HasValue ? new MockDocumentClient(accountConsistencyLevel.Value) : new MockDocumentClient(); CosmosClientBuilder cosmosClientBuilder = new CosmosClientBuilder("http://localhost", MockCosmosUtil.RandomInvalidCorrectlyFormatedAuthKey); customizeClientBuilder?.Invoke(cosmosClientBuilder); return(cosmosClientBuilder.Build(documentClient)); }
private static string GetConsistencyString(Cosmos.ConsistencyLevel?consistency) { if (consistency == null) { return(null); } return(consistency switch { Cosmos.ConsistencyLevel.Strong => "STRONG", Cosmos.ConsistencyLevel.Session => "SESSION", Cosmos.ConsistencyLevel.Eventual => "EVENTUAL", Cosmos.ConsistencyLevel.ConsistentPrefix => "CONSISTENTPREFIX", Cosmos.ConsistencyLevel.BoundedStaleness => "BOUNDEDSTALENESS", _ => consistency.ToString().ToUpper(), });
internal OperationInfo(string regionsContacted, long?responseSizeInBytes, Cosmos.ConsistencyLevel?consistency, string databaseName, string containerName, OperationType?operation, ResourceType?resource, int?statusCode) { this.RegionsContacted = regionsContacted; this.ResponseSizeInBytes = responseSizeInBytes; if (responseSizeInBytes != null) { this.GreaterThan1Kb = responseSizeInBytes > ClientTelemetryOptions.OneKbToBytes; } this.Consistency = OperationInfo.GetConsistencyString(consistency); this.DatabaseName = databaseName; this.ContainerName = containerName; this.Operation = operation?.ToOperationTypeString(); this.Resource = resource?.ToResourceTypeString(); this.StatusCode = statusCode; }
private async Task ValidateAndSetConsistencyLevelAsync(RequestMessage requestMessage) { // Validate the request consistency compatibility with account consistency // Type based access context for requested consistency preferred for performance Cosmos.ConsistencyLevel?consistencyLevel = null; RequestOptions promotedRequestOptions = requestMessage.RequestOptions; if (promotedRequestOptions != null && promotedRequestOptions.BaseConsistencyLevel.HasValue) { consistencyLevel = promotedRequestOptions.BaseConsistencyLevel; } else if (this.RequestedClientConsistencyLevel.HasValue) { consistencyLevel = this.RequestedClientConsistencyLevel; } if (consistencyLevel.HasValue) { if (!this.AccountConsistencyLevel.HasValue) { this.AccountConsistencyLevel = await this.client.GetAccountConsistencyLevelAsync(); } if (ValidationHelpers.IsValidConsistencyLevelOverwrite(this.AccountConsistencyLevel.Value, consistencyLevel.Value)) { // ConsistencyLevel compatibility with back-end configuration will be done by RequestInvokeHandler requestMessage.Headers.Add(HttpConstants.HttpHeaders.ConsistencyLevel, consistencyLevel.Value.ToString()); } else { throw new ArgumentException(string.Format( CultureInfo.CurrentUICulture, RMResources.InvalidConsistencyLevel, consistencyLevel.Value.ToString(), this.AccountConsistencyLevel)); } } }
public static CosmosClient CreateMockCosmosClient( Action <CosmosClientBuilder> customizeClientBuilder = null, Cosmos.ConsistencyLevel?accountConsistencyLevel = null) { DocumentClient documentClient; if (accountConsistencyLevel.HasValue) { documentClient = new MockDocumentClient(accountConsistencyLevel.Value); } else { documentClient = new MockDocumentClient(); } CosmosClientBuilder cosmosClientBuilder = new CosmosClientBuilder("http://localhost", Guid.NewGuid().ToString()); if (customizeClientBuilder != null) { customizeClientBuilder(cosmosClientBuilder); } return(cosmosClientBuilder.Build(documentClient)); }
public async Task <INameValueCollection> CreateCommonHeadersAsync(FeedOptions feedOptions) { INameValueCollection requestHeaders = new DictionaryNameValueCollection(); Cosmos.ConsistencyLevel defaultConsistencyLevel = (Cosmos.ConsistencyLevel) await this.Client.GetDefaultConsistencyLevelAsync(); Cosmos.ConsistencyLevel?desiredConsistencyLevel = (Cosmos.ConsistencyLevel?) await this.Client.GetDesiredConsistencyLevelAsync(); if (!string.IsNullOrEmpty(feedOptions.SessionToken) && !ReplicatedResourceClient.IsReadingFromMaster(this.ResourceTypeEnum, OperationType.ReadFeed)) { if (defaultConsistencyLevel == Cosmos.ConsistencyLevel.Session || (desiredConsistencyLevel.HasValue && desiredConsistencyLevel.Value == Cosmos.ConsistencyLevel.Session)) { // Query across partitions is not supported today. Master resources (for e.g., database) // can span across partitions, whereas server resources (viz: collection, document and attachment) // don't span across partitions. Hence, session token returned by one partition should not be used // when quering resources from another partition. // Since master resources can span across partitions, don't send session token to the backend. // As master resources are sync replicated, we should always get consistent query result for master resources, // irrespective of the chosen replica. // For server resources, which don't span partitions, specify the session token // for correct replica to be chosen for servicing the query result. requestHeaders[HttpConstants.HttpHeaders.SessionToken] = feedOptions.SessionToken; } } requestHeaders[HttpConstants.HttpHeaders.Continuation] = feedOptions.RequestContinuationToken; requestHeaders[HttpConstants.HttpHeaders.IsQuery] = bool.TrueString; // Flow the pageSize only when we are not doing client eval if (feedOptions.MaxItemCount.HasValue) { requestHeaders[HttpConstants.HttpHeaders.PageSize] = feedOptions.MaxItemCount.ToString(); } requestHeaders[HttpConstants.HttpHeaders.EnableCrossPartitionQuery] = feedOptions.EnableCrossPartitionQuery.ToString(); if (feedOptions.MaxDegreeOfParallelism != 0) { requestHeaders[HttpConstants.HttpHeaders.ParallelizeCrossPartitionQuery] = bool.TrueString; } if (this.feedOptions.EnableScanInQuery != null) { requestHeaders[HttpConstants.HttpHeaders.EnableScanInQuery] = this.feedOptions.EnableScanInQuery.ToString(); } if (this.feedOptions.EmitVerboseTracesInQuery != null) { requestHeaders[HttpConstants.HttpHeaders.EmitVerboseTracesInQuery] = this.feedOptions.EmitVerboseTracesInQuery.ToString(); } if (this.feedOptions.EnableLowPrecisionOrderBy != null) { requestHeaders[HttpConstants.HttpHeaders.EnableLowPrecisionOrderBy] = this.feedOptions.EnableLowPrecisionOrderBy.ToString(); } if (!string.IsNullOrEmpty(this.feedOptions.FilterBySchemaResourceId)) { requestHeaders[HttpConstants.HttpHeaders.FilterBySchemaResourceId] = this.feedOptions.FilterBySchemaResourceId; } if (this.feedOptions.ResponseContinuationTokenLimitInKb != null) { requestHeaders[HttpConstants.HttpHeaders.ResponseContinuationTokenLimitInKB] = this.feedOptions.ResponseContinuationTokenLimitInKb.ToString(); } if (this.feedOptions.ConsistencyLevel.HasValue) { await this.Client.EnsureValidOverwriteAsync((Documents.ConsistencyLevel) feedOptions.ConsistencyLevel.Value); requestHeaders.Set(HttpConstants.HttpHeaders.ConsistencyLevel, this.feedOptions.ConsistencyLevel.Value.ToString()); } else if (desiredConsistencyLevel.HasValue) { requestHeaders.Set(HttpConstants.HttpHeaders.ConsistencyLevel, desiredConsistencyLevel.Value.ToString()); } if (this.feedOptions.EnumerationDirection.HasValue) { requestHeaders.Set(HttpConstants.HttpHeaders.EnumerationDirection, this.feedOptions.EnumerationDirection.Value.ToString()); } if (this.feedOptions.ReadFeedKeyType.HasValue) { requestHeaders.Set(HttpConstants.HttpHeaders.ReadFeedKeyType, this.feedOptions.ReadFeedKeyType.Value.ToString()); } if (this.feedOptions.StartId != null) { requestHeaders.Set(HttpConstants.HttpHeaders.StartId, this.feedOptions.StartId); } if (this.feedOptions.EndId != null) { requestHeaders.Set(HttpConstants.HttpHeaders.EndId, this.feedOptions.EndId); } if (this.feedOptions.StartEpk != null) { requestHeaders.Set(HttpConstants.HttpHeaders.StartEpk, this.feedOptions.StartEpk); } if (this.feedOptions.EndEpk != null) { requestHeaders.Set(HttpConstants.HttpHeaders.EndEpk, this.feedOptions.EndEpk); } if (this.feedOptions.PopulateQueryMetrics) { requestHeaders[HttpConstants.HttpHeaders.PopulateQueryMetrics] = bool.TrueString; } if (this.feedOptions.ForceQueryScan) { requestHeaders[HttpConstants.HttpHeaders.ForceQueryScan] = bool.TrueString; } if (this.feedOptions.MergeStaticId != null) { requestHeaders.Set(HttpConstants.HttpHeaders.MergeStaticId, this.feedOptions.MergeStaticId); } if (this.feedOptions.CosmosSerializationFormatOptions != null) { requestHeaders[HttpConstants.HttpHeaders.ContentSerializationFormat] = this.feedOptions.CosmosSerializationFormatOptions.ContentSerializationFormat; } else if (this.feedOptions.ContentSerializationFormat.HasValue) { requestHeaders[HttpConstants.HttpHeaders.ContentSerializationFormat] = this.feedOptions.ContentSerializationFormat.Value.ToString(); } return(requestHeaders); }
public RequestInvokerHandler(CosmosClient client) { this.client = client; this.RequestedClientConsistencyLevel = this.client.ClientOptions.ConsistencyLevel; }