public async Task TestBatchApiRequestsOneRequestAsync() { Trace.WriteLine("POST /batch"); // Start the batch request BatchApiRequest.StartNewBatchRequest(); try { // Make the API calls to be batched await Template.GetTemplatesAsync(); // Make the batch API Reqeust var batchResponses = await BatchApiRequest.SendBatchApiRequest(); // Validate the response to the batch API request ValidateBatchApiCallResponses(batchResponses, 1); // Validate the response to the individual API call ValidateIndividualBatchedApiCallResponse <List <Template> >(batchResponses[0]); } catch (AggregateException exception) { Assert.Fail(exception.ToString()); } }
public async Task TestBatchApiRequestsAbortRequestAsync() { Trace.WriteLine("POST /batch"); // Start the batch request BatchApiRequest.StartNewBatchRequest(); try { // Make the API call to be batched await Template.GetTemplatesAsync(); // Abort the batch request BatchApiRequest.AbortBatchRequest(); // Make another API call and make sure it goes through var snippets = await Snippet.GetSnippetsAsync(); SendwithusClientTest.ValidateResponse(snippets); // Make the aborted batch API Reqeust anyways var batchResponses = await BatchApiRequest.SendBatchApiRequest(); // Make sure no API calls were included in the batch request (empty request) ValidateBatchApiCallResponses(batchResponses, 0); } catch (AggregateException exception) { Assert.Fail(exception.ToString()); } }
public long DetermineRequiredDiskSpace(BatchApiRequest request) { if (request.Operation.Equals(LfsOperationNames.UPLOAD)) { return(request.Objects.Sum(o => o.Size)); } return(0L); }
public ActionResult GitLfsBatchAPI(string repositoryName, BatchApiRequest requestObj) { Guid userGuid = User.Id(); var result = LfsService.GetBatchApiResponse(Request.Url.Scheme, Request.Url.Authority, Request.ApplicationPath, repositoryName, Request.AcceptTypes, requestObj, userGuid); Response.StatusCode = result.HttpStatusCode; return(Content( Newtonsoft.Json.JsonConvert.SerializeObject(result.Content, this.LfsService.GetJsonSerializerSettings()), GitLfsConsts.GIT_LFS_CONTENT_TYPE)); }
public async Task TestBatchApiRequestsTenRequestsAsync() { Trace.WriteLine("POST /batch"); // Start the batch request BatchApiRequest.StartNewBatchRequest(); // Make the API calls to be batched (at least one of each type) try { await TemplateTest.BuildAndSendCreateTemplateRequestWithAllParametersAsync(); // POST await Snippet.GetSnippetsAsync(); // GET await Customer.GetCustomerAsync(CustomerTest.DEFAULT_CUSTOMER_EMAIL_ADDRESS); // GET await RenderTest.BuildAndSendRenderTemplateRequestWithAllParametersId(); // POST await Log.GetLogEventsAsync(BatchApiRequestTest.DEFAULT_LOG_ID); // GET await Customer.GetCustomerAsync(CustomerTest.DEFAULT_CUSTOMER_EMAIL_ADDRESS); // GET await EmailTest.BuildAndSendEmailWithAllParametersAsync(); // POST await DripCampaign.GetDripCampaignsAsync(); // GET await Customer.GetCustomerAsync(CustomerTest.DEFAULT_CUSTOMER_EMAIL_ADDRESS); // GET await Customer.GetCustomerAsync(CustomerTest.DEFAULT_CUSTOMER_EMAIL_ADDRESS); // GET // Make the batch Api Reqeust var batchResponses = await BatchApiRequest.SendBatchApiRequest(); // Validate the response to the batch API request ValidateBatchApiCallResponses(batchResponses, 10); // Validate the response to the individual API calls ValidateIndividualBatchedApiCallResponse <Template>(batchResponses[0]); ValidateIndividualBatchedApiCallResponse <List <Snippet> >(batchResponses[1]); ValidateIndividualBatchedApiCallResponse <Customer>(batchResponses[2]); ValidateIndividualBatchedApiCallResponse <RenderTemplateResponse>(batchResponses[3]); ValidateIndividualBatchedApiCallResponse <List <Log> >(batchResponses[4]); ValidateIndividualBatchedApiCallResponse <Customer>(batchResponses[5]); ValidateIndividualBatchedApiCallResponse <EmailResponse>(batchResponses[6]); ValidateIndividualBatchedApiCallResponse <List <DripCampaignDetails> >(batchResponses[7]); ValidateIndividualBatchedApiCallResponse <Customer>(batchResponses[8]); ValidateIndividualBatchedApiCallResponse <Customer>(batchResponses[9]); } catch (AggregateException exception) { Assert.Fail(exception.ToString()); } }
/// <summary> /// Sends an HTTP DELETE request and returns the reponse as a JSON string /// </summary> /// <param name="resource">The resource identifier for the resource to be called (after /api/<version></version>/)</param> /// <returns>The response content in the form of a JSON string</returns> /// <exception cref="AggregateException">Thrown when the API response status code is not success or when the API call times out</exception> /// <exception cref="InvalidOperationException">Thrown when the call is made in batch mode but the current batch has no more room for additional API calls</exception> public static async Task <string> SendDeleteRequestAsync(string resource) { using (var client = new HttpClient()) { // Prepare the DELETE request ConfigureHttpClient(client); var uri = BuildFullResourceString(resource); // If batch mode is enabled then add the request to the current batch of requests to send later on if (BatchApiRequest.IsBatchApiModeEnabled() == true) { BatchApiRequest.AddApiRequest(new BatchApiRequest(uri, "DELETE")); return(String.Empty); } // Otherwise, send the DELETE request else { return(await RunWithRetries(() => client.DeleteAsync(uri))); } } }
private async Task <BatchRequestResponse> SendBatchRequestAsync(Func <Task> executeRequests) { BatchApiRequest.StartNewBatchRequest(); try { bool isBatchSuccess = true; var data = new List <object>(); await executeRequests(); List <BatchApiResponse> batchResponses = await BatchApiRequest.SendBatchApiRequest(); for (int i = 0; i < batchResponses.Count; i++) { BatchApiResponse batchResponse = batchResponses[i]; if (batchResponse.status_code != 200) { isBatchSuccess = false; BatchApiRequest.AbortBatchRequest(); break; } var body = batchResponses[i].GetBody <object>(); data.Add(body); } var response = new BatchRequestResponse(isBatchSuccess, "200", data.ToJson()); return(response); } catch (AggregateException ex) { BatchApiRequest.AbortBatchRequest(); return(new BatchRequestResponse(false, "500", null, ex.ToString())); } catch (InvalidOperationException ex) { BatchApiRequest.AbortBatchRequest(); return(new BatchRequestResponse(false, "500", null, ex.ToString())); } }
public async Task TestBatchApiRequestsPauseAndResumeRequestAsync() { Trace.WriteLine("POST /batch"); // Start the batch request BatchApiRequest.StartNewBatchRequest(); try { // Make the API call to be batched await Template.GetTemplatesAsync(); // Pause the batch request BatchApiRequest.PauseBatchRequest(); // Make another API call and make sure it goes through var snippets = await Snippet.GetSnippetsAsync(); SendwithusClientTest.ValidateResponse(snippets); // Resume the batch request and add another API call to it BatchApiRequest.ResumeBatchRequest(); await Customer.GetCustomerAsync(CustomerTest.DEFAULT_CUSTOMER_EMAIL_ADDRESS); // Make the final batch request var batchResponses = await BatchApiRequest.SendBatchApiRequest(); // Make sure both API calls were included in the batch request ValidateBatchApiCallResponses(batchResponses, 2); // Valideate each of those requests ValidateIndividualBatchedApiCallResponse <List <Template> >(batchResponses[0]); ValidateIndividualBatchedApiCallResponse <Customer>(batchResponses[1]); } catch (AggregateException exception) { Assert.Fail(exception.ToString()); } }
/// <summary> /// Sends an HTTP PUT request and returns the reponse as a JSON string /// </summary> /// <param name="resource">The resource identifier for the resource to be called (after /api/<version>/)</param> /// <param name="content">The object to be sent with the PUT request. Will be converted to JSON in this function</param> /// <returns>The response content in the form of a JSON string</returns> /// <exception cref="AggregateException">Thrown when the API response status code is not success or when the API call times out</exception> /// <exception cref="InvalidOperationException">Thrown when making a Batch API Request that has already reached the maxmimum API calls per batch request</exception> public static async Task <string> SendPutRequestAsync(string resource, object content) { using (var client = new HttpClient()) { // Prepare the PUT request ConfigureHttpClient(client); var uri = BuildFullResourceString(resource); var httpContent = ConvertObjectToJsonHttpContent(content); // If batch mode is enabled then add the request to the current batch of requests to send later on if (BatchApiRequest.IsBatchApiModeEnabled() == true) { BatchApiRequest.AddApiRequest(new BatchApiRequest(uri, "PUT", content)); return(String.Empty); } // Otherwise, send the PUT request else { return(await RunWithRetries(() => client.PutAsync(uri, httpContent))); } } }
/// <summary> /// Sends an HTTP GET request and returns the reponse as a JSON string /// </summary> /// <param name="resource">The resource identifier for the resource to be called (after /api/<version>/)</param> /// <param name="queryParameters">The query parameters to use with the API call</param> /// <returns>The response content in the form of a JSON string</returns> /// <exception cref="AggregateException">Thrown when the API response status code is not success or when the API call times out</exception> /// <exception cref="InvalidOperationException">Thrown when making a Batch API Request that has already reached the maxmimum API calls per batch request</exception> public static async Task <string> SendGetRequestAsync(string resource, Dictionary <string, object> queryParameters) { using (var client = new HttpClient()) { // Prepare the GET request ConfigureHttpClient(client); var queryString = ConvertQueryParametersToQueryString(queryParameters); var uri = String.Format("{0}{1}", BuildFullResourceString(resource), queryString); // If batch mode is enabled then add the request to the current batch of requests to send later on if (BatchApiRequest.IsBatchApiModeEnabled() == true) { BatchApiRequest.AddApiRequest(new BatchApiRequest(uri, "GET")); return(String.Empty); } // Otherwise, send the GET request else { return(await RunWithRetries(() => client.GetAsync(uri))); } } }
public async Task TestBatchApiRequestsTwelveRequestsWithoutOverrideAsync() { Trace.WriteLine("POST /batch"); // Start the batch request BatchApiRequest.StartNewBatchRequest(); // Override the maximum number of API calls that can be included in this batch BatchApiRequest.OverrideMaximumBatchRequests(12); // Make the API calls to be batched (at least one of each type) try { await TemplateTest.BuildAndSendCreateTemplateRequestWithAllParametersAsync(); // POST await Snippet.GetSnippetsAsync(); // GET await Customer.GetCustomerAsync(CustomerTest.DEFAULT_CUSTOMER_EMAIL_ADDRESS); // GET await RenderTest.BuildAndSendRenderTemplateRequestWithAllParametersId(); // POST await Log.GetLogEventsAsync(BatchApiRequestTest.DEFAULT_LOG_ID); // GET await Customer.GetCustomerAsync(CustomerTest.DEFAULT_CUSTOMER_EMAIL_ADDRESS); // GET await EmailTest.BuildAndSendEmailWithAllParametersAsync(); // POST await DripCampaign.GetDripCampaignsAsync(); // GET await Customer.GetCustomerAsync(CustomerTest.DEFAULT_CUSTOMER_EMAIL_ADDRESS); // GET await Customer.GetCustomerAsync(CustomerTest.DEFAULT_CUSTOMER_EMAIL_ADDRESS); // GET await Customer.GetCustomerAsync(CustomerTest.DEFAULT_CUSTOMER_EMAIL_ADDRESS); // GET // Make the batch Api Request var batchResponses = await BatchApiRequest.SendBatchApiRequest(); // Validate the response to the batch API request ValidateBatchApiCallResponses(batchResponses, 11); // Validate the response to the individual API calls ValidateIndividualBatchedApiCallResponse <Template>(batchResponses[0]); ValidateIndividualBatchedApiCallResponse <List <Snippet> >(batchResponses[1]); ValidateIndividualBatchedApiCallResponse <Customer>(batchResponses[2]); ValidateIndividualBatchedApiCallResponse <RenderTemplateResponse>(batchResponses[3]); ValidateIndividualBatchedApiCallResponse <List <Log> >(batchResponses[4]); ValidateIndividualBatchedApiCallResponse <Customer>(batchResponses[5]); ValidateIndividualBatchedApiCallResponse <EmailResponse>(batchResponses[6]); ValidateIndividualBatchedApiCallResponse <List <DripCampaignDetails> >(batchResponses[7]); ValidateIndividualBatchedApiCallResponse <Customer>(batchResponses[8]); ValidateIndividualBatchedApiCallResponse <Customer>(batchResponses[9]); ValidateIndividualBatchedApiCallResponse <Customer>(batchResponses[10]); } catch (InvalidOperationException exception) { Trace.WriteLine(String.Format("Successfully caught exception triggered by adding too many API calls to the batch API request. Error message: {0}", exception.Message)); Assert.IsTrue(true); } finally { // Return the max batch request limit to its default value BatchApiRequest.SetMaximumBatchRequestsToDefault(); } }
public async Task TestBatchApiRequestsElevenRequestsWithoutOverrideAsync() { Trace.WriteLine("POST /batch"); // Start the batch request BatchApiRequest.StartNewBatchRequest(); try { // Make the API calls to be batched (at least one of each type) await TemplateTest.BuildAndSendCreateTemplateRequestWithAllParametersAsync(); // POST await Snippet.GetSnippetsAsync(); // GET await Customer.GetCustomerAsync(CustomerTest.DEFAULT_CUSTOMER_EMAIL_ADDRESS); // GET await RenderTest.BuildAndSendRenderTemplateRequestWithAllParametersId(); // POST await Log.GetLogEventsAsync(BatchApiRequestTest.DEFAULT_LOG_ID); // GET await Customer.GetCustomerAsync(CustomerTest.DEFAULT_CUSTOMER_EMAIL_ADDRESS); // GET await EmailTest.BuildAndSendEmailWithAllParametersAsync(); // POST await DripCampaign.GetDripCampaignsAsync(); // GET await Customer.GetCustomerAsync(CustomerTest.DEFAULT_CUSTOMER_EMAIL_ADDRESS); // GET await Customer.GetCustomerAsync(CustomerTest.DEFAULT_CUSTOMER_EMAIL_ADDRESS); // GET // Add the 11th API Request try { await Customer.GetCustomerAsync(CustomerTest.DEFAULT_CUSTOMER_EMAIL_ADDRESS); // GET } catch (InvalidOperationException exception) { Trace.WriteLine(String.Format("Successfully caught exception triggered by adding too many API calls to the batch API request. Error message: {0}", exception.Message)); Assert.IsTrue(true); } // Send the batch AP Request and make sure it still goes through (with the previous 10 requests included) var batchResponses = await BatchApiRequest.SendBatchApiRequest(); // Validate the response to the batch API request ValidateBatchApiCallResponses(batchResponses, 10); // Validate the response to the individual API calls ValidateIndividualBatchedApiCallResponse <Template>(batchResponses[0]); ValidateIndividualBatchedApiCallResponse <List <Snippet> >(batchResponses[1]); ValidateIndividualBatchedApiCallResponse <Customer>(batchResponses[2]); ValidateIndividualBatchedApiCallResponse <RenderTemplateResponse>(batchResponses[3]); await Log.GetLogEventsAsync(BatchApiRequestTest.DEFAULT_LOG_ID); // GET ValidateIndividualBatchedApiCallResponse <Customer>(batchResponses[5]); ValidateIndividualBatchedApiCallResponse <EmailResponse>(batchResponses[6]); ValidateIndividualBatchedApiCallResponse <List <DripCampaignDetails> >(batchResponses[7]); ValidateIndividualBatchedApiCallResponse <Customer>(batchResponses[8]); ValidateIndividualBatchedApiCallResponse <Customer>(batchResponses[9]); } catch (AggregateException exception) { Assert.Fail(exception.ToString()); } }
public GitLfsResult GetBatchApiResponse(string urlScheme, string urlAuthority, string requestApplicationPath, string repositoryName, string[] acceptTypes, BatchApiRequest requestObj, Guid userId) { // Validate the request. if (!acceptTypes .Select(at => at.Split(new[] { ';' })) .SelectMany(list => list) .Any(at => at.Equals("application/vnd.git-lfs+json"))) { return(GitLfsResult.From( Newtonsoft.Json.JsonConvert.SerializeObject( new BatchApiErrorResponse() { Message = "Invalid ContentType." }), 406, GitLfsConsts.GIT_LFS_CONTENT_TYPE)); } // Check permissions RepositoryAccessLevel accessLevelRequested; if (requestObj.Operation.Equals(LfsOperationNames.DOWNLOAD)) { accessLevelRequested = RepositoryAccessLevel.Pull; } else if (requestObj.Operation.Equals(LfsOperationNames.UPLOAD)) { accessLevelRequested = RepositoryAccessLevel.Push; } else { accessLevelRequested = RepositoryAccessLevel.Administer; } bool authorized = RepositoryPermissionService.HasPermission(userId, RepositoryRepository.GetRepository(repositoryName).Id, accessLevelRequested); if (!authorized) { return(GitLfsResult.From( Newtonsoft.Json.JsonConvert.SerializeObject( new BatchApiErrorResponse() { Message = "You do not have the required permissions." }), 403, GitLfsConsts.GIT_LFS_CONTENT_TYPE)); } if (requestObj == null) { return(GitLfsResult.From( Newtonsoft.Json.JsonConvert.SerializeObject( new BatchApiErrorResponse() { Message = "Cannot parse request body." }), 400, GitLfsConsts.GIT_LFS_CONTENT_TYPE)); } // Process the request. var requestedTransferAdapters = requestObj.Transfers ?? (new string[] { LfsTransferProviderNames.BASIC }); string firstSupportedTransferAdapter = requestedTransferAdapters.FirstOrDefault(t => t.Equals(LfsTransferProviderNames.BASIC)); if (firstSupportedTransferAdapter != null) { string transferAdapterToUse = firstSupportedTransferAdapter; var requiredSpace = DetermineRequiredDiskSpace(requestObj); if (StorageProvider.SufficientSpace(requiredSpace)) { BatchApiResponse responseObj = new BatchApiResponse() { Transfer = transferAdapterToUse, Objects = requestObj.Objects .Select(ro => new { ro, ActionFactory = new LfsActionFactory() }) .Select(x => new BatchApiResponse.BatchApiObject() { Oid = x.ro.Oid, Size = x.ro.Size, Authenticated = true, Actions = x.ActionFactory.CreateBatchApiObjectActions(urlScheme, urlAuthority, requestApplicationPath, requestObj.Operation, x.ro, repositoryName, StorageProvider) }) .ToArray() }; return(GitLfsResult.From(responseObj, 200, GitLfsConsts.GIT_LFS_CONTENT_TYPE)); } else { return(GitLfsResult.From(new BatchApiErrorResponse() { Message = "Insufficient storage space." }, 507, GitLfsConsts.GIT_LFS_CONTENT_TYPE)); } } else { // None of the requested transfer adapters are supported. return(GitLfsResult.From(new BatchApiErrorResponse() { Message = $"None of the requested transfer adapters are supported." }, 400, GitLfsConsts.GIT_LFS_CONTENT_TYPE)); } }