private static async Task <DocumentClientException> CreateDocumentClientException(HttpResponseMessage responseMessage) { Stream readStream = await responseMessage.Content.ReadAsStreamAsync(); Error error = CosmosResource.LoadFrom <Error>(readStream); // ensure there is no local ActivityId, since in Gateway mode ActivityId // should always come from message headers Trace.CorrelationManager.ActivityId = Guid.Empty; bool isNameBased = false; bool isFeed = false; string resourceTypeString; string resourceIdOrFullName; string resourceLink = responseMessage.RequestMessage.RequestUri.LocalPath; if (!PathsHelper.TryParsePathSegments(resourceLink, out isFeed, out resourceTypeString, out resourceIdOrFullName, out isNameBased)) { // if resourceLink is invalid - we will not set resourceAddress in exception. } return(new DocumentClientException(error, responseMessage.Headers, responseMessage.StatusCode) { StatusDescription = responseMessage.ReasonPhrase, ResourceAddress = resourceIdOrFullName }); }
private async Task <AccountProperties> GetDatabaseAccountAsync(Uri serviceEndpoint) { INameValueCollection headers = new DictionaryNameValueCollection(StringComparer.Ordinal); string authorizationToken = string.Empty; if (this.hasAuthKeyResourceToken) { authorizationToken = HttpUtility.UrlEncode(this.authKeyResourceToken); } else { // Retrieve the document service properties. string xDate = DateTime.UtcNow.ToString("r", CultureInfo.InvariantCulture); headers.Set(HttpConstants.HttpHeaders.XDate, xDate); authorizationToken = AuthorizationHelper.GenerateKeyAuthorizationSignature( HttpConstants.HttpMethods.Get, serviceEndpoint, headers, this.authKeyHashFunction); } headers.Set(HttpConstants.HttpHeaders.Authorization, authorizationToken); using (HttpResponseMessage responseMessage = await this.httpClient.GetAsync(serviceEndpoint, headers)) { using (DocumentServiceResponse documentServiceResponse = await ClientExtensions.ParseResponseAsync(responseMessage)) { return(CosmosResource.FromStream <AccountProperties>(documentServiceResponse)); } } }
public override Task <CosmosStoredProcedureResponse> CreateStoredProcedureAsync( string id, string body, CosmosRequestOptions requestOptions = null, CancellationToken cancellationToken = default(CancellationToken)) { if (string.IsNullOrEmpty(id)) { throw new ArgumentNullException(nameof(id)); } if (string.IsNullOrEmpty(body)) { throw new ArgumentNullException(nameof(body)); } CosmosStoredProcedureSettings storedProcedureSettings = new CosmosStoredProcedureSettings(); storedProcedureSettings.Id = id; storedProcedureSettings.Body = body; Task <CosmosResponseMessage> response = ExecUtils.ProcessResourceOperationStreamAsync( this.container.Database.Client, this.container.LinkUri, ResourceType.StoredProcedure, OperationType.Create, requestOptions, partitionKey: null, streamPayload: CosmosResource.ToStream(storedProcedureSettings), requestEnricher: null, cancellationToken: cancellationToken); return(this.client.ResponseFactory.CreateStoredProcedureResponse(this[id], response)); }
public override Task <CosmosStoredProcedureResponse> CreateStoredProcedureAsync( string id, string body, CosmosRequestOptions requestOptions = null, CancellationToken cancellationToken = default(CancellationToken)) { if (string.IsNullOrEmpty(id)) { throw new ArgumentNullException(nameof(id)); } if (string.IsNullOrEmpty(body)) { throw new ArgumentNullException(nameof(body)); } CosmosStoredProcedureSettings storedProcedureSettings = new CosmosStoredProcedureSettings { Id = id, Body = body }; Task <CosmosResponseMessage> response = this.clientContext.ProcessResourceOperationStreamAsync( resourceUri: this.container.LinkUri, resourceType: ResourceType.StoredProcedure, operationType: OperationType.Create, requestOptions: requestOptions, cosmosContainerCore: this.container, partitionKey: null, streamPayload: CosmosResource.ToStream(storedProcedureSettings), requestEnricher: null, cancellationToken: cancellationToken); return(this.clientContext.ResponseFactory.CreateStoredProcedureResponse(this[id], response)); }
/// <summary> /// Replaces a <see cref="CosmosTriggerSettings"/> in the Azure Cosmos service as an asynchronous operation. /// </summary> /// <param name="triggerSettings">The <see cref="CosmosTriggerSettings"/> object.</param> /// <param name="requestOptions">(Optional) The options for the trigger request <see cref="CosmosRequestOptions"/></param> /// <param name="cancellationToken">(Optional) <see cref="CancellationToken"/> representing request cancellation.</param> /// <returns> /// A <see cref="Task"/> containing a <see cref="CosmosTriggerResponse"/> which wraps a <see cref="CosmosTriggerSettings"/> containing the updated resource record. /// </returns> /// <exception cref="ArgumentNullException">If <paramref name="triggerSettings"/> is not set.</exception> /// <exception cref="CosmosException">This exception can encapsulate many different types of errors. To determine the specific error always look at the StatusCode property. Some common codes you may get when creating a Document are: /// <list type="table"> /// <listheader> /// <term>StatusCode</term><description>Reason for exception</description> /// </listheader> /// <item> /// <term>404</term><description>NotFound - This means the resource you tried to delete did not exist.</description> /// </item> /// </list> /// </exception> /// <example> /// This examples replaces an existing trigger. /// <code language="c#"> /// <![CDATA[ /// //Updated settings /// CosmosTriggerSettings settings = new CosmosTriggerSettings /// { /// Id = "testTriggerId", /// Body = @"function AddTax() { /// var item = getContext().getRequest().getBody(); /// /// // Validate/calculate the tax. /// item.tax = item.cost* .15; /// /// // Update the request -- this is what is going to be inserted. /// getContext().getRequest().setBody(item); /// }", /// TriggerOperation = TriggerOperation.All, /// TriggerType = TriggerType.Post /// }; /// /// CosmosTriggerResponse response = await this.cosmosTrigger.ReplaceAsync(settings); /// ]]> /// </code> /// </example> public virtual Task <CosmosTriggerResponse> ReplaceAsync( CosmosTriggerSettings triggerSettings, CosmosRequestOptions requestOptions = null, CancellationToken cancellationToken = default(CancellationToken)) { return(this.ProcessAsync( partitionKey: null, streamPayload: CosmosResource.ToStream(triggerSettings), operationType: OperationType.Replace, requestOptions: requestOptions, cancellationToken: cancellationToken)); }
internal static T FromStream <T>(DocumentServiceResponse response) { if (response == null) { throw new ArgumentNullException(nameof(response)); } if (response.ResponseBody != null && (!response.ResponseBody.CanSeek || response.ResponseBody.Length > 0)) { return(CosmosResource.FromStream <T>(response.ResponseBody)); } return(default);
internal Task <CosmosDatabaseResponse> CreateDatabaseAsync( CosmosDatabaseSettings databaseSettings, int?throughput = null, CosmosRequestOptions requestOptions = null, CancellationToken cancellationToken = default(CancellationToken)) { Task <CosmosResponseMessage> response = this.CreateDatabaseStreamAsync( streamPayload: CosmosResource.ToStream(databaseSettings), throughput: throughput, requestOptions: requestOptions, cancellationToken: cancellationToken); return(this.clientContext.ResponseFactory.CreateDatabaseResponse(this[databaseSettings.Id], response)); }
public override Task <CosmosContainerResponse> ReplaceAsync( CosmosContainerSettings containerSettings, CosmosContainerRequestOptions requestOptions = null, CancellationToken cancellationToken = default(CancellationToken)) { this.Client.DocumentClient.ValidateResource(containerSettings.Id); Task <CosmosResponseMessage> response = this.ReplaceStreamAsync( streamPayload: CosmosResource.ToStream(containerSettings), requestOptions: requestOptions, cancellationToken: cancellationToken); return(this.Client.ResponseFactory.CreateContainerResponse(this, response)); }
private static async Task <DocumentClientException> CreateDocumentClientException(HttpResponseMessage responseMessage) { // ensure there is no local ActivityId, since in Gateway mode ActivityId // should always come from message headers Trace.CorrelationManager.ActivityId = Guid.Empty; string resourceLink = responseMessage.RequestMessage.RequestUri.LocalPath; if (!PathsHelper.TryParsePathSegments( resourceLink, out bool isFeed, out string resourceTypeString, out string resourceIdOrFullName, out bool isNameBased)) { // if resourceLink is invalid - we will not set resourceAddress in exception. } // If service rejects the initial payload like header is to large it will return an HTML error instead of JSON. if (string.Equals(responseMessage.Content?.Headers?.ContentType?.MediaType, ClientExtensions.MediaTypeJson, StringComparison.OrdinalIgnoreCase)) { Stream readStream = await responseMessage.Content.ReadAsStreamAsync(); Error error = CosmosResource.LoadFrom <Error>(readStream); return(new DocumentClientException( error, responseMessage.Headers, responseMessage.StatusCode) { StatusDescription = responseMessage.ReasonPhrase, ResourceAddress = resourceIdOrFullName }); } else { string message = responseMessage.Content == null ? null : await responseMessage.Content.ReadAsStringAsync(); return(new DocumentClientException( message: message, innerException: null, responseHeaders: responseMessage.Headers, statusCode: responseMessage.StatusCode, requestUri: responseMessage.RequestMessage.RequestUri) { StatusDescription = responseMessage.ReasonPhrase, ResourceAddress = resourceIdOrFullName }); } }
/// <summary> /// Creates a user defined function as an asynchronous operation in the Azure Cosmos DB service. /// </summary> /// <param name="userDefinedFunctionSettings">The <see cref="CosmosUserDefinedFunctionSettings"/> object.</param> /// <param name="requestOptions">(Optional) The options for the user defined function request <see cref="CosmosRequestOptions"/></param> /// <param name="cancellationToken">(Optional) <see cref="CancellationToken"/> representing request cancellation.</param> /// <returns>A task object representing the service response for the asynchronous operation.</returns> /// <exception cref="ArgumentNullException">If <paramref name="userDefinedFunctionSettings"/> is not set.</exception> /// <exception cref="System.AggregateException">Represents a consolidation of failures that occurred during async processing. Look within InnerExceptions to find the actual exception(s)</exception> /// <exception cref="CosmosException">This exception can encapsulate many different types of errors. To determine the specific error always look at the StatusCode property. Some common codes you may get when creating a user defined function are: /// <list type="table"> /// <listheader> /// <term>StatusCode</term><description>Reason for exception</description> /// </listheader> /// <item> /// <term>400</term><description>BadRequest - This means something was wrong with the request supplied. It is likely that an Id was not supplied for the new user defined function or that the Body was malformed.</description> /// </item> /// <item> /// <term>403</term><description>Forbidden - You have reached your quota of user defined functions for the collection supplied. Contact support to have this quota increased.</description> /// </item> /// <item> /// <term>409</term><description>Conflict - This means a <see cref="CosmosUserDefinedFunctionSettings"/> with an id matching the id you supplied already existed.</description> /// </item> /// <item> /// <term>413</term><description>RequestEntityTooLarge - This means the body of the <see cref="CosmosUserDefinedFunctionSettings"/> you tried to create was too large.</description> /// </item> /// </list> /// </exception> /// <example> /// This creates a user defined function then uses the function in an item query. /// <code language="c#"> /// <![CDATA[ /// /// await this.container.UserDefinedFunctions.CreateUserDefinedFunctionAsync( /// new CosmosUserDefinedFunctionSettings /// { /// Id = "calculateTax", /// Body = @"function(amt) { return amt * 0.05; }" /// }); /// /// CosmosSqlQueryDefinition sqlQuery = new CosmosSqlQueryDefinition( /// "SELECT VALUE udf.calculateTax(t.cost) FROM toDoActivity t where t.cost > @expensive and t.status = @status") /// .UseParameter("@expensive", 9000) /// .UseParameter("@status", "Done"); /// /// CosmosResultSetIterator<double> setIterator = this.container.Items.CreateItemQuery<double>( /// sqlQueryDefinition: sqlQuery, /// partitionKey: "Done"); /// /// while (setIterator.HasMoreResults) /// { /// foreach (var tax in await setIterator.FetchNextSetAsync()) /// { /// Console.WriteLine(tax); /// } /// } /// ]]> /// </code> /// </example> public virtual Task <CosmosUserDefinedFunctionResponse> CreateUserDefinedFunctionAsync( CosmosUserDefinedFunctionSettings userDefinedFunctionSettings, CosmosRequestOptions requestOptions = null, CancellationToken cancellationToken = default(CancellationToken)) { Task <CosmosResponseMessage> response = this.clientContext.ProcessResourceOperationStreamAsync( resourceUri: this.container.LinkUri, resourceType: ResourceType.UserDefinedFunction, operationType: OperationType.Create, requestOptions: requestOptions, cosmosContainerCore: this.container, partitionKey: null, streamPayload: CosmosResource.ToStream(userDefinedFunctionSettings), requestEnricher: null, cancellationToken: cancellationToken); return(this.clientContext.ResponseFactory.CreateUserDefinedFunctionResponse(this[userDefinedFunctionSettings.Id], response)); }
/// <summary> /// Creates a trigger as an asynchronous operation in the Azure Cosmos DB service. /// </summary> /// <param name="triggerSettings">The <see cref="CosmosTriggerSettings"/> object.</param> /// <param name="requestOptions">(Optional) The options for the stored procedure request <see cref="CosmosRequestOptions"/></param> /// <param name="cancellationToken">(Optional) <see cref="CancellationToken"/> representing request cancellation.</param> /// <returns>A task object representing the service response for the asynchronous operation.</returns> /// <exception cref="ArgumentNullException">If <paramref name="triggerSettings"/> is not set.</exception> /// <exception cref="System.AggregateException">Represents a consolidation of failures that occurred during async processing. Look within InnerExceptions to find the actual exception(s)</exception> /// <exception cref="CosmosException">This exception can encapsulate many different types of errors. To determine the specific error always look at the StatusCode property. Some common codes you may get when creating a Document are: /// <list type="table"> /// <listheader> /// <term>StatusCode</term><description>Reason for exception</description> /// </listheader> /// <item> /// <term>400</term><description>BadRequest - This means something was wrong with the request supplied. It is likely that an Id was not supplied for the new trigger or that the Body was malformed.</description> /// </item> /// <item> /// <term>403</term><description>Forbidden - You have reached your quota of triggers for the collection supplied. Contact support to have this quota increased.</description> /// </item> /// <item> /// <term>409</term><description>Conflict - This means a <see cref="CosmosTriggerSettings"/> with an id matching the id you supplied already existed.</description> /// </item> /// <item> /// <term>413</term><description>RequestEntityTooLarge - This means the body of the <see cref="CosmosTriggerSettings"/> you tried to create was too large.</description> /// </item> /// </list> /// </exception> /// <example> /// This creates a trigger then uses the trigger in a create item. /// <code language="c#"> /// <![CDATA[ /// CosmosTrigger cosmosTrigger = await this.container.Triggers.CreateTriggerAsync( /// new CosmosTriggerSettings /// { /// Id = "addTax", /// Body = @"function AddTax() { /// var item = getContext().getRequest().getBody(); /// /// // calculate the tax. /// item.tax = item.cost * .15; /// /// // Update the request -- this is what is going to be inserted. /// getContext().getRequest().setBody(item); /// }", /// TriggerOperation = TriggerOperation.All, /// TriggerType = TriggerType.Pre /// }); /// /// CosmosItemRequestOptions options = new CosmosItemRequestOptions() /// { /// PreTriggers = new List<string>() { cosmosTrigger.Id }, /// }; /// /// // Create a new item with trigger set in the request options /// CosmosItemResponse<dynamic> createdItem = await this.container.Items.CreateItemAsync<dynamic>(item.status, item, options); /// double itemTax = createdItem.Resource.tax; /// ]]> /// </code> /// </example> public virtual Task <CosmosTriggerResponse> CreateTriggerAsync( CosmosTriggerSettings triggerSettings, CosmosRequestOptions requestOptions = null, CancellationToken cancellationToken = default(CancellationToken)) { Task <CosmosResponseMessage> response = ExecUtils.ProcessResourceOperationStreamAsync( this.container.Database.Client, this.container.LinkUri, ResourceType.Trigger, OperationType.Create, requestOptions, partitionKey: null, streamPayload: CosmosResource.ToStream(triggerSettings), requestEnricher: null, cancellationToken: cancellationToken); return(this.client.ResponseFactory.CreateTriggerResponse(this[triggerSettings.Id], response)); }
private async Task <CosmosAccountSettings> GetDatabaseAccountAsync(Uri serviceEndpoint) { HttpClient httpClient = this.messageHandler == null ? new HttpClient() : new HttpClient(this.messageHandler); httpClient.DefaultRequestHeaders.Add(HttpConstants.HttpHeaders.Version, HttpConstants.Versions.CurrentVersion); // Send client version. httpClient.AddUserAgentHeader(this.connectionPolicy.UserAgentContainer); httpClient.AddApiTypeHeader(this.apiType); string authorizationToken = string.Empty; if (this.hasAuthKeyResourceToken) { authorizationToken = HttpUtility.UrlEncode(this.authKeyResourceToken); } else { // Retrieve the document service properties. string xDate = DateTime.UtcNow.ToString("r", CultureInfo.InvariantCulture); httpClient.DefaultRequestHeaders.Add(HttpConstants.HttpHeaders.XDate, xDate); INameValueCollection headersCollection = new StringKeyValueCollection(); headersCollection.Add(HttpConstants.HttpHeaders.XDate, xDate); authorizationToken = AuthorizationHelper.GenerateKeyAuthorizationSignature( HttpConstants.HttpMethods.Get, serviceEndpoint, headersCollection, this.authKeyHashFunction); } httpClient.DefaultRequestHeaders.Add(HttpConstants.HttpHeaders.Authorization, authorizationToken); using (HttpResponseMessage responseMessage = await httpClient.GetHttpAsync( serviceEndpoint)) { using (DocumentServiceResponse documentServiceResponse = await ClientExtensions.ParseResponseAsync(responseMessage)) { return(CosmosResource.FromStream <CosmosAccountSettings>(documentServiceResponse)); } } }
internal StoredProcedureResponse(DocumentServiceResponse response, JsonSerializerSettings serializerSettings = null) { this.response = response; this.serializerSettings = serializerSettings; if (typeof(TValue).IsSubclassOf(typeof(JsonSerializable))) { // load resource if (typeof(TValue) == typeof(Document) || typeof(Document).IsAssignableFrom(typeof(TValue))) { this.responseBody = CosmosResource.LoadFromWithConstructor <TValue>(response.ResponseBody, () => (TValue)(object)new Document(), this.serializerSettings); } else if (typeof(TValue) == typeof(Attachment) || typeof(Attachment).IsAssignableFrom(typeof(TValue))) { this.responseBody = CosmosResource.LoadFromWithConstructor <TValue>(response.ResponseBody, () => (TValue)(object)new Attachment(), this.serializerSettings); } else { // sprocs should only have access to documents and attachments throw new ArgumentException("Cannot serialize object if it is not document or attachment"); } } else { // For empty response body use dummy stream and let the serialization take care of the rest, // so that e.g. for TValue = string that would be fine - null string, and for TValue = int -- an error. using (MemoryStream responseStream = new MemoryStream()) using (StreamReader responseReader = new StreamReader(response.ResponseBody ?? responseStream)) { string responseString = responseReader.ReadToEnd(); try { this.responseBody = (TValue)JsonConvert.DeserializeObject(responseString, typeof(TValue), this.serializerSettings); } catch (JsonException ex) { // Don't expose JsonNewton exceptions to the user, convert to appropriate .net exception. throw new SerializationException( string.Format(CultureInfo.InvariantCulture, "Failed to deserialize stored procedure response or convert it to type '{0}': {1}", typeof(TValue).FullName, ex.Message), ex); } } } }
public override Task <CosmosContainerResponse> CreateContainerAsync( CosmosContainerSettings containerSettings, int?throughput = null, CosmosRequestOptions requestOptions = null, CancellationToken cancellationToken = default(CancellationToken)) { if (containerSettings == null) { throw new ArgumentNullException(nameof(containerSettings)); } this.ValidateContainerSettings(containerSettings); Task <CosmosResponseMessage> response = this.CreateContainerStreamAsync( streamPayload: CosmosResource.ToStream(containerSettings), throughput: throughput, requestOptions: requestOptions, cancellationToken: cancellationToken); return(this.client.ResponseFactory.CreateContainerResponse(this[containerSettings.Id], response)); }
public override Task <CosmosStoredProcedureResponse> ReplaceAsync( string body, CosmosRequestOptions requestOptions = null, CancellationToken cancellationToken = default(CancellationToken)) { if (string.IsNullOrEmpty(body)) { throw new ArgumentNullException(nameof(body)); } CosmosStoredProcedureSettings storedProcedureSettings = new CosmosStoredProcedureSettings() { Id = this.Id, Body = body, }; return(this.ProcessAsync( partitionKey: null, streamPayload: CosmosResource.ToStream(storedProcedureSettings), operationType: OperationType.Replace, requestOptions: requestOptions, cancellationToken: cancellationToken)); }
public virtual async Task <AccountProperties> GetDatabaseAccountAsync(HttpRequestMessage requestMessage, CancellationToken cancellationToken = default(CancellationToken)) { AccountProperties databaseAccount = null; // Get the ServiceDocumentResource from the gateway. using (HttpResponseMessage responseMessage = await this.gatewayStoreClient.SendHttpAsync(requestMessage, cancellationToken)) { using (DocumentServiceResponse documentServiceResponse = await ClientExtensions.ParseResponseAsync(responseMessage)) { databaseAccount = CosmosResource.FromStream <AccountProperties>(documentServiceResponse); } long longValue; IEnumerable <string> headerValues; if (responseMessage.Headers.TryGetValues(HttpConstants.HttpHeaders.MaxMediaStorageUsageInMB, out headerValues) && (headerValues.Count() != 0)) { if (long.TryParse(headerValues.First(), out longValue)) { databaseAccount.MaxMediaStorageUsageInMB = longValue; } } if (responseMessage.Headers.TryGetValues(HttpConstants.HttpHeaders.CurrentMediaStorageUsageInMB, out headerValues) && (headerValues.Count() != 0)) { if (long.TryParse(headerValues.First(), out longValue)) { databaseAccount.MediaStorageUsageInMB = longValue; } } if (responseMessage.Headers.TryGetValues(HttpConstants.HttpHeaders.DatabaseAccountConsumedDocumentStorageInMB, out headerValues) && (headerValues.Count() != 0)) { if (long.TryParse(headerValues.First(), out longValue)) { databaseAccount.ConsumedDocumentStorageInMB = longValue; } } if (responseMessage.Headers.TryGetValues(HttpConstants.HttpHeaders.DatabaseAccountProvisionedDocumentStorageInMB, out headerValues) && (headerValues.Count() != 0)) { if (long.TryParse(headerValues.First(), out longValue)) { databaseAccount.ProvisionedDocumentStorageInMB = longValue; } } if (responseMessage.Headers.TryGetValues(HttpConstants.HttpHeaders.DatabaseAccountReservedDocumentStorageInMB, out headerValues) && (headerValues.Count() != 0)) { if (long.TryParse(headerValues.First(), out longValue)) { databaseAccount.ReservedDocumentStorageInMB = longValue; } } } return(databaseAccount); }