com.microsoft.bingads.v13.bulk.BulkOperation Maven / Gradle / Ivy
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.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();
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;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy