/** * @action notify * @disableTags TAG_WIDGET_SESSION,TAG_ENTITLEMENT_ENTRY,TAG_ENTITLEMENT_CATEGORY * @param int $id integration job id */ public function notifyAction($id) { $coreType = IntegrationPlugin::getBatchJobTypeCoreValue(IntegrationBatchJobType::INTEGRATION); $batchJob = BatchJobPeer::retrieveByPK($id); $invalidJobId = false; $invalidKs = false; if (!self::validateKs($batchJob)) { $invalidKs = true; KalturaLog::err("ks not valid for notifying job [{$id}]"); } elseif (!$batchJob) { $invalidJobId = true; KalturaLog::err("Job [{$id}] not found"); } elseif ($batchJob->getJobType() != $coreType) { $invalidJobId = true; KalturaLog::err("Job [{$id}] wrong type [" . $batchJob->getJobType() . "] expected [" . $coreType . "]"); } elseif ($batchJob->getStatus() != KalturaBatchJobStatus::ALMOST_DONE) { $invalidJobId = true; KalturaLog::err("Job [{$id}] wrong status [" . $batchJob->getStatus() . "] expected [" . KalturaBatchJobStatus::ALMOST_DONE . "]"); } elseif ($batchJob->getPartnerId() != kCurrentContext::getCurrentPartnerId()) { $invalidKs = true; KalturaLog::err("Job [{$id}] of wrong partner [" . $batchJob->getPartnerId() . "] expected [" . kCurrentContext::getCurrentPartnerId() . "]"); } if ($invalidJobId) { throw new KalturaAPIException(KalturaErrors::INVALID_BATCHJOB_ID, $id); } if ($invalidKs) { throw new KalturaAPIException(KalturaIntegrationErrors::INTEGRATION_NOTIFY_FAILED); } kJobsManager::updateBatchJob($batchJob, KalturaBatchJobStatus::FINISHED); }
public function updatedJob(BatchJob $dbBatchJob, BatchJob $twinJob = null) { $data = $dbBatchJob->getData(); if (!$data instanceof kDistributionJobData) { return true; } $attUverseCoreValueType = kPluginableEnumsManager::apiToCore('DistributionProviderType', AttUverseDistributionPlugin::getApiValue(AttUverseDistributionProviderType::ATT_UVERSE)); if ($data->getProviderType() != $attUverseCoreValueType) { return true; } $jobTypesToFinish = array(ContentDistributionPlugin::getBatchJobTypeCoreValue(ContentDistributionBatchJobType::DISTRIBUTION_SUBMIT), ContentDistributionPlugin::getBatchJobTypeCoreValue(ContentDistributionBatchJobType::DISTRIBUTION_UPDATE)); if (in_array($dbBatchJob->getJobType(), $jobTypesToFinish) && $dbBatchJob->getStatus() == BatchJob::BATCHJOB_STATUS_FINISHED) { return self::onDistributionJobFinished($dbBatchJob, $data, $twinJob); } if ($dbBatchJob->getJobType() == ContentDistributionPlugin::getBatchJobTypeCoreValue(ContentDistributionBatchJobType::DISTRIBUTION_DELETE) && $dbBatchJob->getStatus() == BatchJob::BATCHJOB_STATUS_PENDING) { kJobsManager::updateBatchJob($dbBatchJob, BatchJob::BATCHJOB_STATUS_FINISHED); } return true; }
public function updatedJob(BatchJob $dbBatchJob) { $data = $dbBatchJob->getData(); if (!$data instanceof kDistributionJobData) { return true; } $doubleClickCoreValueType = kPluginableEnumsManager::apiToCore('DistributionProviderType', DoubleClickDistributionPlugin::getApiValue(DoubleClickDistributionProviderType::DOUBLECLICK)); if ($data->getProviderType() != $doubleClickCoreValueType) { return true; } if ($dbBatchJob->getStatus() != BatchJob::BATCHJOB_STATUS_PENDING) { return true; } $jobTypesToFinish = array(ContentDistributionPlugin::getBatchJobTypeCoreValue(ContentDistributionBatchJobType::DISTRIBUTION_SUBMIT), ContentDistributionPlugin::getBatchJobTypeCoreValue(ContentDistributionBatchJobType::DISTRIBUTION_UPDATE), ContentDistributionPlugin::getBatchJobTypeCoreValue(ContentDistributionBatchJobType::DISTRIBUTION_DELETE), ContentDistributionPlugin::getBatchJobTypeCoreValue(ContentDistributionBatchJobType::DISTRIBUTION_FETCH_REPORT), ContentDistributionPlugin::getBatchJobTypeCoreValue(ContentDistributionBatchJobType::DISTRIBUTION_ENABLE), ContentDistributionPlugin::getBatchJobTypeCoreValue(ContentDistributionBatchJobType::DISTRIBUTION_DISABLE)); if (in_array($dbBatchJob->getJobType(), $jobTypesToFinish)) { kJobsManager::updateBatchJob($dbBatchJob, BatchJob::BATCHJOB_STATUS_FINISHED); } return true; }
/** * @action notify * @disableTags TAG_WIDGET_SESSION,TAG_ENTITLEMENT_ENTRY,TAG_ENTITLEMENT_CATEGORY * @param int $id integration job id */ public function notifyAction($id) { $coreType = IntegrationPlugin::getBatchJobTypeCoreValue(IntegrationBatchJobType::INTEGRATION); $batchJob = BatchJobPeer::retrieveByPK($id); $invalid = false; if (!$batchJob) { $invalid = true; KalturaLog::err("Job [{$id}] not found"); } elseif ($batchJob->getJobType() != $coreType) { $invalid = true; KalturaLog::err("Job [{$id}] wrong type [" . $batchJob->getJobType() . "] expected [" . $coreType . "]"); } elseif ($batchJob->getStatus() != KalturaBatchJobStatus::ALMOST_DONE) { $invalid = true; KalturaLog::err("Job [{$id}] wrong status [" . $batchJob->getStatus() . "] expected [" . KalturaBatchJobStatus::ALMOST_DONE . "]"); } if ($invalid) { throw new KalturaAPIException(KalturaErrors::INVALID_BATCHJOB_ID, $id); } kJobsManager::updateBatchJob($batchJob, KalturaBatchJobStatus::FINISHED); }
public static function addintegrationJob($objectType, $objectId, kIntegrationJobData $data) { $partnerId = kCurrentContext::getCurrentPartnerId(); $batchJob = new BatchJob(); $batchJob->setPartnerId($partnerId); $batchJob->setObjectType($objectType); $batchJob->setObjectId($objectId); if ($objectType == BatchJobObjectType::ENTRY) { $batchJob->setEntryId($objectId); } elseif ($objectType == BatchJobObjectType::ASSET) { $asset = assetPeer::retrieveById($objectId); if ($asset) { $batchJob->setEntryId($asset->getEntryId()); } } $batchJob->setStatus(BatchJob::BATCHJOB_STATUS_DONT_PROCESS); $jobType = IntegrationPlugin::getBatchJobTypeCoreValue(IntegrationBatchJobType::INTEGRATION); $batchJob = kJobsManager::addJob($batchJob, $data, $jobType, $data->getProviderType()); return kJobsManager::updateBatchJob($batchJob, BatchJob::BATCHJOB_STATUS_PENDING); }
/** * @action notify * @disableTags TAG_WIDGET_SESSION,TAG_ENTITLEMENT_ENTRY,TAG_ENTITLEMENT_CATEGORY * @param int $id distribution job id */ public function notifyAction($id) { $submitCoreType = ContentDistributionPlugin::getBatchJobTypeCoreValue(ContentDistributionBatchJobType::DISTRIBUTION_SUBMIT); $updateCoreType = ContentDistributionPlugin::getBatchJobTypeCoreValue(ContentDistributionBatchJobType::DISTRIBUTION_UPDATE); $deleteCoreType = ContentDistributionPlugin::getBatchJobTypeCoreValue(ContentDistributionBatchJobType::DISTRIBUTION_DELETE); $validJobTypes = array($submitCoreType, $updateCoreType, $deleteCoreType); $batchJob = BatchJobPeer::retrieveByPK($id); $invalid = false; if (!$batchJob) { $invalid = true; KalturaLog::err("Job [{$id}] not found"); } elseif (!in_array($batchJob->getJobType(), $validJobTypes)) { $invalid = true; KalturaLog::err("Job [{$id}] wrong type [" . $batchJob->getJobType() . "] expected [" . implode(', ', $validJobTypes) . "]"); } elseif ($batchJob->getJobSubType() != UnicornDistributionProvider::get()->getType()) { $invalid = true; KalturaLog::err("Job [{$id}] wrong sub-type [" . $batchJob->getJobSubType() . "] expected [" . UnicornDistributionProvider::get()->getType() . "]"); } elseif ($batchJob->getStatus() != KalturaBatchJobStatus::ALMOST_DONE) { $invalid = true; KalturaLog::err("Job [{$id}] wrong status [" . $batchJob->getStatus() . "] expected [" . KalturaBatchJobStatus::ALMOST_DONE . "]"); } if ($invalid) { throw new KalturaAPIException(KalturaErrors::INVALID_BATCHJOB_ID, $id); } kJobsManager::updateBatchJob($batchJob, KalturaBatchJobStatus::FINISHED); $data = $batchJob->getData(); /* @var $data kDistributionJobData */ $providerData = $data->getProviderData(); /* @var $providerData kUnicornDistributionJobProviderData */ $entryDistribution = EntryDistributionPeer::retrieveByPK($data->getEntryDistributionId()); if ($entryDistribution) { $entryDistribution->putInCustomData(kUnicornDistributionJobProviderData::CUSTOM_DATA_FLAVOR_ASSET_OLD_VERSION, $providerData->getFlavorAssetVersion()); $entryDistribution->save(); } if ($batchJob->getJobType() == $submitCoreType) { $this->attachRemoteAssetResource($batchJob->getEntry(), $batchJob->getData()); } if ($batchJob->getJobType() == $deleteCoreType) { $this->detachRemoteAssetResource($batchJob->getEntry(), $batchJob->getData()); } }
/** * @param int $eventNotificationType * @param kEventNotificationDispatchJobData $jobData * @param string $partnerId * @param string $entryId * @param BatchJob $parentJob * @return BatchJob */ protected function addEventNotificationDispatchJob($eventNotificationType, kEventNotificationDispatchJobData $jobData, $partnerId = null, $entryId = null, BatchJob $parentJob = null) { $jobType = EventNotificationPlugin::getBatchJobTypeCoreValue(EventNotificationBatchType::EVENT_NOTIFICATION_HANDLER); $batchJob = null; if ($parentJob) { $batchJob = $parentJob->createChild($jobType, $eventNotificationType, false); } else { $batchJob = new BatchJob(); $batchJob->setEntryId($entryId); if (!$partnerId) { $partnerId = kCurrentContext::getCurrentPartnerId(); } $batchJob->setPartnerId($partnerId); } KalturaLog::log("Creating event notification dispatch job on template id [" . $jobData->getTemplateId() . "] engine[{$eventNotificationType}]"); $batchJob->setObjectId($entryId); $batchJob->setObjectType(BatchJobObjectType::ENTRY); $batchJob->setStatus(BatchJob::BATCHJOB_STATUS_DONT_PROCESS); $batchJob = kJobsManager::addJob($batchJob, $jobData, $jobType, $eventNotificationType); $jobData->setJobId($batchJob->getId()); $batchJob->setData($jobData); return kJobsManager::updateBatchJob($batchJob, BatchJob::BATCHJOB_STATUS_PENDING); }
public function updatedJob(BatchJob $dbBatchJob, BatchJob $twinJob = null) { if ($dbBatchJob->getStatus() != BatchJob::BATCHJOB_STATUS_PENDING) { return true; } if ($dbBatchJob->getJobType() == BatchJobType::PROVISION_PROVIDE) { $entry = $dbBatchJob->getEntry(false, false); $partner = $entry->getPartner(); $limeLightLiveParamsJSON = $partner->getLiveStreamProvisionParams(); $limeLightLiveParams = json_decode($limeLightLiveParamsJSON); if (!isset($limeLightLiveParams->Limelight) || !isset($limeLightLiveParams->Limelight->limelightPrimaryPublishUrl) || !isset($limeLightLiveParams->Limelight->limelightSecondaryPublishUrl) || !isset($limeLightLiveParams->Limelight->limelightStreamUrl)) { kJobsManager::updateBatchJob($dbBatchJob, BatchJob::BATCHJOB_STATUS_FAILED); return true; } $data = $dbBatchJob->getData(); $data->setPrimaryBroadcastingUrl($limeLightLiveParams->Limelight->limelightPrimaryPublishUrl); $data->setSecondaryBroadcastingUrl($limeLightLiveParams->Limelight->limelightSecondaryPublishUrl); $data->setRtmp($limeLightLiveParams->Limelight->limelightStreamUrl); $data->setStreamName($entry->getId() . '_%i'); $dbBatchJob->setData($data); } kJobsManager::updateBatchJob($dbBatchJob, BatchJob::BATCHJOB_STATUS_FINISHED); return true; }
public static function addintegrationJob($objectType, $objectId, kIntegrationJobData $data) { $partnerId = kCurrentContext::getCurrentPartnerId(); $providerType = $data->getProviderType(); $integrationProvider = KalturaPluginManager::loadObject('IIntegrationProvider', $providerType); if (!$integrationProvider || !$integrationProvider->validatePermissions($partnerId)) { KalturaLog::err("partner {$partnerId} not permitted with provider type {$providerType}"); return false; } $batchJob = new BatchJob(); $batchJob->setPartnerId($partnerId); $batchJob->setObjectType($objectType); $batchJob->setObjectId($objectId); if ($objectType == BatchJobObjectType::ENTRY) { $batchJob->setEntryId($objectId); } elseif ($objectType == BatchJobObjectType::ASSET) { $asset = assetPeer::retrieveById($objectId); if ($asset) { $batchJob->setEntryId($asset->getEntryId()); } } $batchJob->setStatus(BatchJob::BATCHJOB_STATUS_DONT_PROCESS); $jobType = IntegrationPlugin::getBatchJobTypeCoreValue(IntegrationBatchJobType::INTEGRATION); $batchJob = kJobsManager::addJob($batchJob, $data, $jobType, $providerType); if ($integrationProvider->shouldSendCallBack()) { $jobId = $batchJob->getId(); $ks = self::generateKs($partnerId, $jobId); $callBackUrl = "http://" . kConf::get('cdn_api_host'); $callBackUrl .= "/api_v3/index.php/service/integration_integration/action/notify"; $callBackUrl .= "/id/{$jobId}/ks/{$ks}"; $data = $batchJob->getData(); $data->setCallbackNotificationUrl($callBackUrl); $batchJob->setData($data); } return kJobsManager::updateBatchJob($batchJob, BatchJob::BATCHJOB_STATUS_PENDING); }
/** * @param BatchJob $dbBatchJob * @param kDistributionDeleteJobData $data * @param BatchJob $twinJob * @return BatchJob */ public static function onDistributionDeleteJobPending(BatchJob $dbBatchJob, kDistributionDeleteJobData $data, BatchJob $twinJob = null) { if ($data->getProviderType() == DistributionProviderType::SYNDICATION) { $dbBatchJob = kJobsManager::updateBatchJob($dbBatchJob, BatchJob::BATCHJOB_STATUS_FINISHED); } return $dbBatchJob; }
/** * @param BatchJob $dbBatchJob * @param flavorAsset $currentFlavorAsset * @return BatchJob */ public static function handleConvertFinished(BatchJob $dbBatchJob = null, flavorAsset $currentFlavorAsset) { KalturaLog::debug("entry id [" . $currentFlavorAsset->getEntryId() . "] flavor asset id [" . $currentFlavorAsset->getId() . "]"); $profile = null; try { $profile = myPartnerUtils::getConversionProfile2ForEntry($currentFlavorAsset->getEntryId()); KalturaLog::debug("profile [" . $profile->getId() . "]"); } catch (Exception $e) { KalturaLog::err($e->getMessage()); } $currentReadyBehavior = self::getReadyBehavior($currentFlavorAsset, $profile); KalturaLog::debug("Current ready behavior [{$currentReadyBehavior}]"); if ($currentReadyBehavior == flavorParamsConversionProfile::READY_BEHAVIOR_IGNORE) { return $dbBatchJob; } $rootBatchJob = null; if ($dbBatchJob) { $rootBatchJob = $dbBatchJob->getRootJob(); } if ($rootBatchJob) { KalturaLog::debug("root batch job id [" . $rootBatchJob->getId() . "] type [" . $rootBatchJob->getJobType() . "]"); } // update the root job end exit if ($rootBatchJob && $rootBatchJob->getJobType() == BatchJobType::BULKDOWNLOAD) { $siblingJobs = $rootBatchJob->getChildJobs(); foreach ($siblingJobs as $siblingJob) { // checking only conversion child jobs if ($siblingJob->getJobType() != BatchJobType::CONVERT && $siblingJob->getJobType() != BatchJobType::CONVERT_COLLECTION && $siblingJob->getJobType() != BatchJobType::POSTCONVERT) { continue; } // if not complete leave function if (!in_array($siblingJob->getStatus(), BatchJobPeer::getClosedStatusList())) { KalturaLog::debug("job id [" . $siblingJob->getId() . "] status [" . $siblingJob->getStatus() . "]"); return $dbBatchJob; } } KalturaLog::debug("finish bulk download root job"); // all child jobs completed kJobsManager::updateBatchJob($rootBatchJob, BatchJob::BATCHJOB_STATUS_FINISHED); return $dbBatchJob; } $inheritedFlavorParamsIds = array(); $requiredFlavorParamsIds = array(); $flavorParamsConversionProfileItems = array(); if ($profile) { $flavorParamsConversionProfileItems = flavorParamsConversionProfilePeer::retrieveByConversionProfile($profile->getId()); } foreach ($flavorParamsConversionProfileItems as $flavorParamsConversionProfile) { if ($flavorParamsConversionProfile->getReadyBehavior() == flavorParamsConversionProfile::READY_BEHAVIOR_REQUIRED) { $requiredFlavorParamsIds[$flavorParamsConversionProfile->getFlavorParamsId()] = true; } if ($flavorParamsConversionProfile->getReadyBehavior() == flavorParamsConversionProfile::READY_BEHAVIOR_NO_IMPACT) { $inheritedFlavorParamsIds[] = $flavorParamsConversionProfile->getFlavorParamsId(); } } $flavorParamsItems = assetParamsPeer::retrieveByPKs($inheritedFlavorParamsIds); foreach ($flavorParamsItems as $flavorParams) { if ($flavorParams->getReadyBehavior() == flavorParamsConversionProfile::READY_BEHAVIOR_REQUIRED) { $requiredFlavorParamsIds[$flavorParamsConversionProfile->getFlavorParamsId()] = true; } } KalturaLog::debug("required flavor params ids [" . print_r($requiredFlavorParamsIds, true) . "]"); // go over all the flavor assets of the entry $inCompleteFlavorIds = array(); $origianlAssetFlavorId = null; $siblingFlavorAssets = assetPeer::retrieveFlavorsByEntryId($currentFlavorAsset->getEntryId()); foreach ($siblingFlavorAssets as $siblingFlavorAsset) { KalturaLog::debug("sibling flavor asset id [" . $siblingFlavorAsset->getId() . "] flavor params id [" . $siblingFlavorAsset->getFlavorParamsId() . "]"); // don't mark any incomplete flag if ($siblingFlavorAsset->getStatus() == flavorAsset::FLAVOR_ASSET_STATUS_READY) { KalturaLog::debug("sibling flavor asset id [" . $siblingFlavorAsset->getId() . "] is ready"); if (isset($requiredFlavorParamsIds[$siblingFlavorAsset->getFlavorParamsId()])) { unset($requiredFlavorParamsIds[$siblingFlavorAsset->getFlavorParamsId()]); } continue; } $readyBehavior = self::getReadyBehavior($siblingFlavorAsset, $profile); if ($siblingFlavorAsset->getStatus() == flavorAsset::ASSET_STATUS_EXPORTING) { if ($siblingFlavorAsset->getIsOriginal()) { $origianlAssetFlavorId = $siblingFlavorAsset->getFlavorParamsId(); } else { if ($readyBehavior != flavorParamsConversionProfile::READY_BEHAVIOR_IGNORE) { KalturaLog::debug("sibling flavor asset id [" . $siblingFlavorAsset->getId() . "] is incomplete"); $inCompleteFlavorIds[] = $siblingFlavorAsset->getFlavorParamsId(); } } } if ($readyBehavior == flavorParamsConversionProfile::READY_BEHAVIOR_IGNORE) { KalturaLog::debug("sibling flavor asset id [" . $siblingFlavorAsset->getId() . "] is ignored"); continue; } if ($siblingFlavorAsset->getStatus() == flavorAsset::FLAVOR_ASSET_STATUS_QUEUED || $siblingFlavorAsset->getStatus() == flavorAsset::FLAVOR_ASSET_STATUS_CONVERTING || $siblingFlavorAsset->getStatus() == flavorAsset::FLAVOR_ASSET_STATUS_IMPORTING || $siblingFlavorAsset->getStatus() == flavorAsset::FLAVOR_ASSET_STATUS_VALIDATING) { KalturaLog::debug("sibling flavor asset id [" . $siblingFlavorAsset->getId() . "] is incomplete"); $inCompleteFlavorIds[] = $siblingFlavorAsset->getFlavorParamsId(); } if ($readyBehavior == flavorParamsConversionProfile::READY_BEHAVIOR_REQUIRED) { KalturaLog::debug("sibling flavor asset id [" . $siblingFlavorAsset->getId() . "] is required"); $requiredFlavorParamsIds[$siblingFlavorAsset->getFlavorParamsId()] = true; } } KalturaLog::debug("left required flavor params ids [" . print_r($requiredFlavorParamsIds, true) . "]"); KalturaLog::debug("left incomplete flavor ids [" . print_r($inCompleteFlavorIds, true) . "]"); if (count($requiredFlavorParamsIds)) { $inCompleteRequiredFlavorParamsIds = array_keys($requiredFlavorParamsIds); foreach ($inCompleteRequiredFlavorParamsIds as $inCompleteFlavorId) { $inCompleteFlavorIds[] = $inCompleteFlavorId; } KalturaLog::debug('Convert Finished - has In-Complete Required flavors [[' . print_r($inCompleteRequiredFlavorParamsIds, true) . ']'); } elseif ($currentFlavorAsset->getStatus() == asset::ASSET_STATUS_READY && ($currentReadyBehavior == flavorParamsConversionProfile::READY_BEHAVIOR_OPTIONAL || $currentReadyBehavior == flavorParamsConversionProfile::READY_BEHAVIOR_REQUIRED)) { // mark the entry as ready if all required conversions completed or any of the optionals if ($currentFlavorAsset->getentry()->getReplacedEntryId()) { KalturaLog::debug('Entry is temporary replacement and requires all flavors to complete'); } else { KalturaLog::debug('Mark the entry as ready'); kBatchManager::updateEntry($currentFlavorAsset->getEntryId(), entryStatus::READY); } } if ($origianlAssetFlavorId) { $inCompleteFlavorIds = array_diff($inCompleteFlavorIds, array($origianlAssetFlavorId)); } if (!count($inCompleteFlavorIds)) { KalturaLog::debug('Convert Finished'); if ($origianlAssetFlavorId && $rootBatchJob && $rootBatchJob->getJobType() == BatchJobType::CONVERT_PROFILE) { kStorageExporter::exportSourceAssetFromJob($rootBatchJob); } else { // mark the context root job as finished only if all conversion jobs are completed kBatchManager::updateEntry($currentFlavorAsset->getEntryId(), entryStatus::READY); if ($rootBatchJob && $rootBatchJob->getJobType() == BatchJobType::CONVERT_PROFILE) { kJobsManager::updateBatchJob($rootBatchJob, BatchJob::BATCHJOB_STATUS_FINISHED); } } return $dbBatchJob; } KalturaLog::debug('Convert Finished - has In-Complete flavors [' . print_r($inCompleteFlavorIds, true) . ']'); if (!$rootBatchJob || $rootBatchJob->getJobType() != BatchJobType::CONVERT_PROFILE) { return $dbBatchJob; } $childJobs = $rootBatchJob->getChildJobs(); KalturaLog::debug('Child jobs found [' . count($childJobs) . ']'); if (count($childJobs) > 1) { $allDone = true; foreach ($childJobs as $childJob) { if ($childJob->getId() != $rootBatchJob->getId() && $childJob->getStatus() != BatchJob::BATCHJOB_STATUS_FINISHED) { KalturaLog::debug('Child job id [' . $childJob->getId() . '] status [' . $childJob->getStatus() . ']'); $allDone = false; } } if ($allDone) { KalturaLog::debug('All child jobs done, closing profile'); kJobsManager::updateBatchJob($rootBatchJob, BatchJob::BATCHJOB_STATUS_FINISHED); } } return $dbBatchJob; }
private static function decideSourceFlavorConvert($entryId, assetParams $sourceFlavor = null, flavorAsset $originalFlavorAsset, $conversionProfileId, $flavors, mediaInfo $mediaInfo = null, BatchJob $parentJob, BatchJob $convertProfileJob) { if ($sourceFlavor && ($sourceFlavor->getOperators() || $sourceFlavor->getConversionEngines()) && $originalFlavorAsset->getInterFlowCount() == null) { KalturaLog::log("Source flavor asset requires conversion"); self::adjustAssetParams($entryId, array($sourceFlavor)); $srcSyncKey = $originalFlavorAsset->getSyncKey(flavorAsset::FILE_SYNC_FLAVOR_ASSET_SUB_TYPE_ASSET); $errDescription = null; $sourceFlavorOutput = self::validateFlavorAndMediaInfo($sourceFlavor, $mediaInfo, $errDescription); if (!$sourceFlavorOutput) { if (!$errDescription) { $errDescription = "Failed to create flavor params output from source flavor"; } $originalFlavorAsset->setDescription($originalFlavorAsset->getDescription() . "\n{$errDescription}"); $originalFlavorAsset->setStatus(flavorAsset::ASSET_STATUS_ERROR); $originalFlavorAsset->save(); kBatchManager::updateEntry($entryId, entryStatus::ERROR_CONVERTING); kJobsManager::updateBatchJob($convertProfileJob, BatchJob::BATCHJOB_STATUS_FAILED); return false; } } elseif ($mediaInfo) { /* * Check whether there is a need for an intermediate source pre-processing */ $sourceFlavorOutput = KDLWrap::GenerateIntermediateSource($mediaInfo, $flavors); if (!$sourceFlavorOutput) { return true; } $srcSyncKey = $originalFlavorAsset->getSyncKey(flavorAsset::FILE_SYNC_FLAVOR_ASSET_SUB_TYPE_ASSET); $errDescription = null; /* * Save the original source asset in another asset, in order * to prevent its liquidated by the inter-source asset. * But, do it only if the conversion profile contains source flavor */ if ($sourceFlavor) { $sourceAsset = assetPeer::retrieveById($mediaInfo->getFlavorAssetId()); $copyFlavorParams = assetParamsPeer::retrieveBySystemName(self::SAVE_ORIGINAL_SOURCE_FLAVOR_PARAM_SYS_NAME); if (!$copyFlavorParams) { throw new APIException(APIErrors::OBJECT_NOT_FOUND); } $asset = $sourceAsset->copy(); $asset->setFlavorParamsId($copyFlavorParams->getId()); $asset->setFromAssetParams($copyFlavorParams); $asset->setStatus(flavorAsset::ASSET_STATUS_READY); $asset->setIsOriginal(0); $asset->setTags($copyFlavorParams->getTags()); $asset->incrementVersion(); $asset->save(); kFileSyncUtils::createSyncFileLinkForKey($asset->getSyncKey(asset::FILE_SYNC_ASSET_SUB_TYPE_ASSET), $sourceAsset->getSyncKey(asset::FILE_SYNC_ASSET_SUB_TYPE_ASSET)); $origFileSync = kFileSyncUtils::getLocalFileSyncForKey($sourceAsset->getSyncKey(asset::FILE_SYNC_ASSET_SUB_TYPE_ASSET)); $asset->setSize(intval($origFileSync->getFileSize() / 1000)); $asset->save(); } } /* * '_passthrough' controls whether the source is to be 'passthrough' although there * is a source flavor that contains transcoder settings. * Looks for a '_passthrough' flag on the source's flavor params output. */ if (!$sourceFlavorOutput || $sourceFlavorOutput->_passthrough == true) { return true; } // save flavor params $sourceFlavorOutput->setPartnerId($sourceFlavorOutput->getPartnerId()); $sourceFlavorOutput->setEntryId($entryId); $sourceFlavorOutput->setFlavorAssetId($originalFlavorAsset->getId()); $sourceFlavorOutput->setFlavorAssetVersion($originalFlavorAsset->getVersion()); $sourceFlavorOutput->save(); if ($errDescription) { $originalFlavorAsset->setDescription($originalFlavorAsset->getDescription() . "\n{$errDescription}"); } $errDescription = kBusinessConvertDL::parseFlavorDescription($sourceFlavorOutput); if ($errDescription) { $originalFlavorAsset->setDescription($originalFlavorAsset->getDescription() . "\n{$errDescription}"); } // decided by the business logic layer if ($sourceFlavorOutput->_create_anyway) { KalturaLog::log("Flavor [" . $sourceFlavorOutput->getFlavorParamsId() . "] selected to be created anyway"); } else { if (!$sourceFlavorOutput->IsValid()) { KalturaLog::log("Flavor [" . $sourceFlavorOutput->getFlavorParamsId() . "] is invalid"); $originalFlavorAsset->setStatus(flavorAsset::FLAVOR_ASSET_STATUS_ERROR); $originalFlavorAsset->save(); $errDescription = "Source flavor could not be converted"; self::setError($errDescription, $convertProfileJob, BatchJobType::CONVERT_PROFILE, $convertProfileJob->getEntryId()); return false; } if ($sourceFlavorOutput->_force) { KalturaLog::log("Flavor [" . $sourceFlavorOutput->getFlavorParamsId() . "] is forced"); } elseif ($sourceFlavorOutput->_isNonComply) { KalturaLog::log("Flavor [" . $sourceFlavorOutput->getFlavorParamsId() . "] is none-comply"); } else { KalturaLog::log("Flavor [" . $sourceFlavorOutput->getFlavorParamsId() . "] is valid"); } } $originalFlavorAsset->setStatus(flavorAsset::FLAVOR_ASSET_STATUS_CONVERTING); if (isset($sourceFlavor)) { $originalFlavorAsset->addTags($sourceFlavor->getTagsArray()); $originalFlavorAsset->setFileExt($sourceFlavorOutput->getFileExt()); $originalFlavorAsset->save(); } // save flavor params $sourceFlavorOutput->setFlavorAssetVersion($originalFlavorAsset->getVersion()); $sourceFlavorOutput->save(); $mediaInfoId = null; if ($mediaInfo) { $mediaInfoId = $mediaInfo->getId(); } kJobsManager::addFlavorConvertJob(array($srcSyncKey), $sourceFlavorOutput, $originalFlavorAsset->getId(), $conversionProfileId, $mediaInfoId, $parentJob); return false; }
/** * Function adds bulk upload job to the queue * @param Partner $partner * @param kBulkUploadJobData $jobData * @param string $bulkUploadType * @throws APIException * @return BatchJob */ public static function addBulkUploadJob(Partner $partner, kBulkUploadJobData $jobData, $bulkUploadType = null, $objectId = null, $objectType = null) { KalturaLog::debug("adding BulkUpload job"); $job = new BatchJob(); $job->setPartnerId($partner->getId()); $job->setJobType(BatchJobType::BULKUPLOAD); $job->setJobSubType($bulkUploadType); if (!is_null($objectId) && !is_null($objectType)) { $job->setObjectId($objectId); $job->setObjectType($objectType); } if (is_null($jobData)) { throw new APIException(APIErrors::BULK_UPLOAD_BULK_UPLOAD_TYPE_NOT_VALID, $bulkUploadType); } $job->setStatus(BatchJob::BATCHJOB_STATUS_DONT_PROCESS); $job = kJobsManager::addJob($job, $jobData, BatchJobType::BULKUPLOAD, $bulkUploadType); if (!is_null($jobData->getFilePath())) { $syncKey = $job->getSyncKey(BatchJob::FILE_SYNC_BATCHJOB_SUB_TYPE_BULKUPLOAD); // kFileSyncUtils::file_put_contents($syncKey, file_get_contents($csvFileData["tmp_name"])); try { kFileSyncUtils::moveFromFile($jobData->getFilePath(), $syncKey, true); } catch (Exception $e) { KalturaLog::err($e); throw new APIException(APIErrors::BULK_UPLOAD_CREATE_CSV_FILE_SYNC_ERROR); } $filePath = kFileSyncUtils::getLocalFilePathForKey($syncKey); $jobData->setFilePath($filePath); } if (!$jobData->getBulkUploadObjectType()) { $jobData->setBulkUploadObjectType(BulkUploadObjectType::ENTRY); } if ($jobData->getBulkUploadObjectType() == BulkUploadObjectType::ENTRY && !$jobData->getObjectData()->getConversionProfileId()) { $jobData->setConversionProfileId($partner->getDefaultConversionProfileId()); $kmcVersion = $partner->getKmcVersion(); $check = null; if ($kmcVersion < 2) { $check = ConversionProfilePeer::retrieveByPK($jobData->getConversionProfileId()); } else { $check = conversionProfile2Peer::retrieveByPK($jobData->getConversionProfileId()); } if (!$check) { throw new APIException(APIErrors::CONVERSION_PROFILE_ID_NOT_FOUND, $jobData->getConversionProfileId()); } } $job->setData($jobData); return kJobsManager::updateBatchJob($job, BatchJob::BATCHJOB_STATUS_PENDING); }
public static function cleanExclusiveJobs() { $jobs = kBatchExclusiveLock::getExpiredJobs(); foreach ($jobs as $job) { KalturaLog::log("Cleaning job id[" . $job->getId() . "]"); kJobsManager::updateBatchJob($job, BatchJob::BATCHJOB_STATUS_FATAL); } $c = new Criteria(); $c->add(BatchJobPeer::STATUS, BatchJobPeer::getClosedStatusList(), Criteria::IN); $c->add(BatchJobPeer::BATCH_INDEX, null, Criteria::ISNOTNULL); // The 'closed' jobs should be donn for at least 10min. // before the cleanup starts messing upo with'em // This solves cases when job (convert) completes succesfully, // but the next job (closure)does not get a chance to take over due to the clean-up $c->add(BatchJobPeer::FINISH_TIME, time() - 600, Criteria::LESS_THAN); // MUST be the master DB $jobs = BatchJobPeer::doSelect($c, myDbHelper::getConnection(myDbHelper::DB_HELPER_CONN_PROPEL2)); foreach ($jobs as $job) { KalturaLog::log("Cleaning job id[" . $job->getId() . "]"); $job->setSchedulerId(null); $job->setWorkerId(null); $job->setBatchIndex(null); $job->setProcessorExpiration(null); $job->save(); } return count($jobs); }
private static function decideSourceFlavorConvert($entryId, assetParams $sourceFlavor = null, flavorAsset $originalFlavorAsset, $conversionProfileId, $flavors, mediaInfo $mediaInfo = null, BatchJob $parentJob, BatchJob $convertProfileJob) { if ($sourceFlavor && ($sourceFlavor->getOperators() || $sourceFlavor->getConversionEngines()) && $originalFlavorAsset->getInterFlowCount() == null) { KalturaLog::log("Source flavor asset requires conversion"); self::adjustAssetParams($entryId, array($sourceFlavor)); $srcSyncKey = $originalFlavorAsset->getSyncKey(flavorAsset::FILE_SYNC_FLAVOR_ASSET_SUB_TYPE_ASSET); $errDescription = null; $sourceFlavorOutput = self::validateFlavorAndMediaInfo($sourceFlavor, $mediaInfo, $errDescription); if (!$sourceFlavorOutput) { if (!$errDescription) { $errDescription = "Failed to create flavor params output from source flavor"; } $originalFlavorAsset->setDescription($originalFlavorAsset->getDescription() . "\n{$errDescription}"); $originalFlavorAsset->setStatus(flavorAsset::ASSET_STATUS_ERROR); $originalFlavorAsset->save(); kBatchManager::updateEntry($entryId, entryStatus::ERROR_CONVERTING); kJobsManager::updateBatchJob($convertProfileJob, BatchJob::BATCHJOB_STATUS_FAILED); return false; } /* * If the conversion profile contains source flavor and the source is tagged with 'save_source' ==> * save the original source asset in another asset, in order * to prevent its liquidated by the inter-source asset. */ if (isset($sourceFlavor) && strstr($sourceFlavor->getTagsArray(), assetParams::TAG_SAVE_SOURCE) !== false) { self::saveOriginalSource($mediaInfo); } } elseif ($mediaInfo) { /* * Check whether there is a need for an intermediate source pre-processing */ $sourceFlavorOutput = KDLWrap::GenerateIntermediateSource($mediaInfo, $flavors); if (!$sourceFlavorOutput) { return true; } $srcSyncKey = $originalFlavorAsset->getSyncKey(flavorAsset::FILE_SYNC_FLAVOR_ASSET_SUB_TYPE_ASSET); $errDescription = null; /* * Save the original source asset in another asset, in order * to prevent its liquidated by the inter-source asset. * But, do it only if the conversion profile contains source flavor */ if (isset($sourceFlavor)) { self::saveOriginalSource($mediaInfo); } } /* * '_passthrough' controls whether the source is to be 'passthrough' although there * is a source flavor that contains transcoder settings. * Looks for a '_passthrough' flag on the source's flavor params output. */ if (!isset($sourceFlavorOutput) || $sourceFlavorOutput->_passthrough == true) { return true; } // save flavor params $sourceFlavorOutput->setPartnerId($sourceFlavorOutput->getPartnerId()); $sourceFlavorOutput->setEntryId($entryId); $sourceFlavorOutput->setFlavorAssetId($originalFlavorAsset->getId()); $sourceFlavorOutput->setFlavorAssetVersion($originalFlavorAsset->getVersion()); $sourceFlavorOutput->save(); if ($errDescription) { $originalFlavorAsset->setDescription($originalFlavorAsset->getDescription() . "\n{$errDescription}"); } $errDescription = kBusinessConvertDL::parseFlavorDescription($sourceFlavorOutput); if ($errDescription) { $originalFlavorAsset->setDescription($originalFlavorAsset->getDescription() . "\n{$errDescription}"); } // decided by the business logic layer if ($sourceFlavorOutput->_create_anyway) { KalturaLog::log("Flavor [" . $sourceFlavorOutput->getFlavorParamsId() . "] selected to be created anyway"); } else { if (!$sourceFlavorOutput->IsValid()) { KalturaLog::log("Flavor [" . $sourceFlavorOutput->getFlavorParamsId() . "] is invalid"); $originalFlavorAsset->setStatus(flavorAsset::FLAVOR_ASSET_STATUS_ERROR); $originalFlavorAsset->save(); $errDescription = "Source flavor could not be converted"; self::setError($errDescription, $convertProfileJob, BatchJobType::CONVERT_PROFILE, $convertProfileJob->getEntryId()); return false; } if ($sourceFlavorOutput->_force) { KalturaLog::log("Flavor [" . $sourceFlavorOutput->getFlavorParamsId() . "] is forced"); } elseif ($sourceFlavorOutput->_isNonComply) { KalturaLog::log("Flavor [" . $sourceFlavorOutput->getFlavorParamsId() . "] is none-comply"); } else { KalturaLog::log("Flavor [" . $sourceFlavorOutput->getFlavorParamsId() . "] is valid"); } } $originalFlavorAsset->setStatus(flavorAsset::FLAVOR_ASSET_STATUS_CONVERTING); if (isset($sourceFlavor)) { $tagsArr = $sourceFlavor->getTagsArray(); // No need for 'save_source' tag on the inter-src asset, remove it. if (($key = array_search(assetParams::TAG_SAVE_SOURCE, $tagsArr)) !== false) { unset($tagsArr[$key]); } $originalFlavorAsset->addTags($tagsArr); $originalFlavorAsset->setFileExt($sourceFlavorOutput->getFileExt()); $originalFlavorAsset->save(); } // save flavor params $sourceFlavorOutput->setFlavorAssetVersion($originalFlavorAsset->getVersion()); $sourceFlavorOutput->save(); $mediaInfoId = null; if ($mediaInfo) { $mediaInfoId = $mediaInfo->getId(); } kJobsManager::addFlavorConvertJob(array($srcSyncKey), $sourceFlavorOutput, $originalFlavorAsset->getId(), $conversionProfileId, $mediaInfoId, $parentJob); return false; }
private static function activateConvertProfileJob($entryId, $localFilePath) { $c = new Criteria(); $c->add(BatchJobPeer::ENTRY_ID, $entryId); $c->add(BatchJobPeer::JOB_TYPE, BatchJobType::CONVERT_PROFILE); $c->add(BatchJobPeer::STATUS, BatchJob::BATCHJOB_STATUS_DONT_PROCESS); $batchJob = BatchJobPeer::doSelectOne($c); if ($batchJob) { $data = $batchJob->getData(); $data->setInputFileSyncLocalPath($localFilePath); $batchJob->setData($data); kJobsManager::updateBatchJob($batchJob, BatchJob::BATCHJOB_STATUS_PENDING); return true; } else { return false; } }
public function updatedJob(BatchJob $dbBatchJob) { $dbBatchJobLock = $dbBatchJob->getBatchJobLock(); try { if ($dbBatchJob->getStatus() == BatchJob::BATCHJOB_STATUS_FAILED || $dbBatchJob->getStatus() == BatchJob::BATCHJOB_STATUS_FATAL) { kJobsManager::abortChildJobs($dbBatchJob); } $jobType = $dbBatchJob->getJobType(); switch ($jobType) { case BatchJobType::IMPORT: $dbBatchJob = $this->updatedImport($dbBatchJob, $dbBatchJob->getData()); break; case BatchJobType::EXTRACT_MEDIA: $dbBatchJob = $this->updatedExtractMedia($dbBatchJob, $dbBatchJob->getData()); break; case BatchJobType::CONVERT: $dbBatchJob = $this->updatedConvert($dbBatchJob, $dbBatchJob->getData()); break; case BatchJobType::POSTCONVERT: $dbBatchJob = $this->updatedPostConvert($dbBatchJob, $dbBatchJob->getData()); break; case BatchJobType::BULKUPLOAD: $dbBatchJob = $this->updatedBulkUpload($dbBatchJob, $dbBatchJob->getData()); break; case BatchJobType::CONVERT_PROFILE: $dbBatchJob = $this->updatedConvertProfile($dbBatchJob, $dbBatchJob->getData()); break; case BatchJobType::BULKDOWNLOAD: $dbBatchJob = $this->updatedBulkDownload($dbBatchJob, $dbBatchJob->getData()); break; case BatchJobType::PROVISION_PROVIDE: $dbBatchJob = $this->updatedProvisionProvide($dbBatchJob, $dbBatchJob->getData()); break; case BatchJobType::PROVISION_DELETE: $dbBatchJob = $this->updatedProvisionDelete($dbBatchJob, $dbBatchJob->getData()); break; case BatchJobType::CONVERT_COLLECTION: $dbBatchJob = $this->updatedConvertCollection($dbBatchJob, $dbBatchJob->getData()); break; case BatchJobType::STORAGE_EXPORT: $dbBatchJob = $this->updatedStorageExport($dbBatchJob, $dbBatchJob->getData()); break; case BatchJobType::MOVE_CATEGORY_ENTRIES: $dbBatchJob = $this->updatedMoveCategoryEntries($dbBatchJob, $dbBatchJob->getData()); break; case BatchJobType::STORAGE_DELETE: $dbBatchJob = $this->updatedStorageDelete($dbBatchJob, $dbBatchJob->getData()); break; case BatchJobType::CAPTURE_THUMB: $dbBatchJob = $this->updatedCaptureThumb($dbBatchJob, $dbBatchJob->getData()); break; case BatchJobType::DELETE_FILE: $dbBatchJob = $this->updatedDeleteFile($dbBatchJob, $dbBatchJob->getData()); break; case BatchJobType::INDEX: $dbBatchJob = $this->updatedIndex($dbBatchJob, $dbBatchJob->getData()); break; case BatchJobType::COPY: $dbBatchJob = $this->updatedCopy($dbBatchJob, $dbBatchJob->getData()); break; case BatchJobType::DELETE: $dbBatchJob = $this->updatedDelete($dbBatchJob, $dbBatchJob->getData()); break; case BatchJobType::CONCAT: $dbBatchJob = $this->updatedConcat($dbBatchJob, $dbBatchJob->getData()); break; case BatchJobType::CONVERT_LIVE_SEGMENT: $dbBatchJob = $this->updatedConvertLiveSegment($dbBatchJob, $dbBatchJob->getData()); break; case BatchJobType::LIVE_REPORT_EXPORT: $dbBatchJob = $this->updatedLiveReportExport($dbBatchJob, $dbBatchJob->getData()); break; default: break; } if ($dbBatchJob->getStatus() == BatchJob::BATCHJOB_STATUS_RETRY) { if ($dbBatchJobLock && $dbBatchJobLock->getExecutionAttempts() >= BatchJobLockPeer::getMaxExecutionAttempts($jobType)) { $dbBatchJob = kJobsManager::updateBatchJob($dbBatchJob, BatchJob::BATCHJOB_STATUS_FAILED); } } if (in_array($dbBatchJob->getStatus(), BatchJobPeer::getClosedStatusList())) { $jobEntry = $dbBatchJob->getEntry(); if ($jobEntry && $jobEntry->getMarkedForDeletion()) { myEntryUtils::deleteEntry($jobEntry, null, true); } } } catch (Exception $ex) { self::alert($dbBatchJob, $ex); KalturaLog::err("Error:" . $ex->getMessage()); } return true; }
/** * batch decideProfileConvert is the decision layer for a conversion profile * * @param BatchJob $parentJob * @param BatchJob $convertProfileJob * @param int $mediaInfoId * @return bool true if created all required conversions */ public static function decideProfileConvert(BatchJob $parentJob, BatchJob $convertProfileJob, $mediaInfoId = null) { KalturaLog::log("Conversion decision layer used for entry [" . $parentJob->getEntryId() . "]"); $convertProfileData = $convertProfileJob->getData(); $entryId = $convertProfileJob->getEntryId(); $entry = $convertProfileJob->getEntry(); if (!$entry) { throw new APIException(APIErrors::INVALID_ENTRY, $convertProfileJob, $entryId); } $profile = myPartnerUtils::getConversionProfile2ForEntry($entryId); if (!$profile) { $errDescription = "Conversion profile for entryId [{$entryId}] not found"; $convertProfileJob = kJobsManager::failBatchJob($convertProfileJob, $errDescription, BatchJobType::CONVERT_PROFILE); kBatchManager::updateEntry($convertProfileJob->getEntryId(), entryStatus::ERROR_CONVERTING); KalturaLog::err("No flavors created: {$errDescription}"); return false; } $originalFlavorAsset = assetPeer::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->getEntryId(), entryStatus::ERROR_CONVERTING); return false; } $shouldConvert = true; // gets the list of flavor params of the conversion profile $list = flavorParamsConversionProfilePeer::retrieveByConversionProfile($profile->getId()); if (!count($list)) { $errDescription = "No flavors match the profile id [{$profile->getId()}]"; KalturaLog::err($errDescription); $convertProfileJob = kJobsManager::failBatchJob($convertProfileJob, $errDescription, BatchJobType::CONVERT_PROFILE); kBatchManager::updateEntry($convertProfileJob->getEntryId(), entryStatus::ERROR_CONVERTING); $originalFlavorAsset->setStatus(flavorAsset::FLAVOR_ASSET_STATUS_DELETED); $originalFlavorAsset->setDeletedAt(time()); $originalFlavorAsset->save(); return false; } $mediaInfo = null; if ($mediaInfoId) { $mediaInfo = mediaInfoPeer::retrieveByPK($mediaInfoId); } if ($profile->getCreationMode() == ConversionProfile2::CONVERSION_PROFILE_2_CREATION_MODE_AUTOMATIC_BYPASS_FLV) { KalturaLog::log("The profile created from old conversion profile with bypass flv"); $isFlv = false; if ($mediaInfo) { $isFlv = KDLWrap::CDLIsFLV($mediaInfo); } if ($isFlv && $originalFlavorAsset->hasTag(flavorParams::TAG_MBR)) { KalturaLog::log("The source is mbr and flv, conversion will be bypassed"); $shouldConvert = false; } else { KalturaLog::log("The source is NOT mbr or flv, conversion will NOT be bypassed"); } } // gets the ids of the flavor params $flavorsIds = array(); $conversionProfileFlavorParams = array(); foreach ($list as $flavorParamsConversionProfile) { $flavorsId = $flavorParamsConversionProfile->getFlavorParamsId(); $flavorsIds[] = $flavorsId; $conversionProfileFlavorParams[$flavorsId] = $flavorParamsConversionProfile; } $dynamicFlavorAttributes = $entry->getDynamicFlavorAttributes(); $sourceFlavor = null; $flavors = assetParamsPeer::retrieveFlavorsByPKs($flavorsIds); $entryIngestedFlavors = explode(',', $entry->getFlavorParamsIds()); $ingestedNeeded = false; foreach ($flavors as $index => $flavor) { if (!isset($conversionProfileFlavorParams[$flavor->getId()])) { continue; } $conversionProfileFlavorParamsItem = $conversionProfileFlavorParams[$flavor->getId()]; // if flavor is not source, apply dynamic attributes defined for id -2 (all flavors) if (!$flavor->hasTag(flavorParams::TAG_SOURCE)) { if (isset($dynamicFlavorAttributes[flavorParams::DYNAMIC_ATTRIBUTES_ALL_FLAVORS_INDEX])) { foreach ($dynamicFlavorAttributes[flavorParams::DYNAMIC_ATTRIBUTES_ALL_FLAVORS_INDEX] as $attributeName => $attributeValue) { $flavor->setDynamicAttribute($attributeName, $attributeValue); } } } // overwrite dynamic attributes if defined for this specific flavor if (isset($dynamicFlavorAttributes[$flavor->getId()])) { foreach ($dynamicFlavorAttributes[$flavor->getId()] as $attributeName => $attributeValue) { $flavor->setDynamicAttribute($attributeName, $attributeValue); } } if ($flavor->hasTag(flavorParams::TAG_SOURCE)) { $sourceFlavor = $flavor; unset($flavors[$index]); continue; } if ($conversionProfileFlavorParamsItem->getOrigin() == assetParamsOrigin::CONVERT) { continue; } if ($conversionProfileFlavorParamsItem->getOrigin() == assetParamsOrigin::INGEST) { unset($flavors[$index]); $ingestedNeeded = true; continue; } if (in_array($flavor->getId(), $entryIngestedFlavors)) { unset($flavors[$index]); } } KalturaLog::log(count($flavors) . " destination flavors found for this profile[" . $profile->getId() . "]"); if (!$sourceFlavor) { KalturaLog::log("Source flavor params not found"); $originalFlavorAsset->setStatus(flavorAsset::FLAVOR_ASSET_STATUS_TEMP); $originalFlavorAsset->save(); } elseif ($shouldConvert) { KalturaLog::log("Source flavor params [" . $sourceFlavor->getId() . "] found"); $originalFlavorAsset->setFlavorParamsId($sourceFlavor->getId()); if ($sourceFlavor->getOperators() || $sourceFlavor->getConversionEngines()) { KalturaLog::log("Source flavor asset requires conversion"); $srcSyncKey = $originalFlavorAsset->getSyncKey(flavorAsset::FILE_SYNC_FLAVOR_ASSET_SUB_TYPE_ASSET); $errDescription = null; $sourceFlavorOutput = self::validateFlavorAndMediaInfo($sourceFlavor, $mediaInfo, $errDescription); if (!$sourceFlavorOutput) { if (!$errDescription) { $errDescription = "Failed to create flavor params output from source flavor"; } $originalFlavorAsset->setDescription($originalFlavorAsset->getDescription() . "\n{$errDescription}"); $originalFlavorAsset->setStatus(flavorAsset::ASSET_STATUS_ERROR); $originalFlavorAsset->save(); kBatchManager::updateEntry($entryId, entryStatus::ERROR_CONVERTING); return false; } // save flavor params $sourceFlavorOutput->setPartnerId($sourceFlavorOutput->getPartnerId()); $sourceFlavorOutput->setEntryId($entryId); $sourceFlavorOutput->setFlavorAssetId($originalFlavorAsset->getId()); $sourceFlavorOutput->setFlavorAssetVersion($originalFlavorAsset->getVersion()); $sourceFlavorOutput->save(); if ($errDescription) { $originalFlavorAsset->setDescription($originalFlavorAsset->getDescription() . "\n{$errDescription}"); } $errDescription = kBusinessConvertDL::parseFlavorDescription($sourceFlavorOutput); if ($errDescription) { $originalFlavorAsset->setDescription($originalFlavorAsset->getDescription() . "\n{$errDescription}"); } // decided by the business logic layer if ($sourceFlavorOutput->_create_anyway) { KalturaLog::log("Flavor [" . $sourceFlavorOutput->getFlavorParamsId() . "] selected to be created anyway"); } else { if (!$sourceFlavorOutput->IsValid()) { KalturaLog::log("Flavor [" . $sourceFlavorOutput->getFlavorParamsId() . "] is invalid"); $originalFlavorAsset->setStatus(flavorAsset::FLAVOR_ASSET_STATUS_ERROR); $originalFlavorAsset->save(); $errDescription = "Source flavor could not be converted"; KalturaLog::err($errDescription); $convertProfileJob = kJobsManager::failBatchJob($convertProfileJob, $errDescription, BatchJobType::CONVERT_PROFILE); kBatchManager::updateEntry($convertProfileJob->getEntryId(), entryStatus::ERROR_CONVERTING); return false; } if ($sourceFlavorOutput->_force) { KalturaLog::log("Flavor [" . $sourceFlavorOutput->getFlavorParamsId() . "] is forced"); } elseif ($sourceFlavorOutput->_isNonComply) { KalturaLog::log("Flavor [" . $sourceFlavorOutput->getFlavorParamsId() . "] is none-comply"); } else { KalturaLog::log("Flavor [" . $sourceFlavorOutput->getFlavorParamsId() . "] is valid"); } } // $originalFlavorAsset->incrementVersion(); $originalFlavorAsset->setStatus(flavorAsset::FLAVOR_ASSET_STATUS_CONVERTING); $originalFlavorAsset->addTags($sourceFlavor->getTagsArray()); $originalFlavorAsset->setFileExt($sourceFlavorOutput->getFileExt()); $originalFlavorAsset->save(); // save flavor params $sourceFlavorOutput->setFlavorAssetVersion($originalFlavorAsset->getVersion()); $sourceFlavorOutput->save(); kJobsManager::addFlavorConvertJob($srcSyncKey, $sourceFlavorOutput, $originalFlavorAsset->getId(), $mediaInfoId, $parentJob); return false; } $originalFlavorAsset->setStatusLocalReady(); $originalFlavorAsset->save(); $entry->save(); kFlowHelper::generateThumbnailsFromFlavor($parentJob->getEntryId(), $parentJob); } if (!count($flavors)) { $shouldConvert = false; } if (!$shouldConvert) { if ($ingestedNeeded) { kJobsManager::updateBatchJob($convertProfileJob, BatchJob::BATCHJOB_STATUS_FINISHED); return false; } else { self::bypassConversion($originalFlavorAsset, $entry, $convertProfileJob); return true; } } return self::decideProfileFlavorsConvert($parentJob, $convertProfileJob, $flavors, $conversionProfileFlavorParams, $mediaInfo); }
/** * @param BatchJob $dbBatchJob * @param flavorAsset $currentFlavorAsset * @return BatchJob */ public static function handleConvertFinished(BatchJob $dbBatchJob, flavorAsset $currentFlavorAsset) { $currentReadyBehavior = self::getReadyBehavior($currentFlavorAsset); $rootBatchJob = $dbBatchJob->getRootJob(); // update the root job end exit if ($rootBatchJob && $rootBatchJob->getJobType() == BatchJobType::REMOTE_CONVERT) { kJobsManager::updateBatchJob($rootBatchJob, BatchJob::BATCHJOB_STATUS_FINISHED); return $dbBatchJob; } // update the root job end exit if ($rootBatchJob && $rootBatchJob->getJobType() == BatchJobType::BULKDOWNLOAD) { $siblingJobs = $rootBatchJob->getChildJobs(); foreach ($siblingJobs as $siblingJob) { // checking only conversion child jobs if ($siblingJob->getJobType() != BatchJobType::CONVERT && $siblingJob->getJobType() != BatchJobType::CONVERT_COLLECTION && $siblingJob->getJobType() != BatchJobType::POSTCONVERT) { continue; } // if not complete leave function if ($siblingJob->getStatus() != BatchJob::BATCHJOB_STATUS_FINISHED) { return $dbBatchJob; } } // all child jobs completed kJobsManager::updateBatchJob($rootBatchJob, BatchJob::BATCHJOB_STATUS_FINISHED); return $dbBatchJob; } // go over all the conversion jobs in the context $hasInComplte = false; $hasInComplteRequired = false; $siblingFlavorAssets = flavorAssetPeer::retrieveByEntryId($dbBatchJob->getEntryId()); foreach ($siblingFlavorAssets as $siblingFlavorAsset) { if ($siblingFlavorAsset->getId() == $currentFlavorAsset->getId()) { continue; } // don't mark any incomplete flag if ($siblingFlavorAsset->getStatus() == flavorAsset::FLAVOR_ASSET_STATUS_READY) { continue; } $readyBehavior = self::getReadyBehavior($siblingFlavorAsset); if ($readyBehavior == flavorParamsConversionProfile::READY_BEHAVIOR_IGNORE) { continue; } if ($siblingFlavorAsset->getStatus() == flavorAsset::FLAVOR_ASSET_STATUS_QUEUED || $siblingFlavorAsset->getStatus() == flavorAsset::FLAVOR_ASSET_STATUS_CONVERTING) { $hasInComplte = true; } if ($readyBehavior == flavorParamsConversionProfile::READY_BEHAVIOR_REQUIRED) { $hasInComplteRequired = true; } } if ($hasInComplteRequired) { KalturaLog::debug('Convert Finished - has In-Complte Required jobs'); } elseif ($currentReadyBehavior == flavorParamsConversionProfile::READY_BEHAVIOR_OPTIONAL || $currentReadyBehavior == flavorParamsConversionProfile::READY_BEHAVIOR_REQUIRED) { // mark the entry as ready if all required conversions completed or any of the optionals kBatchManager::updateEntry($dbBatchJob, entryStatus::READY); } // no need to finished the root job if (!$rootBatchJob) { KalturaLog::debug('Convert Finished - no root job to close'); return $dbBatchJob; } // only bulk-download and convert-profile are pending on the conversions to close them, otherwise, return if ($rootBatchJob->getJobType() != BatchJobType::CONVERT_PROFILE) { KalturaLog::debug('Convert Finished - root job type [' . $rootBatchJob->getJobType() . ']'); return $dbBatchJob; } if ($hasInComplte) { KalturaLog::debug('Convert Finished - has In-Complte jobs'); } else { // mark the context root job as finished only if all conversion jobs are completed kJobsManager::updateBatchJob($rootBatchJob, BatchJob::BATCHJOB_STATUS_FINISHED); } return $dbBatchJob; }
public static function handleBulkDownloadPending(BatchJob $dbBatchJob, kBulkDownloadJobData $data, BatchJob $twinJob = null) { $entryIds = explode(',', $data->getEntryIds()); $flavorParamsId = $data->getFlavorParamsId(); $jobIsFinished = true; foreach ($entryIds as $entryId) { $entry = entryPeer::retrieveByPK($entryId); if (is_null($entry)) { KalturaLog::err("Entry id [{$entryId}] not found."); } else { if ($entry->hasDownloadAsset($flavorParamsId)) { // why we don't send the notification in case of image is ready? $flavorAsset = flavorAssetPeer::retrieveByEntryIdAndFlavorParams($entryId, $flavorParamsId); if ($flavorAsset && $flavorAsset->getStatus() == flavorAsset::FLAVOR_ASSET_STATUS_READY) { $syncKey = $flavorAsset->getSyncKey(flavorAsset::FILE_SYNC_FLAVOR_ASSET_SUB_TYPE_ASSET); $downloadUrl = $flavorAsset->getDownloadUrl(); $localPath = kFileSyncUtils::getLocalFilePathForKey($syncKey); $downloadUrl = $flavorAsset->getDownloadUrl(); $notificationData = array("puserId" => $entry->getPuserId(), "entryId" => $entry->getId(), "entryIntId" => $entry->getIntId(), "entryVersion" => $entry->getVersion(), "fileFormat" => $flavorAsset->getFileExt(), "archivedFile" => $localPath, "downoladPath" => $localPath, "conversionQuality" => $entry->getConversionQuality(), "downloadUrl" => $downloadUrl); $extraData = array("data" => json_encode($notificationData), "partner_id" => $entry->getPartnerId(), "puser_id" => $entry->getPuserId(), "entry_id" => $entry->getId(), "entry_int_id" => $entry->getIntId(), "entry_version" => $entry->getVersion(), "file_format" => $flavorAsset->getFileExt(), "archived_file" => $localPath, "downolad_path" => $localPath, "target" => $localPath, "conversion_quality" => $entry->getConversionQuality(), "download_url" => $downloadUrl, "status" => $entry->getStatus(), "abort" => $dbBatchJob->getAbort(), "progress" => $dbBatchJob->getProgress(), "message" => $dbBatchJob->getMessage(), "description" => $dbBatchJob->getDescription(), "updates_count" => $dbBatchJob->getUpdatesCount(), "job_type" => BatchJobType::DOWNLOAD, "status" => BatchJob::BATCHJOB_STATUS_FINISHED, "progress" => 100, "debug" => __LINE__); myNotificationMgr::createNotification(kNotificationJobData::NOTIFICATION_TYPE_BATCH_JOB_SUCCEEDED, $dbBatchJob, $dbBatchJob->getPartnerId(), null, null, $extraData, $entryId); } } else { $jobIsFinished = false; $entry->createDownloadAsset($dbBatchJob, $flavorParamsId, $data->getPuserId()); } } } if ($jobIsFinished) { // mark the job as finished $dbBatchJob = kJobsManager::updateBatchJob($dbBatchJob, BatchJob::BATCHJOB_STATUS_FINISHED); } else { // mark the job as almost done $dbBatchJob = kJobsManager::updateBatchJob($dbBatchJob, BatchJob::BATCHJOB_STATUS_ALMOST_DONE); } return $dbBatchJob; }
public static function cleanExclusiveJobs() { $jobs = kBatchExclusiveLock::getExpiredJobs(); foreach ($jobs as $job) { KalturaLog::log("Cleaning job id[" . $job->getId() . "]"); $job->setMessage("Job was cleaned up."); kJobsManager::updateBatchJob($job, BatchJob::BATCHJOB_STATUS_FATAL); } $jobs = kBatchExclusiveLock::getStatusInconsistentJob(); foreach ($jobs as $job) { KalturaLog::log("Fixing batch job Inconsistency [" . $job->getId() . "]"); $job->delete(); // The job shouldhave been deleted. The reason it got here is since the update // process has failed fataly. Therefore there is no point in retrying to save it. } return 0; }
/** * @param BatchJob $dbBatchJob * @param BatchJob $twinJob * @return bool true if should continue to the next consumer */ public function updatedJob(BatchJob $dbBatchJob, BatchJob $twinJob = null) { try { $jobType = $dbBatchJob->getJobType(); if (is_null($dbBatchJob->getQueueTime()) && $dbBatchJob->getStatus() != BatchJob::BATCHJOB_STATUS_PENDING) { $dbBatchJob->setQueueTime(time()); $dbBatchJob->save(); } if ($dbBatchJob->getStatus() == BatchJob::BATCHJOB_STATUS_FINISHED) { $dbBatchJob->setFinishTime(time()); $dbBatchJob->save(); } if ($dbBatchJob->getStatus() == BatchJob::BATCHJOB_STATUS_RETRY) { $dbBatchJob->setCheckAgainTimeout(time() + BatchJobPeer::getCheckAgainTimeout($jobType)); $dbBatchJob->setQueueTime(null); $dbBatchJob->save(); } if ($dbBatchJob->getStatus() == BatchJob::BATCHJOB_STATUS_ALMOST_DONE) { $dbBatchJob->setCheckAgainTimeout(time() + BatchJobPeer::getCheckAgainTimeout($jobType)); $dbBatchJob->save(); } if ($dbBatchJob->getStatus() == BatchJob::BATCHJOB_STATUS_FAILED || $dbBatchJob->getStatus() == BatchJob::BATCHJOB_STATUS_FATAL) { $dbBatchJob->setFinishTime(time()); $dbBatchJob->save(); // TODO - don't abort if it's bulk upload kJobsManager::abortChildJobs($dbBatchJob); } switch ($jobType) { case BatchJobType::IMPORT: $dbBatchJob = $this->updatedImport($dbBatchJob, $dbBatchJob->getData(), $twinJob); break; case BatchJobType::EXTRACT_MEDIA: $dbBatchJob = $this->updatedExtractMedia($dbBatchJob, $dbBatchJob->getData(), $twinJob); break; case BatchJobType::CONVERT: $dbBatchJob = $this->updatedConvert($dbBatchJob, $dbBatchJob->getData(), $twinJob); break; case BatchJobType::POSTCONVERT: $dbBatchJob = $this->updatedPostConvert($dbBatchJob, $dbBatchJob->getData(), $twinJob); break; case BatchJobType::BULKUPLOAD: $dbBatchJob = $this->updatedBulkUpload($dbBatchJob, $dbBatchJob->getData(), $twinJob); break; case BatchJobType::CONVERT_PROFILE: $dbBatchJob = $this->updatedConvertProfile($dbBatchJob, $dbBatchJob->getData(), $twinJob); break; case BatchJobType::BULKDOWNLOAD: $dbBatchJob = $this->updatedBulkDownload($dbBatchJob, $dbBatchJob->getData(), $twinJob); break; case BatchJobType::PROVISION_PROVIDE: $dbBatchJob = $this->updatedProvisionProvide($dbBatchJob, $dbBatchJob->getData(), $twinJob); break; case BatchJobType::PROVISION_DELETE: $dbBatchJob = $this->updatedProvisionDelete($dbBatchJob, $dbBatchJob->getData(), $twinJob); break; case BatchJobType::CONVERT_COLLECTION: $dbBatchJob = $this->updatedConvertCollection($dbBatchJob, $dbBatchJob->getData(), $twinJob); break; case BatchJobType::STORAGE_EXPORT: $dbBatchJob = $this->updatedStorageExport($dbBatchJob, $dbBatchJob->getData(), $twinJob); break; case BatchJobType::STORAGE_DELETE: $dbBatchJob = $this->updatedStorageDelete($dbBatchJob, $dbBatchJob->getData(), $twinJob); break; case BatchJobType::CAPTURE_THUMB: $dbBatchJob = $this->updatedCaptureThumb($dbBatchJob, $dbBatchJob->getData(), $twinJob); break; default: break; } if (!kConf::get("batch_ignore_duplication")) { if ($dbBatchJob->getStatus() == BatchJob::BATCHJOB_STATUS_FINISHED) { $twinBatchJobs = $dbBatchJob->getTwinJobs(); // update status at all twin jobs foreach ($twinBatchJobs as $twinBatchJob) { if ($twinBatchJob->getStatus() != BatchJob::BATCHJOB_STATUS_FINISHED) { kJobsManager::updateBatchJob($twinBatchJob, BatchJob::BATCHJOB_STATUS_FINISHED); } } } } if ($dbBatchJob->getStatus() == BatchJob::BATCHJOB_STATUS_RETRY && $dbBatchJob->getExecutionAttempts() >= BatchJobPeer::getMaxExecutionAttempts($jobType)) { $dbBatchJob = kJobsManager::updateBatchJob($dbBatchJob, BatchJob::BATCHJOB_STATUS_FAILED); } } catch (Exception $ex) { self::alert($dbBatchJob, $ex); KalturaLog::err("Error:" . $ex->getMessage()); } return true; }
/** * @param BatchJob $dbBatchJob * @param kDistributionDeleteJobData $data * @param BatchJob $twinJob * @return BatchJob */ public static function onDistributionDeleteJobPending(BatchJob $dbBatchJob, kDistributionDeleteJobData $data, BatchJob $twinJob = null) { $entryDistribution = EntryDistributionPeer::retrieveByPK($data->getEntryDistributionId()); if (!$entryDistribution) { KalturaLog::err("Entry distribution [" . $data->getEntryDistributionId() . "] not found"); return $dbBatchJob; } $entryDistribution->setStatus(EntryDistributionStatus::DELETING); $entryDistribution->setDirtyStatus(null); $entryDistribution->save(); if ($data->getProviderType() == DistributionProviderType::SYNDICATION) { $dbBatchJob = kJobsManager::updateBatchJob($dbBatchJob, BatchJob::BATCHJOB_STATUS_FINISHED); } return $dbBatchJob; }