public async void MediaServicesEncoderEncodeNullTest() { // Arrange RequestMediaServicesV3EncodeCreateDTO encodeCreateDTO = null; // Assert var amsEncoder = new MediaServicesV3Encoder(Log, StorageService, AmsV3Services); await Xunit.Assert.ThrowsAsync <ArgumentNullException>(async() => await amsEncoder.EncodeCreateAsync(encodeCreateDTO).ConfigureAwait(false)).ConfigureAwait(false); }
private static string GetExpectedOutputAssetName(RequestMediaServicesV3EncodeCreateDTO encodeCreateDTO) { var expectedAssetName = $"{MediaServicesV3TestData.GoodOutputAccountName}-{MediaServicesV3TestData.GoodOutputContainer}"; if (Uri.TryCreate(encodeCreateDTO?.OutputContainer, UriKind.Absolute, out Uri outputContainerUri)) { var bub = new BlobUriBuilder(outputContainerUri); expectedAssetName = $"{bub.AccountName}-{bub.BlobContainerName}"; } return(expectedAssetName); }
/// <summary> /// EncodeCreateAsync does the heavy lifting to encode and process a video asset in Azure Media Services V3. /// </summary> /// <param name="encodeCreateDTO">Data payload for creating an AMS V3 encode.</param> /// <returns>Returns true if encode request was successful, otherwise false.</returns> public async Task <ServiceOperationResultEncodeDispatched> EncodeCreateAsync(RequestMediaServicesV3EncodeCreateDTO encodeCreateDTO) { _ = encodeCreateDTO ?? throw new ArgumentNullException(nameof(encodeCreateDTO)); // 1. Get or create the transform // 2. Create input asset // 3. Create output asset // 4. Call the encode // 5. Confirm success to base class var operationContext = encodeCreateDTO.OperationContext; // 1. Get or create the transform try { if (string.IsNullOrWhiteSpace(encodeCreateDTO.TransformName)) { throw new ArgumentOutOfRangeException(nameof(encodeCreateDTO), "TransformName can not be null or whitespace"); } } catch (Exception e) { throw new GridwichEncodeCreateDataException("Invalid inputs found in EncodeCreateDTO.", encodeCreateDTO.OperationContext, e, LogEventIds.MediaServicesV3EncodeCreateDtoError); } try { await _amsV3Service.CreateTransformIfNotExistByNameAsync(encodeCreateDTO.TransformName, operationContext).ConfigureAwait(false); } catch (Exception e) { throw new GridwichMediaServicesV3CreateTransformException($"Error creating AMS V3 Transform: {encodeCreateDTO.TransformName}", LogEventIds.MediaServicesV3TransformError, operationContext, e); } // 2. Create input asset var sourceUris = Enumerable.Empty <Uri>(); try { sourceUris = encodeCreateDTO.Inputs.Select(u => new Uri(u.BlobUri, UriKind.Absolute)); if (!sourceUris.Any() || sourceUris.Count() != encodeCreateDTO.Inputs.Count()) { throw new ArgumentException("Could not parse Inputs.", nameof(encodeCreateDTO)); } // Check that all the blobs actually exist. // Create a new muted context for these operations, based on the Op context if available. var internalCorrelator = (operationContext != null) ? operationContext.DeepClone() as JObject : new JObject(); internalCorrelator.Add("~AMS-V3-Encode", $"G:{Guid.NewGuid()}"); var context = new StorageClientProviderContext(internalCorrelator, muted: true); foreach (var blobUri in sourceUris) { var exists = await _storageService.GetBlobExistsAsync(blobUri, context).ConfigureAwait(false); if (!exists) { _log.LogEventObject(LogEventIds.MediaServicesV3AttemptToUseNonexistentBlob, blobUri); throw new GridwichMediaServicesV3Exception($"Attempt to use nonexistent blob as input: {blobUri}", LogEventIds.MediaServicesV3AttemptToUseNonexistentBlob, context.ClientRequestIdAsJObject); } } } catch (Exception e) when(!(e is GridwichMediaServicesV3Exception)) { throw new GridwichEncodeCreateDataException("Invalid inputs found in EncodeCreateDTO.", encodeCreateDTO.OperationContext, e, LogEventIds.MediaServicesV3EncodeCreateDtoError); } string inputAssetName = null; try { inputAssetName = await _amsV3Service.CreateOrUpdateAssetForContainerAsync(sourceUris).ConfigureAwait(false); } catch (Exception e) { throw new GridwichMediaServicesV3CreateAssetException("Error creating/getting AMS V3 Asset.", LogEventIds.MediaServicesV3InputAssetError, operationContext, e); } // 4. Create output asset. Uri outputUri = null; try { outputUri = new Uri(encodeCreateDTO.OutputContainer, UriKind.Absolute); } catch (Exception e) { throw new GridwichEncodeInvalidOutputContainerException($"Invalid output container specified: {encodeCreateDTO.OutputContainer}", operationContext, e, LogEventIds.MediaServicesV3OutputError); } string outputAssetName = null; try { outputAssetName = await _amsV3Service.CreateOrUpdateAssetForContainerAsync(Enumerable.Empty <Uri>().Append(outputUri)).ConfigureAwait(false); } catch (Exception e) { throw new GridwichMediaServicesV3CreateAssetException($"Error creating/getting AMS V3 output Asset: {outputUri}.", LogEventIds.MediaServicesV3OutputError, operationContext, e); } // 5. Execute Encode var uniqueness = Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture).Substring(0, 11); var jobName = outputAssetName + "-" + uniqueness; try { await _amsV3Service.CreateJobAsync(encodeCreateDTO.TransformName, inputAssetName, outputAssetName, jobName, encodeCreateDTO.TimeBasedEncode, new Dictionary <string, string>() { { "mediaServicesV3EncoderSpecificData", JsonConvert.SerializeObject(encodeCreateDTO) }, { "inputAssetName", inputAssetName }, { "outputAssetContainer", encodeCreateDTO.OutputContainer }, { "outputAssetName", outputAssetName }, { "operationContext", encodeCreateDTO.OperationContext.ToString() } }, operationContext).ConfigureAwait(false); } catch (Exception e) { throw new GridwichEncodeCreateJobException($"Error creating AMS V3 job: {jobName}", operationContext, e, LogEventIds.MediaServicesV3CreateJobApiError); } // 6. Confirm success to base class _log.LogEvent(LogEventIds.MediaServicesV3JobSubmitCalled, $"AMS V3 job successfully logged: {jobName}"); return(new ServiceOperationResultEncodeDispatched( workflowJobName: jobName, null, encodeCreateDTO.OperationContext)); }
public async void EncodeCreateAsync_Is_As_ExpectedAsync( RequestMediaServicesV3EncodeCreateDTO encodeCreateDTO, ServiceOperationResultEncodeDispatched expectedEncodeDispatched, Type expectedExceptionType) { // Arrange string expectedOutputAssetName = GetExpectedOutputAssetName(encodeCreateDTO); output.WriteLine($"Using expectedOutputAssetName: {expectedOutputAssetName}"); // Arrange Mocks Mock.Get(AmsV3Services) .Setup(x => x.CreateTransformIfNotExistByNameAsync(It.IsAny <string>(), It.IsAny <JObject>())); Mock.Get(StorageService) .Setup(x => x.GetBlobExistsAsync(It.IsAny <Uri>(), It.IsAny <StorageClientProviderContext>())) .ReturnsAsync(true); Mock.Get(AmsV3Services) .Setup(x => x.CreateJobAsync(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <string>(), It.IsAny <string>(), It.IsAny <TimeBasedEncodeDTO>(), It.IsAny <Dictionary <string, string> >(), It.IsAny <JObject>())); Mock.Get(AmsV3Services) .Setup(x => x.CreateOrUpdateAssetForContainerAsync(It.IsAny <IEnumerable <Uri> >())) .ReturnsAsync(expectedOutputAssetName); // Act var amsEncoder = new MediaServicesV3Encoder(Log, StorageService, AmsV3Services); ServiceOperationResultEncodeDispatched encodeDispatched = null; var exception = await Record.ExceptionAsync(async() => { encodeDispatched = await amsEncoder.EncodeCreateAsync(encodeCreateDTO).ConfigureAwait(true); }).ConfigureAwait(true); // Assert if (expectedExceptionType == null) { // Success cases exception.ShouldBeNull(); } else { // Failure cases exception.ShouldBeOfType(expectedExceptionType); } if (expectedEncodeDispatched != null) { // Success cases if (MediaServicesV3TestData.ServiceOperationResultEncodeDispatched_Is_Expected.WorkflowJobName == null) { encodeDispatched.WorkflowJobName.ShouldBeNull(); } else { encodeDispatched.WorkflowJobName.StartsWith(expectedOutputAssetName); } if (MediaServicesV3TestData.ServiceOperationResultEncodeDispatched_Is_Expected.EncoderContext == null) { encodeDispatched.EncoderContext.ShouldBeNull(); } else { encodeDispatched.EncoderContext.ShouldBe(MediaServicesV3TestData.ServiceOperationResultEncodeDispatched_Is_Expected.EncoderContext); } if (MediaServicesV3TestData.ServiceOperationResultEncodeDispatched_Is_Expected.OperationContext == null) { encodeDispatched.OperationContext.ShouldBeNull(); } else { encodeDispatched.OperationContext.ShouldBe(MediaServicesV3TestData.ServiceOperationResultEncodeDispatched_Is_Expected.OperationContext); } } else { // Failure cases encodeDispatched.ShouldBeNull(); } }