diff --git a/src/main/java/com/microsoft/bingads/internal/OperationStatusRetry.java b/src/main/java/com/microsoft/bingads/internal/OperationStatusRetry.java index 50300ae06c..559ff332c9 100644 --- a/src/main/java/com/microsoft/bingads/internal/OperationStatusRetry.java +++ b/src/main/java/com/microsoft/bingads/internal/OperationStatusRetry.java @@ -8,9 +8,8 @@ import java.util.function.Function; import com.microsoft.bingads.AsyncCallback; -import com.microsoft.bingads.ServiceClient; +import com.microsoft.bingads.internal.functionalinterfaces.BiConsumer; import com.microsoft.bingads.internal.functionalinterfaces.Consumer; -import com.microsoft.bingads.internal.functionalinterfaces.TriConsumer; public class OperationStatusRetry { private static final int INTERVAL_OF_RETRY = 1000; // TimeUnit Milliseconds @@ -28,20 +27,21 @@ public OperationStatusRetry(Function f) { } public void executeWithRetry( - final TriConsumer, AsyncCallback> action, - final TOperationStatusProvider statusProvider, final ServiceClient serviceClient, - final Consumer statusConsumer, final Consumer exceptionConsumer, + final BiConsumer> action, + final TOperationStatusProvider statusProvider, + final Consumer statusConsumer, + final Consumer exceptionConsumer, final int maxRetryCount) { executor = Executors.newSingleThreadScheduledExecutor(); - doPollOperationStatus(action, statusProvider, serviceClient, statusConsumer, exceptionConsumer, maxRetryCount); + doPollOperationStatus(action, statusProvider, statusConsumer, exceptionConsumer, maxRetryCount); } private void doPollOperationStatus( - final TriConsumer, AsyncCallback> action, - final TOperationStatusProvider statusProvider, final ServiceClient serviceClient, + final BiConsumer> action, + final TOperationStatusProvider statusProvider, final Consumer statusConsumer, final Consumer exceptionConsumer, final int maxRetryCount) { - action.accept(statusProvider, serviceClient, new AsyncCallback() { + action.accept(statusProvider, new AsyncCallback() { @Override public void onCompleted(Future result) { @@ -49,22 +49,21 @@ public void onCompleted(Future result) { statusConsumer.accept(result.get()); executor.shutdown(); } catch (InterruptedException exception) { - retryWhenException(action, statusProvider, serviceClient, statusConsumer, exceptionConsumer, + retryWhenException(action, statusProvider, statusConsumer, exceptionConsumer, maxRetryCount, exception); } catch (ExecutionException exception) { - retryWhenException(action, statusProvider, serviceClient, statusConsumer, exceptionConsumer, + retryWhenException(action, statusProvider, statusConsumer, exceptionConsumer, maxRetryCount, exception); } } private void retryWhenException( - final TriConsumer, AsyncCallback> action, - final TOperationStatusProvider statusProvider, final ServiceClient serviceClient, + final BiConsumer> action, + final TOperationStatusProvider statusProvider, final Consumer statusConsumer, final Consumer exceptionConsumer, final int maxRetryCount, Exception exception) { if (maxRetryCount > 0) { - retry(action, statusProvider, serviceClient, statusConsumer, exceptionConsumer, maxRetryCount - 1, - exception); + retry(action, statusProvider, statusConsumer, exceptionConsumer, maxRetryCount - 1, exception); } else { executor.shutdown(); exceptionConsumer.accept(exception); @@ -74,16 +73,15 @@ private void retryWhenException( } private void retry( - final TriConsumer, AsyncCallback> action, - final TOperationStatusProvider statusProvider, final ServiceClient serviceClient, + final BiConsumer> action, + final TOperationStatusProvider statusProvider, final Consumer statusConsumer, final Consumer exceptionConsumer, final int maxRetryCount, Exception exception) { int interval = getInterval(exception, maxRetryCount); executor.schedule(new Runnable() { @Override public void run() { - doPollOperationStatus(action, statusProvider, serviceClient, statusConsumer, exceptionConsumer, - maxRetryCount); + doPollOperationStatus(action, statusProvider, statusConsumer, exceptionConsumer, maxRetryCount); } }, interval, TimeUnit.MILLISECONDS); diff --git a/src/main/java/com/microsoft/bingads/internal/utilities/HttpClientHttpFileService.java b/src/main/java/com/microsoft/bingads/internal/utilities/HttpClientHttpFileService.java index f08dab54ec..2c7f271efa 100644 --- a/src/main/java/com/microsoft/bingads/internal/utilities/HttpClientHttpFileService.java +++ b/src/main/java/com/microsoft/bingads/internal/utilities/HttpClientHttpFileService.java @@ -3,193 +3,280 @@ import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.io.UncheckedIOException; import java.net.URI; import java.net.URISyntaxException; -import java.util.concurrent.Future; +import java.nio.file.CopyOption; +import java.nio.file.Files; +import java.nio.file.StandardCopyOption; +import java.util.Timer; +import java.util.TimerTask; +import com.microsoft.bingads.CouldNotDownloadResultFileException; +import com.microsoft.bingads.CouldNotUploadFileException; +import com.microsoft.bingads.internal.functionalinterfaces.Consumer; +import com.microsoft.bingads.v13.internal.bulk.Config; import org.apache.http.HttpRequest; -import org.apache.http.HttpResponse; -import org.apache.http.client.ClientProtocolException; import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; +import org.apache.http.conn.routing.HttpRoute; import org.apache.http.entity.ContentType; -import org.apache.http.entity.mime.HttpMultipartMode; import org.apache.http.entity.mime.MultipartEntityBuilder; import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.impl.client.HttpClients; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.apache.http.pool.ConnPoolControl; +import org.apache.http.pool.PoolStats; -import com.microsoft.bingads.AsyncCallback; -import com.microsoft.bingads.CouldNotDownloadResultFileException; -import com.microsoft.bingads.CouldNotUploadFileException; -import com.microsoft.bingads.internal.ResultFuture; -import com.microsoft.bingads.internal.functionalinterfaces.Consumer; +import static java.lang.String.format; +import static java.nio.charset.StandardCharsets.UTF_8; +import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static org.apache.http.entity.mime.HttpMultipartMode.BROWSER_COMPATIBLE; -public class HttpClientHttpFileService implements HttpFileService { - - @Override - public void downloadFile(String url, File tempZipFile, boolean overwrite, int timeoutInMilliseconds) throws IOException, URISyntaxException { - if (!overwrite && tempZipFile.exists()) { - throw new IOException(String.format("Could not download result file due to file %s already exists", tempZipFile)); +public class HttpClientHttpFileService implements HttpFileService, ConnPoolControl { + + private static final ContentType APPLICATION_ZIP = ContentType.create("application/zip"); + + private final PoolingHttpClientConnectionManager connectionManager; + private final Timer cleanupTimer = new Timer("Bing Ads idle HTTP connection closer", true); + private volatile int maxIdleInMilliseconds = 15 * 60 * 1000; + private volatile int downloadTimeoutInMilliseconds = Config.DEFAULT_HTTPCLIENT_TIMEOUT_IN_MS; + private CloseableHttpClient downloadClient; + private volatile int uploadTimeoutInMilliseconds = Config.DEFAULT_HTTPCLIENT_TIMEOUT_IN_MS; + private CloseableHttpClient uploadClient; + + public HttpClientHttpFileService() { + this.connectionManager = new PoolingHttpClientConnectionManager(); + + // Default pool config taken from the HTTP client builder. + String keepAlive = System.getProperty("http.keepAlive", "true"); + if ("true".equalsIgnoreCase(keepAlive)) { + int maxConnections = Integer.parseInt(System.getProperty("http.maxConnections", "5")); + connectionManager.setDefaultMaxPerRoute(maxConnections); + connectionManager.setMaxTotal(maxConnections * 2); } - CloseableHttpClient client = HttpClients.custom().setDefaultRequestConfig(RequestConfig.custom() - .setConnectionRequestTimeout(timeoutInMilliseconds) - .setConnectTimeout(timeoutInMilliseconds) - .setSocketTimeout(timeoutInMilliseconds).build()) - .useSystemProperties() - .build(); + TimerTask cleanupTask = new TimerTask() { + @Override + public void run() { + connectionManager.closeIdleConnections(maxIdleInMilliseconds, MILLISECONDS); + } + }; + cleanupTimer.scheduleAtFixedRate(cleanupTask, 60_000, 60_000); + } + @Override + public void close() throws IOException { try { - HttpGet httpget = new HttpGet(new URI(url)); - HttpResponse response = client.execute(httpget); - InputStream content = response.getEntity().getContent(); - - FileOutputStream tempFileOutput = null; - - try { - tempFileOutput = new FileOutputStream(tempZipFile); - - FileUtils.copy(content, tempFileOutput); - } finally { - if (tempFileOutput != null) { - tempFileOutput.close(); - } + if (downloadClient != null) { + downloadClient.close(); } - } catch (IOException ex) { - throw new CouldNotDownloadResultFileException(ex); - } catch (IllegalStateException ex) { - throw new CouldNotDownloadResultFileException(ex); - } finally { - if (client != null) { - client.close(); + if (uploadClient != null) { + uploadClient.close(); } + cleanupTimer.cancel(); + } finally { + connectionManager.close(); } } @Override - public void uploadFile(URI uri, File uploadFilePath, Consumer addHeaders, int timeoutInMilliseconds) { - FileInputStream stream = null; + public void downloadFile(String url, File tempZipFile, boolean overwrite) throws URISyntaxException { + HttpGet get = new HttpGet(new URI(url)); + try (CloseableHttpResponse response = downloadClient().execute(get); + InputStream content = response.getEntity().getContent()) { + Files.copy(content, tempZipFile.toPath(), copyOptions(overwrite)); + } catch (IOException ex) { + throw new CouldNotDownloadResultFileException(ex); + } + } - try { - stream = new FileInputStream(uploadFilePath); + private CopyOption[] copyOptions(boolean overwrite) { + return overwrite ? + new CopyOption[] { StandardCopyOption.REPLACE_EXISTING } : + new CopyOption[0]; + } - CloseableHttpClient client = HttpClients.custom() - .setDefaultRequestConfig(RequestConfig.custom() - .setConnectionRequestTimeout(timeoutInMilliseconds) - .setConnectTimeout(timeoutInMilliseconds) - .setSocketTimeout(timeoutInMilliseconds) - .build()) - .useSystemProperties() - .build(); - - - try { - HttpPost post = new HttpPost(uri); - addHeaders.accept(post); - MultipartEntityBuilder builder = MultipartEntityBuilder.create() - .addBinaryBody("upstream", stream, ContentType.create("application/zip"), uploadFilePath.getName()); - builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE); - - post.setEntity(builder.build()); - - HttpResponse response = client.execute(post); - - if (response.getStatusLine().getStatusCode() != 200) { - InputStream in = response.getEntity().getContent(); - BufferedReader streamReader = new BufferedReader(new InputStreamReader(in, "UTF-8")); - StringBuilder exceptionMessage = new StringBuilder(); - - String inputStr; - while ((inputStr = streamReader.readLine()) != null) { - exceptionMessage.append(inputStr); - } - - throw new CouldNotUploadFileException("Unsuccessful Status Code: " + response.getStatusLine().getStatusCode() + "; Exception Message: " + exceptionMessage); - } - } catch (ClientProtocolException e) { - throw new CouldNotUploadFileException(e); - } catch (IOException e) { - throw new CouldNotUploadFileException(e); - } catch (IllegalStateException e) { - throw new CouldNotUploadFileException(e); - } finally { - if (client != null) { - try { - client.close(); - } catch (IOException e) { - // Ignore - e.printStackTrace(); - } + @Override + public void uploadFile(URI uri, File uploadZipFile, Consumer addHeaders) { + try (FileInputStream stream = new FileInputStream(uploadZipFile)) { + HttpPost post = new HttpPost(uri); + addHeaders.accept(post); + post.setEntity(MultipartEntityBuilder.create() + .addBinaryBody("upstream", stream, APPLICATION_ZIP, uploadZipFile.getName()) + .setMode(BROWSER_COMPATIBLE) + .build()); + try (CloseableHttpResponse response = uploadClient().execute(post)) { + int statusCode = response.getStatusLine().getStatusCode(); + if (statusCode != 200) { + throw new CouldNotUploadFileException(format( + "Unsuccessful Status Code: %d; Exception Message: %s", statusCode, readMessage(response))); } } - } catch (FileNotFoundException e) { + } catch (IOException | UncheckedIOException e) { throw new CouldNotUploadFileException(e); - } finally { - if (stream != null) { - try { - stream.close(); - } catch (IOException e) { - throw new CouldNotUploadFileException(e); - } - } } } + private String readMessage(CloseableHttpResponse response) throws IOException { + StringBuilder exceptionMessage = new StringBuilder(64); + try (InputStream content = response.getEntity().getContent(); + BufferedReader reader = new BufferedReader(new InputStreamReader(content, UTF_8))) { + reader.lines().forEach(exceptionMessage::append); + } + return exceptionMessage.toString(); + } + + // + // Connection pool configuration. + // + @Override - public Future downloadFileAsync(String url, File tempZipFile, AsyncCallback callback, int timeoutInMilliseconds) { - final ResultFuture resultFuture = new ResultFuture(callback); + public int getMaxTotal() { + return connectionManager.getMaxTotal(); + } - CloseableHttpClient client = HttpClients - .custom() - .setDefaultRequestConfig(RequestConfig.custom() - .setConnectionRequestTimeout(timeoutInMilliseconds) - .setConnectTimeout(timeoutInMilliseconds) - .setSocketTimeout(timeoutInMilliseconds) - .build()) - .useSystemProperties() - .build(); + @Override + public void setMaxTotal(int max) { + connectionManager.setMaxTotal(max); + } - try { - - HttpGet httpget = new HttpGet(new URI(url)); - HttpResponse response = client.execute(httpget); - InputStream content = response.getEntity().getContent(); + @Override + public int getDefaultMaxPerRoute() { + return connectionManager.getDefaultMaxPerRoute(); + } - FileOutputStream tempFileOutput = null; + @Override + public void setDefaultMaxPerRoute(int max) { + connectionManager.setDefaultMaxPerRoute(max); + } - try { - tempFileOutput = new FileOutputStream(tempZipFile); - FileUtils.copy(content, tempFileOutput); + @Override + public int getMaxPerRoute(HttpRoute route) { + return connectionManager.getMaxPerRoute(route); + } - resultFuture.setResult(tempZipFile); - } finally { - if (tempFileOutput != null) { - tempFileOutput.close(); - } + @Override + public void setMaxPerRoute(HttpRoute route, int max) { + connectionManager.setMaxPerRoute(route, max); + } + + @Override + public PoolStats getStats(HttpRoute route) { + return connectionManager.getStats(route); + } + + @Override + public PoolStats getTotalStats() { + return connectionManager.getTotalStats(); + } + + /** + * Time after idle HTTP connections get closed. + * Defaults to 15 minutes. + */ + public int getMaxIdleInMilliseconds() { + return maxIdleInMilliseconds; + } + + /** + * Time after idle HTTP connections get closed. + */ + public void setMaxIdleInMilliseconds(int maxIdleInMilliseconds) { + this.maxIdleInMilliseconds = maxIdleInMilliseconds; + } + + // + // Client configuration. + // + + /** + * Timeout when downloading. + * Defaults to {@link Config#DEFAULT_HTTPCLIENT_TIMEOUT_IN_MS}. + */ + public int getDownloadTimeoutInMilliseconds() { + return downloadTimeoutInMilliseconds; + } + + /** + * Timeout when downloading. + * After the first download changes will be ignored. + */ + public void setDownloadTimeoutInMilliseconds(int downloadTimeoutInMilliseconds) { + this.downloadTimeoutInMilliseconds = downloadTimeoutInMilliseconds; + } + + /** + * Timeout when uploading. + * Defaults to {@link Config#DEFAULT_HTTPCLIENT_TIMEOUT_IN_MS}. + */ + public int getUploadTimeoutInMilliseconds() { + return uploadTimeoutInMilliseconds; + } + + /** + * Timeout when uploading. + * After the first upload changes will be ignored. + */ + public void setUploadTimeoutInMilliseconds(int uploadTimeoutInMilliseconds) { + this.uploadTimeoutInMilliseconds = uploadTimeoutInMilliseconds; + } + + // + // Client creation. + // + + private CloseableHttpClient downloadClient() { + synchronized (connectionManager) { + if (downloadClient == null) { + HttpClientBuilder builder = createHttpClient(downloadTimeoutInMilliseconds); + customizeDownloadClient(builder); + downloadClient = builder.build(); } - } catch (URISyntaxException ex) { - resultFuture.setException(ex); - } catch (IOException ex) { - resultFuture.setException(new CouldNotDownloadResultFileException(ex)); - } catch (IllegalStateException ex) { - resultFuture.setException(new CouldNotDownloadResultFileException(ex)); - } finally { - if (client != null) { - try { - client.close(); - } catch (IOException e) { - // Ignore - e.printStackTrace(); - } + return downloadClient; + } + } + + /** + * Overwrite to customize the download client. + */ + protected void customizeDownloadClient(HttpClientBuilder downloadClient) { + } + + private CloseableHttpClient uploadClient() { + synchronized (connectionManager) { + if (uploadClient == null) { + HttpClientBuilder builder = createHttpClient(uploadTimeoutInMilliseconds); + customizeUploadClient(builder); + uploadClient = builder.build(); } + return uploadClient; } + } + + /** + * Overwrite to customize the upload client. + */ + protected void customizeUploadClient(HttpClientBuilder uploadClient) { + } - return resultFuture; + /** + * Default HTTP client. + */ + private HttpClientBuilder createHttpClient(int timeoutInMilliseconds) { + return HttpClients.custom() + .setConnectionManager(connectionManager) + .setDefaultRequestConfig(RequestConfig.custom() + .setConnectionRequestTimeout(timeoutInMilliseconds) + .setConnectTimeout(timeoutInMilliseconds) + .setSocketTimeout(timeoutInMilliseconds) + .build()) + .useSystemProperties(); } } diff --git a/src/main/java/com/microsoft/bingads/internal/utilities/HttpFileService.java b/src/main/java/com/microsoft/bingads/internal/utilities/HttpFileService.java index 2abe7bab94..761aab6ce8 100644 --- a/src/main/java/com/microsoft/bingads/internal/utilities/HttpFileService.java +++ b/src/main/java/com/microsoft/bingads/internal/utilities/HttpFileService.java @@ -1,20 +1,17 @@ package com.microsoft.bingads.internal.utilities; -import com.microsoft.bingads.AsyncCallback; import com.microsoft.bingads.internal.functionalinterfaces.Consumer; + +import java.io.Closeable; import java.io.File; -import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; -import java.util.concurrent.Future; import org.apache.http.HttpRequest; -public interface HttpFileService { - - void downloadFile(String url, File tempZipFile, boolean overwrite, int timeoutInMilliseconds) throws IOException, URISyntaxException; +public interface HttpFileService extends Closeable { - void uploadFile(URI uri, File uploadFilePath, Consumer addHeaders, int timeoutInMilliseconds); + void downloadFile(String url, File tempZipFile, boolean overwrite) throws URISyntaxException; - Future downloadFileAsync(String url, File tempZipFile, AsyncCallback callback, int timeoutInMilliseconds); + void uploadFile(URI uri, File uploadZipFile, Consumer addHeaders); } diff --git a/src/main/java/com/microsoft/bingads/v13/bulk/BulkDownloadOperation.java b/src/main/java/com/microsoft/bingads/v13/bulk/BulkDownloadOperation.java index 40143c6392..c656a5e85c 100644 --- a/src/main/java/com/microsoft/bingads/v13/bulk/BulkDownloadOperation.java +++ b/src/main/java/com/microsoft/bingads/v13/bulk/BulkDownloadOperation.java @@ -2,8 +2,12 @@ import java.util.List; -import com.microsoft.bingads.ApiEnvironment; -import com.microsoft.bingads.AuthorizationData; +import com.microsoft.bingads.ServiceClient; +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.Config; import com.microsoft.bingads.v13.internal.bulk.DownloadStatusProvider; /** @@ -29,23 +33,22 @@ public class BulkDownloadOperation extends BulkOperation { * * @param requestId The identifier of a download request that has previously * been submitted. - * @param authorizationData Represents a user who intends to access the - * corresponding customer and account. */ - public BulkDownloadOperation(String requestId, AuthorizationData authorizationData) { - super(requestId, authorizationData, new DownloadStatusProvider(requestId, authorizationData)); + public BulkDownloadOperation(String requestId, ServiceClient serviceClient, int statusPollIntervalInMilliseconds) { + this( + requestId, null, + new HttpClientHttpFileService(), new SimpleZipExtractor(), + serviceClient, statusPollIntervalInMilliseconds); } - public BulkDownloadOperation(String requestId, AuthorizationData authorizationData, ApiEnvironment apiEnvironment) { - super(requestId, authorizationData, new DownloadStatusProvider(requestId, authorizationData), null, apiEnvironment); - } - - BulkDownloadOperation(String requestId, AuthorizationData authorizationData, String trackingId) { - super(requestId, authorizationData, new DownloadStatusProvider(requestId, authorizationData), trackingId); - } - - BulkDownloadOperation(String requestId, AuthorizationData authorizationData, String trackingId, ApiEnvironment apiEnvironment) { - super(requestId, authorizationData, new DownloadStatusProvider(requestId, authorizationData), trackingId, apiEnvironment); + BulkDownloadOperation( + String requestId, String trackingId, + HttpFileService httpFileService, ZipExtractor zipExtractor, + ServiceClient serviceClient, int statusPollIntervalInMilliseconds) { + super( + requestId, trackingId, + httpFileService, zipExtractor, + new DownloadStatusProvider(requestId, serviceClient, statusPollIntervalInMilliseconds)); } @Override diff --git a/src/main/java/com/microsoft/bingads/v13/bulk/BulkOperation.java b/src/main/java/com/microsoft/bingads/v13/bulk/BulkOperation.java index 77f1e2af28..0df8bb485f 100644 --- a/src/main/java/com/microsoft/bingads/v13/bulk/BulkOperation.java +++ b/src/main/java/com/microsoft/bingads/v13/bulk/BulkOperation.java @@ -6,20 +6,14 @@ 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; /** @@ -31,70 +25,33 @@ */ 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; + private final 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 final String trackingId; - private ServiceClient serviceClient; + private final HttpFileService httpFileService; - private BulkOperationStatus finalStatus; + private final ZipExtractor zipExtractor; - BulkOperation(String requestId, AuthorizationData authorizationData) { - this(requestId, authorizationData, null, null, null); - } + private final BulkOperationStatusProvider statusProvider; - 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); - } + private BulkOperationStatus finalStatus; - 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; + BulkOperation( + String requestId, String trackingId, + HttpFileService httpFileService, ZipExtractor zipExtractor, + BulkOperationStatusProvider 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(); + this.httpFileService = httpFileService; + this.zipExtractor = zipExtractor; + this.statusProvider = statusProvider; } /** @@ -136,7 +93,7 @@ public void onSuccess(BulkOperationStatus status) { private BulkOperationTracker generateTracker(Progress progress) { BulkOperationTracker tracker; - tracker = new PollingBulkOperationTracker(statusProvider, this.serviceClient, progress, this.statusPollIntervalInMilliseconds); + tracker = new PollingBulkOperationTracker(statusProvider, progress); return tracker; } @@ -156,7 +113,7 @@ public Future> getStatusAsync(AsyncCallback>(resultFuture) { + statusProvider.getCurrentStatus(new ParentCallback>(resultFuture) { @Override public void onSuccess(BulkOperationStatus currentStatus) { @@ -172,10 +129,6 @@ public void onSuccess(BulkOperationStatus currentStatus) { return resultFuture; } - public AuthorizationData getAuthorizationData() { - return authorizationData; - } - public String getRequestId() { return requestId; } @@ -188,62 +141,15 @@ 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 @@ -277,7 +183,8 @@ public Future downloadResultFileAsync(File localResultDirectoryName, Strin 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 { + 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) { @@ -338,12 +245,8 @@ private File downloadFileWithFinalStatus(File localResultDirectoryName, String l 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); + private File downloadResultFileZip(String url, File tempZipFile, boolean overwrite) throws URISyntaxException { + httpFileService.downloadFile(url, tempZipFile, overwrite); return tempZipFile; } diff --git a/src/main/java/com/microsoft/bingads/v13/bulk/BulkServiceManager.java b/src/main/java/com/microsoft/bingads/v13/bulk/BulkServiceManager.java index 82d89824fd..a45d598e36 100644 --- a/src/main/java/com/microsoft/bingads/v13/bulk/BulkServiceManager.java +++ b/src/main/java/com/microsoft/bingads/v13/bulk/BulkServiceManager.java @@ -1,6 +1,7 @@ package com.microsoft.bingads.v13.bulk; import java.io.ByteArrayOutputStream; +import java.io.Closeable; import java.io.File; import java.io.IOException; import java.io.UnsupportedEncodingException; @@ -12,7 +13,6 @@ import java.util.UUID; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; -import java.util.stream.Collectors; import jakarta.xml.ws.AsyncHandler; import jakarta.xml.ws.Response; @@ -60,7 +60,7 @@ *

* */ -public class BulkServiceManager { +public class BulkServiceManager implements Closeable { private static final int SYNC_THRESHOLD = 1000; private static final String FORMAT_VERSION = StringTable.FORMAT_VERSION; @@ -76,16 +76,6 @@ public class BulkServiceManager { */ private int statusPollIntervalInMilliseconds; - /** - * The timeout in milliseconds of HttpClient upload operation. - */ - private int uploadHttpTimeoutInMilliseconds; - - /** - * The timeout in milliseconds of HttpClient download operation. - */ - private int downloadHttpTimeoutInMilliseconds; - private final ServiceClient serviceClient; private File workingDirectory; @@ -116,10 +106,22 @@ private BulkServiceManager(AuthorizationData authorizationData, HttpFileService workingDirectory = new File(System.getProperty("java.io.tmpdir"), "BingAdsSDK"); statusPollIntervalInMilliseconds = Config.DEFAULT_STATUS_CHECK_INTERVAL_IN_MS; + } - uploadHttpTimeoutInMilliseconds = Config.DEFAULT_HTTPCLIENT_TIMEOUT_IN_MS; + @Override + public void close() throws IOException { + httpFileService.close(); + cleanupTempFiles(); + } - downloadHttpTimeoutInMilliseconds = Config.DEFAULT_HTTPCLIENT_TIMEOUT_IN_MS; + /** + * Removes all files from the working directory, whether the files are used by this BulkServiceManager or by another + * instance. + */ + public void cleanupTempFiles() { + for (File file : workingDirectory.listFiles()) { + file.delete(); + } } /** @@ -200,9 +202,10 @@ public void handleResponse(Response res) { try { UploadEntityRecordsResponse result = res.get(); if (needToFallBacktoAsync(result)) { - BulkUploadOperation operation = new BulkUploadOperation(result.getRequestId(), authorizationData, service, ServiceUtils.GetTrackingId(res), apiEnvironment); - operation.setStatusPollIntervalInMilliseconds(statusPollIntervalInMilliseconds); - operation.setDownloadHttpTimeoutInMilliseconds(downloadHttpTimeoutInMilliseconds); + BulkUploadOperation operation = new BulkUploadOperation( + result.getRequestId(), ServiceUtils.GetTrackingId(res), + httpFileService, zipExtractor, + serviceClient, statusPollIntervalInMilliseconds); operation.trackAsync(progress, new ParentCallback>(resultFuture) { @Override public void onSuccess(BulkOperationStatus status) throws IOException, URISyntaxException { @@ -504,9 +507,6 @@ public void onSuccess(File localFile) { private Future downloadBulkFileAsync(File resultFileDirectory, String resultFileName, boolean overwriteResultFile, BulkOperation operation, AsyncCallback callback) throws IOException, URISyntaxException { - operation.setHttpFileService(this.httpFileService); - operation.setZipExtractor(this.zipExtractor); - final ResultFuture resultFuture = new ResultFuture(callback); File effectiveResultFileDirectory = resultFileDirectory; @@ -566,14 +566,10 @@ public void handleResponse(Response res) response = res.get(); - String trackingId = ServiceUtils.GetTrackingId(res); - - BulkDownloadOperation operation = new BulkDownloadOperation(response.getDownloadRequestId(), authorizationData, trackingId, - apiEnvironment); - - operation.setStatusPollIntervalInMilliseconds(statusPollIntervalInMilliseconds); - - operation.setDownloadHttpTimeoutInMilliseconds(downloadHttpTimeoutInMilliseconds); + BulkDownloadOperation operation = new BulkDownloadOperation( + response.getDownloadRequestId(), ServiceUtils.GetTrackingId(res), + httpFileService, zipExtractor, + serviceClient, statusPollIntervalInMilliseconds); resultFuture.setResult(operation); } catch (InterruptedException e) { @@ -596,12 +592,10 @@ public void handleResponse(Response res) response = res.get(); - BulkDownloadOperation operation = new BulkDownloadOperation(response.getDownloadRequestId(), authorizationData, - ServiceUtils.GetTrackingId(res), apiEnvironment); - - operation.setStatusPollIntervalInMilliseconds(statusPollIntervalInMilliseconds); - - operation.setDownloadHttpTimeoutInMilliseconds(downloadHttpTimeoutInMilliseconds); + BulkDownloadOperation operation = new BulkDownloadOperation( + response.getDownloadRequestId(), ServiceUtils.GetTrackingId(res), + httpFileService, zipExtractor, + serviceClient, statusPollIntervalInMilliseconds); resultFuture.setResult(operation); } catch (InterruptedException e) { @@ -645,8 +639,6 @@ public void handleResponse(Response res) { try { GetBulkUploadUrlResponse response = res.get(); - String trackingId = ServiceUtils.GetTrackingId(res); - String uploadUrl = response.getUploadUrl(); File effectiveUploadPath = parameters.getUploadFilePath(); @@ -684,7 +676,7 @@ public void addHeader(String name, String value) { MessageHandler.getInstance().handleDirectMessage("Bulk Upload... requestId: " + response.getRequestId() + "; UploadFilePath:" + parameters.getUploadFilePath() + "; uploadUrl: " + uploadUrl); - httpFileService.uploadFile(new URI(uploadUrl), effectiveUploadPath, addHeaders, uploadHttpTimeoutInMilliseconds); + httpFileService.uploadFile(new URI(uploadUrl), effectiveUploadPath, addHeaders); if (shouldCompress) { compressedFilePath.delete(); @@ -692,13 +684,12 @@ public void addHeader(String name, String value) { if (parameters.getAutoDeleteTempFile()) { parameters.getUploadFilePath().delete(); - } - BulkUploadOperation operation = new BulkUploadOperation(response.getRequestId(), authorizationData, service, trackingId, apiEnvironment); - - operation.setStatusPollIntervalInMilliseconds(statusPollIntervalInMilliseconds); - - operation.setDownloadHttpTimeoutInMilliseconds(downloadHttpTimeoutInMilliseconds); + } + BulkUploadOperation operation = new BulkUploadOperation( + response.getRequestId(), ServiceUtils.GetTrackingId(res), + httpFileService, zipExtractor, + serviceClient, statusPollIntervalInMilliseconds); resultFuture.setResult(operation); } catch (InterruptedException e) { @@ -736,16 +727,6 @@ private File compressUploadFile(File uploadFilePath) { return compressedFilePath; } - /** - * Removes all files from the working directory, whether the files are used by this BulkServiceManager or by another - * instance. - */ - public void cleanupTempFiles() { - for (File file : workingDirectory.listFiles()) { - file.delete(); - } - } - private DownloadCampaignsByCampaignIdsRequest generateCampaignsByCampaignIdsRequest(SubmitDownloadParameters parameters) { DownloadCampaignsByCampaignIdsRequest request = new DownloadCampaignsByCampaignIdsRequest(); @@ -894,34 +875,6 @@ public int getStatusPollIntervalInMilliseconds() { public void setStatusPollIntervalInMilliseconds(int statusPollIntervalInMilliseconds) { this.statusPollIntervalInMilliseconds = statusPollIntervalInMilliseconds; } - - /** - * Gets the timeout of HttpClient upload operation. The default value is 100000(100s). - */ - public int getUploadHttpTimeoutInMilliseconds() { - return uploadHttpTimeoutInMilliseconds; - } - - /** - * Sets the timeout of HttpClient upload operation. The default value is 100000(100s). - */ - public void setUploadHttpTimeoutInMilliseconds(int uploadHttpTimeoutInMilliseconds) { - this.uploadHttpTimeoutInMilliseconds = uploadHttpTimeoutInMilliseconds; - } - - /** - * 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; - } } interface WriteAction { diff --git a/src/main/java/com/microsoft/bingads/v13/bulk/BulkUploadOperation.java b/src/main/java/com/microsoft/bingads/v13/bulk/BulkUploadOperation.java index a429829b3c..d8ec542b6f 100644 --- a/src/main/java/com/microsoft/bingads/v13/bulk/BulkUploadOperation.java +++ b/src/main/java/com/microsoft/bingads/v13/bulk/BulkUploadOperation.java @@ -2,8 +2,11 @@ import java.util.List; -import com.microsoft.bingads.ApiEnvironment; -import com.microsoft.bingads.AuthorizationData; +import com.microsoft.bingads.ServiceClient; +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.UploadStatusProvider; /** @@ -25,22 +28,22 @@ public class BulkUploadOperation extends BulkOperation { * Initializes a new instance of this class with the specified requestId and authorization data. * * @param requestId The identifier of an upload request that has previously been submitted. - * @param authorizationData Represents a user who intends to access the corresponding customer and account. */ - public BulkUploadOperation(String requestId, AuthorizationData authorizationData, IBulkService service) { - this(requestId, authorizationData, service, null, null); + public BulkUploadOperation(String requestId, ServiceClient serviceClient, int statusPollIntervalInMilliseconds) { + this( + requestId, null, + new HttpClientHttpFileService(), new SimpleZipExtractor(), + serviceClient, statusPollIntervalInMilliseconds); } - public BulkUploadOperation(String requestId, AuthorizationData authorizationData, IBulkService service, ApiEnvironment apiEnvironment) { - this(requestId, authorizationData, service, null, apiEnvironment); - } - - protected BulkUploadOperation(String requestId, AuthorizationData authorizationData, IBulkService service, String trackingId) { - this(requestId, authorizationData, service, trackingId, null); - } - - protected BulkUploadOperation(String requestId, AuthorizationData authorizationData, IBulkService service, String trackingId, ApiEnvironment apiEnvironment) { - super(requestId, authorizationData, new UploadStatusProvider(requestId), trackingId, apiEnvironment); + BulkUploadOperation( + String requestId, String trackingId, + HttpFileService httpFileService, ZipExtractor zipExtractor, + ServiceClient serviceClient, int statusPollIntervalInMilliseconds) { + super( + requestId, trackingId, + httpFileService, zipExtractor, + new UploadStatusProvider(requestId, serviceClient, statusPollIntervalInMilliseconds)); } @Override diff --git a/src/main/java/com/microsoft/bingads/v13/internal/bulk/BulkOperationStatusProvider.java b/src/main/java/com/microsoft/bingads/v13/internal/bulk/BulkOperationStatusProvider.java index 3b0130b97e..550fcb6e60 100644 --- a/src/main/java/com/microsoft/bingads/v13/internal/bulk/BulkOperationStatusProvider.java +++ b/src/main/java/com/microsoft/bingads/v13/internal/bulk/BulkOperationStatusProvider.java @@ -3,13 +3,13 @@ import java.util.concurrent.Future; import com.microsoft.bingads.AsyncCallback; -import com.microsoft.bingads.ServiceClient; import com.microsoft.bingads.v13.bulk.BulkOperationStatus; -import com.microsoft.bingads.v13.bulk.IBulkService; public interface BulkOperationStatusProvider { - Future> getCurrentStatus(ServiceClient serviceClient, AsyncCallback> callback); + int getStatusPollIntervalInMilliseconds(); + + Future> getCurrentStatus(AsyncCallback> callback); boolean isFinalStatus(BulkOperationStatus currentStatus); diff --git a/src/main/java/com/microsoft/bingads/v13/internal/bulk/DownloadStatusProvider.java b/src/main/java/com/microsoft/bingads/v13/internal/bulk/DownloadStatusProvider.java index 0a2b2b22e9..149ba3a62e 100644 --- a/src/main/java/com/microsoft/bingads/v13/internal/bulk/DownloadStatusProvider.java +++ b/src/main/java/com/microsoft/bingads/v13/internal/bulk/DownloadStatusProvider.java @@ -4,7 +4,6 @@ import java.util.concurrent.Future; import com.microsoft.bingads.AsyncCallback; -import com.microsoft.bingads.AuthorizationData; import com.microsoft.bingads.ServiceClient; import com.microsoft.bingads.internal.ResultFuture; import com.microsoft.bingads.internal.ServiceUtils; @@ -20,16 +19,30 @@ public class DownloadStatusProvider implements BulkOperationStatusProvider { private final String requestId; - - private final AuthorizationData authorizationData; - public DownloadStatusProvider(String requestId, AuthorizationData authorizationData) { + private final ServiceClient serviceClient; + + /** + * The amount of time in milliseconds that the upload and download operations should wait before polling the Bulk service for status. + */ + private final int statusPollIntervalInMilliseconds; + + public DownloadStatusProvider( + String requestId, + ServiceClient serviceClient, + int statusPollIntervalInMilliseconds) { this.requestId = requestId; - this.authorizationData = authorizationData; + this.serviceClient = serviceClient; + this.statusPollIntervalInMilliseconds = statusPollIntervalInMilliseconds; + } + + @Override + public int getStatusPollIntervalInMilliseconds() { + return statusPollIntervalInMilliseconds; } @Override - public Future> getCurrentStatus(ServiceClient serviceClient, AsyncCallback> callback) { + public Future> getCurrentStatus(AsyncCallback> callback) { GetBulkDownloadStatusRequest request = new GetBulkDownloadStatusRequest(); request.setRequestId(this.requestId); @@ -41,13 +54,11 @@ public void handleResponse(Response result) { try { GetBulkDownloadStatusResponse statusResponse = result.get(); - String trackingId = ServiceUtils.GetTrackingId(result); - BulkOperationStatus status = new BulkOperationStatus( DownloadStatus.fromValue(statusResponse.getRequestStatus()), statusResponse.getPercentComplete(), statusResponse.getResultFileUrl(), - trackingId, + ServiceUtils.GetTrackingId(result), statusResponse.getErrors() != null ? statusResponse.getErrors().getOperationErrors() : null ); diff --git a/src/main/java/com/microsoft/bingads/v13/internal/bulk/PollingBulkOperationTracker.java b/src/main/java/com/microsoft/bingads/v13/internal/bulk/PollingBulkOperationTracker.java index 18e268ee04..34311bbc73 100644 --- a/src/main/java/com/microsoft/bingads/v13/internal/bulk/PollingBulkOperationTracker.java +++ b/src/main/java/com/microsoft/bingads/v13/internal/bulk/PollingBulkOperationTracker.java @@ -9,11 +9,10 @@ import java.util.function.Function; import com.microsoft.bingads.AsyncCallback; -import com.microsoft.bingads.ServiceClient; import com.microsoft.bingads.internal.OperationStatusRetry; import com.microsoft.bingads.internal.ResultFuture; +import com.microsoft.bingads.internal.functionalinterfaces.BiConsumer; import com.microsoft.bingads.internal.functionalinterfaces.Consumer; -import com.microsoft.bingads.internal.functionalinterfaces.TriConsumer; import com.microsoft.bingads.internal.utilities.ThreadPool; import com.microsoft.bingads.v13.bulk.AdApiFaultDetail_Exception; import com.microsoft.bingads.v13.bulk.BulkOperationProgressInfo; @@ -33,12 +32,9 @@ public class PollingBulkOperationTracker implements BulkOperationTracke private boolean stopTracking; protected int lastProgressReported; private BulkOperationStatus currentStatus; - private final int statusCheckIntervalInMs; private ResultFuture> trackResultFuture; - private ServiceClient serviceClient; - private OperationStatusRetry, BulkOperationStatusProvider, IBulkService> operationStatusRetry; private int numberOfStatusRetry = 4; @@ -49,13 +45,11 @@ public void run() { } }; - public PollingBulkOperationTracker(BulkOperationStatusProvider statusProvider, - ServiceClient serviceClient, Progress progress, - int statusCheckIntervalInMs) { + public PollingBulkOperationTracker( + BulkOperationStatusProvider statusProvider, + Progress progress) { - this.statusCheckIntervalInMs = statusCheckIntervalInMs; this.statusProvider = statusProvider; - this.serviceClient = serviceClient; this.progress = progress; this.operationStatusRetry = new OperationStatusRetry, BulkOperationStatusProvider, IBulkService>( new Function() { @@ -120,7 +114,7 @@ public void onCompleted(Future> result) { int interval = INITIAL_STATUS_CHECK_INTERVAL_IN_MS; if (numberOfStatusChecks >= NUMBER_OF_INITIAL_STATUS_CHECKS) { - interval = statusCheckIntervalInMs; + interval = statusProvider.getStatusPollIntervalInMilliseconds(); } executorService.schedule(pollExecutorTask, interval, TimeUnit.MILLISECONDS); @@ -206,14 +200,14 @@ private void refreshStatus(AsyncCallback> callback) callback); operationStatusRetry.executeWithRetry( - new TriConsumer, ServiceClient, AsyncCallback>>() { + new BiConsumer, AsyncCallback>>() { @Override - public void accept(BulkOperationStatusProvider statusProvider, - ServiceClient serviceClient, + public void accept( + BulkOperationStatusProvider statusProvider, AsyncCallback> callback) { - statusProvider.getCurrentStatus(serviceClient, callback); + statusProvider.getCurrentStatus(callback); } - }, statusProvider, serviceClient, new Consumer>() { + }, statusProvider, new Consumer>() { @Override public void accept(BulkOperationStatus status) { currentStatus = status; diff --git a/src/main/java/com/microsoft/bingads/v13/internal/bulk/UploadStatusProvider.java b/src/main/java/com/microsoft/bingads/v13/internal/bulk/UploadStatusProvider.java index 59854ee53d..e2da8952fe 100644 --- a/src/main/java/com/microsoft/bingads/v13/internal/bulk/UploadStatusProvider.java +++ b/src/main/java/com/microsoft/bingads/v13/internal/bulk/UploadStatusProvider.java @@ -18,14 +18,31 @@ public class UploadStatusProvider implements BulkOperationStatusProvider { - private final String requestId; + private final String requestId; - public UploadStatusProvider(String requestId) { - this.requestId = requestId; + private final ServiceClient serviceClient; + + /** + * The amount of time in milliseconds that the upload and download operations should wait before polling the Bulk service for status. + */ + private final int statusPollIntervalInMilliseconds; + + public UploadStatusProvider( + String requestId, + ServiceClient serviceClient, + int statusPollIntervalInMilliseconds) { + this.requestId = requestId; + this.serviceClient = serviceClient; + this.statusPollIntervalInMilliseconds = statusPollIntervalInMilliseconds; + } + + @Override + public int getStatusPollIntervalInMilliseconds() { + return statusPollIntervalInMilliseconds; } @Override - public Future> getCurrentStatus(ServiceClient serviceClient, AsyncCallback> callback) { + public Future> getCurrentStatus(AsyncCallback> callback) { GetBulkUploadStatusRequest request = new GetBulkUploadStatusRequest(); request.setRequestId(this.requestId); @@ -39,13 +56,11 @@ public void handleResponse(Response result) { try { GetBulkUploadStatusResponse statusResponse = result.get(); - String trackingId = ServiceUtils.GetTrackingId(result); - BulkOperationStatus status = new BulkOperationStatus( UploadStatus.fromValue(statusResponse.getRequestStatus()), statusResponse.getPercentComplete(), statusResponse.getResultFileUrl(), - trackingId, + ServiceUtils.GetTrackingId(result), statusResponse.getErrors() != null ? statusResponse.getErrors().getOperationErrors() : null ); diff --git a/src/main/java/com/microsoft/bingads/v13/reporting/ReportingDownloadOperation.java b/src/main/java/com/microsoft/bingads/v13/reporting/ReportingDownloadOperation.java index 31ed6b9226..836b278edb 100644 --- a/src/main/java/com/microsoft/bingads/v13/reporting/ReportingDownloadOperation.java +++ b/src/main/java/com/microsoft/bingads/v13/reporting/ReportingDownloadOperation.java @@ -5,16 +5,12 @@ import java.net.URISyntaxException; 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; /** @@ -25,99 +21,45 @@ */ public class ReportingDownloadOperation { - /** - * Represents a user who intends to access the corresponding customer and account. - */ - private AuthorizationData authorizationData; - /** * The request identifier corresponding to the reporting download. */ - private String requestId; + private final String requestId; /** * The identifier of the log entry that contains the details of the download request. */ - private String trackingId; + private final String trackingId; /** - * The amount of time in milliseconds that the download operations should wait before polling the Reporting service for status. + * The service to download files. */ - private int statusPollIntervalInMilliseconds; - + private final HttpFileService httpFileService; + /** - * The timeout in milliseconds of HttpClient download operation. - */ - private int downloadHttpTimeoutInMilliseconds; - + * To process download file. + */ + private final ZipExtractor zipExtractor; + /** * Provide the status of the reporting download operation. */ - ReportingStatusProvider statusProvider; - + private final ReportingStatusProvider statusProvider; + /** - * The service to download files. - */ - private HttpFileService httpFileService; - - /** - * To process download file. - */ - private ZipExtractor zipExtractor; - - /** - * The client of reporting service. - */ - private ServiceClient serviceClient; - - /** * The final status of reporting download operation. */ private ReportingOperationStatus finalStatus; - /**@param requestId - * @param authorizationData - */ - public ReportingDownloadOperation(String requestId, AuthorizationData authorizationData) { - this(requestId, authorizationData, null, null); - } - - public ReportingDownloadOperation(String requestId, AuthorizationData authorizationData, ApiEnvironment apiEnvironment) { - this(requestId, authorizationData, null, apiEnvironment); - } - - /**@param requestId - * @param authorizationData - * @param trackingId - */ - ReportingDownloadOperation(String requestId, AuthorizationData authorizationData, String trackingId) { - this(requestId, authorizationData, new ReportingStatusProvider(requestId, authorizationData), trackingId, null); - } - - ReportingDownloadOperation(String requestId, AuthorizationData authorizationData, String trackingId, ApiEnvironment apiEnvironment) { - this(requestId, authorizationData, new ReportingStatusProvider(requestId, authorizationData), trackingId, apiEnvironment); - } - - /**@param requestId - * @param authorizationData - * @param statusProvider - * @param trackingId - */ - ReportingDownloadOperation(String requestId, AuthorizationData authorizationData, ReportingStatusProvider statusProvider, String trackingId, ApiEnvironment apiEnvironment) { - this.statusProvider = statusProvider; + ReportingDownloadOperation( + String requestId, String trackingId, + HttpFileService httpFileService, ZipExtractor zipExtractor, + ServiceClient serviceClient, int statusPollIntervalInMilliseconds) { this.requestId = requestId; - this.authorizationData = authorizationData; this.trackingId = trackingId; - - statusPollIntervalInMilliseconds = ReportingConfig.DEFAULT_STATUS_CHECK_INTERVAL_IN_MS; - - downloadHttpTimeoutInMilliseconds = ReportingConfig.DEFAULT_HTTPCLIENT_TIMEOUT_IN_MS; - - this.serviceClient = new ServiceClient(authorizationData, apiEnvironment, IReportingService.class); - - zipExtractor = new SimpleZipExtractor(); - - httpFileService = new HttpClientHttpFileService(); + this.httpFileService = httpFileService; + this.zipExtractor = zipExtractor; + this.statusProvider = new ReportingStatusProvider(requestId, serviceClient, statusPollIntervalInMilliseconds); } /** @@ -148,7 +90,7 @@ public void onSuccess(ReportingOperationStatus status) { private ReportingOperationTracker generateTracker() { ReportingOperationTracker tracker; - tracker = new ReportingOperationTracker(statusProvider, this.serviceClient, this.statusPollIntervalInMilliseconds); + tracker = new ReportingOperationTracker(statusProvider); return tracker; } @@ -168,7 +110,7 @@ public Future getStatusAsync(AsyncCallback(resultFuture) { + statusProvider.getCurrentStatus(new ParentCallback(resultFuture) { @Override public void onSuccess(ReportingOperationStatus currentStatus) { if (statusProvider.isFinalStatus(currentStatus)) { @@ -283,22 +225,11 @@ private File downloadFileWithFinalStatus(File localResultDirectoryName, String l } private File downloadResultFileZip(String url, File tempZipFile, boolean overwrite) throws IOException, URISyntaxException { - if (httpFileService == null) { - httpFileService = new HttpClientHttpFileService(); - } - - httpFileService.downloadFile(url, tempZipFile, overwrite, downloadHttpTimeoutInMilliseconds); + httpFileService.downloadFile(url, tempZipFile, overwrite); return tempZipFile; } - /** - * @return the authorizationData - */ - public AuthorizationData getAuthorizationData() { - return authorizationData; - } - /** * @return the requestId */ @@ -306,13 +237,6 @@ public String getRequestId() { return requestId; } - /** - * @param requestId the requestId to set - */ - public void setRequestId(String requestId) { - this.requestId = requestId; - } - /** * @return the trackingId */ @@ -320,13 +244,6 @@ public String getTrackingId() { return trackingId; } - /** - * @param trackingId the trackingId to set - */ - public void setTrackingId(String trackingId) { - this.trackingId = trackingId; - } - /** * @return the statusProvider */ @@ -334,13 +251,6 @@ public ReportingStatusProvider getStatusProvider() { return statusProvider; } - /** - * @param statusProvider the statusProvider to set - */ - public void setStatusProvider(ReportingStatusProvider statusProvider) { - this.statusProvider = statusProvider; - } - /** * @return the httpFileService */ @@ -348,13 +258,6 @@ public HttpFileService getHttpFileService() { return httpFileService; } - /** - * @param httpFileService the httpFileService to set - */ - public void setHttpFileService(HttpFileService httpFileService) { - this.httpFileService = httpFileService; - } - /** * @return the zipExtractor */ @@ -362,27 +265,6 @@ public ZipExtractor getZipExtractor() { return zipExtractor; } - /** - * @param zipExtractor the zipExtractor to set - */ - public void setZipExtractor(ZipExtractor zipExtractor) { - this.zipExtractor = zipExtractor; - } - - /** - * @return the serviceClient - */ - public ServiceClient getServiceClient() { - return serviceClient; - } - - /** - * @param serviceClient the serviceClient to set - */ - public void setServiceClient(ServiceClient serviceClient) { - this.serviceClient = serviceClient; - } - /** * @return the finalStatus */ @@ -396,32 +278,4 @@ public ReportingOperationStatus getFinalStatus() { public void setFinalStatus(ReportingOperationStatus finalStatus) { this.finalStatus = finalStatus; } - - /** - * 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; - } } diff --git a/src/main/java/com/microsoft/bingads/v13/reporting/ReportingOperationTracker.java b/src/main/java/com/microsoft/bingads/v13/reporting/ReportingOperationTracker.java index edb6dd9a4b..28b602515a 100644 --- a/src/main/java/com/microsoft/bingads/v13/reporting/ReportingOperationTracker.java +++ b/src/main/java/com/microsoft/bingads/v13/reporting/ReportingOperationTracker.java @@ -12,8 +12,8 @@ import com.microsoft.bingads.ServiceClient; import com.microsoft.bingads.internal.OperationStatusRetry; import com.microsoft.bingads.internal.ResultFuture; +import com.microsoft.bingads.internal.functionalinterfaces.BiConsumer; import com.microsoft.bingads.internal.functionalinterfaces.Consumer; -import com.microsoft.bingads.internal.functionalinterfaces.TriConsumer; /** * Track the status of reporting operation. @@ -29,7 +29,6 @@ public class ReportingOperationTracker { private boolean stopTracking; protected int lastProgressReported; private ReportingOperationStatus currentStatus; - private final int statusCheckIntervalInMs; private ResultFuture trackResultFuture; @@ -45,12 +44,9 @@ public void run() { } }; - public ReportingOperationTracker(ReportingStatusProvider statusProvider, - ServiceClient serviceClient, int statusCheckIntervalInMs) { + public ReportingOperationTracker(ReportingStatusProvider statusProvider) { - this.statusCheckIntervalInMs = statusCheckIntervalInMs; this.statusProvider = statusProvider; - this.serviceClient = serviceClient; this.operationStatusRetry = new OperationStatusRetry( new Function() { @@ -112,7 +108,7 @@ public void onCompleted(Future result) { int interval = INITIAL_STATUS_CHECK_INTERVAL_IN_MS; if (numberOfStatusChecks >= NUMBER_OF_INITIAL_STATUS_CHECKS) { - interval = statusCheckIntervalInMs; + interval = statusProvider.getStatusPollIntervalInMilliseconds(); } executorService.schedule(pollExecutorTask, interval, TimeUnit.MILLISECONDS); @@ -160,14 +156,14 @@ private void refreshStatus(AsyncCallback callback) { callback); operationStatusRetry.executeWithRetry( - new TriConsumer, AsyncCallback>() { + new BiConsumer>() { @Override - public void accept(ReportingStatusProvider statusProvider, - ServiceClient serviceClient, + public void accept( + ReportingStatusProvider statusProvider, AsyncCallback callback) { - statusProvider.getCurrentStatus(serviceClient, callback); + statusProvider.getCurrentStatus(callback); } - }, statusProvider, serviceClient, new Consumer() { + }, statusProvider, new Consumer() { @Override public void accept(ReportingOperationStatus status) { currentStatus = status; diff --git a/src/main/java/com/microsoft/bingads/v13/reporting/ReportingServiceManager.java b/src/main/java/com/microsoft/bingads/v13/reporting/ReportingServiceManager.java index 94eab680f1..3f6f11b1e7 100644 --- a/src/main/java/com/microsoft/bingads/v13/reporting/ReportingServiceManager.java +++ b/src/main/java/com/microsoft/bingads/v13/reporting/ReportingServiceManager.java @@ -1,5 +1,6 @@ package com.microsoft.bingads.v13.reporting; +import java.io.Closeable; import java.io.File; import java.io.IOException; import java.net.URISyntaxException; @@ -36,7 +37,7 @@ *

* */ -public class ReportingServiceManager { +public class ReportingServiceManager implements Closeable { private AuthorizationData authorizationData; private HttpFileService httpFileService; @@ -48,11 +49,6 @@ public class ReportingServiceManager { * */ private int statusPollIntervalInMilliseconds; - /** - * The timeout in milliseconds of HttpClient download operation. - */ - private int downloadHttpTimeoutInMilliseconds; - private final ServiceClient serviceClient; private File workingDirectory; @@ -82,8 +78,22 @@ private ReportingServiceManager(AuthorizationData authorizationData, workingDirectory = new File(System.getProperty("java.io.tmpdir"), "BingAdsSDK"); statusPollIntervalInMilliseconds = ReportingConfig.DEFAULT_STATUS_CHECK_INTERVAL_IN_MS; - - downloadHttpTimeoutInMilliseconds = ReportingConfig.DEFAULT_HTTPCLIENT_TIMEOUT_IN_MS; + } + + @Override + public void close() throws IOException { + httpFileService.close(); + cleanupTempFiles(); + } + + /** + * Removes all files from the working directory, whether the files are used by this BulkServiceManager or by another + * instance. + */ + public void cleanupTempFiles() { + for (File file : workingDirectory.listFiles()) { + file.delete(); + } } /** @@ -171,9 +181,6 @@ public void onSuccess(File localFile) { } private Future downloadReportingFileAsync(File resultFileDirectory, String resultFileName, boolean overwriteResultFile, ReportingDownloadOperation operation, AsyncCallback callback) throws IOException, URISyntaxException { - operation.setHttpFileService(this.httpFileService); - operation.setZipExtractor(this.zipExtractor); - final ResultFuture resultFuture = new ResultFuture(callback); File effectiveResultFileDirectory = resultFileDirectory; @@ -232,13 +239,10 @@ public void handleResponse(Response res) { response = res.get(); - String trackingId = ServiceUtils.GetTrackingId(res); - - ReportingDownloadOperation operation = new ReportingDownloadOperation(response.getReportRequestId(), authorizationData, trackingId, apiEnvironment); - - operation.setStatusPollIntervalInMilliseconds(statusPollIntervalInMilliseconds); - - operation.setDownloadHttpTimeoutInMilliseconds(downloadHttpTimeoutInMilliseconds); + ReportingDownloadOperation operation = new ReportingDownloadOperation( + response.getReportRequestId(), ServiceUtils.GetTrackingId(res), + httpFileService, zipExtractor, + serviceClient, statusPollIntervalInMilliseconds); resultFuture.setResult(operation); } catch (InterruptedException e) { @@ -308,27 +312,4 @@ public int getStatusPollIntervalInMilliseconds() { 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; - } - - /** - * Removes all files from the working directory, whether the files are used by this BulkServiceManager or by another instance. - */ - public void cleanupTempFiles() { - for(File file : workingDirectory.listFiles()) { - file.delete(); - } - } } diff --git a/src/main/java/com/microsoft/bingads/v13/reporting/ReportingStatusProvider.java b/src/main/java/com/microsoft/bingads/v13/reporting/ReportingStatusProvider.java index def37bd201..5d45cc3872 100644 --- a/src/main/java/com/microsoft/bingads/v13/reporting/ReportingStatusProvider.java +++ b/src/main/java/com/microsoft/bingads/v13/reporting/ReportingStatusProvider.java @@ -8,21 +8,36 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; + +import com.microsoft.bingads.v13.bulk.IBulkService; import jakarta.xml.ws.AsyncHandler; import jakarta.xml.ws.Response; public class ReportingStatusProvider{ private final String requestId; - - private final AuthorizationData authorizationData; - public ReportingStatusProvider(String requestId, AuthorizationData authorizationData) { + private final ServiceClient serviceClient; + + /** + * The amount of time in milliseconds that the upload and download operations should wait before polling the Bulk service for status. + */ + private final int statusPollIntervalInMilliseconds; + + public ReportingStatusProvider( + String requestId, + ServiceClient serviceClient, + int statusPollIntervalInMilliseconds) { this.requestId = requestId; - this.authorizationData = authorizationData; + this.serviceClient = serviceClient; + this.statusPollIntervalInMilliseconds = statusPollIntervalInMilliseconds; } - public Future getCurrentStatus(ServiceClient serviceClient, AsyncCallback callback) { + public int getStatusPollIntervalInMilliseconds() { + return statusPollIntervalInMilliseconds; + } + + public Future getCurrentStatus(AsyncCallback callback) { PollGenerateReportRequest request = new PollGenerateReportRequest(); request.setReportRequestId(this.requestId); @@ -34,12 +49,10 @@ public void handleResponse(Response result) { try { PollGenerateReportResponse statusResponse = result.get(); - String trackingId = ServiceUtils.GetTrackingId(result); - ReportingOperationStatus status = new ReportingOperationStatus( ReportRequestStatusType.fromValue(statusResponse.getReportRequestStatus().getStatus().value()), statusResponse.getReportRequestStatus().getReportDownloadUrl(), - trackingId + ServiceUtils.GetTrackingId(result) ); resultFuture.setResult(status); } catch (InterruptedException e) { diff --git a/src/test/java/com/microsoft/bingads/v13/api/test/operations/BulkServiceTest.java b/src/test/java/com/microsoft/bingads/v13/api/test/operations/BulkServiceTest.java index 66259fc2e6..af798adbd3 100644 --- a/src/test/java/com/microsoft/bingads/v13/api/test/operations/BulkServiceTest.java +++ b/src/test/java/com/microsoft/bingads/v13/api/test/operations/BulkServiceTest.java @@ -248,7 +248,7 @@ public void accept(String url, File file) { verify(zipExtractor); assertEquals(new File("file path"), file); - assertTrue(httpFileService.getDownloadWasCalled()); + assertTrue(httpFileService.isDownloadWasCalled()); } @Test @@ -351,7 +351,7 @@ public void accept(String url, File file) { verify(zipExtractor); assertEquals(bulkEntities, resultEntities); - assertTrue(httpFileService.getDownloadWasCalled()); + assertTrue(httpFileService.isDownloadWasCalled()); } private static AuthorizationData createUserData() { diff --git a/src/test/java/com/microsoft/bingads/v13/api/test/operations/FakeHttpFileService.java b/src/test/java/com/microsoft/bingads/v13/api/test/operations/FakeHttpFileService.java index bfb0a33522..9730159a5f 100644 --- a/src/test/java/com/microsoft/bingads/v13/api/test/operations/FakeHttpFileService.java +++ b/src/test/java/com/microsoft/bingads/v13/api/test/operations/FakeHttpFileService.java @@ -1,15 +1,10 @@ package com.microsoft.bingads.v13.api.test.operations; import java.io.File; -import java.io.IOException; import java.net.URI; -import java.net.URISyntaxException; -import java.util.ArrayList; -import java.util.concurrent.Future; import org.apache.http.HttpRequest; -import com.microsoft.bingads.AsyncCallback; import com.microsoft.bingads.internal.functionalinterfaces.BiConsumer; import com.microsoft.bingads.internal.functionalinterfaces.Consumer; import com.microsoft.bingads.internal.utilities.HttpFileService; @@ -17,8 +12,9 @@ public class FakeHttpFileService implements HttpFileService { private BiConsumer onDownloadFile; - private Boolean downloadWasCalled; - + private boolean downloadWasCalled; + private boolean closeWasCalled; + public BiConsumer getOnDownloadFile() { return onDownloadFile; } @@ -27,32 +23,28 @@ public void setOnDownloadFile(BiConsumer value) { onDownloadFile = value; } - public Boolean getDownloadWasCalled() { + public boolean isDownloadWasCalled() { return downloadWasCalled; } - - @Override - public void downloadFile(String url, File tempZipFile, boolean overwrite, int timeoutInMilliseconds) throws IOException, URISyntaxException { - onDownloadFile.accept(url, tempZipFile); - - downloadWasCalled = true; + + public boolean isCloseWasCalled() { + return closeWasCalled; } @Override - public void uploadFile(URI uri, File uploadFilePath, Consumer addHeaders, int timeoutInMilliseconds) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + public void close() { + closeWasCalled = true; } @Override - public Future downloadFileAsync(String url, File tempZipFile, AsyncCallback callback, int timeoutInMilliseconds) { + public void downloadFile(String url, File tempZipFile, boolean overwrite) { onDownloadFile.accept(url, tempZipFile); - Future result = new CompleteResponse(tempZipFile, new ArrayList()); - - callback.onCompleted(result); - downloadWasCalled = true; - - return result; - } + } + + @Override + public void uploadFile(URI uri, File uploadZipFile, Consumer addHeaders) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } } diff --git a/src/test/java/com/microsoft/bingads/v13/api/test/operations/bulk_download_operation/BulkDownloadOperationTest.java b/src/test/java/com/microsoft/bingads/v13/api/test/operations/bulk_download_operation/BulkDownloadOperationTest.java index e9fc857f27..ae0459b315 100644 --- a/src/test/java/com/microsoft/bingads/v13/api/test/operations/bulk_download_operation/BulkDownloadOperationTest.java +++ b/src/test/java/com/microsoft/bingads/v13/api/test/operations/bulk_download_operation/BulkDownloadOperationTest.java @@ -2,11 +2,13 @@ import com.microsoft.bingads.AuthorizationData; import com.microsoft.bingads.PasswordAuthentication; +import com.microsoft.bingads.ServiceClient; import com.microsoft.bingads.v13.api.test.operations.FakeApiTest; import com.microsoft.bingads.v13.bulk.ArrayOfKeyValuePairOfstringstring; import com.microsoft.bingads.v13.bulk.BulkDownloadOperation; import com.microsoft.bingads.v13.bulk.GetBulkDownloadStatusResponse; import com.microsoft.bingads.v13.bulk.IBulkService; +import com.microsoft.bingads.v13.internal.bulk.Config; public class BulkDownloadOperationTest extends FakeApiTest { @@ -23,13 +25,10 @@ private static AuthorizationData createUserData() { } protected BulkDownloadOperation createBulkDownloadOperation(Integer statusCheckIntervalInMs) { - BulkDownloadOperation operation = new BulkDownloadOperation("request123", createUserData()); - - if (statusCheckIntervalInMs != null) { - operation.setStatusPollIntervalInMilliseconds(statusCheckIntervalInMs); - } - - return operation; + return new BulkDownloadOperation( + "request123", + new ServiceClient<>(createUserData(), IBulkService.class), + statusCheckIntervalInMs != null ? statusCheckIntervalInMs : Config.DEFAULT_STATUS_CHECK_INTERVAL_IN_MS); } protected GetBulkDownloadStatusResponse createStatusResponse(Integer percentComplete, String status, String resultFileUrl) { diff --git a/src/test/java/com/microsoft/bingads/v13/api/test/operations/bulk_upload_operation/BulkUploadOperationTest.java b/src/test/java/com/microsoft/bingads/v13/api/test/operations/bulk_upload_operation/BulkUploadOperationTest.java index 159c77867c..cc22bd6298 100644 --- a/src/test/java/com/microsoft/bingads/v13/api/test/operations/bulk_upload_operation/BulkUploadOperationTest.java +++ b/src/test/java/com/microsoft/bingads/v13/api/test/operations/bulk_upload_operation/BulkUploadOperationTest.java @@ -3,11 +3,13 @@ import com.microsoft.bingads.AuthorizationData; import com.microsoft.bingads.PasswordAuthentication; +import com.microsoft.bingads.ServiceClient; import com.microsoft.bingads.v13.api.test.operations.FakeApiTest; import com.microsoft.bingads.v13.bulk.ArrayOfKeyValuePairOfstringstring; import com.microsoft.bingads.v13.bulk.BulkUploadOperation; import com.microsoft.bingads.v13.bulk.GetBulkUploadStatusResponse; import com.microsoft.bingads.v13.bulk.IBulkService; +import com.microsoft.bingads.v13.internal.bulk.Config; public class BulkUploadOperationTest extends FakeApiTest { @@ -24,13 +26,10 @@ private static AuthorizationData createUserData() { } protected BulkUploadOperation createBulkUploadOperation(Integer statusCheckIntervalInMs) { - BulkUploadOperation operation = new BulkUploadOperation("request123", createUserData(), service); - - if (statusCheckIntervalInMs != null) { - operation.setStatusPollIntervalInMilliseconds(statusCheckIntervalInMs); - } - - return operation; + return new BulkUploadOperation( + "request123", + new ServiceClient<>(createUserData(), IBulkService.class), + statusCheckIntervalInMs != null ? statusCheckIntervalInMs : Config.DEFAULT_STATUS_CHECK_INTERVAL_IN_MS); } protected GetBulkUploadStatusResponse createStatusResponse(Integer percentComplete, String status, String resultFileUrl) {