From c50f559bdcc3d091d2057fcb00d37368e58fa778 Mon Sep 17 00:00:00 2001 From: Neil Sutton Date: Fri, 8 Jul 2022 14:25:48 +0100 Subject: [PATCH] Added exception handling for Forge calls. --- bucket.manager/Form1.cs | 422 ++++++++++++++++++++++------------------ 1 file changed, 231 insertions(+), 191 deletions(-) diff --git a/bucket.manager/Form1.cs b/bucket.manager/Form1.cs index 6cdebf4..7f0450c 100644 --- a/bucket.manager/Form1.cs +++ b/bucket.manager/Form1.cs @@ -69,22 +69,29 @@ private async void btnAuthenticate_Click(object sender, EventArgs e) { if (string.IsNullOrWhiteSpace(txtClientId.Text) || string.IsNullOrWhiteSpace(txtClientSecret.Text)) return; - // get the access token - TwoLeggedApi oAuth = new TwoLeggedApi(); - Bearer token = (await oAuth.AuthenticateAsync( - txtClientId.Text, - txtClientSecret.Text, - oAuthConstants.CLIENT_CREDENTIALS, - new Scope[] { Scope.BucketRead, Scope.BucketCreate, Scope.DataRead, Scope.DataWrite })).ToObject(); - txtAccessToken.Text = token.AccessToken; - _expiresAt = DateTime.Now.AddSeconds(token.ExpiresIn.Value); - - // keep track on time - _tokenTimer.Tick += new EventHandler(tickTokenTimer); - _tokenTimer.Interval = 1000; - _tokenTimer.Enabled = true; - - btnRefreshToken_Click(null, null); + try + { + // get the access token + TwoLeggedApi oAuth = new TwoLeggedApi(); + Bearer token = (await oAuth.AuthenticateAsync( + txtClientId.Text, + txtClientSecret.Text, + oAuthConstants.CLIENT_CREDENTIALS, + new Scope[] { Scope.BucketRead, Scope.BucketCreate, Scope.DataRead, Scope.DataWrite })).ToObject(); + txtAccessToken.Text = token.AccessToken; + _expiresAt = DateTime.Now.AddSeconds(token.ExpiresIn.Value); + + // keep track on time + _tokenTimer.Tick += new EventHandler(tickTokenTimer); + _tokenTimer.Interval = 1000; + _tokenTimer.Enabled = true; + + btnRefreshToken_Click(null, null); + } catch (Exception ex) + { + MessageBox.Show(ex.Message, "Exception when authenticating", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } void tickTokenTimer(object sender, EventArgs e) @@ -107,29 +114,35 @@ private async void btnRefreshToken_Click(object sender, EventArgs e) { treeBuckets.Nodes.Clear(); - BucketsApi bucketApi = new BucketsApi(); - bucketApi.Configuration.AccessToken = AccessToken; + try + { + BucketsApi bucketApi = new BucketsApi(); + bucketApi.Configuration.AccessToken = AccessToken; - // control GetBucket pagination - string lastBucket = null; + // control GetBucket pagination + string lastBucket = null; - Buckets buckets = null; - do - { - buckets = (await bucketApi.GetBucketsAsync(cmbRegion.Text, 100, lastBucket)).ToObject(); - foreach (var bucket in buckets.Items) + Buckets buckets = null; + do { - TreeNode nodeBucket = new TreeNode(bucket.BucketKey); - nodeBucket.Tag = bucket.BucketKey; - treeBuckets.Nodes.Add(nodeBucket); - lastBucket = bucket.BucketKey; // after the loop, this will contain the last bucketKey - } - } while (buckets.Items.Count > 0); - - // for each bucket, show the objects - foreach (TreeNode n in treeBuckets.Nodes) - if (n != null) // async? - await ShowBucketObjects(n); + buckets = (await bucketApi.GetBucketsAsync(cmbRegion.Text, 100, lastBucket)).ToObject(); + foreach (var bucket in buckets.Items) + { + TreeNode nodeBucket = new TreeNode(bucket.BucketKey); + nodeBucket.Tag = bucket.BucketKey; + treeBuckets.Nodes.Add(nodeBucket); + lastBucket = bucket.BucketKey; // after the loop, this will contain the last bucketKey + } + } while (buckets.Items.Count > 0); + + // for each bucket, show the objects + foreach (TreeNode n in treeBuckets.Nodes) + if (n != null) // async? + await ShowBucketObjects(n); + } catch (Exception ex) + { + MessageBox.Show(ex.Message, "Exception when refreshing token", MessageBoxButtons.OK, MessageBoxIcon.Error); + } } private async Task ShowBucketObjects(TreeNode nodeBucket) @@ -158,83 +171,88 @@ private async void btnUpload_Click(object sender, EventArgs e) MessageBox.Show("Please select a bucket", "Bucket required", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } - string bucketKey = treeBuckets.SelectedNode.Text; - - // ask user to select file - OpenFileDialog formSelectFile = new OpenFileDialog(); - formSelectFile.Multiselect = false; - if (formSelectFile.ShowDialog() != DialogResult.OK) return; - string filePath = formSelectFile.FileName; - string objectKey = Path.GetFileName(filePath); - - ObjectsApi objects = new ObjectsApi(); - objects.Configuration.AccessToken = AccessToken; - - // get file size - long fileSize = (new FileInfo(filePath)).Length; - - // show progress bar for upload - progressBar.DisplayStyle = ProgressBarDisplayText.CustomText; - progressBar.Show(); - progressBar.Value = 0; - progressBar.Minimum = 0; - progressBar.CustomText = "Preparing to upload file..."; - - // decide if upload direct or resumable (by chunks) - if (fileSize > UPLOAD_CHUNK_SIZE * 1024 * 1024) // upload in chunks + try { - long chunkSize = 2 * 1024 * 1024; // 2 Mb - long numberOfChunks = (long)Math.Round((double)(fileSize / chunkSize)) + 1; - - progressBar.Maximum = (int)numberOfChunks; - - long start = 0; - chunkSize = (numberOfChunks > 1 ? chunkSize : fileSize); - long end = chunkSize; - string sessionId = Guid.NewGuid().ToString(); - - // upload one chunk at a time - using (BinaryReader reader = new BinaryReader(new FileStream(filePath, FileMode.Open))) + string bucketKey = treeBuckets.SelectedNode.Text; + + // ask user to select file + OpenFileDialog formSelectFile = new OpenFileDialog(); + formSelectFile.Multiselect = false; + if (formSelectFile.ShowDialog() != DialogResult.OK) return; + string filePath = formSelectFile.FileName; + string objectKey = Path.GetFileName(filePath); + + ObjectsApi objects = new ObjectsApi(); + objects.Configuration.AccessToken = AccessToken; + + // get file size + long fileSize = (new FileInfo(filePath)).Length; + + // show progress bar for upload + progressBar.DisplayStyle = ProgressBarDisplayText.CustomText; + progressBar.Show(); + progressBar.Value = 0; + progressBar.Minimum = 0; + progressBar.CustomText = "Preparing to upload file..."; + + // decide if upload direct or resumable (by chunks) + if (fileSize > UPLOAD_CHUNK_SIZE * 1024 * 1024) // upload in chunks { - for (int chunkIndex = 0; chunkIndex < numberOfChunks; chunkIndex++) - { - string range = string.Format("bytes {0}-{1}/{2}", start, end, fileSize); + long chunkSize = 2 * 1024 * 1024; // 2 Mb + long numberOfChunks = (long)Math.Round((double)(fileSize / chunkSize)) + 1; - long numberOfBytes = chunkSize + 1; - byte[] fileBytes = new byte[numberOfBytes]; - MemoryStream memoryStream = new MemoryStream(fileBytes); - reader.BaseStream.Seek((int)start, SeekOrigin.Begin); - int count = reader.Read(fileBytes, 0, (int)numberOfBytes); - memoryStream.Write(fileBytes, 0, (int)numberOfBytes); - memoryStream.Position = 0; + progressBar.Maximum = (int)numberOfChunks; - dynamic chunkUploadResponse = await objects.UploadChunkAsync(bucketKey, objectKey, (int)numberOfBytes, range, sessionId, memoryStream); + long start = 0; + chunkSize = (numberOfChunks > 1 ? chunkSize : fileSize); + long end = chunkSize; + string sessionId = Guid.NewGuid().ToString(); - start = end + 1; - chunkSize = ((start + chunkSize > fileSize) ? fileSize - start - 1 : chunkSize); - end = start + chunkSize; - - progressBar.CustomText = string.Format("{0} Mb uploaded...", (chunkIndex * chunkSize) / 1024 / 1024); - progressBar.Value = chunkIndex; + // upload one chunk at a time + using (BinaryReader reader = new BinaryReader(new FileStream(filePath, FileMode.Open))) + { + for (int chunkIndex = 0; chunkIndex < numberOfChunks; chunkIndex++) + { + string range = string.Format("bytes {0}-{1}/{2}", start, end, fileSize); + + long numberOfBytes = chunkSize + 1; + byte[] fileBytes = new byte[numberOfBytes]; + MemoryStream memoryStream = new MemoryStream(fileBytes); + reader.BaseStream.Seek((int)start, SeekOrigin.Begin); + int count = reader.Read(fileBytes, 0, (int)numberOfBytes); + memoryStream.Write(fileBytes, 0, (int)numberOfBytes); + memoryStream.Position = 0; + + dynamic chunkUploadResponse = await objects.UploadChunkAsync(bucketKey, objectKey, (int)numberOfBytes, range, sessionId, memoryStream); + + start = end + 1; + chunkSize = ((start + chunkSize > fileSize) ? fileSize - start - 1 : chunkSize); + end = start + chunkSize; + + progressBar.CustomText = string.Format("{0} Mb uploaded...", (chunkIndex * chunkSize) / 1024 / 1024); + progressBar.Value = chunkIndex; + } } - } - } - else // upload in a single call - { - using (StreamReader streamReader = new StreamReader(filePath)) + } else // upload in a single call { - progressBar.Value = 50; // random... - progressBar.Maximum = 100; - dynamic uploadedObj = await objects.UploadObjectAsync(bucketKey, - objectKey, (int)streamReader.BaseStream.Length, streamReader.BaseStream, - "application/octet-stream"); + using (StreamReader streamReader = new StreamReader(filePath)) + { + progressBar.Value = 50; // random... + progressBar.Maximum = 100; + dynamic uploadedObj = await objects.UploadObjectAsync(bucketKey, + objectKey, (int)streamReader.BaseStream.Length, streamReader.BaseStream, + "application/octet-stream"); + } + } + progressBar.Hide(); + await ShowBucketObjects(treeBuckets.SelectedNode); + treeBuckets.SelectedNode.Expand(); + } catch (Exception ex) + { + MessageBox.Show(ex.Message, "Exception when uploading", MessageBoxButtons.OK, MessageBoxIcon.Error); } - - progressBar.Hide(); - await ShowBucketObjects(treeBuckets.SelectedNode); - treeBuckets.SelectedNode.Expand(); } private void Form1_Load(object sender, EventArgs e) @@ -263,10 +281,12 @@ private async void onClickTranslate(object sender, EventArgs e) MessageBox.Show("Please select an object", "Objects required", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } - string urn = (string)treeBuckets.SelectedNode.Tag; + try + { + string urn = (string)treeBuckets.SelectedNode.Tag; - // prepare a SVF translation - List outputs = new List() + // prepare a SVF translation + List outputs = new List() { new JobPayloadItem( JobPayloadItem.TypeEnum.Svf, @@ -276,29 +296,33 @@ private async void onClickTranslate(object sender, EventArgs e) JobPayloadItem.ViewsEnum._3d }) }; - JobPayload job; - //if (string.IsNullOrEmpty(objModel.rootFilename)) - job = new JobPayload(new JobPayloadInput(urn), new JobPayloadOutput(outputs)); - //else - // job = new JobPayload(new JobPayloadInput(objModel.objectKey, true, objModel.rootFilename), new JobPayloadOutput(outputs)); - - // start progress bar for translation - progressBar.Show(); - progressBar.Value = 0; - progressBar.Minimum = 0; - progressBar.Maximum = 100; - progressBar.CustomText = "Starting translation job..."; - - // start translation job - DerivativesApi derivative = new DerivativesApi(); - derivative.Configuration.AccessToken = AccessToken; - dynamic jobPosted = await derivative.TranslateAsync(job, true); - - // start a monitor job to follow the translation - _translationTimer.Tick += new EventHandler(isTranslationReady); - _translationTimer.Tag = urn; - _translationTimer.Interval = 5000; - _translationTimer.Enabled = true; + JobPayload job; + //if (string.IsNullOrEmpty(objModel.rootFilename)) + job = new JobPayload(new JobPayloadInput(urn), new JobPayloadOutput(outputs)); + //else + // job = new JobPayload(new JobPayloadInput(objModel.objectKey, true, objModel.rootFilename), new JobPayloadOutput(outputs)); + + // start progress bar for translation + progressBar.Show(); + progressBar.Value = 0; + progressBar.Minimum = 0; + progressBar.Maximum = 100; + progressBar.CustomText = "Starting translation job..."; + + // start translation job + DerivativesApi derivative = new DerivativesApi(); + derivative.Configuration.AccessToken = AccessToken; + dynamic jobPosted = await derivative.TranslateAsync(job, true); + + // start a monitor job to follow the translation + _translationTimer.Tick += new EventHandler(isTranslationReady); + _translationTimer.Tag = urn; + _translationTimer.Interval = 5000; + _translationTimer.Enabled = true; + } catch (Exception ex) + { + MessageBox.Show(ex.Message, "Exception when translating", MessageBoxButtons.OK, MessageBoxIcon.Error); + } } private async void isTranslationReady(object sender, EventArgs e) @@ -331,16 +355,21 @@ private async void btnDeleteObject_Click(object sender, EventArgs e) MessageBox.Show("Please select an object", "Objects required", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } - - if (MessageBox.Show("This objects will be permantly delete, confirm?", "Are you sure?", - MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes) - return; - - // call API to delete object on the bucket - ObjectsApi objects = new ObjectsApi(); - objects.Configuration.AccessToken = AccessToken; - await objects.DeleteObjectAsync((string)treeBuckets.SelectedNode.Parent.Tag, (string)treeBuckets.SelectedNode.Text); - await ShowBucketObjects(treeBuckets.SelectedNode.Parent); + try + { + if (MessageBox.Show("This objects will be permantly delete, confirm?", "Are you sure?", + MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes) + return; + + // call API to delete object on the bucket + ObjectsApi objects = new ObjectsApi(); + objects.Configuration.AccessToken = AccessToken; + await objects.DeleteObjectAsync((string)treeBuckets.SelectedNode.Parent.Tag, (string)treeBuckets.SelectedNode.Text); + await ShowBucketObjects(treeBuckets.SelectedNode.Parent); + } catch (Exception ex) + { + MessageBox.Show(ex.Message, "Exception when deleting", MessageBoxButtons.OK, MessageBoxIcon.Error); + } } private void Form1_FormClosing(object sender, FormClosingEventArgs e) @@ -362,12 +391,18 @@ private async void btnCreateBucket_Click(object sender, EventArgs e) string bucketKey = string.Empty; if (Prompt.ShowDialog("Enter bucket name: ", "Create new bucket", txtClientId.Text.ToLower() + DateTime.Now.Ticks.ToString(), out bucketKey) == DialogResult.OK) { - BucketsApi buckets = new BucketsApi(); - buckets.Configuration.AccessToken = AccessToken; - PostBucketsPayload bucketPayload = new PostBucketsPayload(bucketKey.ToLower(), null, PostBucketsPayload.PolicyKeyEnum.Transient); - await buckets.CreateBucketAsync(bucketPayload, cmbRegion.Text); + try + { + BucketsApi buckets = new BucketsApi(); + buckets.Configuration.AccessToken = AccessToken; + PostBucketsPayload bucketPayload = new PostBucketsPayload(bucketKey.ToLower(), null, PostBucketsPayload.PolicyKeyEnum.Transient); + await buckets.CreateBucketAsync(bucketPayload, cmbRegion.Text); - btnRefreshToken_Click(null, null); + btnRefreshToken_Click(null, null); + } catch (Exception ex) + { + MessageBox.Show(ex.Message, "Exception when creating bucket", MessageBoxButtons.OK, MessageBoxIcon.Error); + } } } @@ -384,62 +419,67 @@ private async void btnDownloadSVF_Click(object sender, EventArgs e) MessageBox.Show("Please select an object", "Objects required", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } - string urn = (string)treeBuckets.SelectedNode.Tag; - - // select a folder to download the files - string folderPath = string.Empty; - using (var fbd = new FolderBrowserDialog()) + try { - if (fbd.ShowDialog() != DialogResult.OK || string.IsNullOrWhiteSpace(fbd.SelectedPath)) return; - folderPath = fbd.SelectedPath; - folderPath = Path.Combine(folderPath, treeBuckets.SelectedNode.Text); - if (Directory.Exists(folderPath)) Directory.Delete(folderPath, true); - Directory.CreateDirectory(folderPath); - } + string urn = (string)treeBuckets.SelectedNode.Tag; - // prepare the UI - progressBar.Show(); - progressBar.DisplayStyle = ProgressBarDisplayText.CustomText; - progressBar.Value = 0; - progressBar.CustomText = "Starting extraction..."; - - // get the list of resources to download - List resourcesToDownload = await ForgeUtils.Derivatives.ExtractSVFAsync(urn, AccessToken); + // select a folder to download the files + string folderPath = string.Empty; + using (var fbd = new FolderBrowserDialog()) + { + if (fbd.ShowDialog() != DialogResult.OK || string.IsNullOrWhiteSpace(fbd.SelectedPath)) return; + folderPath = fbd.SelectedPath; + folderPath = Path.Combine(folderPath, treeBuckets.SelectedNode.Text); + if (Directory.Exists(folderPath)) Directory.Delete(folderPath, true); + Directory.CreateDirectory(folderPath); + } - // update the UI - progressBar.Minimum = 0; - progressBar.Maximum = resourcesToDownload.Count; - progressBar.Step = 1; + // prepare the UI + progressBar.Show(); + progressBar.DisplayStyle = ProgressBarDisplayText.CustomText; + progressBar.Value = 0; + progressBar.CustomText = "Starting extraction..."; - IRestClient client = new RestClient("https://developer.api.autodesk.com/"); - foreach (ForgeUtils.Derivatives.Resource resource in resourcesToDownload) - { - progressBar.PerformStep(); - progressBar.CustomText = "Downloading " + resource.FileName; + // get the list of resources to download + List resourcesToDownload = await ForgeUtils.Derivatives.ExtractSVFAsync(urn, AccessToken); - // prepare the GET to download the file - RestRequest request = new RestRequest(resource.RemotePath, Method.GET); - request.AddHeader("Authorization", "Bearer " + AccessToken); - request.AddHeader("Accept-Encoding", "gzip, deflate"); - IRestResponse response = await client.ExecuteTaskAsync(request); + // update the UI + progressBar.Minimum = 0; + progressBar.Maximum = resourcesToDownload.Count; + progressBar.Step = 1; - if (response.StatusCode != System.Net.HttpStatusCode.OK) + IRestClient client = new RestClient("https://developer.api.autodesk.com/"); + foreach (ForgeUtils.Derivatives.Resource resource in resourcesToDownload) { - // something went wrong with this file... - MessageBox.Show(string.Format("Error downloading {0}: {1}", - resource.FileName, response.StatusCode.ToString())); + progressBar.PerformStep(); + progressBar.CustomText = "Downloading " + resource.FileName; - // any other action? - } - else - { - // combine with selected local path - string pathToSave = Path.Combine(folderPath, resource.LocalPath); - // ensure local dir exists - Directory.CreateDirectory(Path.GetDirectoryName(pathToSave)); - // save file - File.WriteAllBytes(pathToSave, response.RawBytes); + // prepare the GET to download the file + RestRequest request = new RestRequest(resource.RemotePath, Method.GET); + request.AddHeader("Authorization", "Bearer " + AccessToken); + request.AddHeader("Accept-Encoding", "gzip, deflate"); + IRestResponse response = await client.ExecuteTaskAsync(request); + + if (response.StatusCode != System.Net.HttpStatusCode.OK) + { + // something went wrong with this file... + MessageBox.Show(string.Format("Error downloading {0}: {1}", + resource.FileName, response.StatusCode.ToString())); + + // any other action? + } else + { + // combine with selected local path + string pathToSave = Path.Combine(folderPath, resource.LocalPath); + // ensure local dir exists + Directory.CreateDirectory(Path.GetDirectoryName(pathToSave)); + // save file + File.WriteAllBytes(pathToSave, response.RawBytes); + } } + } catch (Exception ex) + { + MessageBox.Show(ex.Message, "Exception when downloading svf", MessageBoxButtons.OK, MessageBoxIcon.Error); } progressBar.Hide();