From 8ae783481a0bc3050e868d10270fd3de622c1c2a Mon Sep 17 00:00:00 2001 From: Jake Willey Date: Thu, 30 Apr 2020 09:37:59 -0700 Subject: [PATCH 1/5] Expose CosmosResponseFactory so users can create instance of the response types. --- Microsoft.Azure.Cosmos/src/CosmosClient.cs | 23 +- .../src/Linq/CosmosLinqQuery.cs | 6 +- .../src/Linq/CosmosLinqQueryProvider.cs | 4 +- .../src/Resource/ClientContextCore.cs | 8 +- .../src/Resource/Conflict/ConflictsCore.cs | 4 +- .../Resource/Container/ContainerCore.Items.cs | 20 +- .../src/Resource/Container/ContainerCore.cs | 18 +- .../src/Resource/CosmosClientContext.cs | 2 +- .../src/Resource/CosmosResponseFactory.cs | 265 ++---------------- .../src/Resource/CosmosResponseFactoryCore.cs | 262 +++++++++++++++++ .../Resource/CosmosResponseFactoryInternal.cs | 54 ++++ .../src/Resource/Database/DatabaseCore.cs | 52 ++-- .../src/Resource/Offer/CosmosOffers.cs | 4 +- .../src/Resource/Permission/PermissionCore.cs | 18 +- .../src/Resource/Scripts/ScriptsCore.cs | 24 +- .../src/Resource/User/UserCore.cs | 30 +- .../CosmosJsonSeriliazerUnitTests.cs | 18 +- .../DotNetSDKAPI.json | 31 ++ 18 files changed, 492 insertions(+), 351 deletions(-) create mode 100644 Microsoft.Azure.Cosmos/src/Resource/CosmosResponseFactoryCore.cs create mode 100644 Microsoft.Azure.Cosmos/src/Resource/CosmosResponseFactoryInternal.cs diff --git a/Microsoft.Azure.Cosmos/src/CosmosClient.cs b/Microsoft.Azure.Cosmos/src/CosmosClient.cs index b4f7eabe7f..44dd665115 100644 --- a/Microsoft.Azure.Cosmos/src/CosmosClient.cs +++ b/Microsoft.Azure.Cosmos/src/CosmosClient.cs @@ -256,6 +256,11 @@ internal CosmosClient( /// public virtual CosmosClientOptions ClientOptions => this.ClientContext.ClientOptions; + /// + /// The response factory used to initialize CosmosClient response types + /// + public virtual CosmosResponseFactory ResponseFactory => this.ClientContext.ResponseFactory; + /// /// Gets the endpoint Uri for the Azure Cosmos DB service. /// @@ -474,7 +479,7 @@ virtual Task CreateDatabaseIfNotExistsAsync( if (readResponse.StatusCode != HttpStatusCode.NotFound) { - return await this.ClientContext.ResponseFactory.CreateDatabaseResponseAsync(database, Task.FromResult(readResponse)); + return this.ClientContext.ResponseFactory.CreateDatabaseResponse(database, readResponse); } ResponseMessage createResponse = await this.CreateDatabaseStreamAsync(databaseProperties, throughputProperties, requestOptions, cancellationToken); @@ -483,7 +488,7 @@ virtual Task CreateDatabaseIfNotExistsAsync( createResponse.DiagnosticsContext.AddDiagnosticsInternal(readResponse.DiagnosticsContext); if (createResponse.StatusCode != HttpStatusCode.Conflict) { - return await this.ClientContext.ResponseFactory.CreateDatabaseResponseAsync(this.GetDatabase(databaseProperties.Id), Task.FromResult(createResponse)); + return this.ClientContext.ResponseFactory.CreateDatabaseResponse(this.GetDatabase(databaseProperties.Id), createResponse); } // This second Read is to handle the race condition when 2 or more threads have Read the database and only one succeeds with Create @@ -492,7 +497,7 @@ virtual Task CreateDatabaseIfNotExistsAsync( requestOptions: requestOptions, cancellationToken: cancellationToken); readResponseAfterConflict.DiagnosticsContext.AddDiagnosticsInternal(readResponse.DiagnosticsContext); - return await this.ClientContext.ResponseFactory.CreateDatabaseResponseAsync(this.GetDatabase(databaseProperties.Id), Task.FromResult(readResponseAfterConflict)); + return this.ClientContext.ResponseFactory.CreateDatabaseResponse(this.GetDatabase(databaseProperties.Id), readResponseAfterConflict); }); } @@ -840,13 +845,13 @@ internal virtual Task CreateDatabaseStreamAsync( cancellationToken)); } - internal Task CreateDatabaseAsync( + internal async Task CreateDatabaseAsync( DatabaseProperties databaseProperties, ThroughputProperties throughputProperties, RequestOptions requestOptions = null, CancellationToken cancellationToken = default(CancellationToken)) { - Task response = this.ClientContext.ProcessResourceOperationStreamAsync( + ResponseMessage response = await this.ClientContext.ProcessResourceOperationStreamAsync( resourceUri: this.DatabaseRootUri, resourceType: ResourceType.Database, operationType: OperationType.Create, @@ -858,22 +863,22 @@ internal Task CreateDatabaseAsync( diagnosticsContext: null, cancellationToken: cancellationToken); - return this.ClientContext.ResponseFactory.CreateDatabaseResponseAsync(this.GetDatabase(databaseProperties.Id), response); + return this.ClientContext.ResponseFactory.CreateDatabaseResponse(this.GetDatabase(databaseProperties.Id), response); } - internal Task CreateDatabaseAsync( + internal async Task CreateDatabaseAsync( DatabaseProperties databaseProperties, int? throughput = null, RequestOptions requestOptions = null, CancellationToken cancellationToken = default(CancellationToken)) { - Task response = this.CreateDatabaseStreamInternalAsync( + ResponseMessage response = await this.CreateDatabaseStreamInternalAsync( streamPayload: this.ClientContext.SerializerCore.ToStream(databaseProperties), throughput: throughput, requestOptions: requestOptions, cancellationToken: cancellationToken); - return this.ClientContext.ResponseFactory.CreateDatabaseResponseAsync(this.GetDatabase(databaseProperties.Id), response); + return this.ClientContext.ResponseFactory.CreateDatabaseResponse(this.GetDatabase(databaseProperties.Id), response); } private Task CreateDatabaseStreamInternalAsync( diff --git a/Microsoft.Azure.Cosmos/src/Linq/CosmosLinqQuery.cs b/Microsoft.Azure.Cosmos/src/Linq/CosmosLinqQuery.cs index f634d01a08..d45f2c3934 100644 --- a/Microsoft.Azure.Cosmos/src/Linq/CosmosLinqQuery.cs +++ b/Microsoft.Azure.Cosmos/src/Linq/CosmosLinqQuery.cs @@ -27,7 +27,7 @@ internal sealed class CosmosLinqQuery : IDocumentQuery, IOrderedQueryable< private readonly ContainerInternal container; private readonly CosmosQueryClientCore queryClient; - private readonly CosmosResponseFactory responseFactory; + private readonly CosmosResponseFactoryInternal responseFactory; private readonly QueryRequestOptions cosmosQueryRequestOptions; private readonly bool allowSynchronousQueryExecution = false; private readonly string continuationToken; @@ -35,7 +35,7 @@ internal sealed class CosmosLinqQuery : IDocumentQuery, IOrderedQueryable< public CosmosLinqQuery( ContainerInternal container, - CosmosResponseFactory responseFactory, + CosmosResponseFactoryInternal responseFactory, CosmosQueryClientCore queryClient, string continuationToken, QueryRequestOptions cosmosQueryRequestOptions, @@ -66,7 +66,7 @@ public CosmosLinqQuery( public CosmosLinqQuery( ContainerInternal container, - CosmosResponseFactory responseFactory, + CosmosResponseFactoryInternal responseFactory, CosmosQueryClientCore queryClient, string continuationToken, QueryRequestOptions cosmosQueryRequestOptions, diff --git a/Microsoft.Azure.Cosmos/src/Linq/CosmosLinqQueryProvider.cs b/Microsoft.Azure.Cosmos/src/Linq/CosmosLinqQueryProvider.cs index 91fc82f733..3bf8b8cca7 100644 --- a/Microsoft.Azure.Cosmos/src/Linq/CosmosLinqQueryProvider.cs +++ b/Microsoft.Azure.Cosmos/src/Linq/CosmosLinqQueryProvider.cs @@ -18,7 +18,7 @@ internal sealed class CosmosLinqQueryProvider : IQueryProvider { private readonly ContainerInternal container; private readonly CosmosQueryClientCore queryClient; - private readonly CosmosResponseFactory responseFactory; + private readonly CosmosResponseFactoryInternal responseFactory; private readonly QueryRequestOptions cosmosQueryRequestOptions; private readonly bool allowSynchronousQueryExecution; private readonly Action onExecuteScalarQueryCallback; @@ -27,7 +27,7 @@ internal sealed class CosmosLinqQueryProvider : IQueryProvider public CosmosLinqQueryProvider( ContainerInternal container, - CosmosResponseFactory responseFactory, + CosmosResponseFactoryInternal responseFactory, CosmosQueryClientCore queryClient, string continuationToken, QueryRequestOptions cosmosQueryRequestOptions, diff --git a/Microsoft.Azure.Cosmos/src/Resource/ClientContextCore.cs b/Microsoft.Azure.Cosmos/src/Resource/ClientContextCore.cs index 723c5c27d4..20b4568a4d 100644 --- a/Microsoft.Azure.Cosmos/src/Resource/ClientContextCore.cs +++ b/Microsoft.Azure.Cosmos/src/Resource/ClientContextCore.cs @@ -23,7 +23,7 @@ internal class ClientContextCore : CosmosClientContext private readonly CosmosClient client; private readonly DocumentClient documentClient; private readonly CosmosSerializerCore serializerCore; - private readonly CosmosResponseFactory responseFactory; + private readonly CosmosResponseFactoryInternal responseFactory; private readonly RequestInvokerHandler requestHandler; private readonly CosmosClientOptions clientOptions; private readonly string userAgent; @@ -34,7 +34,7 @@ private ClientContextCore( CosmosClient client, CosmosClientOptions clientOptions, CosmosSerializerCore serializerCore, - CosmosResponseFactory cosmosResponseFactory, + CosmosResponseFactoryInternal cosmosResponseFactory, RequestInvokerHandler requestHandler, DocumentClient documentClient, string userAgent, @@ -115,7 +115,7 @@ internal static CosmosClientContext Create( clientOptions.Serializer, clientOptions.SerializerOptions); - CosmosResponseFactory responseFactory = new CosmosResponseFactory(serializerCore); + CosmosResponseFactoryInternal responseFactory = new CosmosResponseFactoryCore(serializerCore); return new ClientContextCore( client: cosmosClient, @@ -138,7 +138,7 @@ internal static CosmosClientContext Create( internal override CosmosSerializerCore SerializerCore => this.ThrowIfDisposed(this.serializerCore); - internal override CosmosResponseFactory ResponseFactory => this.ThrowIfDisposed(this.responseFactory); + internal override CosmosResponseFactoryInternal ResponseFactory => this.ThrowIfDisposed(this.responseFactory); internal override RequestInvokerHandler RequestHandler => this.ThrowIfDisposed(this.requestHandler); diff --git a/Microsoft.Azure.Cosmos/src/Resource/Conflict/ConflictsCore.cs b/Microsoft.Azure.Cosmos/src/Resource/Conflict/ConflictsCore.cs index 3d5027b528..4ec57233a8 100644 --- a/Microsoft.Azure.Cosmos/src/Resource/Conflict/ConflictsCore.cs +++ b/Microsoft.Azure.Cosmos/src/Resource/Conflict/ConflictsCore.cs @@ -161,7 +161,7 @@ public override async Task> ReadCurrentAsync( uriPathSegment: Paths.DocumentsPathSegment, id: cosmosConflict.SourceResourceId); - Task response = this.clientContext.ProcessResourceOperationStreamAsync( + ResponseMessage response = await this.clientContext.ProcessResourceOperationStreamAsync( resourceUri: itemLink, resourceType: ResourceType.Document, operationType: OperationType.Read, @@ -173,7 +173,7 @@ public override async Task> ReadCurrentAsync( diagnosticsContext: null, cancellationToken: cancellationToken); - return await this.clientContext.ResponseFactory.CreateItemResponseAsync(response); + return this.clientContext.ResponseFactory.CreateItemResponse(response); } public override T ReadConflictContent(ConflictProperties cosmosConflict) diff --git a/Microsoft.Azure.Cosmos/src/Resource/Container/ContainerCore.Items.cs b/Microsoft.Azure.Cosmos/src/Resource/Container/ContainerCore.Items.cs index a48fe901d3..63d10ad279 100644 --- a/Microsoft.Azure.Cosmos/src/Resource/Container/ContainerCore.Items.cs +++ b/Microsoft.Azure.Cosmos/src/Resource/Container/ContainerCore.Items.cs @@ -72,7 +72,7 @@ public override async Task> CreateItemAsync( CosmosDiagnosticsContext diagnosticsContext = CosmosDiagnosticsContext.Create(requestOptions); using (diagnosticsContext.GetOverallScope()) { - Task response = this.ExtractPartitionKeyAndProcessItemStreamAsync( + ResponseMessage response = await this.ExtractPartitionKeyAndProcessItemStreamAsync( partitionKey: partitionKey, itemId: null, item: item, @@ -81,7 +81,7 @@ public override async Task> CreateItemAsync( diagnosticsContext: diagnosticsContext, cancellationToken: cancellationToken); - return await this.ClientContext.ResponseFactory.CreateItemResponseAsync(response); + return this.ClientContext.ResponseFactory.CreateItemResponse(response); } } @@ -114,7 +114,7 @@ public override async Task> ReadItemAsync( CosmosDiagnosticsContext diagnosticsContext = CosmosDiagnosticsContext.Create(requestOptions); using (diagnosticsContext.GetOverallScope()) { - Task response = this.ProcessItemStreamAsync( + ResponseMessage response = await this.ProcessItemStreamAsync( partitionKey: partitionKey, itemId: id, streamPayload: null, @@ -123,7 +123,7 @@ public override async Task> ReadItemAsync( diagnosticsContext: diagnosticsContext, cancellationToken: cancellationToken); - return await this.ClientContext.ResponseFactory.CreateItemResponseAsync(response); + return this.ClientContext.ResponseFactory.CreateItemResponse(response); } } @@ -161,7 +161,7 @@ public override async Task> UpsertItemAsync( CosmosDiagnosticsContext diagnosticsContext = CosmosDiagnosticsContext.Create(requestOptions); using (diagnosticsContext.GetOverallScope()) { - Task response = this.ExtractPartitionKeyAndProcessItemStreamAsync( + ResponseMessage response = await this.ExtractPartitionKeyAndProcessItemStreamAsync( partitionKey: partitionKey, itemId: null, item: item, @@ -170,7 +170,7 @@ public override async Task> UpsertItemAsync( diagnosticsContext: diagnosticsContext, cancellationToken: cancellationToken); - return await this.ClientContext.ResponseFactory.CreateItemResponseAsync(response); + return this.ClientContext.ResponseFactory.CreateItemResponse(response); } } @@ -215,7 +215,7 @@ public override async Task> ReplaceItemAsync( CosmosDiagnosticsContext diagnosticsContext = CosmosDiagnosticsContext.Create(requestOptions); using (diagnosticsContext.GetOverallScope()) { - Task response = this.ExtractPartitionKeyAndProcessItemStreamAsync( + ResponseMessage response = await this.ExtractPartitionKeyAndProcessItemStreamAsync( partitionKey: partitionKey, itemId: id, item: item, @@ -224,7 +224,7 @@ public override async Task> ReplaceItemAsync( diagnosticsContext: diagnosticsContext, cancellationToken: cancellationToken); - return await this.ClientContext.ResponseFactory.CreateItemResponseAsync(response); + return this.ClientContext.ResponseFactory.CreateItemResponse(response); } } @@ -257,7 +257,7 @@ public override async Task> DeleteItemAsync( CosmosDiagnosticsContext diagnosticsContext = CosmosDiagnosticsContext.Create(requestOptions); using (diagnosticsContext.GetOverallScope()) { - Task response = this.ProcessItemStreamAsync( + ResponseMessage response = await this.ProcessItemStreamAsync( partitionKey: partitionKey, itemId: id, streamPayload: null, @@ -266,7 +266,7 @@ public override async Task> DeleteItemAsync( diagnosticsContext: diagnosticsContext, cancellationToken: cancellationToken); - return await this.ClientContext.ResponseFactory.CreateItemResponseAsync(response); + return this.ClientContext.ResponseFactory.CreateItemResponse(response); } } diff --git a/Microsoft.Azure.Cosmos/src/Resource/Container/ContainerCore.cs b/Microsoft.Azure.Cosmos/src/Resource/Container/ContainerCore.cs index 5072297636..c0eb0fd725 100644 --- a/Microsoft.Azure.Cosmos/src/Resource/Container/ContainerCore.cs +++ b/Microsoft.Azure.Cosmos/src/Resource/Container/ContainerCore.cs @@ -60,18 +60,18 @@ protected ContainerCore( public override Scripts.Scripts Scripts { get; } - public override Task ReadContainerAsync( + public override async Task ReadContainerAsync( ContainerRequestOptions requestOptions = null, CancellationToken cancellationToken = default(CancellationToken)) { - Task response = this.ReadContainerStreamAsync( + ResponseMessage response = await this.ReadContainerStreamAsync( requestOptions: requestOptions, cancellationToken: cancellationToken); - return this.ClientContext.ResponseFactory.CreateContainerResponseAsync(this, response); + return this.ClientContext.ResponseFactory.CreateContainerResponse(this, response); } - public override Task ReplaceContainerAsync( + public override async Task ReplaceContainerAsync( ContainerProperties containerProperties, ContainerRequestOptions requestOptions = null, CancellationToken cancellationToken = default(CancellationToken)) @@ -82,23 +82,23 @@ public override Task ReplaceContainerAsync( } this.ClientContext.ValidateResource(containerProperties.Id); - Task response = this.ReplaceStreamInternalAsync( + ResponseMessage response = await this.ReplaceStreamInternalAsync( streamPayload: this.ClientContext.SerializerCore.ToStream(containerProperties), requestOptions: requestOptions, cancellationToken: cancellationToken); - return this.ClientContext.ResponseFactory.CreateContainerResponseAsync(this, response); + return this.ClientContext.ResponseFactory.CreateContainerResponse(this, response); } - public override Task DeleteContainerAsync( + public override async Task DeleteContainerAsync( ContainerRequestOptions requestOptions = null, CancellationToken cancellationToken = default(CancellationToken)) { - Task response = this.DeleteContainerStreamAsync( + ResponseMessage response = await this.DeleteContainerStreamAsync( requestOptions: requestOptions, cancellationToken: cancellationToken); - return this.ClientContext.ResponseFactory.CreateContainerResponseAsync(this, response); + return this.ClientContext.ResponseFactory.CreateContainerResponse(this, response); } public override async Task ReadThroughputAsync( diff --git a/Microsoft.Azure.Cosmos/src/Resource/CosmosClientContext.cs b/Microsoft.Azure.Cosmos/src/Resource/CosmosClientContext.cs index afedb75028..71d6251713 100644 --- a/Microsoft.Azure.Cosmos/src/Resource/CosmosClientContext.cs +++ b/Microsoft.Azure.Cosmos/src/Resource/CosmosClientContext.cs @@ -29,7 +29,7 @@ internal abstract class CosmosClientContext : IDisposable internal abstract CosmosSerializerCore SerializerCore { get; } - internal abstract CosmosResponseFactory ResponseFactory { get; } + internal abstract CosmosResponseFactoryInternal ResponseFactory { get; } internal abstract RequestInvokerHandler RequestHandler { get; } diff --git a/Microsoft.Azure.Cosmos/src/Resource/CosmosResponseFactory.cs b/Microsoft.Azure.Cosmos/src/Resource/CosmosResponseFactory.cs index 7d4d4a4f27..71c79ce2d7 100644 --- a/Microsoft.Azure.Cosmos/src/Resource/CosmosResponseFactory.cs +++ b/Microsoft.Azure.Cosmos/src/Resource/CosmosResponseFactory.cs @@ -9,248 +9,37 @@ namespace Microsoft.Azure.Cosmos using System.Threading.Tasks; using Microsoft.Azure.Cosmos.Scripts; - internal class CosmosResponseFactory + /// + /// This response factory converts response messages + /// to the corresponding type response. + /// + public abstract class CosmosResponseFactory { /// - /// This is used for all meta data types + /// Creates a FeedResponse from a response message /// - private readonly CosmosSerializerCore serializerCore; + /// The user type of the serialized item + /// The response message from the stream API + /// An instance of FeedResponse + public abstract FeedResponse CreateItemFeedResponse( + ResponseMessage responseMessage); - internal CosmosResponseFactory( - CosmosSerializerCore jsonSerializerCore) - { - this.serializerCore = jsonSerializerCore; - } - - internal FeedResponse CreateChangeFeedUserTypeResponse( - ResponseMessage responseMessage) - { - return this.CreateChangeFeedResponseHelper( - responseMessage, - Documents.ResourceType.Document); - } - - internal FeedResponse CreateChangeFeedUserTypeResponse( - ResponseMessage responseMessage, - Documents.ResourceType resourceType) - { - return this.CreateChangeFeedResponseHelper( - responseMessage, - resourceType); - } - - internal FeedResponse CreateQueryFeedUserTypeResponse( - ResponseMessage responseMessage) - { - return this.CreateQueryFeedResponseHelper( - responseMessage, - Documents.ResourceType.Document); - } - - internal FeedResponse CreateQueryFeedResponse( - ResponseMessage responseMessage, - Documents.ResourceType resourceType) - { - return this.CreateQueryFeedResponseHelper( - responseMessage, - resourceType); - } - - private FeedResponse CreateQueryFeedResponseHelper( - ResponseMessage cosmosResponseMessage, - Documents.ResourceType resourceType) - { - //Throw the exception - cosmosResponseMessage.EnsureSuccessStatusCode(); - - QueryResponse queryResponse = cosmosResponseMessage as QueryResponse; - if (queryResponse != null) - { - return QueryResponse.CreateResponse( - cosmosQueryResponse: queryResponse, - serializerCore: this.serializerCore); - } - - return ReadFeedResponse.CreateResponse( - cosmosResponseMessage, - this.serializerCore, - resourceType); - } - - private FeedResponse CreateChangeFeedResponseHelper( - ResponseMessage cosmosResponseMessage, - Documents.ResourceType resourceType) - { - return ReadFeedResponse.CreateResponse( - cosmosResponseMessage, - this.serializerCore, - resourceType); - } - - internal Task> CreateItemResponseAsync( - Task cosmosResponseMessageTask) - { - return this.ProcessMessageAsync(cosmosResponseMessageTask, (cosmosResponseMessage) => - { - T item = this.ToObjectInternal(cosmosResponseMessage); - return new ItemResponse( - cosmosResponseMessage.StatusCode, - cosmosResponseMessage.Headers, - item, - cosmosResponseMessage.Diagnostics); - }); - } - - internal Task CreateContainerResponseAsync( - Container container, - Task cosmosResponseMessageTask) - { - return this.ProcessMessageAsync(cosmosResponseMessageTask, (cosmosResponseMessage) => - { - ContainerProperties containerProperties = this.ToObjectInternal(cosmosResponseMessage); - return new ContainerResponse( - cosmosResponseMessage.StatusCode, - cosmosResponseMessage.Headers, - containerProperties, - container, - cosmosResponseMessage.Diagnostics); - }); - } - - internal Task CreateUserResponseAsync( - User user, - Task cosmosResponseMessageTask) - { - return this.ProcessMessageAsync(cosmosResponseMessageTask, (cosmosResponseMessage) => - { - UserProperties userProperties = this.ToObjectInternal(cosmosResponseMessage); - return new UserResponse( - cosmosResponseMessage.StatusCode, - cosmosResponseMessage.Headers, - userProperties, - user, - cosmosResponseMessage.Diagnostics); - }); - } - - internal Task CreatePermissionResponseAsync( - Permission permission, - Task cosmosResponseMessageTask) - { - return this.ProcessMessageAsync(cosmosResponseMessageTask, (cosmosResponseMessage) => - { - PermissionProperties permissionProperties = this.ToObjectInternal(cosmosResponseMessage); - return new PermissionResponse( - cosmosResponseMessage.StatusCode, - cosmosResponseMessage.Headers, - permissionProperties, - permission, - cosmosResponseMessage.Diagnostics); - }); - } - - internal Task CreateDatabaseResponseAsync( - Database database, - Task cosmosResponseMessageTask) - { - return this.ProcessMessageAsync(cosmosResponseMessageTask, (cosmosResponseMessage) => - { - DatabaseProperties databaseProperties = this.ToObjectInternal(cosmosResponseMessage); - - return new DatabaseResponse( - cosmosResponseMessage.StatusCode, - cosmosResponseMessage.Headers, - databaseProperties, - database, - cosmosResponseMessage.Diagnostics); - }); - } - - internal Task CreateThroughputResponseAsync( - Task cosmosResponseMessageTask) - { - return this.ProcessMessageAsync(cosmosResponseMessageTask, (cosmosResponseMessage) => - { - ThroughputProperties throughputProperties = this.ToObjectInternal(cosmosResponseMessage); - return new ThroughputResponse( - cosmosResponseMessage.StatusCode, - cosmosResponseMessage.Headers, - throughputProperties, - cosmosResponseMessage.Diagnostics); - }); - } - - internal Task> CreateStoredProcedureExecuteResponseAsync(Task cosmosResponseMessageTask) - { - return this.ProcessMessageAsync(cosmosResponseMessageTask, (cosmosResponseMessage) => - { - T item = this.ToObjectInternal(cosmosResponseMessage); - return new StoredProcedureExecuteResponse( - cosmosResponseMessage.StatusCode, - cosmosResponseMessage.Headers, - item, - cosmosResponseMessage.Diagnostics); - }); - } - - internal Task CreateStoredProcedureResponseAsync(Task cosmosResponseMessageTask) - { - return this.ProcessMessageAsync(cosmosResponseMessageTask, (cosmosResponseMessage) => - { - StoredProcedureProperties cosmosStoredProcedure = this.ToObjectInternal(cosmosResponseMessage); - return new StoredProcedureResponse( - cosmosResponseMessage.StatusCode, - cosmosResponseMessage.Headers, - cosmosStoredProcedure, - cosmosResponseMessage.Diagnostics); - }); - } - - internal Task CreateTriggerResponseAsync(Task cosmosResponseMessageTask) - { - return this.ProcessMessageAsync(cosmosResponseMessageTask, (cosmosResponseMessage) => - { - TriggerProperties triggerProperties = this.ToObjectInternal(cosmosResponseMessage); - return new TriggerResponse( - cosmosResponseMessage.StatusCode, - cosmosResponseMessage.Headers, - triggerProperties, - cosmosResponseMessage.Diagnostics); - }); - } - - internal Task CreateUserDefinedFunctionResponseAsync(Task cosmosResponseMessageTask) - { - return this.ProcessMessageAsync(cosmosResponseMessageTask, (cosmosResponseMessage) => - { - UserDefinedFunctionProperties settings = this.ToObjectInternal(cosmosResponseMessage); - return new UserDefinedFunctionResponse( - cosmosResponseMessage.StatusCode, - cosmosResponseMessage.Headers, - settings, - cosmosResponseMessage.Diagnostics); - }); - } - - internal async Task ProcessMessageAsync(Task cosmosResponseTask, Func createResponse) - { - using (ResponseMessage message = await cosmosResponseTask) - { - //Throw the exception - message.EnsureSuccessStatusCode(); - - return createResponse(message); - } - } - - internal T ToObjectInternal(ResponseMessage responseMessage) - { - if (responseMessage.Content == null) - { - return default(T); - } + /// + /// Creates a FeedResponse from a response message + /// + /// The user + /// The response message from the stream API + /// An instance of FeedResponse + public abstract ItemResponse CreateItemResponse( + ResponseMessage responseMessage); - return this.serializerCore.FromStream(responseMessage.Content); - } + /// + /// Creates a StoredProcedureExecuteResponse from a response message + /// + /// The user + /// The response message from the stream API + /// An instance of FeedResponse + public abstract StoredProcedureExecuteResponse CreateStoredProcedureExecuteResponse( + ResponseMessage responseMessage); } } \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Resource/CosmosResponseFactoryCore.cs b/Microsoft.Azure.Cosmos/src/Resource/CosmosResponseFactoryCore.cs new file mode 100644 index 0000000000..5596eef32b --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Resource/CosmosResponseFactoryCore.cs @@ -0,0 +1,262 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos +{ + using System; + using Microsoft.Azure.Cosmos.Scripts; + + internal sealed class CosmosResponseFactoryCore : CosmosResponseFactoryInternal + { + /// + /// This is used for all meta data types + /// + private readonly CosmosSerializerCore serializerCore; + + public CosmosResponseFactoryCore( + CosmosSerializerCore jsonSerializerCore) + { + this.serializerCore = jsonSerializerCore; + } + + public override FeedResponse CreateItemFeedResponse(ResponseMessage responseMessage) + { + return this.CreateQueryFeedResponseHelper( + responseMessage, + Documents.ResourceType.Document); + } + + public override FeedResponse CreateChangeFeedUserTypeResponse( + ResponseMessage responseMessage) + { + return this.CreateChangeFeedResponseHelper( + responseMessage, + Documents.ResourceType.Document); + } + + public override FeedResponse CreateChangeFeedUserTypeResponse( + ResponseMessage responseMessage, + Documents.ResourceType resourceType) + { + return this.CreateChangeFeedResponseHelper( + responseMessage, + resourceType); + } + + public override FeedResponse CreateQueryFeedUserTypeResponse( + ResponseMessage responseMessage) + { + return this.CreateQueryFeedResponseHelper( + responseMessage, + Documents.ResourceType.Document); + } + + public override FeedResponse CreateQueryFeedResponse( + ResponseMessage responseMessage, + Documents.ResourceType resourceType) + { + return this.CreateQueryFeedResponseHelper( + responseMessage, + resourceType); + } + + private FeedResponse CreateQueryFeedResponseHelper( + ResponseMessage cosmosResponseMessage, + Documents.ResourceType resourceType) + { + //Throw the exception + cosmosResponseMessage.EnsureSuccessStatusCode(); + + QueryResponse queryResponse = cosmosResponseMessage as QueryResponse; + if (queryResponse != null) + { + return QueryResponse.CreateResponse( + cosmosQueryResponse: queryResponse, + serializerCore: this.serializerCore); + } + + return ReadFeedResponse.CreateResponse( + cosmosResponseMessage, + this.serializerCore, + resourceType); + } + + private FeedResponse CreateChangeFeedResponseHelper( + ResponseMessage cosmosResponseMessage, + Documents.ResourceType resourceType) + { + return ReadFeedResponse.CreateResponse( + cosmosResponseMessage, + this.serializerCore, + resourceType); + } + + public override ItemResponse CreateItemResponse( + ResponseMessage responseMessage) + { + return this.ProcessMessage(responseMessage, (cosmosResponseMessage) => + { + T item = this.ToObjectpublic(cosmosResponseMessage); + return new ItemResponse( + cosmosResponseMessage.StatusCode, + cosmosResponseMessage.Headers, + item, + cosmosResponseMessage.Diagnostics); + }); + } + + public override ContainerResponse CreateContainerResponse( + Container container, + ResponseMessage responseMessage) + { + return this.ProcessMessage(responseMessage, (cosmosResponseMessage) => + { + ContainerProperties containerProperties = this.ToObjectpublic(cosmosResponseMessage); + return new ContainerResponse( + cosmosResponseMessage.StatusCode, + cosmosResponseMessage.Headers, + containerProperties, + container, + cosmosResponseMessage.Diagnostics); + }); + } + + public override UserResponse CreateUserResponse( + User user, + ResponseMessage responseMessage) + { + return this.ProcessMessage(responseMessage, (cosmosResponseMessage) => + { + UserProperties userProperties = this.ToObjectpublic(cosmosResponseMessage); + return new UserResponse( + cosmosResponseMessage.StatusCode, + cosmosResponseMessage.Headers, + userProperties, + user, + cosmosResponseMessage.Diagnostics); + }); + } + + public override PermissionResponse CreatePermissionResponse( + Permission permission, + ResponseMessage responseMessage) + { + return this.ProcessMessage(responseMessage, (cosmosResponseMessage) => + { + PermissionProperties permissionProperties = this.ToObjectpublic(cosmosResponseMessage); + return new PermissionResponse( + cosmosResponseMessage.StatusCode, + cosmosResponseMessage.Headers, + permissionProperties, + permission, + cosmosResponseMessage.Diagnostics); + }); + } + + public override DatabaseResponse CreateDatabaseResponse( + Database database, + ResponseMessage responseMessage) + { + return this.ProcessMessage(responseMessage, (cosmosResponseMessage) => + { + DatabaseProperties databaseProperties = this.ToObjectpublic(cosmosResponseMessage); + + return new DatabaseResponse( + cosmosResponseMessage.StatusCode, + cosmosResponseMessage.Headers, + databaseProperties, + database, + cosmosResponseMessage.Diagnostics); + }); + } + + public override ThroughputResponse CreateThroughputResponse( + ResponseMessage responseMessage) + { + return this.ProcessMessage(responseMessage, (cosmosResponseMessage) => + { + ThroughputProperties throughputProperties = this.ToObjectpublic(cosmosResponseMessage); + return new ThroughputResponse( + cosmosResponseMessage.StatusCode, + cosmosResponseMessage.Headers, + throughputProperties, + cosmosResponseMessage.Diagnostics); + }); + } + + public override StoredProcedureExecuteResponse CreateStoredProcedureExecuteResponse(ResponseMessage responseMessage) + { + return this.ProcessMessage(responseMessage, (cosmosResponseMessage) => + { + T item = this.ToObjectpublic(cosmosResponseMessage); + return new StoredProcedureExecuteResponse( + cosmosResponseMessage.StatusCode, + cosmosResponseMessage.Headers, + item, + cosmosResponseMessage.Diagnostics); + }); + } + + public override StoredProcedureResponse CreateStoredProcedureResponse(ResponseMessage responseMessage) + { + return this.ProcessMessage(responseMessage, (cosmosResponseMessage) => + { + StoredProcedureProperties cosmosStoredProcedure = this.ToObjectpublic(cosmosResponseMessage); + return new StoredProcedureResponse( + cosmosResponseMessage.StatusCode, + cosmosResponseMessage.Headers, + cosmosStoredProcedure, + cosmosResponseMessage.Diagnostics); + }); + } + + public override TriggerResponse CreateTriggerResponse(ResponseMessage responseMessage) + { + return this.ProcessMessage(responseMessage, (cosmosResponseMessage) => + { + TriggerProperties triggerProperties = this.ToObjectpublic(cosmosResponseMessage); + return new TriggerResponse( + cosmosResponseMessage.StatusCode, + cosmosResponseMessage.Headers, + triggerProperties, + cosmosResponseMessage.Diagnostics); + }); + } + + public override UserDefinedFunctionResponse CreateUserDefinedFunctionResponse( + ResponseMessage responseMessage) + { + return this.ProcessMessage(responseMessage, (cosmosResponseMessage) => + { + UserDefinedFunctionProperties settings = this.ToObjectpublic(cosmosResponseMessage); + return new UserDefinedFunctionResponse( + cosmosResponseMessage.StatusCode, + cosmosResponseMessage.Headers, + settings, + cosmosResponseMessage.Diagnostics); + }); + } + + public T ProcessMessage(ResponseMessage responseMessage, Func createResponse) + { + using (ResponseMessage message = responseMessage) + { + //Throw the exception + message.EnsureSuccessStatusCode(); + + return createResponse(message); + } + } + + public T ToObjectpublic(ResponseMessage responseMessage) + { + if (responseMessage.Content == null) + { + return default(T); + } + + return this.serializerCore.FromStream(responseMessage.Content); + } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Resource/CosmosResponseFactoryInternal.cs b/Microsoft.Azure.Cosmos/src/Resource/CosmosResponseFactoryInternal.cs new file mode 100644 index 0000000000..0093092fc9 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Resource/CosmosResponseFactoryInternal.cs @@ -0,0 +1,54 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos +{ + using System.Threading.Tasks; + using Microsoft.Azure.Cosmos.Scripts; + + internal abstract class CosmosResponseFactoryInternal : CosmosResponseFactory + { + public abstract FeedResponse CreateChangeFeedUserTypeResponse( + ResponseMessage responseMessage); + + public abstract FeedResponse CreateChangeFeedUserTypeResponse( + ResponseMessage responseMessage, + Documents.ResourceType resourceType); + + public abstract FeedResponse CreateQueryFeedUserTypeResponse( + ResponseMessage responseMessage); + + public abstract FeedResponse CreateQueryFeedResponse( + ResponseMessage responseMessage, + Documents.ResourceType resourceType); + + public abstract ContainerResponse CreateContainerResponse( + Container container, + ResponseMessage responseMessage); + + public abstract UserResponse CreateUserResponse( + User user, + ResponseMessage responseMessage); + + public abstract PermissionResponse CreatePermissionResponse( + Permission permission, + ResponseMessage responseMessage); + + public abstract DatabaseResponse CreateDatabaseResponse( + Database database, + ResponseMessage responseMessage); + + public abstract ThroughputResponse CreateThroughputResponse( + ResponseMessage responseMessage); + + public abstract StoredProcedureResponse CreateStoredProcedureResponse( + ResponseMessage responseMessage); + + public abstract TriggerResponse CreateTriggerResponse( + ResponseMessage responseMessage); + + public abstract UserDefinedFunctionResponse CreateUserDefinedFunctionResponse( + ResponseMessage responseMessage); + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Resource/Database/DatabaseCore.cs b/Microsoft.Azure.Cosmos/src/Resource/Database/DatabaseCore.cs index 234f2465cd..8a25fa67c0 100644 --- a/Microsoft.Azure.Cosmos/src/Resource/Database/DatabaseCore.cs +++ b/Microsoft.Azure.Cosmos/src/Resource/Database/DatabaseCore.cs @@ -38,26 +38,26 @@ protected DatabaseCore( internal override CosmosClientContext ClientContext { get; } - public override Task ReadAsync( + public override async Task ReadAsync( RequestOptions requestOptions = null, CancellationToken cancellationToken = default(CancellationToken)) { - Task response = this.ReadStreamAsync( + ResponseMessage response = await this.ReadStreamAsync( requestOptions: requestOptions, cancellationToken: cancellationToken); - return this.ClientContext.ResponseFactory.CreateDatabaseResponseAsync(this, response); + return this.ClientContext.ResponseFactory.CreateDatabaseResponse(this, response); } - public override Task DeleteAsync( + public override async Task DeleteAsync( RequestOptions requestOptions = null, CancellationToken cancellationToken = default(CancellationToken)) { - Task response = this.DeleteStreamAsync( + ResponseMessage response = await this.DeleteStreamAsync( requestOptions: requestOptions, cancellationToken: cancellationToken); - return this.ClientContext.ResponseFactory.CreateDatabaseResponseAsync(this, response); + return this.ClientContext.ResponseFactory.CreateDatabaseResponse(this, response); } public async override Task ReadThroughputAsync( @@ -137,7 +137,7 @@ public override Task CreateContainerStreamAsync( cancellationToken: cancellationToken); } - public override Task CreateContainerAsync( + public override async Task CreateContainerAsync( ContainerProperties containerProperties, ThroughputProperties throughputProperties, RequestOptions requestOptions = null, @@ -150,13 +150,13 @@ public override Task CreateContainerAsync( this.ValidateContainerProperties(containerProperties); - Task response = this.ProcessCollectionCreateAsync( + ResponseMessage response = await this.ProcessCollectionCreateAsync( streamPayload: this.ClientContext.SerializerCore.ToStream(containerProperties), throughputProperties: throughputProperties, requestOptions: requestOptions, cancellationToken: cancellationToken); - return this.ClientContext.ResponseFactory.CreateContainerResponseAsync(this.GetContainer(containerProperties.Id), response); + return this.ClientContext.ResponseFactory.CreateContainerResponse(this.GetContainer(containerProperties.Id), response); } public override async Task CreateContainerIfNotExistsAsync( ContainerProperties containerProperties, @@ -177,9 +177,9 @@ public override async Task CreateContainerIfNotExistsAsync( if (readResponse.StatusCode != HttpStatusCode.NotFound) { - ContainerResponse retrivedContainerResponse = await this.ClientContext.ResponseFactory.CreateContainerResponseAsync( + ContainerResponse retrivedContainerResponse = this.ClientContext.ResponseFactory.CreateContainerResponse( container, - Task.FromResult(readResponse)); + readResponse); if (!retrivedContainerResponse.Resource.PartitionKeyPath.Equals(containerProperties.PartitionKeyPath)) { throw new ArgumentException( @@ -206,7 +206,7 @@ public override async Task CreateContainerIfNotExistsAsync( if (readResponse.StatusCode != HttpStatusCode.Conflict) { - return await this.ClientContext.ResponseFactory.CreateContainerResponseAsync(container, Task.FromResult(createResponse)); + return this.ClientContext.ResponseFactory.CreateContainerResponse(container, createResponse); } // This second Read is to handle the race condition when 2 or more threads have Read the database and only one succeeds with Create @@ -216,7 +216,7 @@ public override async Task CreateContainerIfNotExistsAsync( // Merge the previous message diagnostics createResponse.DiagnosticsContext.AddDiagnosticsInternal(readResponse.DiagnosticsContext); - return await this.ClientContext.ResponseFactory.CreateContainerResponseAsync(container, Task.FromResult(readResponseAfterCreate)); + return this.ClientContext.ResponseFactory.CreateContainerResponse(container, readResponseAfterCreate); } public override async Task ReplaceThroughputAsync( @@ -267,7 +267,7 @@ public override Task DeleteStreamAsync( cancellationToken); } - public override Task CreateContainerAsync( + public override async Task CreateContainerAsync( ContainerProperties containerProperties, int? throughput = null, RequestOptions requestOptions = null, @@ -280,13 +280,13 @@ public override Task CreateContainerAsync( this.ValidateContainerProperties(containerProperties); - Task response = this.CreateContainerStreamInternalAsync( + ResponseMessage response = await this.CreateContainerStreamInternalAsync( streamPayload: this.ClientContext.SerializerCore.ToStream(containerProperties), throughput: throughput, requestOptions: requestOptions, cancellationToken: cancellationToken); - return this.ClientContext.ResponseFactory.CreateContainerResponseAsync(this.GetContainer(containerProperties.Id), response); + return this.ClientContext.ResponseFactory.CreateContainerResponse(this.GetContainer(containerProperties.Id), response); } public override Task CreateContainerAsync( @@ -334,9 +334,9 @@ public override async Task CreateContainerIfNotExistsAsync( if (readResponse.StatusCode != HttpStatusCode.NotFound) { - ContainerResponse retrivedContainerResponse = await this.ClientContext.ResponseFactory.CreateContainerResponseAsync( + ContainerResponse retrivedContainerResponse = this.ClientContext.ResponseFactory.CreateContainerResponse( container, - Task.FromResult(readResponse)); + readResponse); if (!retrivedContainerResponse.Resource.PartitionKeyPath.Equals(containerProperties.PartitionKeyPath)) { throw new ArgumentException( @@ -363,7 +363,7 @@ public override async Task CreateContainerIfNotExistsAsync( if (readResponse.StatusCode != HttpStatusCode.Conflict) { - return await this.ClientContext.ResponseFactory.CreateContainerResponseAsync(container, Task.FromResult(createResponse)); + return this.ClientContext.ResponseFactory.CreateContainerResponse(container, createResponse); } // This second Read is to handle the race condition when 2 or more threads have Read the database and only one succeeds with Create @@ -373,7 +373,7 @@ public override async Task CreateContainerIfNotExistsAsync( // Merge the previous message diagnostics createResponse.DiagnosticsContext.AddDiagnosticsInternal(readResponse.DiagnosticsContext); - return await this.ClientContext.ResponseFactory.CreateContainerResponseAsync(container, Task.FromResult(readResponseAfterCreate)); + return this.ClientContext.ResponseFactory.CreateContainerResponse(container, readResponseAfterCreate); } public override Task CreateContainerIfNotExistsAsync( @@ -430,7 +430,7 @@ public override Task CreateContainerStreamAsync( cancellationToken); } - public override Task CreateUserAsync( + public override async Task CreateUserAsync( string id, RequestOptions requestOptions = null, CancellationToken cancellationToken = default(CancellationToken)) @@ -442,12 +442,12 @@ public override Task CreateUserAsync( UserProperties userProperties = new UserProperties(id); - Task response = this.CreateUserStreamAsync( + ResponseMessage response = await this.CreateUserStreamAsync( userProperties: userProperties, requestOptions: requestOptions, cancellationToken: cancellationToken); - return this.ClientContext.ResponseFactory.CreateUserResponseAsync(this.GetUser(userProperties.Id), response); + return this.ClientContext.ResponseFactory.CreateUserResponse(this.GetUser(userProperties.Id), response); } public override User GetUser(string id) @@ -482,7 +482,7 @@ public Task CreateUserStreamAsync( cancellationToken: cancellationToken); } - public override Task UpsertUserAsync(string id, + public override async Task UpsertUserAsync(string id, RequestOptions requestOptions, CancellationToken cancellationToken = default(CancellationToken)) { @@ -493,12 +493,12 @@ public override Task UpsertUserAsync(string id, this.ClientContext.ValidateResource(id); - Task response = this.ProcessUserUpsertAsync( + ResponseMessage response = await this.ProcessUserUpsertAsync( streamPayload: this.ClientContext.SerializerCore.ToStream(new UserProperties(id)), requestOptions: requestOptions, cancellationToken: cancellationToken); - return this.ClientContext.ResponseFactory.CreateUserResponseAsync(this.GetUser(id), response); + return this.ClientContext.ResponseFactory.CreateUserResponse(this.GetUser(id), response); } public override FeedIterator GetContainerQueryStreamIterator( diff --git a/Microsoft.Azure.Cosmos/src/Resource/Offer/CosmosOffers.cs b/Microsoft.Azure.Cosmos/src/Resource/Offer/CosmosOffers.cs index 9b13be0f57..6e16f957ae 100644 --- a/Microsoft.Azure.Cosmos/src/Resource/Offer/CosmosOffers.cs +++ b/Microsoft.Azure.Cosmos/src/Resource/Offer/CosmosOffers.cs @@ -252,7 +252,7 @@ private async Task GetThroughputResponseAsync( RequestOptions requestOptions = null, CancellationToken cancellationToken = default(CancellationToken)) { - Task responseMessage = this.ClientContext.ProcessResourceOperationStreamAsync( + ResponseMessage responseMessage = await this.ClientContext.ProcessResourceOperationStreamAsync( resourceUri: linkUri, resourceType: resourceType, operationType: operationType, @@ -263,7 +263,7 @@ private async Task GetThroughputResponseAsync( requestEnricher: null, diagnosticsContext: null, cancellationToken: cancellationToken); - return await this.ClientContext.ResponseFactory.CreateThroughputResponseAsync(responseMessage); + return this.ClientContext.ResponseFactory.CreateThroughputResponse(responseMessage); } } } diff --git a/Microsoft.Azure.Cosmos/src/Resource/Permission/PermissionCore.cs b/Microsoft.Azure.Cosmos/src/Resource/Permission/PermissionCore.cs index 0f5cb81767..b5f8f680b5 100644 --- a/Microsoft.Azure.Cosmos/src/Resource/Permission/PermissionCore.cs +++ b/Microsoft.Azure.Cosmos/src/Resource/Permission/PermissionCore.cs @@ -37,14 +37,14 @@ internal PermissionCore( public override string Id { get; } /// - public override Task DeleteAsync(RequestOptions requestOptions = null, + public override async Task DeleteAsync(RequestOptions requestOptions = null, CancellationToken cancellationToken = default(CancellationToken)) { - Task response = this.DeletePermissionStreamAsync( + ResponseMessage response = await this.DeletePermissionStreamAsync( requestOptions: requestOptions, cancellationToken: cancellationToken); - return this.clientContext.ResponseFactory.CreatePermissionResponseAsync(this, response); + return this.clientContext.ResponseFactory.CreatePermissionResponse(this, response); } public Task DeletePermissionStreamAsync( @@ -59,16 +59,16 @@ public Task DeletePermissionStreamAsync( } /// - public override Task ReadAsync(int? tokenExpiryInSeconds = null, + public override async Task ReadAsync(int? tokenExpiryInSeconds = null, RequestOptions requestOptions = null, CancellationToken cancellationToken = default(CancellationToken)) { - Task response = this.ReadPermissionStreamAsync( + ResponseMessage response = await this.ReadPermissionStreamAsync( tokenExpiryInSeconds: tokenExpiryInSeconds, requestOptions: requestOptions, cancellationToken: cancellationToken); - return this.clientContext.ResponseFactory.CreatePermissionResponseAsync(this, response); + return this.clientContext.ResponseFactory.CreatePermissionResponse(this, response); } public Task ReadPermissionStreamAsync(int? tokenExpiryInSeconds = null, @@ -84,7 +84,7 @@ public Task ReadPermissionStreamAsync(int? tokenExpiryInSeconds } /// - public override Task ReplaceAsync(PermissionProperties permissionProperties, + public override async Task ReplaceAsync(PermissionProperties permissionProperties, int? tokenExpiryInSeconds = null, RequestOptions requestOptions = null, CancellationToken cancellationToken = default(CancellationToken)) @@ -95,13 +95,13 @@ public override Task ReplaceAsync(PermissionProperties permi } this.clientContext.ValidateResource(permissionProperties.Id); - Task response = this.ReplaceStreamInternalAsync( + ResponseMessage response = await this.ReplaceStreamInternalAsync( streamPayload: this.clientContext.SerializerCore.ToStream(permissionProperties), tokenExpiryInSeconds: tokenExpiryInSeconds, requestOptions: requestOptions, cancellationToken: cancellationToken); - return this.clientContext.ResponseFactory.CreatePermissionResponseAsync(this, response); + return this.clientContext.ResponseFactory.CreatePermissionResponse(this, response); } public Task ReplacePermissionStreamAsync(PermissionProperties permissionProperties, diff --git a/Microsoft.Azure.Cosmos/src/Resource/Scripts/ScriptsCore.cs b/Microsoft.Azure.Cosmos/src/Resource/Scripts/ScriptsCore.cs index 66af9e35dd..5f49901b65 100644 --- a/Microsoft.Azure.Cosmos/src/Resource/Scripts/ScriptsCore.cs +++ b/Microsoft.Azure.Cosmos/src/Resource/Scripts/ScriptsCore.cs @@ -153,21 +153,21 @@ public override Task DeleteStoredProcedureAsync( cancellationToken: cancellationToken); } - public override Task> ExecuteStoredProcedureAsync( + public override async Task> ExecuteStoredProcedureAsync( string storedProcedureId, Cosmos.PartitionKey partitionKey, dynamic[] parameters, StoredProcedureRequestOptions requestOptions = null, CancellationToken cancellationToken = default(CancellationToken)) { - Task response = this.ExecuteStoredProcedureStreamAsync( + ResponseMessage response = await this.ExecuteStoredProcedureStreamAsync( storedProcedureId: storedProcedureId, partitionKey: partitionKey, parameters: parameters, requestOptions: requestOptions, cancellationToken: cancellationToken); - return this.clientContext.ResponseFactory.CreateStoredProcedureExecuteResponseAsync(response); + return this.clientContext.ResponseFactory.CreateStoredProcedureExecuteResponse(response); } public override Task ExecuteStoredProcedureStreamAsync( @@ -560,14 +560,14 @@ private Task ProcessStoredProcedureOperationAsync( cancellationToken: cancellationToken); } - private Task ProcessStoredProcedureOperationAsync( + private async Task ProcessStoredProcedureOperationAsync( Uri linkUri, OperationType operationType, Stream streamPayload, RequestOptions requestOptions, CancellationToken cancellationToken) { - Task response = this.ProcessStreamOperationAsync( + ResponseMessage response = await this.ProcessStreamOperationAsync( resourceUri: linkUri, resourceType: ResourceType.StoredProcedure, operationType: operationType, @@ -576,7 +576,7 @@ private Task ProcessStoredProcedureOperationAsync( streamPayload: streamPayload, cancellationToken: cancellationToken); - return this.clientContext.ResponseFactory.CreateStoredProcedureResponseAsync(response); + return this.clientContext.ResponseFactory.CreateStoredProcedureResponse(response); } private Task ProcessTriggerOperationAsync( @@ -599,14 +599,14 @@ private Task ProcessTriggerOperationAsync( cancellationToken: cancellationToken); } - private Task ProcessTriggerOperationAsync( + private async Task ProcessTriggerOperationAsync( Uri linkUri, OperationType operationType, Stream streamPayload, RequestOptions requestOptions, CancellationToken cancellationToken) { - Task response = this.ProcessStreamOperationAsync( + ResponseMessage response = await this.ProcessStreamOperationAsync( resourceUri: linkUri, resourceType: ResourceType.Trigger, operationType: operationType, @@ -615,7 +615,7 @@ private Task ProcessTriggerOperationAsync( streamPayload: streamPayload, cancellationToken: cancellationToken); - return this.clientContext.ResponseFactory.CreateTriggerResponseAsync(response); + return this.clientContext.ResponseFactory.CreateTriggerResponse(response); } private Task ProcessStreamOperationAsync( @@ -660,14 +660,14 @@ private Task ProcessUserDefinedFunctionOperationAsy cancellationToken: cancellationToken); } - private Task ProcessUserDefinedFunctionOperationAsync( + private async Task ProcessUserDefinedFunctionOperationAsync( Uri linkUri, OperationType operationType, Stream streamPayload, RequestOptions requestOptions, CancellationToken cancellationToken) { - Task response = this.ProcessStreamOperationAsync( + ResponseMessage response = await this.ProcessStreamOperationAsync( resourceUri: linkUri, resourceType: ResourceType.UserDefinedFunction, operationType: operationType, @@ -676,7 +676,7 @@ private Task ProcessUserDefinedFunctionOperationAsy streamPayload: streamPayload, cancellationToken: cancellationToken); - return this.clientContext.ResponseFactory.CreateUserDefinedFunctionResponseAsync(response); + return this.clientContext.ResponseFactory.CreateUserDefinedFunctionResponse(response); } } } diff --git a/Microsoft.Azure.Cosmos/src/Resource/User/UserCore.cs b/Microsoft.Azure.Cosmos/src/Resource/User/UserCore.cs index 60933fa863..8115af1adb 100644 --- a/Microsoft.Azure.Cosmos/src/Resource/User/UserCore.cs +++ b/Microsoft.Azure.Cosmos/src/Resource/User/UserCore.cs @@ -45,14 +45,14 @@ internal UserCore( internal virtual CosmosClientContext ClientContext { get; } /// - public override Task ReadAsync(RequestOptions requestOptions = null, + public override async Task ReadAsync(RequestOptions requestOptions = null, CancellationToken cancellationToken = default(CancellationToken)) { - Task response = this.ReadStreamAsync( + ResponseMessage response = await this.ReadStreamAsync( requestOptions: requestOptions, cancellationToken: cancellationToken); - return this.ClientContext.ResponseFactory.CreateUserResponseAsync(this, response); + return this.ClientContext.ResponseFactory.CreateUserResponse(this, response); } public Task ReadStreamAsync(RequestOptions requestOptions = null, @@ -66,7 +66,7 @@ public Task ReadStreamAsync(RequestOptions requestOptions = nul } /// - public override Task ReplaceAsync(UserProperties userProperties, + public override async Task ReplaceAsync(UserProperties userProperties, RequestOptions requestOptions = null, CancellationToken cancellationToken = default(CancellationToken)) { @@ -76,12 +76,12 @@ public override Task ReplaceAsync(UserProperties userProperties, } this.ClientContext.ValidateResource(userProperties.Id); - Task response = this.ReplaceStreamInternalAsync( + ResponseMessage response = await this.ReplaceStreamInternalAsync( streamPayload: this.ClientContext.SerializerCore.ToStream(userProperties), requestOptions: requestOptions, cancellationToken: cancellationToken); - return this.ClientContext.ResponseFactory.CreateUserResponseAsync(this, response); + return this.ClientContext.ResponseFactory.CreateUserResponse(this, response); } public Task ReplaceStreamAsync(UserProperties userProperties, @@ -101,14 +101,14 @@ public Task ReplaceStreamAsync(UserProperties userProperties, } /// - public override Task DeleteAsync(RequestOptions requestOptions = null, + public override async Task DeleteAsync(RequestOptions requestOptions = null, CancellationToken cancellationToken = default(CancellationToken)) { - Task response = this.DeleteStreamAsync( + ResponseMessage response = await this.DeleteStreamAsync( requestOptions: requestOptions, cancellationToken: cancellationToken); - return this.ClientContext.ResponseFactory.CreateUserResponseAsync(this, response); + return this.ClientContext.ResponseFactory.CreateUserResponse(this, response); } public Task DeleteStreamAsync(RequestOptions requestOptions = null, @@ -136,7 +136,7 @@ public override Permission GetPermission(string id) } /// - public override Task CreatePermissionAsync(PermissionProperties permissionProperties, + public override async Task CreatePermissionAsync(PermissionProperties permissionProperties, int? tokenExpiryInSeconds = null, RequestOptions requestOptions = null, CancellationToken cancellationToken = default(CancellationToken)) @@ -148,13 +148,13 @@ public override Task CreatePermissionAsync(PermissionPropert this.ClientContext.ValidateResource(permissionProperties.Id); - Task response = this.CreatePermissionStreamInternalAsync( + ResponseMessage response = await this.CreatePermissionStreamInternalAsync( streamPayload: this.ClientContext.SerializerCore.ToStream(permissionProperties), tokenExpiryInSeconds: tokenExpiryInSeconds, requestOptions: requestOptions, cancellationToken: cancellationToken); - return this.ClientContext.ResponseFactory.CreatePermissionResponseAsync(this.GetPermission(permissionProperties.Id), response); + return this.ClientContext.ResponseFactory.CreatePermissionResponse(this.GetPermission(permissionProperties.Id), response); } public Task CreatePermissionStreamAsync(PermissionProperties permissionProperties, @@ -176,7 +176,7 @@ public Task CreatePermissionStreamAsync(PermissionProperties pe cancellationToken); } - public override Task UpsertPermissionAsync(PermissionProperties permissionProperties, + public override async Task UpsertPermissionAsync(PermissionProperties permissionProperties, int? tokenExpiryInSeconds = null, RequestOptions requestOptions = null, CancellationToken cancellationToken = default(CancellationToken)) @@ -188,13 +188,13 @@ public override Task UpsertPermissionAsync(PermissionPropert this.ClientContext.ValidateResource(permissionProperties.Id); - Task response = this.UpsertPermissionStreamInternalAsync( + ResponseMessage response = await this.UpsertPermissionStreamInternalAsync( streamPayload: this.ClientContext.SerializerCore.ToStream(permissionProperties), tokenExpiryInSeconds: tokenExpiryInSeconds, requestOptions: requestOptions, cancellationToken: cancellationToken); - return this.ClientContext.ResponseFactory.CreatePermissionResponseAsync(this.GetPermission(permissionProperties.Id), response); + return this.ClientContext.ResponseFactory.CreatePermissionResponse(this.GetPermission(permissionProperties.Id), response); } /// diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosJsonSeriliazerUnitTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosJsonSeriliazerUnitTests.cs index 2a5c074cbd..2d5b5ce176 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosJsonSeriliazerUnitTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosJsonSeriliazerUnitTests.cs @@ -167,7 +167,7 @@ public void ValidateCustomSerializerSettings() } [TestMethod] - public async Task ValidateResponseFactoryJsonSerializer() + public void ValidateResponseFactoryJsonSerializer() { ResponseMessage databaseResponse = this.CreateResponse(); ResponseMessage containerResponse = this.CreateResponse(); @@ -179,7 +179,7 @@ public async Task ValidateResponseFactoryJsonSerializer() Mock mockUserJsonSerializer = new Mock(); CosmosSerializerCore serializerCore = new CosmosSerializerCore(mockUserJsonSerializer.Object); - CosmosResponseFactory cosmosResponseFactory = new CosmosResponseFactory( + CosmosResponseFactoryInternal cosmosResponseFactory = new CosmosResponseFactoryCore( serializerCore); // Test the user specified response @@ -187,8 +187,8 @@ public async Task ValidateResponseFactoryJsonSerializer() mockUserJsonSerializer.Setup(x => x.FromStream(storedProcedureExecuteResponse.Content)).Callback(input => input.Dispose()).Returns(new ToDoActivity()); // Verify all the user types use the user specified version - await cosmosResponseFactory.CreateItemResponseAsync(Task.FromResult(itemResponse)); - await cosmosResponseFactory.CreateStoredProcedureExecuteResponseAsync(Task.FromResult(storedProcedureExecuteResponse)); + cosmosResponseFactory.CreateItemResponse(itemResponse); + cosmosResponseFactory.CreateStoredProcedureExecuteResponse(storedProcedureExecuteResponse); // Throw if the setups were not called mockUserJsonSerializer.VerifyAll(); @@ -219,11 +219,11 @@ public async Task ValidateResponseFactoryJsonSerializer() Mock mockDatabase = new Mock(); // Verify all the system types that should always use default - await cosmosResponseFactory.CreateContainerResponseAsync(mockContainer.Object, Task.FromResult(containerResponse)); - await cosmosResponseFactory.CreateDatabaseResponseAsync(mockDatabase.Object, Task.FromResult(databaseResponse)); - await cosmosResponseFactory.CreateStoredProcedureResponseAsync(Task.FromResult(storedProcedureResponse)); - await cosmosResponseFactory.CreateTriggerResponseAsync(Task.FromResult(triggerResponse)); - await cosmosResponseFactory.CreateUserDefinedFunctionResponseAsync(Task.FromResult(udfResponse)); + cosmosResponseFactory.CreateContainerResponse(mockContainer.Object, containerResponse); + cosmosResponseFactory.CreateDatabaseResponse(mockDatabase.Object, databaseResponse); + cosmosResponseFactory.CreateStoredProcedureResponse(storedProcedureResponse); + cosmosResponseFactory.CreateTriggerResponse(triggerResponse); + cosmosResponseFactory.CreateUserDefinedFunctionResponse(udfResponse); } [TestMethod] diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/DotNetSDKAPI.json b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/DotNetSDKAPI.json index 27589cc42c..2ee3b3410d 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/DotNetSDKAPI.json +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/DotNetSDKAPI.json @@ -1300,6 +1300,16 @@ "Attributes": [], "MethodInfo": "Microsoft.Azure.Cosmos.CosmosClientOptions get_ClientOptions()" }, + "Microsoft.Azure.Cosmos.CosmosResponseFactory get_ResponseFactory()": { + "Type": "Method", + "Attributes": [], + "MethodInfo": "Microsoft.Azure.Cosmos.CosmosResponseFactory get_ResponseFactory()" + }, + "Microsoft.Azure.Cosmos.CosmosResponseFactory ResponseFactory": { + "Type": "Property", + "Attributes": [], + "MethodInfo": null + }, "Microsoft.Azure.Cosmos.Database GetDatabase(System.String)": { "Type": "Method", "Attributes": [], @@ -1906,6 +1916,27 @@ }, "NestedTypes": {} }, + "CosmosResponseFactory": { + "Subclasses": {}, + "Members": { + "Microsoft.Azure.Cosmos.FeedResponse`1[T] CreateItemFeedResponse[T](Microsoft.Azure.Cosmos.ResponseMessage)": { + "Type": "Method", + "Attributes": [], + "MethodInfo": "Microsoft.Azure.Cosmos.FeedResponse`1[T] CreateItemFeedResponse[T](Microsoft.Azure.Cosmos.ResponseMessage)" + }, + "Microsoft.Azure.Cosmos.ItemResponse`1[T] CreateItemResponse[T](Microsoft.Azure.Cosmos.ResponseMessage)": { + "Type": "Method", + "Attributes": [], + "MethodInfo": "Microsoft.Azure.Cosmos.ItemResponse`1[T] CreateItemResponse[T](Microsoft.Azure.Cosmos.ResponseMessage)" + }, + "Microsoft.Azure.Cosmos.Scripts.StoredProcedureExecuteResponse`1[T] CreateStoredProcedureExecuteResponse[T](Microsoft.Azure.Cosmos.ResponseMessage)": { + "Type": "Method", + "Attributes": [], + "MethodInfo": "Microsoft.Azure.Cosmos.Scripts.StoredProcedureExecuteResponse`1[T] CreateStoredProcedureExecuteResponse[T](Microsoft.Azure.Cosmos.ResponseMessage)" + } + }, + "NestedTypes": {} + }, "CosmosSerializationOptions": { "Subclasses": {}, "Members": { From a618098db59fc5825db1fccb3f8cd11b8f17e5ef Mon Sep 17 00:00:00 2001 From: Jake Willey Date: Thu, 30 Apr 2020 10:37:49 -0700 Subject: [PATCH 2/5] Adding unit tests --- .../CosmosJsonSeriliazerUnitTests.cs | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosJsonSeriliazerUnitTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosJsonSeriliazerUnitTests.cs index 2d5b5ce176..4298a731bc 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosJsonSeriliazerUnitTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosJsonSeriliazerUnitTests.cs @@ -12,6 +12,7 @@ namespace Microsoft.Azure.Cosmos.Core.Tests using System.Text; using System.Threading; using System.Threading.Tasks; + using Microsoft.Azure.Cosmos.CosmosElements; using Microsoft.Azure.Cosmos.Query.Core; using Microsoft.Azure.Cosmos.Scripts; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -176,6 +177,7 @@ public void ValidateResponseFactoryJsonSerializer() ResponseMessage triggerResponse = this.CreateResponse(); ResponseMessage udfResponse = this.CreateResponse(); ResponseMessage itemResponse = this.CreateResponse(); + Mock mockUserJsonSerializer = new Mock(); CosmosSerializerCore serializerCore = new CosmosSerializerCore(mockUserJsonSerializer.Object); @@ -193,6 +195,27 @@ public void ValidateResponseFactoryJsonSerializer() // Throw if the setups were not called mockUserJsonSerializer.VerifyAll(); + // Test read feed scenario + ResponseMessage readFeedResponse = this.CreateReadFeedResponse(); + mockUserJsonSerializer.Setup(x => x.FromStream(It.IsAny())).Callback(input => input.Dispose()).Returns(new ToDoActivity()); + FeedResponse feedResponse = cosmosResponseFactory.CreateItemFeedResponse(readFeedResponse); + foreach(ToDoActivity toDoActivity in feedResponse) + { + Assert.IsNotNull(toDoActivity); + } + + mockUserJsonSerializer.VerifyAll(); + + ResponseMessage queryResponse = this.CreateReadFeedResponse(); + mockUserJsonSerializer.Setup(x => x.FromStream(It.IsAny())).Callback(input => input.Dispose()).Returns(new ToDoActivity()); + FeedResponse queryFeedResponse = cosmosResponseFactory.CreateItemFeedResponse(queryResponse); + foreach (ToDoActivity toDoActivity in queryFeedResponse) + { + Assert.IsNotNull(toDoActivity); + } + + mockUserJsonSerializer.VerifyAll(); + // Test the system specified response ContainerProperties containerSettings = new ContainerProperties("mockId", "/pk"); DatabaseProperties databaseSettings = new DatabaseProperties() @@ -306,6 +329,44 @@ private ResponseMessage CreateResponse() return cosmosResponse; } + private ResponseMessage CreateQueryResponse() + { + List cosmosElements = new List(); + string serializedItem = this.GetSerializedToDoActivity(); + CosmosObject cosmosObject = CosmosObject.Parse(serializedItem); + cosmosElements.Add(cosmosObject); + + ResponseMessage cosmosResponse = QueryResponse.CreateSuccess( + cosmosElements, + 1, + Encoding.UTF8.GetByteCount(serializedItem), + new CosmosQueryResponseMessageHeaders( + continauationToken: null, + disallowContinuationTokenMessage: null, + resourceType: Documents.ResourceType.Document, + "+o4fAPfXPzw="), + new CosmosDiagnosticsContextCore(), + null); + + return cosmosResponse; + } + + private ResponseMessage CreateReadFeedResponse() + { + string documentWrapper = $"{{\"_rid\":\"+o4fAPfXPzw=\",\"Documents\":[{this.GetSerializedToDoActivity()}],\"_count\":1}}"; + ResponseMessage cosmosResponse = new ResponseMessage(statusCode: HttpStatusCode.OK) + { + Content = new MemoryStream(Encoding.UTF8.GetBytes(documentWrapper)) + }; + + return cosmosResponse; + } + + private string GetSerializedToDoActivity() + { + return @"{""id"":""c1d433c1-369d-430e-91e5-14e3ce588f71"",""taskNum"":42,""cost"":1.7976931348623157E+308,""status"":""TBD""}"; + } + public class ToDoActivity { public string id { get; set; } From f09b097861e45c4043ca2eb2a19ab368799af5aa Mon Sep 17 00:00:00 2001 From: Jake Willey Date: Thu, 30 Apr 2020 11:06:59 -0700 Subject: [PATCH 3/5] Updating documentation --- Microsoft.Azure.Cosmos/src/CosmosClient.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Microsoft.Azure.Cosmos/src/CosmosClient.cs b/Microsoft.Azure.Cosmos/src/CosmosClient.cs index 44dd665115..95ed65d80b 100644 --- a/Microsoft.Azure.Cosmos/src/CosmosClient.cs +++ b/Microsoft.Azure.Cosmos/src/CosmosClient.cs @@ -257,8 +257,14 @@ internal CosmosClient( public virtual CosmosClientOptions ClientOptions => this.ClientContext.ClientOptions; /// - /// The response factory used to initialize CosmosClient response types + /// The response factory used to create CosmosClient response types. /// + /// + /// This can be used for generating responses for tests, and allows users to create + /// a custom container that modifies the response. For example the client encryption + /// uses this to decrypt responses before returning to the caller. + /// user composition to + /// public virtual CosmosResponseFactory ResponseFactory => this.ClientContext.ResponseFactory; /// From 3cbd3e4fbff851ae22b488c594c818e749e982be Mon Sep 17 00:00:00 2001 From: Jake Willey Date: Thu, 30 Apr 2020 11:17:19 -0700 Subject: [PATCH 4/5] Added preview flag to API --- Microsoft.Azure.Cosmos/src/CosmosClient.cs | 7 ++++- .../src/Resource/CosmosResponseFactory.cs | 10 +++--- .../DotNetSDKAPI.json | 31 ------------------- 3 files changed, 12 insertions(+), 36 deletions(-) diff --git a/Microsoft.Azure.Cosmos/src/CosmosClient.cs b/Microsoft.Azure.Cosmos/src/CosmosClient.cs index 95ed65d80b..df5c20d062 100644 --- a/Microsoft.Azure.Cosmos/src/CosmosClient.cs +++ b/Microsoft.Azure.Cosmos/src/CosmosClient.cs @@ -265,7 +265,12 @@ internal CosmosClient( /// uses this to decrypt responses before returning to the caller. /// user composition to /// - public virtual CosmosResponseFactory ResponseFactory => this.ClientContext.ResponseFactory; +#if PREVIEW + public +#else + internal +#endif + virtual CosmosResponseFactory ResponseFactory => this.ClientContext.ResponseFactory; /// /// Gets the endpoint Uri for the Azure Cosmos DB service. diff --git a/Microsoft.Azure.Cosmos/src/Resource/CosmosResponseFactory.cs b/Microsoft.Azure.Cosmos/src/Resource/CosmosResponseFactory.cs index 71c79ce2d7..475707079a 100644 --- a/Microsoft.Azure.Cosmos/src/Resource/CosmosResponseFactory.cs +++ b/Microsoft.Azure.Cosmos/src/Resource/CosmosResponseFactory.cs @@ -4,16 +4,18 @@ namespace Microsoft.Azure.Cosmos { - using System; - using System.IO; - using System.Threading.Tasks; using Microsoft.Azure.Cosmos.Scripts; /// /// This response factory converts response messages /// to the corresponding type response. /// - public abstract class CosmosResponseFactory +#if PREVIEW + public +#else + internal +#endif + abstract class CosmosResponseFactory { /// /// Creates a FeedResponse from a response message diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/DotNetSDKAPI.json b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/DotNetSDKAPI.json index 2ee3b3410d..27589cc42c 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/DotNetSDKAPI.json +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/DotNetSDKAPI.json @@ -1300,16 +1300,6 @@ "Attributes": [], "MethodInfo": "Microsoft.Azure.Cosmos.CosmosClientOptions get_ClientOptions()" }, - "Microsoft.Azure.Cosmos.CosmosResponseFactory get_ResponseFactory()": { - "Type": "Method", - "Attributes": [], - "MethodInfo": "Microsoft.Azure.Cosmos.CosmosResponseFactory get_ResponseFactory()" - }, - "Microsoft.Azure.Cosmos.CosmosResponseFactory ResponseFactory": { - "Type": "Property", - "Attributes": [], - "MethodInfo": null - }, "Microsoft.Azure.Cosmos.Database GetDatabase(System.String)": { "Type": "Method", "Attributes": [], @@ -1916,27 +1906,6 @@ }, "NestedTypes": {} }, - "CosmosResponseFactory": { - "Subclasses": {}, - "Members": { - "Microsoft.Azure.Cosmos.FeedResponse`1[T] CreateItemFeedResponse[T](Microsoft.Azure.Cosmos.ResponseMessage)": { - "Type": "Method", - "Attributes": [], - "MethodInfo": "Microsoft.Azure.Cosmos.FeedResponse`1[T] CreateItemFeedResponse[T](Microsoft.Azure.Cosmos.ResponseMessage)" - }, - "Microsoft.Azure.Cosmos.ItemResponse`1[T] CreateItemResponse[T](Microsoft.Azure.Cosmos.ResponseMessage)": { - "Type": "Method", - "Attributes": [], - "MethodInfo": "Microsoft.Azure.Cosmos.ItemResponse`1[T] CreateItemResponse[T](Microsoft.Azure.Cosmos.ResponseMessage)" - }, - "Microsoft.Azure.Cosmos.Scripts.StoredProcedureExecuteResponse`1[T] CreateStoredProcedureExecuteResponse[T](Microsoft.Azure.Cosmos.ResponseMessage)": { - "Type": "Method", - "Attributes": [], - "MethodInfo": "Microsoft.Azure.Cosmos.Scripts.StoredProcedureExecuteResponse`1[T] CreateStoredProcedureExecuteResponse[T](Microsoft.Azure.Cosmos.ResponseMessage)" - } - }, - "NestedTypes": {} - }, "CosmosSerializationOptions": { "Subclasses": {}, "Members": { From d1188dde0c83798e8c04b61f1b3aeaa6123da9fb Mon Sep 17 00:00:00 2001 From: Jake Willey Date: Fri, 1 May 2020 14:43:39 -0700 Subject: [PATCH 5/5] fixed comments --- Microsoft.Azure.Cosmos/src/CosmosClient.cs | 1 - Microsoft.Azure.Cosmos/src/Resource/CosmosResponseFactory.cs | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Microsoft.Azure.Cosmos/src/CosmosClient.cs b/Microsoft.Azure.Cosmos/src/CosmosClient.cs index df5c20d062..57dcf9ca41 100644 --- a/Microsoft.Azure.Cosmos/src/CosmosClient.cs +++ b/Microsoft.Azure.Cosmos/src/CosmosClient.cs @@ -263,7 +263,6 @@ internal CosmosClient( /// This can be used for generating responses for tests, and allows users to create /// a custom container that modifies the response. For example the client encryption /// uses this to decrypt responses before returning to the caller. - /// user composition to /// #if PREVIEW public diff --git a/Microsoft.Azure.Cosmos/src/Resource/CosmosResponseFactory.cs b/Microsoft.Azure.Cosmos/src/Resource/CosmosResponseFactory.cs index 475707079a..371d25f880 100644 --- a/Microsoft.Azure.Cosmos/src/Resource/CosmosResponseFactory.cs +++ b/Microsoft.Azure.Cosmos/src/Resource/CosmosResponseFactory.cs @@ -8,7 +8,8 @@ namespace Microsoft.Azure.Cosmos /// /// This response factory converts response messages - /// to the corresponding type response. + /// to the corresponding type response using the + /// CosmosClient serializer /// #if PREVIEW public