com.microsoft.bingads.v13.bulk.BulkOperation Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of microsoft.bingads Show documentation
Show all versions of microsoft.bingads Show documentation
The Bing Ads Java SDK is a library improving developer experience when working with the Bing Ads services by providing high-level access to features such as Bulk API, OAuth Authorization and SOAP API.
package com.microsoft.bingads.v13.bulk;
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.List;
import java.util.concurrent.Future;
import com.microsoft.bingads.ApiEnvironment;
import com.microsoft.bingads.AsyncCallback;
import com.microsoft.bingads.AuthorizationData;
import com.microsoft.bingads.ServiceClient;
import com.microsoft.bingads.internal.MessageHandler;
import com.microsoft.bingads.internal.ParentCallback;
import com.microsoft.bingads.internal.ResultFuture;
import com.microsoft.bingads.internal.utilities.HttpClientHttpFileService;
import com.microsoft.bingads.internal.utilities.HttpFileService;
import com.microsoft.bingads.internal.utilities.SimpleZipExtractor;
import com.microsoft.bingads.internal.utilities.ZipExtractor;
import com.microsoft.bingads.v13.internal.bulk.BulkOperationStatusProvider;
import com.microsoft.bingads.v13.internal.bulk.BulkOperationTracker;
import com.microsoft.bingads.v13.internal.bulk.Config;
import com.microsoft.bingads.v13.internal.bulk.PollingBulkOperationTracker;
/**
* Reserved for internal use.
*
* The abstract base class that can be derived to represent a bulk operation requested by a user. You can use either the {@link BulkDownloadOperation} or {@link BulkUploadOperation} derived class to poll for the operation status, and then download the results file when available.
*
* @param type of bulk operation status is being tracked
*/
public abstract class BulkOperation {
/**
* Represents a user who intends to access the corresponding customer and account.
*/
private AuthorizationData authorizationData;
/**
* The request identifier corresponding to the bulk upload or download, depending on the derived type.
*/
private String requestId;
/**
* The identifier of the log entry that contains the details of the upload or download request.
*/
private String trackingId;
/**
* The amount of time in milliseconds that the upload and download operations should wait before polling the Bulk service for status.
*/
private int statusPollIntervalInMilliseconds;
/**
* The timeout in milliseconds of HttpClient download operation.
*/
private int downloadHttpTimeoutInMilliseconds;
BulkOperationStatusProvider statusProvider;
private HttpFileService httpFileService;
private ZipExtractor zipExtractor;
private ServiceClient serviceClient;
private BulkOperationStatus finalStatus;
BulkOperation(String requestId, AuthorizationData authorizationData) {
this(requestId, authorizationData, null, null, null);
}
BulkOperation(String requestId, AuthorizationData authorizationData, ApiEnvironment apiEnvironment) {
this(requestId, authorizationData, null, null, apiEnvironment);
}
BulkOperation(String requestId, AuthorizationData authorizationData, BulkOperationStatusProvider statusProvider) {
this(requestId, authorizationData, statusProvider, null, null);
}
BulkOperation(String requestId, AuthorizationData authorizationData, BulkOperationStatusProvider statusProvider, String trackingId) {
this(requestId, authorizationData, statusProvider, trackingId, null);
}
BulkOperation(String requestId, AuthorizationData authorizationData, BulkOperationStatusProvider statusProvider, String trackingId, ApiEnvironment apiEnvironment) {
this.statusProvider = statusProvider;
this.requestId = requestId;
this.authorizationData = authorizationData;
this.trackingId = trackingId;
statusPollIntervalInMilliseconds = Config.DEFAULT_STATUS_CHECK_INTERVAL_IN_MS;
downloadHttpTimeoutInMilliseconds = Config.DEFAULT_HTTPCLIENT_TIMEOUT_IN_MS;
this.serviceClient = new ServiceClient(authorizationData, apiEnvironment, IBulkService.class);
zipExtractor = new SimpleZipExtractor();
httpFileService = new HttpClientHttpFileService();
}
/**
* Runs asynchronously until the bulk service has finished processing the bulk operation.
*
* @param callback A handler that will be called with the BulkOperation when it has completed
*
* @return a Future that will be completed when the result file is available
*/
public Future> trackAsync(AsyncCallback> callback) {
return trackAsync(null, callback);
}
/**
* Runs asynchronously until the bulk service has finished processing the bulk operation.
*
* @param progress An object to be updated with the progress of the operation
* @param callback A handler that will be called with the BulkOperation when it has completed
*
* @return a Future that will be completed when the result file is available
*/
public Future> trackAsync(Progress progress, AsyncCallback> callback) {
BulkOperationTracker tracker = generateTracker(progress);
final ResultFuture> resultFuture = new ResultFuture>(callback);
tracker.trackResultFileAsync(new ParentCallback>(resultFuture) {
@Override
public void onSuccess(BulkOperationStatus status) {
finalStatus = status;
resultFuture.setResult(finalStatus);
}
});
return resultFuture;
}
private BulkOperationTracker generateTracker(Progress progress) {
BulkOperationTracker tracker;
tracker = new PollingBulkOperationTracker(statusProvider, this.serviceClient, progress, this.statusPollIntervalInMilliseconds);
return tracker;
}
/**
* Gets the status of the bulk operation.
*
* @return the current status of the bulk operation
*/
public Future> getStatusAsync(AsyncCallback> callback) {
final ResultFuture> resultFuture = new ResultFuture>(callback);
if (finalStatus != null) {
resultFuture.setResult(this.finalStatus);
return resultFuture;
}
statusProvider.getCurrentStatus(this.serviceClient, new ParentCallback>(resultFuture) {
@Override
public void onSuccess(BulkOperationStatus currentStatus) {
if (statusProvider.isFinalStatus(currentStatus)) {
finalStatus = currentStatus;
}
resultFuture.setResult(currentStatus);
}
});
return resultFuture;
}
public AuthorizationData getAuthorizationData() {
return authorizationData;
}
public String getRequestId() {
return requestId;
}
public String getTrackingId() {
return trackingId;
}
BulkOperationStatusProvider getStatusProvider() {
return statusProvider;
}
void setRequestId(String requestId) {
this.requestId = requestId;
}
void setTrackingId(String trackingId) {
this.trackingId = trackingId;
}
void setStatusProvider(BulkOperationStatusProvider statusProvider) {
this.statusProvider = statusProvider;
}
HttpFileService getHttpFileService() {
return httpFileService;
}
void setHttpFileService(HttpFileService httpFileService) {
this.httpFileService = httpFileService;
}
ZipExtractor getZipExtractor() {
return zipExtractor;
}
void setZipExtractor(ZipExtractor zipExtractor) {
this.zipExtractor = zipExtractor;
}
/**
* Gets the time interval in milliseconds between two status polling attempts. The default value is 5000 (5 second).
*/
public int getStatusPollIntervalInMilliseconds() {
return statusPollIntervalInMilliseconds;
}
/**
* Sets the time interval in milliseconds between two status polling attempts. The default value is 5000 (5 second).
*/
public void setStatusPollIntervalInMilliseconds(int statusPollIntervalInMilliseconds) {
this.statusPollIntervalInMilliseconds = statusPollIntervalInMilliseconds;
}
/**
* Gets the timeout of HttpClient download operation. The default value is 100000(100s).
*/
public int getDownloadHttpTimeoutInMilliseconds() {
return downloadHttpTimeoutInMilliseconds;
}
/**
* Sets the timeout of HttpClient download operation. The default value is 100000(100s).
*/
public void setDownloadHttpTimeoutInMilliseconds(int downloadHttpTimeoutInMilliseconds) {
this.downloadHttpTimeoutInMilliseconds = downloadHttpTimeoutInMilliseconds;
}
/**
* Downloads and optionally decompress the result file from the bulk operation
* @param localResultDirectoryName the directory to place the result file in
* @param localResultFileName the name to use for final result file
* @param decompress indicates whether the result file should be unzipped
* @param callback {@link AsyncCallback} object with {@link File}
*
* @return a {@link File} object pointing to the result file wrapped in Future
*
* @throws IOException
* @throws URISyntaxException
*/
public Future downloadResultFileAsync(File localResultDirectoryName, String localResultFileName, boolean decompress, AsyncCallback callback) throws IOException, URISyntaxException {
return downloadResultFileAsync(localResultDirectoryName, localResultFileName, decompress, false, callback);
}
/**
* Downloads and optionally decompress the result file from the bulk operation, allows to overwrite the local result file.
*
* @param localResultDirectoryName the directory to place the result file in
* @param localResultFileName the name to use for final result file
* @param decompress indicates whether the result file should be unzipped
* @param overwrite indicates whether can overwrite if target file exists
* @param callback {@link AsyncCallback} object with {@link File}
*
* @return a {@link File} object pointing to the result file wrapped in Future
*/
public Future downloadResultFileAsync(File localResultDirectoryName, String localResultFileName, boolean decompress, boolean overwrite, AsyncCallback callback) throws IOException, URISyntaxException {
return downloadResultFileAsyncImpl(localResultDirectoryName, localResultFileName, decompress, overwrite, callback);
}
abstract RuntimeException getOperationCouldNotBeCompletedException(List errors, TStatus status);
private Future downloadResultFileAsyncImpl(final File localResultDirectoryName, final String localResultFileName, final boolean decompress, final boolean overwrite, AsyncCallback callback) throws IOException, URISyntaxException {
final ResultFuture resultFuture = new ResultFuture(callback);
if (finalStatus == null) {
getStatusAsync(new ParentCallback>(resultFuture) {
@Override
public void onSuccess(BulkOperationStatus result) throws IOException, URISyntaxException {
if (finalStatus == null) {
resultFuture.setException(new BulkOperationInProgressException());
return;
}
File resultFile = downloadFileWithFinalStatus(localResultDirectoryName, localResultFileName, decompress, overwrite);
resultFuture.setResult(resultFile);
}
});
} else {
File resultFile = downloadFileWithFinalStatus(localResultDirectoryName, localResultFileName, decompress, overwrite);
resultFuture.setResult(resultFile);
}
return resultFuture;
}
private File downloadFileWithFinalStatus(File localResultDirectoryName, String localResultFileName, final boolean decompress, final boolean overwrite) throws IOException, URISyntaxException {
if (!statusProvider.isSuccessStatus(finalStatus.getStatus())) {
List errors = finalStatus.getErrors();
throw getOperationCouldNotBeCompletedException(errors, finalStatus.getStatus());
}
String effectiveFileName;
if (localResultFileName == null) {
effectiveFileName = requestId;
} else {
effectiveFileName = localResultFileName;
}
final File fullPath = new File(localResultDirectoryName, effectiveFileName);
final File zipResultPath = new File(localResultDirectoryName, effectiveFileName + ".zip");
downloadResultFileZip(finalStatus.getResultFileUrl(), zipResultPath, overwrite);
if (!decompress) {
return zipResultPath;
}
File extractedFile = zipExtractor.extractFirstEntryToFile(zipResultPath, fullPath, localResultFileName == null, overwrite);
zipResultPath.delete();
MessageHandler.getInstance().handleDirectMessage("Bulk Download... RequestId: " + requestId + "; DownloadUrl: " + finalStatus.getResultFileUrl() + "; LocalPath: " + localResultDirectoryName.getPath());
return extractedFile;
}
private File downloadResultFileZip(String url, File tempZipFile, boolean overwrite) throws IOException, URISyntaxException {
if (httpFileService == null) {
httpFileService = new HttpClientHttpFileService();
}
httpFileService.downloadFile(url, tempZipFile, overwrite, downloadHttpTimeoutInMilliseconds);
return tempZipFile;
}
}