Ejemplo n.º 1
0
        /// <summary>
        /// Stores provisioning completed event.
        /// </summary>
        /// <param name="provisioningCompletedEventModel">Event to store</param>
        /// <param name="logger">Logger to log data</param>
        /// <returns>Stored provisioning completed event</returns>
        public async Task <ProvisioningCompletedEventModel> CreateAsync(ProvisioningCompletedEventModel provisioningCompletedEventModel, ILogger logger)
        {
            var message = JsonConvert.SerializeObject(provisioningCompletedEventModel);

            // Encode message to Base64 before sending to the queue
            await this.queue.SendMessageAsync(QueueServiceHelper.EncodeToBase64(message)).ConfigureAwait(false);

            logger.LogInformation($"ProvisioningCompletedEventStorageService::CreateAsync successfully added request to the queue: provisioningCompletedEventModel={LogHelper.FormatObjectForLog(provisioningCompletedEventModel)}");

            return(provisioningCompletedEventModel);
        }
        /// <summary>
        /// Provisions processed assets
        /// </summary>
        /// <param name="provisioningRequestModel">Request to process</param>
        /// <param name="logger">Logger to log data</param>
        /// <returns>Task for async operation</returns>
        public async Task ProvisionAsync(ProvisioningRequestModel provisioningRequestModel, ILogger logger)
        {
            logger.LogInformation($"ProvisioningOrchestrator::ProvisionAsync started: provisioningRequestModel={LogHelper.FormatObjectForLog(provisioningRequestModel)}");

            // Create provisioning completed event and start filling out data
            var provisioningCompletedEventModel = new ProvisioningCompletedEventModel
            {
                Id        = Guid.NewGuid().ToString(),
                AssetName = provisioningRequestModel.ProcessedAssetName
            };

            // Iterate through all available provisioning services and let each service handle provisioning request.
            // Services are called in the same order as in the list, in most cases that is important, provisioning services may have dependency on each other
            foreach (var service in this.provisioningServices)
            {
                // provisioningCompletedEventModel is updated with each call
                await service.ProvisionAsync(provisioningRequestModel, provisioningCompletedEventModel, logger).ConfigureAwait(false);
            }

            // Provisioning is done, store event
            await this.provisioningCompletedEventStorageService.CreateAsync(provisioningCompletedEventModel, logger).ConfigureAwait(false);

            logger.LogInformation($"ProvisioningOrchestrator::ProvisionAsync completed: provisioningRequestModel={LogHelper.FormatObjectForLog(provisioningRequestModel)}");
        }
        /// <summary>
        /// Provisions clear streaming locator in all Azure Media Services instances for a given processed asset.
        /// </summary>
        /// <param name="provisioningRequest">Provisioning request associated with processed asset</param>
        /// <param name="provisioningCompletedEventModel">Provision completed event model to store provisioning data</param>
        /// <param name="logger">Logger to log data</param>
        /// <returns></returns>
        public async Task ProvisionAsync(ProvisioningRequestModel provisioningRequest, ProvisioningCompletedEventModel provisioningCompletedEventModel, ILogger logger)
        {
            logger.LogInformation($"ClearStreamingProvisioningService::ProvisionAsync started: provisioningRequest={LogHelper.FormatObjectForLog(provisioningRequest)}");

            // Make sure that account name that asset is provisioned exists in current configuration
            if (!this.configService.MediaServiceInstanceConfiguration.ContainsKey(provisioningRequest.ProcessedAssetMediaServiceAccountName))
            {
                throw new Exception($"ClearStreamingProvisioningService::ProvisionAsync does not have configuration for account={provisioningRequest.ProcessedAssetMediaServiceAccountName}");
            }

            // Get source configuration that asset is provisioned as part of encoding job
            var sourceClientConfiguration = this.configService.MediaServiceInstanceConfiguration[provisioningRequest.ProcessedAssetMediaServiceAccountName];

            // Get Azure Media Services instance client associated with provisioned asset
            var sourceClient = this.mediaServiceInstanceFactory.GetMediaServiceInstance(provisioningRequest.ProcessedAssetMediaServiceAccountName, logger);

            // Create locator for the source instance
            var sourceLocator = new StreamingLocator(
                assetName: provisioningRequest.ProcessedAssetName,
                streamingPolicyName: PredefinedStreamingPolicy.ClearStreamingOnly);

            // Provision created locator
            sourceLocator = await ProvisionLocatorAsync(
                sourceClient,
                sourceClientConfiguration,
                provisioningRequest.ProcessedAssetName,
                provisioningRequest.StreamingLocatorName,
                sourceLocator,
                logger).ConfigureAwait(false);

            // Record the fact that locator was created
            provisioningCompletedEventModel.AddClearStreamingLocators(sourceLocator);

            // Create a list of Azure Media Services instances that locator needs to be provisioned. It should be all instances listed in configuration, except source instance
            var targetInstances = this.configService.MediaServiceInstanceConfiguration.Keys.Where(
                i => !i.Equals(provisioningRequest.ProcessedAssetMediaServiceAccountName, StringComparison.InvariantCultureIgnoreCase));

            // Iterate through the list of all Azure Media Services instance names that locator needs to be provisioned to
            foreach (var target in targetInstances)
            {
                // Get target configuration
                var targetClientConfiguration = this.configService.MediaServiceInstanceConfiguration[target];

                // Get client associated with target instance
                var targetClient = this.mediaServiceInstanceFactory.GetMediaServiceInstance(target, logger);

                // Create locator for target instance
                var targetLocator = new StreamingLocator(
                    assetName: sourceLocator.AssetName,
                    streamingPolicyName: sourceLocator.StreamingPolicyName,
                    id: sourceLocator.Id,
                    name: sourceLocator.Name,
                    type: sourceLocator.Type,
                    streamingLocatorId: sourceLocator.StreamingLocatorId);

                // Provision created locator
                targetLocator = await ProvisionLocatorAsync(
                    targetClient,
                    targetClientConfiguration,
                    provisioningRequest.ProcessedAssetName,
                    provisioningRequest.StreamingLocatorName,
                    targetLocator,
                    logger).ConfigureAwait(false);

                // Record fact that locator was provisioned to target instance
                provisioningCompletedEventModel.AddClearStreamingLocators(targetLocator);
            }

            logger.LogInformation($"ClearStreamingProvisioningService::ProvisionAsync completed: provisioningRequest={LogHelper.FormatObjectForLog(provisioningRequest)}");
        }
        /// <summary>
        /// Provisions clear key streaming locator in all Azure Media Services instances for a given processed asset.
        /// This implementation is based on https://github.com/Azure-Samples/media-services-v3-dotnet-core-tutorials/tree/master/NETCore/EncodeHTTPAndPublishAESEncrypted
        /// </summary>
        /// <param name="provisioningRequest">Provisioning request associated with processed asset</param>
        /// <param name="provisioningCompletedEventModel">Provision completed event model to store provisioning data</param>
        /// <param name="logger">Logger to log data</param>
        /// <returns></returns>
        public async Task ProvisionAsync(ProvisioningRequestModel provisioningRequest, ProvisioningCompletedEventModel provisioningCompletedEventModel, ILogger logger)
        {
            logger.LogInformation($"OutputEncryptionStreamingProvisioningService::ProvisionAsync started: provisioningRequest={LogHelper.FormatObjectForLog(provisioningRequest)}");

            // Make sure that account name that asset is provisioned exists in current configuration
            if (!this.configService.MediaServiceInstanceConfiguration.ContainsKey(provisioningRequest.ProcessedAssetMediaServiceAccountName))
            {
                throw new Exception($"OutputEncryptionStreamingProvisioningService::ProvisionAsync does not have configuration for account={provisioningRequest.ProcessedAssetMediaServiceAccountName}");
            }

            // Get source configuration that asset is provisioned as part of processing job
            var sourceClientConfiguration = this.configService.MediaServiceInstanceConfiguration[provisioningRequest.ProcessedAssetMediaServiceAccountName];

            // Create a custom streaming locator name, it has to differ from originally requested locator name to avoid name collision
            var streamingLocatorName = $"{provisioningRequest.StreamingLocatorName}-encrypted";

            // Get Azure Media Services instance client associated with provisioned asset
            var sourceClient = this.mediaServiceInstanceFactory.GetMediaServiceInstance(provisioningRequest.ProcessedAssetMediaServiceAccountName, logger);

            // Create locator for the source instance
            var sourceLocator = new StreamingLocator(
                assetName: provisioningRequest.ProcessedAssetName,
                streamingPolicyName: PredefinedStreamingPolicy.ClearKey,
                defaultContentKeyPolicyName: this.configService.ContentKeyPolicyName);

            // Provision created locator
            sourceLocator = await ProvisionLocatorAsync(
                sourceClient,
                sourceClientConfiguration,
                provisioningRequest.ProcessedAssetName,
                streamingLocatorName,
                sourceLocator,
                logger).ConfigureAwait(false);

            // Record the fact that locator was created
            provisioningCompletedEventModel.AddClearKeyStreamingLocators(sourceLocator);

            // List all content keys
            var sourceContentKeysResponse = await sourceClient.StreamingLocators.ListContentKeysAsync(sourceClientConfiguration.ResourceGroup, sourceClientConfiguration.AccountName, streamingLocatorName).ConfigureAwait(false);

            var keyIdentifier = sourceContentKeysResponse.ContentKeys.First().Id.ToString();

            // Generate primary URL for streaming, it includes token to decrypt content
            provisioningCompletedEventModel.PrimaryUrl = await this.GenerateStreamingUrl(sourceClient, sourceClientConfiguration, streamingLocatorName, keyIdentifier).ConfigureAwait(false);

            // Create a list of Azure Media Services instances that locator needs to be provisioned. It should be all instances listed in configuration, except source instance
            var targetInstances = this.configService.MediaServiceInstanceConfiguration.Keys.Where(
                i => !i.Equals(provisioningRequest.ProcessedAssetMediaServiceAccountName, StringComparison.InvariantCultureIgnoreCase));

            // Iterate through the list of all Azure Media Services instance names that locator needs to be provisioned to
            foreach (var target in targetInstances)
            {
                // Get target configuration
                var targetClientConfiguration = this.configService.MediaServiceInstanceConfiguration[target];

                // Get client associated with target instance
                var targetClient = this.mediaServiceInstanceFactory.GetMediaServiceInstance(target, logger);

                // Create locator for target instance
                var targetLocator = new StreamingLocator(
                    assetName: sourceLocator.AssetName,
                    streamingPolicyName: sourceLocator.StreamingPolicyName,
                    id: sourceLocator.Id,
                    name: sourceLocator.Name,
                    type: sourceLocator.Type,
                    streamingLocatorId: sourceLocator.StreamingLocatorId,
                    defaultContentKeyPolicyName: sourceLocator.DefaultContentKeyPolicyName,
                    contentKeys: sourceContentKeysResponse.ContentKeys);

                // Provision created locator
                targetLocator = await ProvisionLocatorAsync(
                    targetClient,
                    targetClientConfiguration,
                    provisioningRequest.ProcessedAssetName,
                    streamingLocatorName,
                    targetLocator,
                    logger).ConfigureAwait(false);

                // Record fact that locator was provisioned to target instance
                provisioningCompletedEventModel.AddClearKeyStreamingLocators(targetLocator);
            }

            logger.LogInformation($"OutputEncryptionStreamingProvisioningService::ProvisionAsync completed: provisioningRequest={LogHelper.FormatObjectForLog(provisioningRequest)}");
        }
        /// <summary>
        /// Provisions processed assets from Azure Media Services source instance to all other Azure Media Services instances.
        /// </summary>
        /// <param name="provisioningRequestModel">Model to provision</param>
        /// <param name="provisioningCompletedEventModel">Provision completed event model to store provisioning data</param>
        /// <param name="logger">Logger to log data</param>
        public async Task ProvisionAsync(ProvisioningRequestModel provisioningRequest, ProvisioningCompletedEventModel provisioningCompletedEventModel, ILogger logger)
        {
            logger.LogInformation($"AssetDataProvisioningService::ProvisionAsync started: provisioningRequest={LogHelper.FormatObjectForLog(provisioningRequest)}");

            // Make sure that account name that asset is provisioned exists in current configuration
            if (!this.configService.MediaServiceInstanceConfiguration.ContainsKey(provisioningRequest.ProcessedAssetMediaServiceAccountName))
            {
                throw new Exception($"AssetDataProvisioningService::ProvisionAsync does not have configuration for account={provisioningRequest.ProcessedAssetMediaServiceAccountName}");
            }

            // Get source configuration that asset is provisioned as part of encoding job
            var sourceClientConfiguration = this.configService.MediaServiceInstanceConfiguration[provisioningRequest.ProcessedAssetMediaServiceAccountName];

            provisioningCompletedEventModel.AddMediaServiceAccountName(provisioningRequest.ProcessedAssetMediaServiceAccountName);

            // Get Azure Media Services instance client associated with provisioned asset
            var sourceClient = this.mediaServiceInstanceFactory.GetMediaServiceInstance(provisioningRequest.ProcessedAssetMediaServiceAccountName, logger);

            // Create a list of Azure Media Services instances that asset needs to be provisioned. It should be all instances listed in configuration, except source instance
            var targetInstances = this.configService.MediaServiceInstanceConfiguration.Keys.Where(
                i => !i.Equals(provisioningRequest.ProcessedAssetMediaServiceAccountName, StringComparison.InvariantCultureIgnoreCase));

            // Iterate through the list of all Azure Media Services instance names that asset needs to be provisioned to
            foreach (var target in targetInstances)
            {
                // Get target configuration
                var targetClientConfiguration = this.configService.MediaServiceInstanceConfiguration[target];

                // Get client associated with target instance
                var targetClient = this.mediaServiceInstanceFactory.GetMediaServiceInstance(target, logger);

                // Copy data from source instance to target instance
                var asset = await this.CopyAssetAsync(sourceClient, sourceClientConfiguration, targetClient, targetClientConfiguration, provisioningRequest, logger).ConfigureAwait(false);

                // Record fact that asset was provisioned to target instance
                provisioningCompletedEventModel.AddMediaServiceAccountName(target);
            }

            logger.LogInformation($"AssetDataProvisioningService::ProvisionAsync completed: provisioningRequest={LogHelper.FormatObjectForLog(provisioningRequest)}");
        }