com.aliyun.datahub.client.impl.AbstractDatahubClient Maven / Gradle / Ivy
The newest version!
package com.aliyun.datahub.client.impl;
import com.aliyun.datahub.client.DatahubClient;
import com.aliyun.datahub.client.auth.Account;
import com.aliyun.datahub.client.common.DatahubConfig;
import com.aliyun.datahub.client.common.DatahubConstant;
import com.aliyun.datahub.client.common.ErrorCode;
import com.aliyun.datahub.client.exception.*;
import com.aliyun.datahub.client.http.HttpClient;
import com.aliyun.datahub.client.http.HttpConfig;
import com.aliyun.datahub.client.impl.schemaregistry.DefaultSchemaRegistryFactory;
import com.aliyun.datahub.client.impl.schemaregistry.SchemaRegistryClient;
import com.aliyun.datahub.client.impl.schemaregistry.SchemaRegistryFactory;
import com.aliyun.datahub.client.metircs.ClientMetrics;
import com.aliyun.datahub.client.model.BaseResult;
import com.aliyun.datahub.client.model.CompressType;
import com.aliyun.datahub.client.util.ClientUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import retrofit2.Call;
import retrofit2.Response;
import retrofit2.Retrofit;
import java.io.IOException;
import static com.aliyun.datahub.client.common.ErrorCode.*;
public abstract class AbstractDatahubClient implements DatahubClient {
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractDatahubClient.class);
protected static final int MAX_FETCH_SIZE = 1000;
protected static final int MIN_FETCH_SIZE = 1;
protected static final String MAX_SHARD_ID = String.valueOf(0xffffffffL); // "4294967295"
protected static final int MAX_WAITING_TIME_IN_MS = 30000;
protected static final ClientMetrics.MetricProxy METRIC_PROXY = ClientMetrics.getMetricProxy();
private final String endpoint;
protected HttpConfig httpConfig;
private final Retrofit retrofit;
private SchemaRegistryClient schemaRegistry;
public AbstractDatahubClient(String endpoint, Account account, DatahubConfig datahubConfig, HttpConfig httpConfig,
String userAgent, SchemaRegistryFactory schemaRegistryFactory) {
this.endpoint = endpoint;
this.httpConfig = httpConfig;
this.retrofit = HttpClient.createClient(
endpoint,
newHttpConfig(datahubConfig.getProtocol() == DatahubConfig.Protocol.BATCH),
userAgent,
account);
if (schemaRegistryFactory == null) {
schemaRegistryFactory = new DefaultSchemaRegistryFactory();
}
this.schemaRegistry = schemaRegistryFactory.getSchemaRegistry(endpoint, account.getPrimaryKey(),
SchemaRegistryFactory.SCHEMA_UPDATE_INTERVAL_MS, this);
}
private HttpConfig newHttpConfig(boolean enableBatch) {
if (!enableBatch) {
return this.httpConfig;
}
HttpConfig newConfig = this.httpConfig.deepCopy();
// if enable batch, not enable http compress
newConfig.setCompressType(CompressType.NONE);
return newConfig;
}
public SchemaRegistryClient getSchemaRegistry() {
return this.schemaRegistry;
}
public void setSchemaRegistry(SchemaRegistryClient schemaRegistry) {
this.schemaRegistry = schemaRegistry;
}
protected T getService(Class cls) {
return this.retrofit.create(cls);
}
protected DataHubService getService() {
return getService(DataHubService.class);
}
final protected T callWrapper(Call call) {
try {
return retryExecute(call);
} catch (DatahubClientException ex) {
LOGGER.debug("Request fail. error:", ex);
checkAndThrow(ex);
} catch (Exception ex) {
LOGGER.warn("Request fail. error:", ex);
throw new DatahubClientException(ex.getMessage() == null ?
getExceptionStack(ex) : ex.getMessage(), ex);
}
// should never go here
return null;
}
final private T retryExecute(Call call) {
int count = 1;
int httpStatus = DatahubConstant.DEFAULT_CLIENT_ERROR_STATUS;
String requestId = null;
while (true) {
try {
Response response = call.execute();
httpStatus = response.code();
requestId = response.headers().get(DatahubConstant.X_DATAHUB_REQUEST_ID);
if (response.body() instanceof BaseResult) {
((BaseResult) response.body()).setRequestId(requestId);
}
return response.body();
} catch (DatahubClientException ex) {
if (count >= httpConfig.getMaxRetryCount() || !ErrorCode.canRetry(ex.getErrorCode())) {
ex.setHttpStatus(httpStatus);
throw ex;
}
} catch (IOException ex) {
// try cancel before clone
call.cancel();
if (count >= httpConfig.getMaxRetryCount()) {
LOGGER.warn("Request fail. endpoint: {}", endpoint, ex);
throw new DatahubClientException(httpStatus, requestId,
null, ex.getMessage() + ", endpoint: " + endpoint, ex);
}
}
ClientUtils.silentSleep(httpConfig.getRetryIntervalMs());
++count;
call = call.clone();
}
}
private void checkAndThrow(DatahubClientException ex) {
String errCode = ex.getErrorCode();
if (INVALID_PARAMETER.equalsIgnoreCase(errCode) ||
INVALID_CURSOR.equalsIgnoreCase(errCode)) {
throw new InvalidParameterException(ex);
} else if (NO_SUCH_SHARD.equalsIgnoreCase(errCode)) {
throw new ShardNotFoundException(ex);
} else if (RESOURCE_NOT_FOUND.equalsIgnoreCase(errCode) ||
NO_SUCH_PROJECT.equalsIgnoreCase(errCode) ||
NO_SUCH_TOPIC.equalsIgnoreCase(errCode) ||
NO_SUCH_CONNECTOR.equalsIgnoreCase(errCode) ||
NO_SUCH_SUBSCRIPTION.equalsIgnoreCase(errCode) ||
NO_SUCH_CONSUMER.equalsIgnoreCase(errCode) ||
NO_SUCH_METER_INFO.equalsIgnoreCase(errCode)) {
throw new ResourceNotFoundException(ex);
} else if (RESOURCE_ALREADY_EXIST.equalsIgnoreCase(errCode) ||
PROJECT_ALREADY_EXIST.equalsIgnoreCase(errCode) ||
TOPIC_ALREADY_EXIST.equalsIgnoreCase(errCode) ||
CONNECTOR_ALREADY_EXIST.equalsIgnoreCase(errCode)) {
throw new ResourceAlreadyExistException(ex);
} else if (SEEK_OUT_OF_RANGE.equalsIgnoreCase(errCode)) {
throw new SeekOutOfRangeException(ex);
} else if (UN_AUTHORIZED.equalsIgnoreCase(errCode)) {
throw new AuthorizationFailureException(ex);
} else if (NO_PERMISSION.equalsIgnoreCase(errCode)) {
throw new NoPermissionException(ex);
} else if (OPERATOR_DENIED.equalsIgnoreCase(errCode)) {
throw new OperationDeniedException(ex);
} else if (INVALID_SHARD_OPERATION.equalsIgnoreCase(errCode)) {
throw new ShardSealedException(ex);
} else if (LIMIT_EXCEED.equalsIgnoreCase(errCode)) {
throw new LimitExceededException(ex);
} else if (SUBSCRIPTION_OFFLINE.equalsIgnoreCase(errCode)) {
throw new SubscriptionOfflineException(ex);
} else if (OFFSET_SESSION_CHANGED.equalsIgnoreCase(errCode) ||
OFFSET_SESSION_CLOSED.equalsIgnoreCase(errCode)) {
throw new SubscriptionSessionInvalidException(ex);
} else if (OFFSET_RESETED.equalsIgnoreCase(errCode)) {
throw new SubscriptionOffsetResetException(ex);
} else if (MALFORMED_RECORD.equalsIgnoreCase(errCode)) {
throw new MalformedRecordException(ex);
} else if (CONSUMER_GROUP_IN_PROCESS.equalsIgnoreCase(errCode)) {
throw new ServiceInProcessException(ex);
} else if (EXPIRED_ACCESS_TOKEN.equalsIgnoreCase(errCode)) {
throw new ExpiredAccessTokenException(ex);
} else if(TOPIC_OFFLINE.equalsIgnoreCase(errCode)) {
throw new ResourceOfflineException(ex);
} else if (REQUEST_ENTITY_TOO_LARGE.equalsIgnoreCase(errCode)) {
throw new RequestEntityTooLargeException(ex);
} else {
throw ex;
}
}
private String getExceptionStack(Exception ex) {
if (ex.getMessage() != null) {
return ex.getMessage();
}
StackTraceElement element = ex.getStackTrace()[0];
StringBuilder sb = new StringBuilder()
.append("Exception:").append(ex.getClass().getName()).append("|")
.append("ClassName:").append(element.getClassName()).append("|")
.append("File:").append(element.getFileName()).append("|")
.append("Line:").append(element.getLineNumber()).append("|")
.append("Method:").append(element.getMethodName());
return sb.toString();
}
}