Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Azcopy for upload #288

Merged
merged 20 commits into from
Feb 3, 2021
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
331268d
Added azcopy support for file upload
austeja-bentley Nov 23, 2020
e66afd1
Rush change
austeja-bentley Nov 23, 2020
76f51ad
Minor function parameter name refactoring
austeja-bentley Nov 23, 2020
7e5c20b
Merge branch 'master' into azcopy-for-upload
austeja-bentley Feb 1, 2021
70e8154
Merge branch 'master' into azcopy-for-upload
austeja-bentley Feb 1, 2021
e20d247
Merge branch 'master' into azcopy-for-upload
mergify[bot] Feb 1, 2021
b720a46
Merge branch 'master' into azcopy-for-upload
mergify[bot] Feb 1, 2021
bb5aa04
Merge branch 'master' into azcopy-for-upload
mergify[bot] Feb 1, 2021
829e280
Merge branch 'master' into azcopy-for-upload
mergify[bot] Feb 1, 2021
39b54ab
Merge branch 'master' into azcopy-for-upload
mergify[bot] Feb 1, 2021
8a44e90
Merge branch 'master' into azcopy-for-upload
mergify[bot] Feb 2, 2021
967632c
Merge branch 'master' into azcopy-for-upload
mergify[bot] Feb 2, 2021
15df0db
Merge branch 'master' into azcopy-for-upload
mergify[bot] Feb 2, 2021
0d18c30
Merge branch 'master' into azcopy-for-upload
mergify[bot] Feb 2, 2021
da7319b
Merge branch 'master' into azcopy-for-upload
mergify[bot] Feb 3, 2021
46ad685
Merge branch 'master' into azcopy-for-upload
mergify[bot] Feb 3, 2021
a8642b3
Merge branch 'master' into azcopy-for-upload
austeja-bentley Feb 3, 2021
46bf663
Merge branch 'master' into azcopy-for-upload
mergify[bot] Feb 3, 2021
ee2154a
Merge branch 'master' into azcopy-for-upload
mergify[bot] Feb 3, 2021
01ffabe
Merge branch 'master' into azcopy-for-upload
mergify[bot] Feb 3, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"changes": [
{
"packageName": "@bentley/backend-itwin-client",
"comment": "Added support for file upload using azcopy",
"type": "none"
}
],
"packageName": "@bentley/backend-itwin-client",
"email": "70565417+austeja-bentley@users.noreply.github.com"
}
41 changes: 29 additions & 12 deletions core/backend-itwin-client/src/imodelhub/AzureFileHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ export class AzureFileHandler implements FileHandler {
fs.mkdirSync(dirPath);
}

private async downloadFileUsingAzCopy(requestContext: AuthorizedClientRequestContext, downloadUrl: string, downloadToPathname: string, _fileSize?: number, progressCallback?: ProgressCallback): Promise<void> {
private async transferFileUsingAzCopy(requestContext: AuthorizedClientRequestContext, source: string, target: string, progressCallback?: ProgressCallback): Promise<void> {
requestContext.enter();
Logger.logTrace(loggerCategory, `Using AzCopy with verison ${AzCopy.getVersion()} located at ${AzCopy.execPath}`);

Expand Down Expand Up @@ -180,7 +180,7 @@ export class AzureFileHandler implements FileHandler {
Logger.logInfo(loggerCategory, `AzCopy runtime error: ${args}`);
});
// start download by spawning in a azcopy process
const rc = await azcopy.copy(downloadUrl, downloadToPathname);
const rc = await azcopy.copy(source, target);
if (rc !== 0) {
throw new Error(`AzCopy failed with return code: ${rc}`);
}
Expand Down Expand Up @@ -297,6 +297,23 @@ export class AzureFileHandler implements FileHandler {
return false;
}

/**
* Determine if azcopy should be used for file transfer
* @param fileSize size of the transferred file in bytes
*/
private useAzCopyForFileTransfer(fileSize?: number): boolean {
let useAzcopy = AzCopy.isAvailable;

// suppress azcopy for smaller file as it take longer to spawn and exit then it take Http downloader to download it.
if (useAzcopy && fileSize) {
const minFileSize = Config.App.getNumber("imjs_az_min_filesize_threshold", 500 * 1024 * 1024 /** 500 Mb */);
if (fileSize < minFileSize)
useAzcopy = false;
}

return useAzcopy;
}

/**
* Download a file from AzureBlobStorage for iModelHub. Creates the directory containing the file if necessary. If there is an error in the operation, incomplete file is deleted from disk.
* @param requestContext The client request context
Expand All @@ -323,15 +340,8 @@ export class AzureFileHandler implements FileHandler {

AzureFileHandler.makeDirectoryRecursive(path.dirname(downloadToPathname));
try {
// suppress azcopy for smaller file as it take longer to spawn and exit then it take Http downloader to download it.
let useAzcopy = AzCopy.isAvailable;
if (useAzcopy && fileSize) {
const minFileSize = Config.App.getNumber("imjs_az_min_filesize_threshold", 500 * 1024 * 1024 /** 500 Mb */);
if (fileSize < minFileSize)
useAzcopy = false;
}
if (useAzcopy) {
await this.downloadFileUsingAzCopy(requestContext, downloadUrl, downloadToPathname, fileSize, progressCallback);
if (this.useAzCopyForFileTransfer(fileSize)) {
await this.transferFileUsingAzCopy(requestContext, downloadUrl, downloadToPathname, progressCallback);
} else {
await this.downloadFileUsingHttps(requestContext, downloadUrl, downloadToPathname, fileSize, progressCallback, cancelRequest);
}
Expand Down Expand Up @@ -403,9 +413,16 @@ export class AzureFileHandler implements FileHandler {
ArgumentCheck.defined("uploadFromPathname", uploadFromPathname);

const fileSize = this.getFileSize(uploadFromPathname);
if (this.useAzCopyForFileTransfer(fileSize)) {
await this.transferFileUsingAzCopy(requestContext, uploadFromPathname, uploadUrlString, progressCallback);
} else {
await this.uploadFileUsingHttps(requestContext, uploadUrlString, uploadFromPathname, fileSize, progressCallback);
}
}

private async uploadFileUsingHttps(requestContext: AuthorizedClientRequestContext, uploadUrlString: string, uploadFromPathname: string, fileSize: number, progressCallback?: ProgressCallback): Promise<void> {
const file = fs.openSync(uploadFromPathname, "r");
const chunkSize = 4 * 1024 * 1024;

try {
let blockList = '<?xml version=\"1.0\" encoding=\"utf-8\"?><BlockList>';
let i = 0;
Expand Down