use of com.azure.android.core.http.PolicyCompleter in project azure-sdk-for-android by Azure.
the class HttpLoggingPolicy method process.
@Override
public void process(HttpPipelinePolicyChain chain) {
// No logging will be performed, trigger a no-op.
if (httpLogDetailLevel == HttpLogDetailLevel.NONE) {
chain.processNextPolicy(chain.getRequest());
return;
}
// final ClientLogger logger = new ClientLogger((String) context.getData("caller-method").orElse(""));
// TODO: bring context ^
final ClientLogger logger = new ClientLogger((String) "caller-method");
if (!logger.canLogAtLevel(LogLevel.INFORMATIONAL)) {
chain.processNextPolicy(chain.getRequest());
return;
}
final long startNs = System.nanoTime();
final HttpRequest httpRequest = chain.getRequest();
// final Integer retryCount = context.getData(RETRY_COUNT_CONTEXT);
// final Integer retryCount = null; // TODO: bring context ^
StringBuilder requestLogMessage = new StringBuilder();
if (httpLogDetailLevel.shouldLogUrl()) {
requestLogMessage.append("--> ").append(httpRequest.getHttpMethod()).append(" ").append(this.getRedactedUrl(httpRequest.getUrl())).append(LINE_SEPARATOR);
// if (retryCount != null) {
// requestLogMessage.append(retryCount).append(LINE_SEPARATOR);
// }
}
this.appendHeaders(logger, httpRequest.getHeaders(), requestLogMessage);
if (httpLogDetailLevel.shouldLogBody()) {
if (httpRequest.getBody() == null) {
requestLogMessage.append("(empty body)").append(LINE_SEPARATOR).append("--> END ").append(httpRequest.getHttpMethod()).append(LINE_SEPARATOR);
} else {
final String requestContentType = httpRequest.getHeaders().getValue("Content-Type");
final long requestContentLength = this.getContentLength(logger, httpRequest.getHeaders());
if (this.isContentLoggable(requestContentType, requestContentLength)) {
final String content = this.convertBytesToString(httpRequest.getBody(), logger);
requestLogMessage.append(requestContentLength).append("-byte body:").append(LINE_SEPARATOR).append(content).append(LINE_SEPARATOR).append("--> END ").append(httpRequest.getHttpMethod()).append(LINE_SEPARATOR);
} else {
requestLogMessage.append(requestContentLength).append("-byte body: (content not logged)").append(LINE_SEPARATOR).append("--> END ").append(httpRequest.getHttpMethod()).append(LINE_SEPARATOR);
}
}
}
logger.info(requestLogMessage.toString());
chain.processNextPolicy(httpRequest, new NextPolicyCallback() {
@Override
public PolicyCompleter.CompletionState onSuccess(HttpResponse response, PolicyCompleter completer) {
long tookMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNs);
final String contentLengthHeaderValue = response.getHeaderValue("Content-Length");
final String contentLengthMessage = (contentLengthHeaderValue == null || contentLengthHeaderValue.length() == 0) ? "unknown-length body" : contentLengthHeaderValue + "-byte body";
StringBuilder responseLogMessage = new StringBuilder();
if (httpLogDetailLevel.shouldLogUrl()) {
responseLogMessage.append("<-- ").append(response.getStatusCode()).append(" ").append(getRedactedUrl(response.getRequest().getUrl())).append(" (").append(tookMs).append(" ms, ").append(contentLengthMessage).append(")").append(LINE_SEPARATOR);
}
appendHeaders(logger, response.getHeaders(), responseLogMessage);
HttpResponse httpResponse = response;
if (httpLogDetailLevel.shouldLogBody()) {
final String responseContentType = response.getHeaderValue("Content-Type");
final long responseContentLength = getContentLength(logger, response.getHeaders());
if (isContentLoggable(responseContentType, responseContentLength)) {
httpResponse = response.buffer();
final String content = convertBytesToString(httpResponse.getBodyAsByteArray(), logger);
responseLogMessage.append("Response body:").append(LINE_SEPARATOR).append(content).append(LINE_SEPARATOR).append("<-- END HTTP");
} else {
responseLogMessage.append("(body content not logged)").append(LINE_SEPARATOR).append("<-- END HTTP");
}
} else {
responseLogMessage.append("<-- END HTTP");
}
logger.info(responseLogMessage.toString());
return completer.completed(httpResponse);
}
@Override
public PolicyCompleter.CompletionState onError(Throwable error, PolicyCompleter completer) {
logger.warning("<-- HTTP FAILED: ", error);
return completer.completedError(error);
}
});
}
use of com.azure.android.core.http.PolicyCompleter in project azure-sdk-for-android by Azure.
the class CookiePolicy method process.
@Override
public void process(HttpPipelinePolicyChain chain) {
HttpRequest httpRequest = chain.getRequest();
final URI uri;
try {
uri = httpRequest.getUrl().toURI();
} catch (URISyntaxException error) {
chain.completedError(error);
return;
}
Map<String, List<String>> cookieHeaders = new HashMap<>();
for (HttpHeader header : httpRequest.getHeaders()) {
cookieHeaders.put(header.getName(), Arrays.asList(chain.getRequest().getHeaders().getValues(header.getName())));
}
final Map<String, List<String>> requestCookies;
try {
requestCookies = cookies.get(uri, cookieHeaders);
} catch (IOException error) {
chain.completedError(error);
return;
}
for (Map.Entry<String, List<String>> entry : requestCookies.entrySet()) {
httpRequest.getHeaders().put(entry.getKey(), TextUtils.join(",", entry.getValue()));
}
chain.processNextPolicy(httpRequest, new NextPolicyCallback() {
@Override
public PolicyCompleter.CompletionState onSuccess(HttpResponse response, PolicyCompleter completer) {
Map<String, List<String>> responseHeaders = new HashMap<>();
for (HttpHeader header : response.getHeaders()) {
responseHeaders.put(header.getName(), Collections.singletonList(header.getValue()));
}
try {
cookies.put(uri, responseHeaders);
} catch (IOException error) {
return completer.completedError(error);
}
return completer.completed(response);
}
@Override
public PolicyCompleter.CompletionState onError(Throwable error, PolicyCompleter completer) {
return completer.completedError(error);
}
});
}
use of com.azure.android.core.http.PolicyCompleter in project azure-sdk-for-android by Azure.
the class RetryPolicy method retryIfRequired.
private PolicyCompleter.CompletionState retryIfRequired(HttpPipelinePolicyChain chain, HttpResponse response, Throwable error, PolicyCompleter completer, final int retryAttempts) {
if (chain.getCancellationToken().isCancellationRequested()) {
if (response != null) {
response.close();
}
return completer.completedError(new IOException("Canceled."));
}
if (!shouldRetry(response, error, retryAttempts)) {
if (response != null) {
return completer.completed(response);
} else {
if (retryAttempts >= this.retryStrategy.getMaxRetries()) {
final RuntimeException maxRetriedError = new RuntimeException(String.format("The max retries (%d times) for the service call is exceeded.", this.retryStrategy.getMaxRetries()));
if (error != null) {
maxRetriedError.addSuppressed(error);
}
return completer.completedError(maxRetriedError);
} else {
return completer.completedError(error);
}
}
} else {
Duration delay = null;
Throwable userError = null;
try {
delay = calculateRetryDelay(response, null, retryAttempts);
} catch (Throwable e) {
userError = e;
} finally {
if (response != null) {
response.close();
}
}
if (userError != null) {
return completer.completedError(userError);
} else {
chain.processNextPolicy(chain.getRequest(), new NextPolicyCallback() {
@Override
public PolicyCompleter.CompletionState onSuccess(HttpResponse response, PolicyCompleter completer) {
return retryIfRequired(chain, response, null, completer, retryAttempts + 1);
}
@Override
public PolicyCompleter.CompletionState onError(Throwable error, PolicyCompleter completer) {
return retryIfRequired(chain, null, error, completer, retryAttempts + 1);
}
}, delay.toMillis(), TimeUnit.MILLISECONDS);
return completer.defer();
}
}
}
use of com.azure.android.core.http.PolicyCompleter in project azure-sdk-for-android by Azure.
the class RecordNetworkCallPolicy method process.
@Override
public void process(HttpPipelinePolicyChain chain) {
final NetworkCallRecord networkCallRecord = new NetworkCallRecord();
Map<String, String> headers = new HashMap<>();
captureRequestHeaders(chain.getRequest().getHeaders(), headers, X_MS_CLIENT_REQUEST_ID, CONTENT_TYPE, X_MS_VERSION, USER_AGENT);
networkCallRecord.setHeaders(headers);
networkCallRecord.setMethod(chain.getRequest().getHttpMethod().toString());
// Remove sensitive information such as SAS token signatures from the recording.
UrlBuilder urlBuilder = UrlBuilder.parse(chain.getRequest().getUrl());
redactedAccountName(urlBuilder);
if (urlBuilder.getQuery().containsKey(SIG)) {
urlBuilder.setQueryParameter(SIG, "REDACTED");
}
networkCallRecord.setUri(urlBuilder.toString().replaceAll("\\?$", ""));
chain.processNextPolicy(chain.getRequest(), new NextPolicyCallback() {
@Override
public PolicyCompleter.CompletionState onSuccess(HttpResponse response, PolicyCompleter completer) {
final HttpResponse bufferedResponse = response.buffer();
Map<String, String> responseData = extractResponseData(bufferedResponse);
networkCallRecord.setResponse(responseData);
String body = responseData.get(BODY);
// Remove pre-added header if this is a waiting or redirection
if (body != null && body.contains("<Status>InProgress</Status>") || Integer.parseInt(responseData.get(STATUS_CODE)) == HttpURLConnection.HTTP_MOVED_TEMP) {
logger.info("Waiting for a response or redirection.");
} else {
recordedData.addNetworkCall(networkCallRecord);
}
return completer.completed(bufferedResponse);
}
@Override
public PolicyCompleter.CompletionState onError(Throwable error, PolicyCompleter completer) {
networkCallRecord.setException(new NetworkCallError(error));
recordedData.addNetworkCall(networkCallRecord);
return completer.completedError(error);
}
});
}
Aggregations