Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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<TOperationStatus, TOperationStatusProvider, TService> {
private static final int INTERVAL_OF_RETRY = 1000; // TimeUnit Milliseconds
Expand All @@ -28,43 +27,43 @@ public OperationStatusRetry(Function<Exception, Integer> f) {
}

public void executeWithRetry(
final TriConsumer<TOperationStatusProvider, ServiceClient<TService>, AsyncCallback<TOperationStatus>> action,
final TOperationStatusProvider statusProvider, final ServiceClient<TService> serviceClient,
final Consumer<TOperationStatus> statusConsumer, final Consumer<Exception> exceptionConsumer,
final BiConsumer<TOperationStatusProvider, AsyncCallback<TOperationStatus>> action,
final TOperationStatusProvider statusProvider,
final Consumer<TOperationStatus> statusConsumer,
final Consumer<Exception> 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<TOperationStatusProvider, ServiceClient<TService>, AsyncCallback<TOperationStatus>> action,
final TOperationStatusProvider statusProvider, final ServiceClient<TService> serviceClient,
final BiConsumer<TOperationStatusProvider, AsyncCallback<TOperationStatus>> action,
final TOperationStatusProvider statusProvider,
final Consumer<TOperationStatus> statusConsumer, final Consumer<Exception> exceptionConsumer,
final int maxRetryCount) {
action.accept(statusProvider, serviceClient, new AsyncCallback<TOperationStatus>() {
action.accept(statusProvider, new AsyncCallback<TOperationStatus>() {

@Override
public void onCompleted(Future<TOperationStatus> result) {
try {
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<TOperationStatusProvider, ServiceClient<TService>, AsyncCallback<TOperationStatus>> action,
final TOperationStatusProvider statusProvider, final ServiceClient<TService> serviceClient,
final BiConsumer<TOperationStatusProvider, AsyncCallback<TOperationStatus>> action,
final TOperationStatusProvider statusProvider,
final Consumer<TOperationStatus> statusConsumer, final Consumer<Exception> 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);
Expand All @@ -74,16 +73,15 @@ private void retryWhenException(
}

private void retry(
final TriConsumer<TOperationStatusProvider, ServiceClient<TService>, AsyncCallback<TOperationStatus>> action,
final TOperationStatusProvider statusProvider, final ServiceClient<TService> serviceClient,
final BiConsumer<TOperationStatusProvider, AsyncCallback<TOperationStatus>> action,
final TOperationStatusProvider statusProvider,
final Consumer<TOperationStatus> statusConsumer, final Consumer<Exception> 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);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,193 +3,91 @@
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 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.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.HttpClients;

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;

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));
}

CloseableHttpClient client = HttpClients.custom().setDefaultRequestConfig(RequestConfig.custom()
.setConnectionRequestTimeout(timeoutInMilliseconds)
.setConnectTimeout(timeoutInMilliseconds)
.setSocketTimeout(timeoutInMilliseconds).build())
.useSystemProperties()
.build();
import static java.lang.String.format;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.apache.http.entity.mime.HttpMultipartMode.BROWSER_COMPATIBLE;

try {
HttpGet httpget = new HttpGet(new URI(url));
HttpResponse response = client.execute(httpget);
InputStream content = response.getEntity().getContent();
public class HttpClientHttpFileService implements HttpFileService {

FileOutputStream tempFileOutput = null;
private static final ContentType APPLICATION_ZIP = ContentType.create("application/zip");

try {
tempFileOutput = new FileOutputStream(tempZipFile);

FileUtils.copy(content, tempFileOutput);
} finally {
if (tempFileOutput != null) {
tempFileOutput.close();
}
@Override
public void downloadFile(String url, File tempZipFile, boolean overwrite, int timeoutInMilliseconds) throws URISyntaxException {
try (CloseableHttpClient client = createHttpClient(timeoutInMilliseconds)) {
HttpGet get = new HttpGet(new URI(url));
try (CloseableHttpResponse response = client.execute(get)) {
InputStream content = response.getEntity().getContent();
Files.copy(content, tempZipFile.toPath(), copyOptions(overwrite));
}
} catch (IOException ex) {
throw new CouldNotDownloadResultFileException(ex);
} catch (IllegalStateException ex) {
throw new CouldNotDownloadResultFileException(ex);
} finally {
if (client != null) {
client.close();
}
}
}

private CopyOption[] copyOptions(boolean overwrite) {
return overwrite ?
new CopyOption[] { StandardCopyOption.REPLACE_EXISTING } :
new CopyOption[0];
}

@Override
public void uploadFile(URI uri, File uploadFilePath, Consumer<HttpRequest> addHeaders, int timeoutInMilliseconds) {
FileInputStream stream = null;

try {
stream = new FileInputStream(uploadFilePath);

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();
}
try (CloseableHttpClient client = createHttpClient(timeoutInMilliseconds);
FileInputStream stream = new FileInputStream(uploadFilePath)) {
HttpPost post = new HttpPost(uri);
addHeaders.accept(post);
post.setEntity(MultipartEntityBuilder.create()
.addBinaryBody("upstream", stream, APPLICATION_ZIP, uploadFilePath.getName())
.setMode(BROWSER_COMPATIBLE)
.build());
try (CloseableHttpResponse response = client.execute(post)) {
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != 200) {
InputStream content = response.getEntity().getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(content, UTF_8));
StringBuilder exceptionMessage = new StringBuilder(64);
reader.lines().forEach(exceptionMessage::append);
throw new CouldNotUploadFileException(format(
"Unsuccessful Status Code: %d; Exception Message: %s", statusCode, exceptionMessage));
}
}
} 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);
}
}
}
}

@Override
public Future<File> downloadFileAsync(String url, File tempZipFile, AsyncCallback<File> callback, int timeoutInMilliseconds) {
final ResultFuture<File> resultFuture = new ResultFuture<File>(callback);

CloseableHttpClient client = HttpClients
.custom()
private CloseableHttpClient createHttpClient(int timeoutInMilliseconds) {
return HttpClients.custom()
.setDefaultRequestConfig(RequestConfig.custom()
.setConnectionRequestTimeout(timeoutInMilliseconds)
.setConnectTimeout(timeoutInMilliseconds)
.setSocketTimeout(timeoutInMilliseconds)
.build())
.setConnectionRequestTimeout(timeoutInMilliseconds)
.setConnectTimeout(timeoutInMilliseconds)
.setSocketTimeout(timeoutInMilliseconds)
.build())
.useSystemProperties()
.build();

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);

resultFuture.setResult(tempZipFile);
} finally {
if (tempFileOutput != null) {
tempFileOutput.close();
}
}
} 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 resultFuture;
}
}
Original file line number Diff line number Diff line change
@@ -1,20 +1,15 @@
package com.microsoft.bingads.internal.utilities;

import com.microsoft.bingads.AsyncCallback;
import com.microsoft.bingads.internal.functionalinterfaces.Consumer;
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;
void downloadFile(String url, File tempZipFile, boolean overwrite, int timeoutInMilliseconds) throws URISyntaxException;

void uploadFile(URI uri, File uploadFilePath, Consumer<HttpRequest> addHeaders, int timeoutInMilliseconds);

Future<File> downloadFileAsync(String url, File tempZipFile, AsyncCallback<File> callback, int timeoutInMilliseconds);

}
Loading