示例#1
0
        private async Task <MobileAppContentFile> RenewStorageUri(IMobileAppContentFileRequestBuilder contentFileRequestBuilder)
        {
            logger.LogInformation($"Renewing SAS URI for {contentFileRequestBuilder.RequestUrl}.");
            await contentFileRequestBuilder.RenewUpload().Request().PostAsync();

            return(await WaitForStateAsync(contentFileRequestBuilder, MobileAppContentFileUploadState.AzureStorageUriRenewalSuccess));
        }
示例#2
0
        // waits for the desired status, refreshing the file along the way
        private async Task <MobileAppContentFile> WaitForStateAsync(IMobileAppContentFileRequestBuilder contentFileRequestBuilder, MobileAppContentFileUploadState state)
        {
            logger.LogInformation($"Waiting for app content file to have a state of {state}.");

            var waitStopwatch = Stopwatch.StartNew();

            while (true)
            {
                var contentFile = await contentFileRequestBuilder.Request().GetAsync();

                if (contentFile.UploadState == state)
                {
                    logger.LogInformation($"Waited {waitStopwatch.ElapsedMilliseconds}ms for app content file to have a state of {state}.");
                    return(contentFile);
                }

                var failedStates = new[]
                {
                    MobileAppContentFileUploadState.AzureStorageUriRequestFailed,
                    MobileAppContentFileUploadState.AzureStorageUriRenewalFailed,
                    MobileAppContentFileUploadState.CommitFileFailed
                };

                if (failedStates.Contains(contentFile.UploadState.GetValueOrDefault()))
                {
                    throw new InvalidOperationException($"{nameof(contentFile.UploadState)} is in a failed state of {contentFile.UploadState} - was waiting for {state}.");
                }
                const int waitTimeout  = 600000;
                const int testInterval = 2000;
                if (waitStopwatch.ElapsedMilliseconds > waitTimeout)
                {
                    throw new InvalidOperationException($"Timed out waiting for {nameof(contentFile.UploadState)} of {state} - current state is {contentFile.UploadState}.");
                }
                await Task.Delay(testInterval);
            }
        }
示例#3
0
        private async Task CreateBlobAsync(IntuneAppPackage package, MobileAppContentFile contentFile, IMobileAppContentFileRequestBuilder contentFileRequestBuilder)
        {
            var blockCount = 0;
            var blockIds   = new List <string>();

            const int chunkSize = 25 * 1024 * 1024;

            package.Data.Seek(0, SeekOrigin.Begin);
            var lastBlockId = (Math.Ceiling((double)package.Data.Length / chunkSize) - 1).ToString("0000");
            var sw          = Stopwatch.StartNew();

            foreach (var chunk in Chunk(package.Data, chunkSize, false))
            {
                if (sw.ElapsedMilliseconds >= 450000)
                {
                    contentFile = await RenewStorageUri(contentFileRequestBuilder);

                    sw.Restart();
                }

                var blockId = blockCount++.ToString("0000");
                logger.LogInformation($"Uploading block {blockId} of {lastBlockId} to {contentFile.AzureStorageUri}.");

                await using (var ms = new MemoryStream(chunk))
                {
                    try
                    {
                        await TryPutBlockAsync(contentFile, blockId, ms);
                    }
                    catch (StorageException ex) when(ex.RequestInformation.HttpStatusCode == 403)
                    {
                        // normally the timer should account for renewing upload URIs, but the Intune APIs are fundamentally unstable and sometimes 403s will be encountered randomly
                        contentFile = await RenewStorageUri(contentFileRequestBuilder);

                        sw.Restart();
                        await TryPutBlockAsync(contentFile, blockId, ms);
                    }
                }

                blockIds.Add(blockId);
            }

            await new CloudBlockBlob(new Uri(contentFile.AzureStorageUri)).PutBlockListAsync(blockIds);
        }