/** * @covers BatchJobUtils::DownloadBatchJobResults * @expectedException BatchJobException */ public function testDownloadBatchJobResultsFailsWithBatchJobException() { $curlUtils = $this->getMock('CurlUtils'); $curlUtils->expects($this->any())->method('GetInfo')->will($this->returnValue(500)); $curlUtils->expects($this->any())->method('Error')->will($this->returnValue('Internal server error')); $batchJobUtils = new BatchJobUtils(self::$DUMMY_UPLOAD_URL, 0, $curlUtils); $batchJobUtils->DownloadBatchJobResults(self::$DUMMY_DOWNLOAD_URL); }
/** * Runs the example. * @param AdWordsUser $user the user to run the example with */ function AddCompleteCampaignUsingBatchJobExample(AdWordsUser $user) { // Get the service, which loads the required classes. $batchJobService = $user->GetService('BatchJobService', ADWORDS_VERSION); // Create a BatchJob. $addOp = new BatchJobOperation(); $addOp->operator = 'ADD'; $addOp->operand = new BatchJob(); $addOps[] = $addOp; $result = $batchJobService->mutate($addOps); $batchJob = $result->value[0]; // Get the upload URL from the new job. $uploadUrl = $batchJob->uploadUrl->url; printf("Created BatchJob with ID %d, status '%s' and upload 'URL' %s.\n", $batchJob->id, $batchJob->status, $uploadUrl); $namePrefix = uniqid(); // Create and add an operation to create a new budget. $budgetOperation = buildBudgetOperation($namePrefix); $operations = array($budgetOperation); // Create and add an operation to create new campaigns. $campaignOperations = buildCampaignOperations($namePrefix, $budgetOperation); $operations = array_merge($operations, $campaignOperations); // Create and add operations to create new negative keyword criteria for // each campaign. $campaignCriterionOperations = buildCampaignCriterionOperations($campaignOperations); $operations = array_merge($operations, $campaignCriterionOperations); // Create and add operations to create new ad groups. $adGroupOperations = buildAdGroupOperations($namePrefix, $campaignOperations); $operations = array_merge($operations, $adGroupOperations); // Create and add operations to create new ad group criteria (keywords). $adGroupCriterionOperations = buildAdGroupCriterionOperations($adGroupOperations); $operations = array_merge($operations, $adGroupCriterionOperations); // Create and add operations to create new ad group ads (text ads). $adGroupAdOperations = buildAdGroupAdOperations($adGroupOperations); $operations = array_merge($operations, $adGroupAdOperations); // Use BatchJobUtils to upload all operations. $batchJobUtils = new BatchJobUtils($batchJob->uploadUrl->url); $batchJobUtils->UploadBatchJobOperations($operations); printf("Uploaded %d operations for batch job with ID %d.\n", count($operations), $batchJob->id); // Poll for completion of the batch job using an exponential back off. $pollAttempts = 0; $isPending = true; do { $sleepSeconds = POLL_FREQUENCY_SECONDS * pow(2, $pollAttempts); printf("Sleeping %d seconds...\n", $sleepSeconds); sleep($sleepSeconds); $selector = new Selector(); $selector->fields = array('Id', 'Status', 'DownloadUrl', 'ProcessingErrors', 'ProgressStats'); $selector->predicates[] = new Predicate('Id', 'EQUALS', $batchJob->id); $batchJob = $batchJobService->get($selector)->entries[0]; printf("Batch job ID %d has status '%s'.\n", $batchJob->id, $batchJob->status); $pollAttempts++; if ($batchJob->status !== 'ACTIVE' && $batchJob->status !== 'AWAITING_FILE' && $batchJob->status !== 'CANCELING') { $isPending = false; } } while ($isPending && $pollAttempts <= MAX_POLL_ATTEMPTS); if ($isPending) { throw new BatchJobException(sprintf("Job is still pending state after polling %d times.", MAX_POLL_ATTEMPTS)); } if ($batchJob->processingErrors !== null) { $i = 0; foreach ($batchJob->processingErrors as $processingError) { printf(" Processing error [%d]: errorType=%s, trigger=%s, errorString=%s," . " fieldPath=%s, reason=%s\n", $i++, $processingError->ApiErrorType, $processingError->trigger, $processingError->errorString, $processingError->fieldPath, $processingError->reason); } } else { printf("No processing errors found.\n"); } if ($batchJob->downloadUrl !== null && $batchJob->downloadUrl->url !== null) { $xmlResponse = $batchJobUtils->DownloadBatchJobResults($batchJob->downloadUrl->url); printf("Downloaded results from %s:\n", $batchJob->downloadUrl->url); $deserializer = new XmlDeserializer(BatchJobUtils::$CLASS_MAP); $mutateResponse = $deserializer->ConvertXmlToObject($xmlResponse); if (empty($mutateResponse)) { printf(" No results available.\n"); } else { foreach ($mutateResponse->rval as $mutateResult) { $outcome = $mutateResult->errorList === null ? 'SUCCESS' : 'FAILURE'; printf(" Operation [%d] - %s\n", $mutateResult->index, $outcome); } } } else { printf("No results available for download.\n"); } }
/** * Runs the example. * * @param AdWordsUser $user the user to run the example with * @param string $adGroupId the ID of the ad group to add the keywords to */ function AddKeywordsUsingIncrementalBatchJob(AdWordsUser $user, $adGroupId) { // Get the service, which loads the required classes. $batchJobService = $user->GetService('BatchJobService', ADWORDS_VERSION); // Create a BatchJob. $addOp = new BatchJobOperation(); $addOp->operator = 'ADD'; $addOp->operand = new BatchJob(); $addOps[] = $addOp; $result = $batchJobService->mutate($addOps); $batchJob = $result->value[0]; // Get the upload URL from the new job. $uploadUrl = $batchJob->uploadUrl->url; printf("Created BatchJob with ID %d, status '%s' and upload URL '%s'.\n", $batchJob->id, $batchJob->status, $uploadUrl); // Use BatchJobUtils to upload all operations. $batchJobUtils = new BatchJobUtils($uploadUrl); // Generate and upload the first set of operations. $adGroupCriterionOperations = buildAdGroupCriterionOperations($adGroupId); $batchJobUtils->UploadIncrementalBatchJobOperations($adGroupCriterionOperations); printf("Uploaded %d operations for batch job with ID %d.\n", count($adGroupCriterionOperations), $batchJob->id); // Generate and upload the second set of operations. $adGroupCriterionOperations = buildAdGroupCriterionOperations($adGroupId); $batchJobUtils->UploadIncrementalBatchJobOperations($adGroupCriterionOperations); printf("Uploaded %d operations for batch job with ID %d.\n", count($adGroupCriterionOperations), $batchJob->id); // Generate and upload the third and final set of operations. $adGroupCriterionOperations = buildAdGroupCriterionOperations($adGroupId); $batchJobUtils->UploadIncrementalBatchJobOperations($adGroupCriterionOperations, true); printf("Uploaded %d operations for batch job with ID %d.\n", count($adGroupCriterionOperations), $batchJob->id); // Poll for completion of the batch job using an exponential back off. $pollAttempts = 0; $isPending = true; $wasCancelRequested = false; $selector = new Selector(); $selector->fields = array('Id', 'Status', 'DownloadUrl', 'ProcessingErrors', 'ProgressStats'); $selector->predicates[] = new Predicate('Id', 'EQUALS', $batchJob->id); do { $sleepSeconds = POLL_FREQUENCY_SECONDS * pow(2, $pollAttempts); printf("Sleeping %d seconds...\n", $sleepSeconds); sleep($sleepSeconds); $batchJob = $batchJobService->get($selector)->entries[0]; printf("Batch job ID %d has status '%s'.\n", $batchJob->id, $batchJob->status); $pollAttempts++; if ($batchJob->status !== 'ACTIVE' && $batchJob->status !== 'AWAITING_FILE' && $batchJob->status !== 'CANCELING') { $isPending = false; } // Optional: Cancel the job if it has not completed after polling // MAX_POLL_ATTEMPTS times. if ($isPending && !$wasCancelRequested && $pollAttempts == MAX_POLL_ATTEMPTS) { $batchJob->status = 'CANCELING'; $batchJobSetOperation = new BatchJobOperation(); $batchJobSetOperation->operand = $batchJob; $batchJobSetOperation->operator = 'SET'; // Only request cancellation once per job. $wasCancelRequested = true; try { $operations[] = $batchJobSetOperation; $batchJob = $batchJobService->mutate($operations)->value[0]; printf("Requested cancellation of batch job with ID %d.\n", $batchJob->id); // Reset the poll attempt counter to wait for cancellation. $pollAttempts = 0; } catch (Exception $e) { $errors = $e->detail->ApiExceptionFault->errors; if ($errors !== null && $errors->enc_value instanceof BatchJobError) { if ($errors->enc_value->reason === 'INVALID_STATE_CHANGE') { printf("Attempt to cancel batch job with ID %d was rejected because" . " the job already completed or was canceled.\n", $batchJob->id); // Reset the poll attempt counter to wait for cancellation. $pollAttempts = 0; continue; } } throw $e; } } } while ($isPending && $pollAttempts <= MAX_POLL_ATTEMPTS); if ($isPending) { throw new BatchJobException(sprintf("Job is still pending state after polling %d times.", MAX_POLL_ATTEMPTS)); } if ($batchJob->processingErrors !== null) { $i = 0; foreach ($batchJob->processingErrors as $processingError) { printf(" Processing error [%d]: errorType=%s, trigger=%s, errorString=%s," . " fieldPath=%s, reason=%s\n", $i++, $processingError->ApiErrorType, $processingError->trigger, $processingError->errorString, $processingError->fieldPath, $processingError->reason); } } else { printf("No processing errors found.\n"); } if ($batchJob->downloadUrl !== null && $batchJob->downloadUrl->url !== null) { $xmlResponse = $batchJobUtils->DownloadBatchJobResults($batchJob->downloadUrl->url); printf("Downloaded results from %s:\n", $batchJob->downloadUrl->url); $deserializer = new XmlDeserializer(BatchJobUtils::$CLASS_MAP); $mutateResponse = $deserializer->ConvertXmlToObject($xmlResponse); if (empty($mutateResponse)) { printf(" No results available.\n"); } else { foreach ($mutateResponse->rval as $mutateResult) { $outcome = $mutateResult->errorList === null ? 'SUCCESS' : 'FAILURE'; printf(" Operation [%d] - %s\n", $mutateResult->index, $outcome); } } } else { printf("No results available for download.\n"); } }