All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.baidu.haotianjing.core.client.DefaultClient Maven / Gradle / Ivy

package com.baidu.haotianjing.core.client;

import com.baidu.haotianjing.core.auth.Credentials;
import com.baidu.haotianjing.core.auth.Signer;
import com.baidu.haotianjing.core.endpoint.EndpointRunningContext;
import com.baidu.haotianjing.core.exception.RiskSdkException;
import com.baidu.haotianjing.core.http.HttpClientConfig;
import com.baidu.haotianjing.core.http.HttpClientFactory;
import com.baidu.haotianjing.core.http.HttpHeaders;
import com.baidu.haotianjing.core.http.HttpRequest;
import com.baidu.haotianjing.core.request.BaseRequest;
import com.baidu.haotianjing.core.response.BaseResponse;
import com.baidu.haotianjing.core.utils.AssertUtils;
import com.baidu.haotianjing.core.utils.JacksonUtils;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
import org.apache.hc.core5.http.ClassicHttpRequest;
import org.apache.hc.core5.http.ConnectionRequestTimeoutException;
import org.apache.hc.core5.http.ContentType;
import org.apache.hc.core5.http.HttpEntity;
import org.apache.hc.core5.http.HttpStatus;
import org.apache.hc.core5.http.io.entity.ByteArrayEntity;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.http.io.support.ClassicRequestBuilder;

import java.io.Closeable;
import java.io.IOException;
import java.util.Map;

public class DefaultClient implements Client, Closeable {

    private final String regionCodes;

    private final String protocol;

    private final Signer signer;

    private final Credentials credentials;

    private final int totalReqCount;

    private CloseableHttpClient httpClient;

    private final EndpointRunningContext endpointRunningContext;

    public DefaultClient(ClientProfile clientProfile) {
        AssertUtils.notBlank(clientProfile.getRegionCodes(), "regionCode should not be empty");
        AssertUtils.notNull(clientProfile.getCredentials(), "credentials should not be null");
        regionCodes = clientProfile.getRegionCodes();
        signer = clientProfile.getSigner();
        credentials = clientProfile.getCredentials();
        totalReqCount = 1 + Math.max(clientProfile.maxRetryCount(), 0);
        HttpClientConfig httpClientConfig = clientProfile.getHttpClientConfig();
        if (null == httpClientConfig) {
            httpClientConfig = HttpClientConfig.defaultConfig();
        }
        protocol = httpClientConfig.protocol();
        httpClient = HttpClientFactory.create(httpClientConfig);
        endpointRunningContext = new EndpointRunningContext(
                clientProfile.getServiceCode(), clientProfile.getRegionCodes(), clientProfile.getFailOverOn());
    }

    @Override
    public  T execute(BaseRequest baseRequest) throws RiskSdkException {
        String mode = baseRequest.getMode();
        baseRequest.validate();
        RiskSdkException riskSdkException = null;
        ClassicHttpRequest classicHttpRequest = createHttpRequest(baseRequest);
        CloseableHttpResponse closeableHttpResponse = null;
        for (int cnt = 1; cnt <= totalReqCount; cnt++) {
            riskSdkException = null;
            if (null != closeableHttpResponse) {
                EntityUtils.consumeQuietly(closeableHttpResponse.getEntity());
            }
            try {
                closeableHttpResponse = httpClient.execute(classicHttpRequest);
                if (isServerErr(closeableHttpResponse)) {
                    endpointRunningContext.mustDetect(mode);
                } else {
                    riskSdkException = null;
                    break;
                }
            } catch (ConnectionRequestTimeoutException e) {
                riskSdkException = new RiskSdkException("Req Server Fail: " + e.getMessage(), e);
            } catch (Exception e) {
                riskSdkException = new RiskSdkException("Req Server Fail: " + e.getMessage(), e);
                endpointRunningContext.mustDetect(mode);
            }
        }

        if (null == riskSdkException) {
            try {
                return parseResponse(baseRequest.getResponseClass(), closeableHttpResponse);
            } catch (RiskSdkException e) {
                if (isServerErr(closeableHttpResponse)) {
                    endpointRunningContext.mustDetect(mode);
                } else {
                    throw e;
                }
                return null;
            } finally {
                if (null != closeableHttpResponse) {
                    EntityUtils.consumeQuietly(closeableHttpResponse.getEntity());
                }
            }
        } else {
            if (null != closeableHttpResponse) {
                EntityUtils.consumeQuietly(closeableHttpResponse.getEntity());
            }
            throw riskSdkException;
        }
    }

    private static boolean isServerErr(CloseableHttpResponse closeableHttpResponse) {
        return null == closeableHttpResponse ||
                closeableHttpResponse.getCode() >= HttpStatus.SC_SERVER_ERROR ||
                null == closeableHttpResponse.getEntity();
    }

    @Override
    public void close() throws IOException {
        try {
            if (null != httpClient) {
                httpClient.close();
            }
        } catch (IOException e) {
            // just do nothing
        }
    }

    private ClassicHttpRequest createHttpRequest(BaseRequest baseRequest) {
        if ("1".equals(baseRequest.getMode())) {
            String primaryDomain = endpointRunningContext.primaryDomain();
            baseRequest.setDomain(primaryDomain);
        }
        HttpRequest httpRequest = baseRequest.toHttpRequest(protocol, signer, credentials);

        Map headers = baseRequest.getHeaders();

        ClassicRequestBuilder classicRequestBuilder = ClassicRequestBuilder.create("POST");

        classicRequestBuilder.setUri(httpRequest.assembleUrl());

        headers.forEach(classicRequestBuilder::addHeader);

        byte[] body = httpRequest.getBody();
        ContentType contentType = ContentType.parse(headers.get(HttpHeaders.CONTENT_TYPE));
        String contentEncoding = headers.get(HttpHeaders.CONTENT_ENCODING);
        classicRequestBuilder.setEntity(new ByteArrayEntity(body, contentType, contentEncoding));

        return classicRequestBuilder.build();
    }

     T parseResponse(Class clazz, CloseableHttpResponse closeableHttpResponse) throws RiskSdkException {
        if (null == closeableHttpResponse) {
            throw new RiskSdkException("Server Err, Resp Is Null.");
        }

        int statusCode = closeableHttpResponse.getCode();
        HttpEntity httpEntity = closeableHttpResponse.getEntity();
        if (null == httpEntity) {
            throw new RiskSdkException("Server Err. Resp Body Is Null. Code: " + statusCode);
        }

        String result;
        try {
            result = EntityUtils.toString(httpEntity);
        } catch (Exception e) {
            throw new RiskSdkException("Read Resp Body Err. Code: " + statusCode, e);
        }

        if (statusCode >= HttpStatus.SC_SERVER_ERROR) {
            throw new RiskSdkException(String.format("Server Err. Code: %s, Result: %s.", statusCode, result));
        }

        if (statusCode >= HttpStatus.SC_OK && statusCode < HttpStatus.SC_REDIRECTION) {
            try {
                // return result;
                return JacksonUtils.toObject(result, clazz);
            } catch (Exception e) {
                throw new RiskSdkException(
                        String.format("Parse Result Err. Code: %s, Result: %s.", statusCode, result), e);
            }
        } else {
            throw new RiskSdkException(String.format("Server Resp Err. Code: %s, Result: %s.", statusCode, result));
        }

    }

    @Override
    public EndpointRunningContext endpointRunningContext() {
        return endpointRunningContext;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy