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

org.mydotey.artemis.client.common.ArtemisHttpClient Maven / Gradle / Ivy

The newest version!
package org.mydotey.artemis.client.common;

import com.google.common.base.Preconditions;
import com.google.common.collect.Maps;

import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.client.methods.HttpPost;
import org.mydotey.artemis.HasResponseStatus;
import org.mydotey.artemis.ResponseStatus;
import org.mydotey.scf.filter.RangeValueFilter;
import org.mydotey.caravan.util.metric.EventMetric;
import org.mydotey.caravan.util.metric.EventMetricManager;
import org.mydotey.caravan.util.metric.MetricConfig;
import org.mydotey.artemis.util.ResponseStatusUtil;
import org.mydotey.codec.json.JacksonJsonCodec;
import org.mydotey.java.StringExtension;
import org.mydotey.java.ThreadExtension;
import org.mydotey.rpc.client.http.apache.HttpRequestFactory;
import org.mydotey.rpc.client.http.apache.sync.DynamicPoolingHttpClientProvider;
import org.mydotey.rpc.client.http.apache.sync.HttpRequestExecutors;
import org.mydotey.scf.Property;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;

/**
 * Created by fang_j on 10/07/2016.
 */
public class ArtemisHttpClient {
    protected final Logger _logger = LoggerFactory.getLogger(this.getClass());
    private final DynamicPoolingHttpClientProvider _clientProvider;
    private final AddressManager _addressManager;
    private final Property _httpClientRetryTimes;
    private final Property _retryInterval;
    private final String _distributionMetricName;
    protected final EventMetricManager _eventMetricManager;

    public ArtemisHttpClient(final ArtemisClientConfig config, final String httpClientId) {
        Preconditions.checkArgument(config != null, "config");
        Preconditions.checkArgument(!StringExtension.isBlank(httpClientId), "httpClientId");
        _clientProvider = new DynamicPoolingHttpClientProvider(httpClientId + ".http-client",
            config.properties().getManager());
        _addressManager = config.addressManager();
        _httpClientRetryTimes = config.properties().getIntProperty(httpClientId + ".http-client.retry-times", 5,
            new RangeValueFilter<>(1, 10));
        _retryInterval = config.properties().getIntProperty(httpClientId + ".http-client.retry-interval", 100,
            new RangeValueFilter<>(0, 1000));
        _distributionMetricName = config.key("http-response.status-code");
        _eventMetricManager = config.eventMetricManager();
    }

    public  T request(final String path, final Object request, final Class clazz) {
        final int retryTimes = _httpClientRetryTimes.getValue().intValue();
        ResponseStatus responseStatus = null;
        for (int i = 0; i < retryTimes; i++) {
            AddressContext context = null;
            try {
                context = _addressManager.getContext();
                String requestUrl = context.customHttpUrl(path);
                HttpEntityEnclosingRequestBase httpRequest = HttpRequestFactory.createRequest(
                    requestUrl, HttpPost.METHOD_NAME, request, JacksonJsonCodec.DEFAULT);
                HttpRequestFactory.gzipRequest(httpRequest);
                T response = HttpRequestExecutors.execute(_clientProvider.get(), httpRequest,
                    JacksonJsonCodec.DEFAULT, clazz);
                if (response == null || response.getResponseStatus() == null)
                    throw new RuntimeException("Got null response or null response status.");

                responseStatus = response.getResponseStatus();
                boolean isServiceDown = ResponseStatusUtil.isServiceDown(responseStatus);
                boolean isRerunnable = ResponseStatusUtil.isRerunnable(responseStatus);
                if (!(isServiceDown || isRerunnable))
                    return response;

                if (isServiceDown)
                    context.markUnavailable();

                _logger.info("get response failed, but can be retried. at turn: " + (i + 1) + ". responseStatus: "
                    + responseStatus);
            } catch (final Throwable e) {
                if (context != null)
                    context.markUnavailable();

                if (i < retryTimes - 1) {
                    _logger.info("get response failed in this turn: " + (i + 1), e);
                } else {
                    _logger.error("与 SOA 注册中心通信时发生错误", e);
                    throw e;
                }
            }

            ThreadExtension.sleep(_retryInterval.getValue());
        }

        throw new RuntimeException("Got failed response: " + responseStatus);
    }

    protected void logEvent(final String service, final String operation) {
        logEvent(null, service, operation);
    }

    protected void logEvent(final ResponseStatus status, final String service, final String operation) {
        final String metricId = _distributionMetricName + "|" + service + "|" + operation;
        final Map metadata = Maps.newHashMap();
        metadata.put("metric_name_distribution", _distributionMetricName);
        metadata.put("service", service);
        metadata.put("operation", operation);
        final EventMetric metric = _eventMetricManager.getMetric(metricId, new MetricConfig(metadata));
        if (status == null) {
            metric.addEvent("null");
        } else {
            metric.addEvent(status.getErrorCode());
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy