com.aliyun.openservices.log.http.comm.ServiceClient Maven / Gradle / Ivy
package com.aliyun.openservices.log.http.comm;
import com.aliyun.openservices.log.http.client.ClientConfiguration;
import com.aliyun.openservices.log.http.client.ClientException;
import com.aliyun.openservices.log.http.client.HttpMethod;
import com.aliyun.openservices.log.http.client.ServiceException;
import com.aliyun.openservices.log.http.utils.HttpUtil;
import com.aliyun.openservices.log.util.Args;
import org.apache.http.conn.HttpClientConnectionManager;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
public abstract class ServiceClient {
public static class Request extends HttpMessage {
private String uri;
private HttpMethod method;
public Request() {
}
public String getUri() {
return this.uri;
}
public void setUrl(String uri) {
this.uri = uri;
}
/**
* @return the method
*/
public HttpMethod getMethod() {
return method;
}
/**
* @param method the method to set
*/
public void setMethod(HttpMethod method) {
this.method = method;
}
}
private static final int DEFAULT_MARK_LIMIT = 1024 * 4;
protected ClientConfiguration config;
protected ServiceClient(ClientConfiguration config) {
this.config = config;
}
public ClientConfiguration getClientConfiguration() {
return this.config;
}
/**
* Returns response from the service.
*
* @param request Request message.
* @param charset encode charset.
*/
public ResponseMessage sendRequest(RequestMessage request, String charset)
throws ServiceException, ClientException {
Args.notNull(request, "request");
Args.notNullOrEmpty(charset, "charset");
try {
return sendRequestImpl(request, charset);
} finally {
// Close the request stream as well after the request is complete.
try {
request.close();
} catch (IOException e) {
}
}
}
private ResponseMessage sendRequestImpl(RequestMessage request,
String charset) throws ClientException, ServiceException {
InputStream requestContent = request.getContent();
if (requestContent != null && requestContent.markSupported()) {
requestContent.mark(DEFAULT_MARK_LIMIT);
}
int retries = 0;
RetryStrategy retryStrategy = config.getRetryStrategy() != null ? config.getRetryStrategy()
: this.getDefaultRetryStrategy();
while (true) {
try {
if (retries > 0) {
pause(retries, retryStrategy);
if (requestContent != null && requestContent.markSupported()) {
try {
requestContent.reset();
} catch (IOException ex) {
throw new ClientException("Failed to reset the request input stream: ", ex);
}
}
}
Request httpRequest = buildRequest(request, charset);
return sendRequestCore(httpRequest, charset);
} catch (ServiceException sex) {
if (!shouldRetry(sex, request, retries, retryStrategy)) {
throw sex;
}
} catch (ClientException cex) {
if (!shouldRetry(cex, request, retries, retryStrategy)) {
throw cex;
}
} catch (Exception ex) {
throw new ClientException(ex.getMessage(), ex);
} finally {
retries++;
}
}
}
/**
* Implements the core logic to send requests to Aliyun services.
*
* @param request
* @param charset
* @return response message
* @throws Exception
*/
protected abstract ResponseMessage sendRequestCore(Request request, String charset)
throws Exception;
private void pause(int retries, RetryStrategy retryStrategy) throws ClientException {
long delay = retryStrategy.getPauseDelay(retries);
try {
Thread.sleep(delay);
} catch (InterruptedException e) {
throw new ClientException(e.getMessage(), e);
}
}
private boolean shouldRetry(Exception exception, RequestMessage request,
int retries,
RetryStrategy retryStrategy) {
if (retries >= config.getMaxErrorRetry()) {
return false;
}
if (!request.isRepeatable()) {
return false;
}
if (retryStrategy.shouldRetry(exception, request, retries)) {
return true;
}
return false;
}
protected abstract RetryStrategy getDefaultRetryStrategy();
private Request buildRequest(RequestMessage requestMessage, String charset)
throws ClientException {
Request request = new Request();
request.setMethod(requestMessage.getMethod());
request.setHeaders(requestMessage.getHeaders());
// The header must be converted after the request is signed,
// otherwise the signature will be incorrect.
if (request.getHeaders() != null) {
HttpUtil.convertHeaderCharsetToIso88591(request.getHeaders());
}
final String delimiter = "/";
String uri = requestMessage.getEndpoint().toString();
if (!uri.endsWith(delimiter)
&& (requestMessage.getResourcePath() == null ||
!requestMessage.getResourcePath().startsWith(delimiter))) {
uri += delimiter;
}
if (requestMessage.getResourcePath() != null) {
uri += requestMessage.getResourcePath();
}
String paramString = HttpUtil.paramToQueryString(requestMessage.getParameters(), charset);
/*
* For all non-POST requests, and any POST requests that already have a
* payload, we put the encoded params directly in the URI, otherwise,
* we'll put them in the POST request's payload.
*/
boolean requestHasNoPayload = requestMessage.getContent() != null;
boolean requestIsPost = requestMessage.getMethod() == HttpMethod.POST;
boolean putParamsInUri = !requestIsPost || requestHasNoPayload;
if (paramString != null && putParamsInUri) {
uri += "?" + paramString;
}
request.setUrl(uri);
if (requestIsPost && requestMessage.getContent() == null && paramString != null) {
// Put the param string to the request body if POSTing and
// no content.
try {
byte[] buf = paramString.getBytes(charset);
ByteArrayInputStream content = new ByteArrayInputStream(buf);
request.setContent(content);
request.setContentLength(buf.length);
} catch (UnsupportedEncodingException e) {
throw new AssertionError("EncodingFailed" + e.getMessage());
}
} else {
request.setContent(requestMessage.getContent());
request.setContentLength(requestMessage.getContentLength());
}
return request;
}
public abstract void shutdown();
public abstract HttpClientConnectionManager getConnectionManager();
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy