/// <summary> /// Creates or updates Media Service call history record /// </summary> /// <param name="mediaServiceCallHistoryModel">Data to store</param> /// <param name="logger">Logger to log</param> /// <returns>Stored model</returns> public async Task <MediaServiceCallHistoryModel> CreateOrUpdateAsync(MediaServiceCallHistoryModel mediaServiceCallHistoryModel, ILogger logger) { var mediaServiceCallHistoryResult = await this.tableStorageService.CreateOrUpdateAsync(new MediaServiceCallHistoryModelTableEntity(mediaServiceCallHistoryModel)).ConfigureAwait(false); var mediaServiceCallHistoryModelResult = mediaServiceCallHistoryResult.GetMediaServiceCallHistoryModel(); logger.LogInformation($"MediaServiceCallHistoryStorageService::CreateOrUpdateAsync completed: mediaServiceCallHistoryModel={LogHelper.FormatObjectForLog(mediaServiceCallHistoryModelResult)}"); return(mediaServiceCallHistoryModelResult); }
/// <summary> /// Constructor to create object from MediaServiceCallHistoryModel object /// </summary> /// <param name="mediaServiceCallHistoryModel">source object</param> public MediaServiceCallHistoryModelTableEntity(MediaServiceCallHistoryModel mediaServiceCallHistoryModel) { this.PartitionKey = mediaServiceCallHistoryModel.MediaServiceAccountName; this.RowKey = mediaServiceCallHistoryModel.Id; this.MediaServiceCallHistoryModelId = mediaServiceCallHistoryModel.Id; this.HttpStatus = (int)mediaServiceCallHistoryModel.HttpStatus; this.MediaServiceAccountName = mediaServiceCallHistoryModel.MediaServiceAccountName; this.EventTime = mediaServiceCallHistoryModel.EventTime; this.CallInfo = mediaServiceCallHistoryModel.CallInfo; }
/// <summary> /// Sends http request to server. /// </summary> /// <param name="request">request to send</param> /// <param name="cancellationToken">cancellation token</param> /// <returns></returns> protected override async Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { HttpResponseMessage response; try { response = await base.SendAsync(request, cancellationToken).ConfigureAwait(false); } catch (Exception) { // any exception triggers reconnect to Media Services API this.mediaServiceInstanceFactory.ResetMediaServiceInstance(); throw; } // any 5xx errors triggers reconnect to Media Services API if ((int)response.StatusCode > 499) { this.mediaServiceInstanceFactory.ResetMediaServiceInstance(); } // Typical path that is used here, need to parse it // /subscriptions/<subscriptionId>/resourceGroups/<resourceGroypName>/providers/Microsoft.Media/mediaServices/<accountName>/assets/<assetName> // or // /subscriptions/<subscriptionId>/resourceGroups/<resourceGroypName>/providers/Microsoft.Media/mediaServices/<accountName>/transforms/<transformName>/jobs/<jobName> var items = request.RequestUri.AbsolutePath.Split('/'); var amsOperations = items.SkipWhile(i => !i.Equals("mediaServices", StringComparison.InvariantCultureIgnoreCase)).ToList(); var accountName = string.Empty; var callInfo = string.Empty; if (amsOperations.Count > 1) { // account name always follows mediaServices string accountName = amsOperations.ElementAt(1); } if (amsOperations.Count > 2) { // everything else after account name callInfo = string.Join("/", amsOperations.Skip(2)); } // Create model and initialize common field values var mediaServiceCallHistoryModel = new MediaServiceCallHistoryModel { Id = Guid.NewGuid().ToString(), MediaServiceAccountName = accountName, CallInfo = $"{request.Method} {callInfo}", EventTime = DateTime.UtcNow, HttpStatus = response.StatusCode }; // In order to keep this operation idempotent, there is no need to fail even if recording call data fails. Otherwise when request is resubmitted it can result in data duplication. var retryCount = 3; var retryTimeOut = 1000; do { try { // try to store data await this.mediaServiceCallHistoryStorageService.CreateOrUpdateAsync(mediaServiceCallHistoryModel, this.logger).ConfigureAwait(false); // no exception, break break; } #pragma warning disable CA1031 // Do not catch general exception types catch (Exception e) #pragma warning restore CA1031 // Do not catch general exception types { this.logger.LogError($"CallHistoryHandler::SendAsync got exception calling mediaServiceCallHistoryStorageService.CreateOrUpdateAsync: retryCount={retryCount} message={e.Message} mediaServiceCallHistoryModel={LogHelper.FormatObjectForLog(mediaServiceCallHistoryModel)}"); retryCount--; await Task.Delay(retryTimeOut).ConfigureAwait(false); } }while (retryCount > 0); return(response); }