static function executeCopyTask($copyTask, $overwrite)
{
//Check if failover condition is active
$testBucket = new CCloudStorageBucket($copyTask["SOURCE_BUCKET_ID"]);
if (
($testBucket->isFailoverEnabled() && CCloudFailover::IsEnabled())
&& ($testBucket->FAILOVER_ACTIVE === "Y")
)
{
return CCloudFailover::ST_FAILOVER;
}
$testBucket = new CCloudStorageBucket($copyTask["TARGET_BUCKET_ID"]);
if (
($testBucket->isFailoverEnabled() && CCloudFailover::IsEnabled())
&& ($testBucket->FAILOVER_ACTIVE === "Y")
)
{
return CCloudFailover::ST_FAILOVER;
}
//Initialize storages
$sourceBucket = new CCloudStorageBucket($copyTask["SOURCE_BUCKET_ID"], false);
if (!$sourceBucket->Init())
{
BitrixCloudsCopyQueueTable::update($copyTask["ID"], array(
"FAIL_COUNTER" => $copyTask["FAIL_COUNTER"] + 1,
"STATUS" => $copyTask["FAIL_COUNTER"] >= COption::GetOptionInt("clouds", "max_copy_fail_count")? "F": $copyTask["STATUS"],
"ERROR_MESSAGE" => "CCloudFailover::executeCopyQueue(".$copyTask["ID"]."): failed to init source bucket."
));
return CCloudFailover::ST_ERROR;
}
$targetBucket = new CCloudStorageBucket($copyTask["TARGET_BUCKET_ID"], false);
if (!$targetBucket->Init())
{
BitrixCloudsCopyQueueTable::update($copyTask["ID"], array(
"FAIL_COUNTER" => $copyTask["FAIL_COUNTER"] + 1,
"STATUS" => $copyTask["FAIL_COUNTER"] >= COption::GetOptionInt("clouds", "max_copy_fail_count")? "F": $copyTask["STATUS"],
"ERROR_MESSAGE" => "CCloudFailover::executeCopyQueue(".$copyTask["ID"]."): failed to init target bucket."
));
return CCloudFailover::ST_ERROR;
}
//Check if source file is exists
if (!$sourceBucket->FileExists($copyTask["SOURCE_FILE_PATH"]))
{
BitrixCloudsCopyQueueTable::update($copyTask["ID"], array(
"FAIL_COUNTER" => $copyTask["FAIL_COUNTER"] + 1,
"STATUS" => $copyTask["FAIL_COUNTER"] >= COption::GetOptionInt("clouds", "max_copy_fail_count")? "F": $copyTask["STATUS"],
"ERROR_MESSAGE" => "CCloudFailover::executeCopyQueue(".$copyTask["ID"]."): source file does not exists."
));
return CCloudFailover::ST_ERROR;
}
$CONTENT_TYPE = $sourceBucket->GetService()->GetLastRequestHeader('Content-Type');
$CONTENT_LENGTH = $sourceBucket->GetService()->GetLastRequestHeader('Content-Length');
if ($copyTask["FILE_SIZE"] == -1)
{
if ($CONTENT_LENGTH)
{
$copyTask["FILE_SIZE"] = intval($CONTENT_LENGTH);
}
else
{
$copyTask["FILE_SIZE"] = $sourceBucket->GetFileSize($copyTask["SOURCE_FILE_PATH"]);
}
BitrixCloudsCopyQueueTable::update($copyTask["ID"], array(
"FILE_SIZE" => $copyTask["FILE_SIZE"],
));
}
//AddMessage2Log($copyTask);
$targetBucket->setQueueFlag(false);
$tempPath = $copyTask["TARGET_FILE_PATH"].".fail-over-copy-part";
$CLOchunkSize = $targetBucket->GetService()->GetMinUploadPartSize();
if ($copyTask["FILE_SIZE"] <= $CLOchunkSize)
{
$http = new BitrixMainWebHttpClient(array(
"streamTimeout" => 0,
));
$arFile = array(
"type" => $CONTENT_TYPE,
"content" => false,
);
$arFile["content"] = $http->get($sourceBucket->GetFileSRC($copyTask["SOURCE_FILE_PATH"]));
if ($arFile["content"] === false)
{
BitrixCloudsCopyQueueTable::update($copyTask["ID"], array(
"FAIL_COUNTER" => $copyTask["FAIL_COUNTER"] + 1,
"STATUS" => $copyTask["FAIL_COUNTER"] >= COption::GetOptionInt("clouds", "max_copy_fail_count")? "F": $copyTask["STATUS"],
"ERROR_MESSAGE" => "CCloudFailover::executeCopyQueue(".$copyTask["ID"]."): failed to download."
));
return CCloudFailover::ST_ERROR;
}
if (!$overwrite && $targetBucket->FileExists($copyTask["TARGET_FILE_PATH"]))
{
BitrixCloudsCopyQueueTable::delete($copyTask["ID"]);
return CCloudFailover::ST_CONTINUE;
}
$res = $targetBucket->SaveFile($copyTask["TARGET_FILE_PATH"], $arFile);
if ($res)
{
BitrixCloudsCopyQueueTable::delete($copyTask["ID"]);
return CCloudFailover::ST_CONTINUE;
}
else
{
BitrixCloudsCopyQueueTable::update($copyTask["ID"], array(
"FAIL_COUNTER" => $copyTask["FAIL_COUNTER"] + 1,
"STATUS" => $copyTask["FAIL_COUNTER"] >= COption::GetOptionInt("clouds", "max_copy_fail_count")? "F": $copyTask["STATUS"],
"ERROR_MESSAGE" => "CCloudFailover::executeCopyQueue(".$copyTask["ID"]."): failed to upload file."
));
return CCloudFailover::ST_ERROR;
}
}
$upload = new CCloudStorageUpload($tempPath);
if ($copyTask["FILE_POS"] == 0)
{
if (!$overwrite && $targetBucket->FileExists($copyTask["TARGET_FILE_PATH"]))
{
BitrixCloudsCopyQueueTable::delete($copyTask["ID"]);
return CCloudFailover::ST_CONTINUE;
}
if (!$upload->isStarted())
{
if (!$upload->Start($targetBucket, $copyTask["FILE_SIZE"], $CONTENT_TYPE))
{
BitrixCloudsCopyQueueTable::update($copyTask["ID"], array(
"FAIL_COUNTER" => $copyTask["FAIL_COUNTER"] + 1,
"STATUS" => $copyTask["FAIL_COUNTER"] >= COption::GetOptionInt("clouds", "max_copy_fail_count")? "F": $copyTask["STATUS"],
"ERROR_MESSAGE" => "CCloudFailover::executeCopyQueue(".$copyTask["ID"]."): failed to start upload."
));
return CCloudFailover::ST_ERROR;
}
}
}
//Download part
$http = new BitrixMainWebHttpClient();
$rangeStart = $copyTask["FILE_POS"];
$rangeEnd = min($copyTask["FILE_POS"] + $targetBucket->getService()->GetMinUploadPartSize(), $copyTask["FILE_SIZE"]) - 1;
$http->setHeader("Range", "bytes=".$rangeStart."-".$rangeEnd);
$data = $http->get($sourceBucket->GetFileSRC($copyTask["SOURCE_FILE_PATH"]));
$uploadResult = false;
while ($upload->hasRetries())
{
if ($upload->Next($data, $targetBucket))
{
$uploadResult = true;
break;
}
}
if (!$uploadResult)
{
BitrixCloudsCopyQueueTable::update($copyTask["ID"], array(
"FAIL_COUNTER" => $copyTask["FAIL_COUNTER"] + 1,
"STATUS" => $copyTask["FAIL_COUNTER"] >= COption::GetOptionInt("clouds", "max_copy_fail_count")? "F": $copyTask["STATUS"],
"ERROR_MESSAGE" => "CCloudFailover::executeCopyQueue(".$copyTask["ID"]."): upload part failed."
));
return CCloudFailover::ST_ERROR;
}
$filePos = $upload->getPos();
//Continue next time
if ($filePos < $copyTask["FILE_SIZE"])
{
BitrixCloudsCopyQueueTable::update($copyTask["ID"], array(
"FILE_POS" => $filePos,
));
return CCloudFailover::ST_CONTINUE;
}
if (!$upload->Finish($targetBucket))
{
BitrixCloudsCopyQueueTable::update($copyTask["ID"], array(
"FAIL_COUNTER" => $copyTask["FAIL_COUNTER"] + 1,
"STATUS" => $copyTask["FAIL_COUNTER"] >= COption::GetOptionInt("clouds", "max_copy_fail_count")? "F": $copyTask["STATUS"],
"ERROR_MESSAGE" => "CCloudFailover::executeCopyQueue(".$copyTask["ID"]."): finish has failed."
));
return CCloudFailover::ST_ERROR;
}
if (!CCloudTempFile::IsTempFile($copyTask["TARGET_FILE_PATH"]))
{
$targetBucket->IncFileCounter($copyTask["FILE_SIZE"]);
}
if ($overwrite && $targetBucket->FileExists($copyTask["TARGET_FILE_PATH"]))
{
$fileSize = $targetBucket->GetFileSize($copyTask["TARGET_FILE_PATH"]);
if ($targetBucket->DeleteFile($copyTask["TARGET_FILE_PATH"]))
{
if (!CCloudTempFile::IsTempFile($copyTask["TARGET_FILE_PATH"]))
{
$targetBucket->DecFileCounter($fileSize);
}
}
}
if (!$targetBucket->FileRename($tempPath, $copyTask["TARGET_FILE_PATH"]))
{
BitrixCloudsCopyQueueTable::update($copyTask["ID"], array(
"FAIL_COUNTER" => $copyTask["FAIL_COUNTER"] + 1,
"STATUS" => $copyTask["FAIL_COUNTER"] >= COption::GetOptionInt("clouds", "max_copy_fail_count")? "F": $copyTask["STATUS"],
"ERROR_MESSAGE" => "CCloudFailover::executeCopyQueue(".$copyTask["ID"]."): rename failed."
));
return CCloudFailover::ST_ERROR;
}
BitrixCloudsCopyQueueTable::delete($copyTask["ID"]);
return CCloudFailover::ST_CONTINUE;
}