protected function updatedImport(BatchJob $dbBatchJob, kImportJobData $data, BatchJob $twinJob = null) { switch ($dbBatchJob->getStatus()) { case BatchJob::BATCHJOB_STATUS_FINISHED: return kFlowHelper::handleImportFinished($dbBatchJob, $data, $twinJob); case BatchJob::BATCHJOB_STATUS_FAILED: case BatchJob::BATCHJOB_STATUS_FATAL: kBatchManager::updateEntry($dbBatchJob, entryStatus::ERROR_IMPORTING); return $dbBatchJob; default: return $dbBatchJob; } }
public static function decideProfileFlavorsConvert(BatchJob $parentJob, BatchJob $convertProfileJob, array $flavors, array $conversionProfileFlavorParams, mediaInfo $mediaInfo = null) { $entryId = $convertProfileJob->getEntryId(); $originalFlavorAsset = flavorAssetPeer::retrieveOriginalByEntryId($entryId); if (is_null($originalFlavorAsset)) { $errDescription = 'Original flavor asset not found'; KalturaLog::err($errDescription); $convertProfileJob = kJobsManager::failBatchJob($convertProfileJob, $errDescription, BatchJobType::CONVERT_PROFILE); kBatchManager::updateEntry($convertProfileJob, entryStatus::ERROR_CONVERTING); return false; } $errDescription = null; $finalFlavors = self::validateConversionProfile($convertProfileJob->getPartnerId(), $entryId, $mediaInfo, $flavors, $conversionProfileFlavorParams, $errDescription); KalturaLog::log(count($finalFlavors) . " flavors returned from the decision layer"); if (is_null($finalFlavors)) { $convertProfileJob = kJobsManager::failBatchJob($convertProfileJob, $errDescription); KalturaLog::log("No flavors created"); throw new Exception($errDescription); } if (strlen($errDescription)) { $err = $convertProfileJob->getDescription() . $errDescription; $convertProfileJob->setDescription($err); $convertProfileJob->save(); } $srcSyncKey = $originalFlavorAsset->getSyncKey(flavorAsset::FILE_SYNC_FLAVOR_ASSET_SUB_TYPE_ASSET); $conversionsCreated = 0; $entry = $convertProfileJob->getEntry(); if (!$entry) { throw new APIException(APIErrors::INVALID_ENTRY, $convertProfileJob, $entryId); } $flavorsCollections = array(); // create a convert job per each flavor foreach ($finalFlavors as $flavor) { $flavorAsset = kBatchManager::createFlavorAsset($flavor, $entry->getPartnerId(), $entry->getId()); if (!$flavorAsset) { KalturaLog::log("Flavor asset could not be created, flavor conversion won't be created"); continue; } $collectionTag = $flavor->getCollectionTag(); if ($collectionTag) { $flavorsCollections[$collectionTag][] = $flavor; continue; } KalturaLog::log("Adding flavor conversion with flavor params output id [" . $flavor->getId() . "] and flavor params asset id [" . $flavorAsset->getId() . "]"); $madiaInfoId = $mediaInfo ? $mediaInfo->getId() : null; $createdJob = kJobsManager::addFlavorConvertJob($srcSyncKey, $flavor, $flavorAsset->getId(), $madiaInfoId, $parentJob); if ($createdJob) { $conversionsCreated++; } } foreach ($flavorsCollections as $tag => $flavors) { switch ($tag) { case flavorParams::TAG_ISM: $createdJob = kJobsManager::addConvertIsmCollectionJob($tag, $srcSyncKey, $entry, $parentJob, $flavors); if ($createdJob) { $conversionsCreated++; } break; default: KalturaLog::log("Error: Invalid collection tag [{$tag}]"); break; } } if (!$conversionsCreated) { $convertProfileJob = kJobsManager::failBatchJob($convertProfileJob, $errDescription); KalturaLog::log("No flavors created: {$errDescription}"); return false; } return true; }
public static function handleProvisionProvideFailed(BatchJob $dbBatchJob, kProvisionJobData $data, BatchJob $twinJob = null) { kBatchManager::updateEntry($dbBatchJob, entryStatus::ERROR_CONVERTING); return $dbBatchJob; }
public static function handleConvertFailed(BatchJob $dbBatchJob, $engineType, $flavorAssetId, $flavorParamsOutputId, $mediaInfoId) { $flavorAsset = assetPeer::retrieveById($flavorAssetId); // verifies that flavor asset exists if (!$flavorAsset) { throw new APIException(APIErrors::INVALID_FLAVOR_ASSET_ID, $flavorAssetId); } $flavorAsset->setStatus(flavorAsset::FLAVOR_ASSET_STATUS_ERROR); $flavorAsset->save(); // try to create a convert job with the next engine if (!is_null($engineType)) { $data = $dbBatchJob->getData(); if ($data instanceof kConvartableJobData) { $data->incrementOperationSet(); $dbBatchJob->setData($data); $dbBatchJob->save(); } $newDbBatchJob = kBusinessPreConvertDL::redecideFlavorConvert($flavorAssetId, $flavorParamsOutputId, $mediaInfoId, $dbBatchJob, $engineType); if ($newDbBatchJob) { return true; } } // find the root job $rootBatchJob = $dbBatchJob->getRootJob(); if (!$rootBatchJob) { return false; } // the root is already failed if ($rootBatchJob->getStatus() == BatchJob::BATCHJOB_STATUS_FAILED || $rootBatchJob->getStatus() == BatchJob::BATCHJOB_STATUS_FATAL) { return false; } // bulk download root job no need to handle if ($rootBatchJob->getJobType() == BatchJobType::BULKDOWNLOAD) { kJobsManager::failBatchJob($rootBatchJob, "Convert job " . $dbBatchJob->getId() . " failed"); return false; } if (is_null($flavorParamsOutputId)) { kJobsManager::failBatchJob($rootBatchJob, "Job " . $dbBatchJob->getId() . " failed"); kBatchManager::updateEntry($dbBatchJob->getEntryId(), entryStatus::ERROR_CONVERTING); return false; } $readyBehavior = $dbBatchJob->getData()->getReadyBehavior(); if ($readyBehavior == flavorParamsConversionProfile::READY_BEHAVIOR_REQUIRED) { kJobsManager::failBatchJob($rootBatchJob, "Job " . $dbBatchJob->getId() . " failed"); kBatchManager::updateEntry($dbBatchJob->getEntryId(), entryStatus::ERROR_CONVERTING); return false; } // failing the root profile job if all child jobs failed if ($rootBatchJob->getJobType() != BatchJobType::CONVERT_PROFILE) { return false; } $siblingJobs = $rootBatchJob->getChildJobs(); foreach ($siblingJobs as $siblingJob) { /* @var $siblingJob BatchJob */ // not conversion job and should be ignored if ($siblingJob->getJobType() != BatchJobType::CONVERT && $siblingJob->getJobType() != BatchJobType::POSTCONVERT) { continue; } $jobData = $siblingJob->getData(); if (!$jobData || !$jobData instanceof kConvertJobData && !$jobData instanceof kPostConvertJobData) { KalturaLog::err("Job id [" . $siblingJob->getId() . "] has no valid job data"); continue; } // found child flavor asset that hasn't failed, no need to fail the root job $siblingFlavorAssetId = $jobData->getFlavorAssetId(); $siblingFlavorAsset = assetPeer::retrieveById($siblingFlavorAssetId); if ($siblingFlavorAsset->getStatus() != flavorAsset::FLAVOR_ASSET_STATUS_ERROR && $siblingFlavorAsset->getStatus() != flavorAsset::FLAVOR_ASSET_STATUS_NOT_APPLICABLE && $siblingFlavorAsset->getStatus() != flavorAsset::FLAVOR_ASSET_STATUS_DELETED) { return false; } } // all conversions failed, should fail the root job kJobsManager::failBatchJob($rootBatchJob, "All conversions failed"); kBatchManager::updateEntry($dbBatchJob->getEntryId(), entryStatus::ERROR_CONVERTING); return false; }
private static function setError($errDescription, BatchJob $batchJob, $batchJobType, $entryId) { $batchJob = kJobsManager::failBatchJob($batchJob, $errDescription, $batchJobType); kBatchManager::updateEntry($entryId, entryStatus::ERROR_CONVERTING); KalturaLog::err($errDescription); }
/** * @param BatchJob $batchJob * @param entry $entry * @param string $flavorAssetId * @param string $inputFileSyncLocalPath * @return BatchJob */ public static function addConvertProfileJob(BatchJob $parentJob = null, entry $entry, $flavorAssetId, $inputFileSyncLocalPath) { KalturaLog::debug("Parent job [" . ($parentJob ? $parentJob->getId() : 'none') . "] entry [" . $entry->getId() . "] flavor asset [{$flavorAssetId}] input file [{$inputFileSyncLocalPath}]"); if ($entry->getConversionQuality() == conversionProfile2::CONVERSION_PROFILE_NONE) { $entry->setStatus(entryStatus::PENDING); $entry->save(); KalturaLog::notice('Entry should not be converted'); return null; } $importingSources = false; // if file size is 0, do not create conversion profile and set entry status as error converting if (!file_exists($inputFileSyncLocalPath) || kFile::fileSize($inputFileSyncLocalPath) == 0) { KalturaLog::debug("Input file [{$inputFileSyncLocalPath}] does not exist"); $partner = $entry->getPartner(); $conversionProfile = myPartnerUtils::getConversionProfile2ForEntry($entry->getId()); // load the asset params to the instance pool $flavorIds = flavorParamsConversionProfilePeer::getFlavorIdsByProfileId($conversionProfile->getId()); assetParamsPeer::retrieveByPKs($flavorIds); $conversionRequired = false; $sourceFileRequiredStorages = array(); $sourceIncludedInProfile = false; $flavorAsset = assetPeer::retrieveById($flavorAssetId); $flavors = flavorParamsConversionProfilePeer::retrieveByConversionProfile($conversionProfile->getId()); KalturaLog::debug("Found flavors [" . count($flavors) . "] in conversion profile [" . $conversionProfile->getId() . "]"); foreach ($flavors as $flavor) { /* @var $flavor flavorParamsConversionProfile */ if ($flavor->getFlavorParamsId() == $flavorAsset->getFlavorParamsId()) { KalturaLog::debug("Flavor [" . $flavor->getFlavorParamsId() . "] is ingested source"); $sourceIncludedInProfile = true; continue; } $flavorParams = assetParamsPeer::retrieveByPK($flavor->getFlavorParamsId()); if ($flavorParams instanceof liveParams || $flavor->getOrigin() == assetParamsOrigin::INGEST) { KalturaLog::debug("Flavor [" . $flavor->getFlavorParamsId() . "] should be ingested"); continue; } if ($flavor->getOrigin() == assetParamsOrigin::CONVERT_WHEN_MISSING) { $siblingFlavorAsset = assetPeer::retrieveByEntryIdAndParams($entry->getId(), $flavor->getFlavorParamsId()); if ($siblingFlavorAsset) { KalturaLog::debug("Flavor [" . $flavor->getFlavorParamsId() . "] already ingested"); continue; } } $sourceFileRequiredStorages[] = $flavorParams->getSourceRemoteStorageProfileId(); $conversionRequired = true; break; } if ($conversionRequired) { foreach ($sourceFileRequiredStorages as $storageId) { if ($storageId == StorageProfile::STORAGE_KALTURA_DC) { $key = $flavorAsset->getSyncKey(flavorAsset::FILE_SYNC_FLAVOR_ASSET_SUB_TYPE_ASSET); list($syncFile, $local) = kFileSyncUtils::getReadyFileSyncForKey($key, true, false); if ($syncFile && $syncFile->getFileType() == FileSync::FILE_SYNC_FILE_TYPE_URL && $partner && $partner->getImportRemoteSourceForConvert()) { KalturaLog::debug("Creates import job for remote file sync"); $url = $syncFile->getExternalUrl($entry->getId()); kJobsManager::addImportJob($parentJob, $entry->getId(), $partner->getId(), $url, $flavorAsset, null, null, true); $importingSources = true; continue; } } elseif ($flavorAsset->getExternalUrl($storageId)) { continue; } kBatchManager::updateEntry($entry->getId(), entryStatus::ERROR_CONVERTING); $flavorAsset = assetPeer::retrieveById($flavorAssetId); $flavorAsset->setStatus(flavorAsset::FLAVOR_ASSET_STATUS_ERROR); $flavorAsset->setDescription('Entry of size 0 should not be converted'); $flavorAsset->save(); KalturaLog::err('Entry of size 0 should not be converted'); return null; } } else { if ($flavorAsset->getStatus() == asset::FLAVOR_ASSET_STATUS_QUEUED) { if ($sourceIncludedInProfile) { $flavorAsset->setStatusLocalReady(); } else { $flavorAsset->setStatus(asset::FLAVOR_ASSET_STATUS_DELETED); $flavorAsset->setDeletedAt(time()); } $flavorAsset->save(); if ($sourceIncludedInProfile) { kBusinessPostConvertDL::handleConvertFinished(null, $flavorAsset); } } return null; } } if ($entry->getStatus() != entryStatus::READY) { $entry->setStatus(entryStatus::PRECONVERT); } $jobData = new kConvertProfileJobData(); $jobData->setFlavorAssetId($flavorAssetId); $jobData->setInputFileSyncLocalPath($inputFileSyncLocalPath); $jobData->setExtractMedia(true); if ($entry->getType() != entryType::MEDIA_CLIP) { $jobData->setExtractMedia(false); $entry->setCreateThumb(false); } $entry->save(); $batchJob = null; if ($parentJob) { $batchJob = $parentJob->createChild(BatchJobType::CONVERT_PROFILE); } else { $batchJob = new BatchJob(); $batchJob->setEntryId($entry->getId()); $batchJob->setPartnerId($entry->getPartnerId()); $batchJob->setUseNewRoot(true); } $batchJob->setObjectId($entry->getId()); $batchJob->setObjectType(BatchJobObjectType::ENTRY); if ($importingSources) { $batchJob->setStatus(BatchJob::BATCHJOB_STATUS_DONT_PROCESS); } return self::addJob($batchJob, $jobData, BatchJobType::CONVERT_PROFILE); }
public static function handleConvertFailed(BatchJob $dbBatchJob, $engineType, $flavorAssetId, $flavorParamsOutputId, $mediaInfoId) { $flavorAsset = assetPeer::retrieveById($flavorAssetId); // verifies that flavor asset exists if (!$flavorAsset) { throw new APIException(APIErrors::INVALID_FLAVOR_ASSET_ID, $flavorAssetId); } /* * On Webex error, roll back the inter-src asset version in order to allow the retry to get ARF as a source, * rather than the invlaid WMV file (product of bad nbrplayer session) */ if ($dbBatchJob->getErrNumber() == BatchJobAppErrors::BLACK_OR_SILENT_CONTENT) { $prevVer = $flavorAsset->getPreviousVersion(); $currVer = $flavorAsset->getVersion(); KalturaLog::log("Webex conversion - Garbled Audio or Black frame or Silence. Rolling back asset/file-sync version - curr({$currVer}), prev({$prevVer})"); if (isset($prevVer)) { $syncKey = $flavorAsset->getSyncKey(asset::FILE_SYNC_ASSET_SUB_TYPE_ASSET, $currVer); if (isset($syncKey)) { kFileSyncUtils::deleteSyncFileForKey($syncKey, false, true); $flavorAsset->setVersion($prevVer); $flavorAsset->setPreviousVersion(null); KalturaLog::log("Webex conversion - Rolled back"); } } } $flavorAsset->setStatus(flavorAsset::FLAVOR_ASSET_STATUS_ERROR); $flavorAsset->save(); // try to create a convert job with the next engine if (!is_null($engineType)) { $data = $dbBatchJob->getData(); if ($data instanceof kConvartableJobData) { $data->incrementOperationSet(); $dbBatchJob->setData($data); $dbBatchJob->save(); } $newDbBatchJob = kBusinessPreConvertDL::redecideFlavorConvert($flavorAssetId, $flavorParamsOutputId, $mediaInfoId, $dbBatchJob, $engineType); if ($newDbBatchJob) { return true; } } // find the root job $rootBatchJob = $dbBatchJob->getRootJob(); if (!$rootBatchJob) { return false; } // the root is already failed if ($rootBatchJob->getStatus() == BatchJob::BATCHJOB_STATUS_FAILED || $rootBatchJob->getStatus() == BatchJob::BATCHJOB_STATUS_FATAL) { return false; } // bulk download root job no need to handle if ($rootBatchJob->getJobType() == BatchJobType::BULKDOWNLOAD) { kJobsManager::failBatchJob($rootBatchJob, "Convert job " . $dbBatchJob->getId() . " failed"); return false; } if (is_null($flavorParamsOutputId)) { kJobsManager::failBatchJob($rootBatchJob, "Job " . $dbBatchJob->getId() . " failed"); kBatchManager::updateEntry($dbBatchJob->getEntryId(), entryStatus::ERROR_CONVERTING); return false; } $readyBehavior = $dbBatchJob->getData()->getReadyBehavior(); if ($readyBehavior == flavorParamsConversionProfile::READY_BEHAVIOR_REQUIRED) { kJobsManager::failBatchJob($rootBatchJob, "Job " . $dbBatchJob->getId() . " failed"); kBatchManager::updateEntry($dbBatchJob->getEntryId(), entryStatus::ERROR_CONVERTING); return false; } // failing the root profile job if all child jobs failed if ($rootBatchJob->getJobType() != BatchJobType::CONVERT_PROFILE) { return false; } $siblingJobs = $rootBatchJob->getChildJobs(); foreach ($siblingJobs as $siblingJob) { /* @var $siblingJob BatchJob */ // not conversion job and should be ignored if ($siblingJob->getJobType() != BatchJobType::CONVERT && $siblingJob->getJobType() != BatchJobType::POSTCONVERT) { continue; } $jobData = $siblingJob->getData(); if (!$jobData || !$jobData instanceof kConvertJobData && !$jobData instanceof kPostConvertJobData) { KalturaLog::err("Job id [" . $siblingJob->getId() . "] has no valid job data"); continue; } // found child flavor asset that hasn't failed, no need to fail the root job $siblingFlavorAssetId = $jobData->getFlavorAssetId(); $siblingFlavorAsset = assetPeer::retrieveById($siblingFlavorAssetId); if ($siblingFlavorAsset && $siblingFlavorAsset->getStatus() != flavorAsset::FLAVOR_ASSET_STATUS_ERROR && $siblingFlavorAsset->getStatus() != flavorAsset::FLAVOR_ASSET_STATUS_NOT_APPLICABLE && $siblingFlavorAsset->getStatus() != flavorAsset::FLAVOR_ASSET_STATUS_DELETED) { return false; } } // all conversions failed, should fail the root job kJobsManager::failBatchJob($rootBatchJob, "All conversions failed"); kBatchManager::updateEntry($dbBatchJob->getEntryId(), entryStatus::ERROR_CONVERTING); return false; }
/** * @param UploadToken $uploadToken */ public static function handleUploadFinished(UploadToken $uploadToken) { if (!is_subclass_of($uploadToken->getObjectType(), assetPeer::OM_CLASS) && $uploadToken->getObjectType() != FileAssetPeer::OM_CLASS && $uploadToken->getObjectType() != entryPeer::OM_CLASS) { KalturaLog::info("Class [" . $uploadToken->getObjectType() . "] not supported"); return; } $fullPath = kUploadTokenMgr::getFullPathByUploadTokenId($uploadToken->getId()); if (!file_exists($fullPath)) { KalturaLog::info("File path [{$fullPath}] not found"); $remoteDCHost = kUploadTokenMgr::getRemoteHostForUploadToken($uploadToken->getId(), kDataCenterMgr::getCurrentDcId()); if (!$remoteDCHost) { KalturaLog::err("File path [{$fullPath}] could not be redirected"); return; } kFileUtils::dumpApiRequest($remoteDCHost); } if ($uploadToken->getObjectType() == FileAssetPeer::OM_CLASS) { $dbFileAsset = FileAssetPeer::retrieveByPK($uploadToken->getObjectId()); if (!$dbFileAsset) { KalturaLog::err("File asset id [" . $uploadToken->getObjectId() . "] not found"); return; } if (!$dbFileAsset->getFileExt()) { $dbFileAsset->setFileExt(pathinfo($fullPath, PATHINFO_EXTENSION)); } $dbFileAsset->incrementVersion(); $dbFileAsset->save(); $syncKey = $dbFileAsset->getSyncKey(FileAsset::FILE_SYNC_ASSET); try { kFileSyncUtils::moveFromFile($fullPath, $syncKey, true); } catch (Exception $e) { $dbFileAsset->setStatus(FileAssetStatus::ERROR); $dbFileAsset->save(); throw $e; } if ($dbFileAsset->getStatus() == FileAssetStatus::UPLOADING) { $finalPath = kFileSyncUtils::getLocalFilePathForKey($syncKey); $dbFileAsset->setSize(kFile::fileSize($finalPath)); $dbFileAsset->setStatus(FileAssetStatus::READY); $dbFileAsset->save(); } $uploadToken->setStatus(UploadToken::UPLOAD_TOKEN_CLOSED); $uploadToken->save(); KalturaLog::info("File asset [" . $dbFileAsset->getId() . "] handled"); return; } if (is_subclass_of($uploadToken->getObjectType(), assetPeer::OM_CLASS)) { $dbAsset = assetPeer::retrieveById($uploadToken->getObjectId()); if (!$dbAsset) { KalturaLog::err("Asset id [" . $uploadToken->getObjectId() . "] not found"); return; } $ext = pathinfo($fullPath, PATHINFO_EXTENSION); $dbAsset->setFileExt($ext); $dbAsset->incrementVersion(); $dbAsset->save(); $syncKey = $dbAsset->getSyncKey(flavorAsset::FILE_SYNC_FLAVOR_ASSET_SUB_TYPE_ASSET); try { kFileSyncUtils::moveFromFile($fullPath, $syncKey, true); } catch (Exception $e) { if ($dbAsset instanceof flavorAsset) { kBatchManager::updateEntry($dbAsset->getEntryId(), entryStatus::ERROR_IMPORTING); } $dbAsset->setStatus(flavorAsset::FLAVOR_ASSET_STATUS_ERROR); $dbAsset->save(); throw $e; } if ($dbAsset->getStatus() == flavorAsset::FLAVOR_ASSET_STATUS_IMPORTING) { $finalPath = kFileSyncUtils::getLocalFilePathForKey($syncKey); $dbAsset->setSize(kFile::fileSize($finalPath)); if ($dbAsset instanceof flavorAsset) { if ($dbAsset->getIsOriginal()) { $dbAsset->setStatus(flavorAsset::FLAVOR_ASSET_STATUS_QUEUED); } else { $dbAsset->setStatus(flavorAsset::FLAVOR_ASSET_STATUS_VALIDATING); } } else { $dbAsset->setStatus(thumbAsset::FLAVOR_ASSET_STATUS_READY); } if ($dbAsset instanceof thumbAsset) { list($width, $height, $type, $attr) = getimagesize($finalPath); $dbAsset->setWidth($width); $dbAsset->setHeight($height); } $dbAsset->save(); kEventsManager::raiseEvent(new kObjectAddedEvent($dbAsset)); } $uploadToken->setStatus(UploadToken::UPLOAD_TOKEN_CLOSED); $uploadToken->save(); } if ($uploadToken->getObjectType() == entryPeer::OM_CLASS) { $dbEntry = entryPeer::retrieveByPK($uploadToken->getObjectId()); if (!$dbEntry) { KalturaLog::err("Entry id [" . $uploadToken->getObjectId() . "] not found"); return; } //Keep original extention $ext = pathinfo($fullPath, PATHINFO_EXTENSION); // increments version $dbEntry->setData('100000.' . $ext); $dbEntry->save(); $syncKey = $dbEntry->getSyncKey(entry::FILE_SYNC_ENTRY_SUB_TYPE_DATA); try { kFileSyncUtils::moveFromFile($fullPath, $syncKey, true); } catch (Exception $e) { if ($dbAsset instanceof flavorAsset) { kBatchManager::updateEntry($dbEntry->getId(), entryStatus::ERROR_IMPORTING); } throw $e; } $dbEntry->setStatus(entryStatus::READY); $dbEntry->save(); $uploadToken->setStatus(UploadToken::UPLOAD_TOKEN_CLOSED); $uploadToken->save(); } }