Пример #1
0
        /// <summary>
        /// Does the heavy lifting, encodes the asset.
        /// </summary>
        /// <param name="cloudPortEncodeCreateDTO">Encode context data object.</param>
        /// <returns>A unique Job Id in string format.</returns>
        public async Task <ServiceOperationResultEncodeDispatched> EncodeCreateAsync(RequestCloudPortEncodeCreateDTO cloudPortEncodeCreateDTO)
        {
            _ = cloudPortEncodeCreateDTO ?? throw new ArgumentNullException(nameof(cloudPortEncodeCreateDTO));

            // EncodeAsync is broken into 2 parts
            //  1. Configure any storage needs for the encoder
            //  2. Call the encode

            // 1. configure storage for encoder
            string   sasUri;
            TimeSpan ttl     = cloudPortEncodeCreateDTO.SecToLive == 0 ? TimeSpan.FromHours(6) : TimeSpan.FromSeconds(cloudPortEncodeCreateDTO.SecToLive);
            var      inputs  = cloudPortEncodeCreateDTO.Inputs.ToArray();
            var      context = new StorageClientProviderContext(cloudPortEncodeCreateDTO.OperationContext);
            var      input   = new Uri(inputs[0].BlobUri);

            var exists = await _storageService.GetBlobExistsAsync(input, context).ConfigureAwait(false);

            if (!exists)
            {
                throw new GridwichCloudPortMissingInputException(
                          $"Attempt to use nonexistent blob as input: {input}",
                          input.AbsoluteUri, context.ClientRequestIdAsJObject);
            }
            try
            {
                sasUri = _storageService.GetSasUrlForBlob(input, ttl, context);
            }
            catch (Exception e)
            {
                throw new GridwichCloudPortSASException($"Failed to generate SAS for: {input}", cloudPortEncodeCreateDTO.OperationContext, e);
            }

            if (string.IsNullOrEmpty(sasUri))
            {
                throw new GridwichCloudPortSASException($"Failed to generate SAS for: {input}", cloudPortEncodeCreateDTO.OperationContext);
            }

            // 2. Execute Encode
            var result = await CreateWorkflowJobAsync(sasUri, string.Empty, cloudPortEncodeCreateDTO).ConfigureAwait(false);

            return(new ServiceOperationResultEncodeDispatched(
                       workflowJobName: result.Id,
                       null,
                       cloudPortEncodeCreateDTO.OperationContext));
        }
Пример #2
0
        private async Task <WorkflowJob> CreateWorkflowJobAsync(string inputURL, string jobName, RequestCloudPortEncodeCreateDTO cloudPortEncodeCreateDTO)
        {
            var workflow = await GetWorkflowByNameAsync(cloudPortEncodeCreateDTO.WorkflowName).ConfigureAwait(false);

            var store = await _telestreamCloudStorageProvider.GetStoreByNameAsync(new Uri(cloudPortEncodeCreateDTO.OutputContainer)).ConfigureAwait(false);

            var workflowJob = new WorkflowJob
            {
                Name = jobName
            };

            // We need to pass all source files
            var workflowJobSources = new Dictionary <string, string>();

            foreach (var source in workflow.Input.Sources)
            {
                workflowJobSources[source.Key] = inputURL;
            }

            var variables = ProcessWorkflowVariables(workflow, cloudPortEncodeCreateDTO);

            workflowJob.Inputs = new WorkflowJobInputs(sources: workflowJobSources, variables: variables);

            // Configure the encode payload for OpContext and other data that needs to be tunneled thru the payload.
            // Pass the OutputContainer in the Payload, so we can get it back from CloudPort.
            var payload = new CloudPortPayload()
            {
                OperationContext = cloudPortEncodeCreateDTO.OperationContext,
                OutputContainer  = cloudPortEncodeCreateDTO.OutputContainer
            };

            workflowJob.Payload = JsonConvert.SerializeObject(payload);

            // The Storage Reference section of the Input is where the workflow will advertise which Actions (denoted by the Identifier associated with those actions) which have been configured to emit outputs.
            // Additionally, this information will indicate which outputs are TRANSIENT (or temporary) and which outputs are PERMANENT (or intended to exist beyond the lifetime of the job)
            // The intent of the Storage Reference section is to provide the entity which is submitting to this workflow the requisite information necessary to specify the desired STORAGE that the action should utilize when running.
            workflowJob.StorageReferences = new Dictionary <string, WorkflowJobStorageReferences>();

            foreach (var workflowStorageReference in workflow.Input.StorageReferences)
            {
                workflowJob.StorageReferences[workflowStorageReference.Key] = new WorkflowJobStorageReferences(
                    storeId: store.Id,
                    folderOffset: ":id");  // use the job id as a blob name prefix.
            }

            try
            {
                var job = await _telestreamCloudClientProvider.CloudPortApi.CreateWorkflowJobAsync(workflow.Id, workflowJob).ConfigureAwait(false);

                return(job);
            }
            catch (ApiException ae)
            {
                throw new GridwichCloudPortApiException("Error calling CreateWorkflowJobAsync.", cloudPortEncodeCreateDTO.OperationContext, ae);
            }
        }
Пример #3
0
        private static Dictionary <string, string> ProcessWorkflowVariables(Workflow workflow, RequestCloudPortEncodeCreateDTO cloudPortEncodeCreateDTO)
        {
            _ = workflow ?? throw new ArgumentNullException(nameof(workflow));
            _ = cloudPortEncodeCreateDTO ?? throw new ArgumentNullException(nameof(cloudPortEncodeCreateDTO));

            var outputVars = new Dictionary <string, string>();

            // Handle the case where workflow takes 0 parameters.
            if (workflow.Input is null || workflow.Input.Variables is null)
            {
                // If supplied parameter count is also 0, we are good.
                if (cloudPortEncodeCreateDTO.Parameters is null || cloudPortEncodeCreateDTO.Parameters.Count == 0)
                {
                    return(outputVars);
                }
Пример #4
0
        public async void CloudPortTestWithGoodAndBadData(RequestCloudPortEncodeCreateDTO encodeCreateData, bool blobShouldExist, Type shouldThrowThis, Uri sasUri)
        {
            // Arrange
            var wfj = new WorkflowJob();

            Mock.Get(_telestreamCloudClientProvider.CloudPortApi)
            .Setup(x => x.CreateWorkflowJobAsync(It.IsAny <string>(), It.IsAny <WorkflowJob>()))
            .ReturnsAsync(wfj);

            var wf1 = new Workflow(name: "TestWorkflow2")
            {
                Input = new WorkflowInput
                {
                    Sources = new Dictionary <string, VantageNickName>()
                    {
                        { "any value", new VantageNickName() }
                    },
                    Variables = new Dictionary <string, VantageVariable>(),
                }
            };

            wf1.Input.Variables.Add("var1", new VantageVariable("0", "0"));

            var wf2 = new Workflow();
            WorkflowsCollection wfc = new WorkflowsCollection()
            {
                Workflows = new List <Workflow>()
                {
                    wf1, wf2
                }
            };

            Mock.Get(_telestreamCloudClientProvider.CloudPortApi)
            .Setup(x => x.ListWorkflowsAsync(null, null, null))
            .ReturnsAsync(wfc);

            Mock.Get(_telestreamCloudClientProvider.CloudPortApi)
            .Setup(x => x.GetWorkflowAsync(It.IsAny <string>()))
            .ReturnsAsync(wf1);

            var sr = new StorageReference();

            wf1.Input.StorageReferences = new Dictionary <string, StorageReference>()
            {
                { "DavesStorageReference", sr }
            };

            Mock.Get(_storageService)
            .Setup(x => x.GetBlobExistsAsync(It.IsAny <Uri>(), It.IsAny <StorageClientProviderContext>()))
            .ReturnsAsync(blobShouldExist);

            Mock.Get(_storageService)
            .Setup(x => x.GetSasUrlForBlob(It.IsAny <Uri>(), It.IsAny <TimeSpan>(), It.IsAny <StorageClientProviderContext>()))
            .Returns(sasUri?.ToString());

            Mock.Get(_settingsProvider)
            .Setup(x => x.GetAppSettingsValue(It.IsAny <string>()))
            .Returns("telestreamCloudApiKey");

            Mock.Get(_telestreamCloudStorageProvider)
            .Setup(x => x.GetStoreByNameAsync(It.IsAny <Uri>()))
            .ReturnsAsync(new Store());

            // Act
            var cloudPortService = new CloudPortService(_storageService, _telestreamCloudClientProvider, _telestreamCloudStorageProvider);
            var ex = await Record.ExceptionAsync(async() => await cloudPortService.EncodeCreateAsync(encodeCreateData).ConfigureAwait(false)).ConfigureAwait(false);

            // Assert
            if (shouldThrowThis is null)
            {
                // if there are no throws, test is successful.
                Assert.Null(ex);
            }
            else
            {
                Assert.NotNull(ex);
                Assert.IsType(shouldThrowThis, ex);
            }
        }