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

com.aliyun.datahub.client.http.common.HttpRequest Maven / Gradle / Ivy

The newest version!
package com.aliyun.datahub.client.http.common;

import com.aliyun.datahub.client.util.JsonUtils;
import okhttp3.*;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.aliyun.datahub.client.http.common.Constants.CONTENT_JSON;

public class HttpRequest {
    private HttpInterceptor interceptor;
    private String endpoint;
    private String path;
    private HttpMethod method;
    private Map headers = new HashMap<>();
    private Map> queryParams = new HashMap<>();

    private OkHttpClient client;
    private HttpEntity entity;
    private int maxRetryCount = 1;

    public HttpRequest(OkHttpClient client) {
        this.client = client;
    }

    public OkHttpClient getClient() { return this.client; }

    public HttpRequest interceptor(HttpInterceptor interceptor) {
        this.interceptor = interceptor;
        return this;
    }

    public HttpRequest endpoint(String endpoint) {
        this.endpoint = endpoint;
        return this;
    }

    public HttpRequest path(String path) {
        this.path = path;
        return this;
    }

    public String getPath() {
        return path;
    }

    public HttpRequest method(HttpMethod method) {
        this.method = method;
        return this;
    }

    public HttpMethod getMethod() {
        return method;
    }

    public HttpRequest header(String key, String value) {
        headers.put(key, value);
        return this;
    }

    public Map getHeaders() {
        return headers;
    }

    public HttpRequest queryParam(String key, Object value) {
        if (queryParams.containsKey(key)) {
            List values = queryParams.get(key);
            values.add(value);
        } else {
            List values = new ArrayList();
            values.add(value);
            queryParams.put(key, values);
        }
        return this;
    }

    public Map> getQueryParams() {
        return queryParams;
    }

    public HttpEntity getEntity() {
        return entity;
    }

    public HttpRequest entity(HttpEntity entity) {
        this.entity = entity;
        return this;
    }

    public HttpRequest maxRetryCount(int retryCount) {
        this.maxRetryCount = retryCount;
        return this;
    }

    public  T get(Class returnType) {
        method(HttpMethod.GET);
        return fetchResponse().getEntity(returnType);
    }

    public  T post(Class returnType) {
        method(HttpMethod.POST);
        return fetchResponse().getEntity(returnType);
    }

    public  T post(HttpEntity entity, Class returnType) {
        entity(entity);
        return post(returnType);
    }

    public  T put(Class returnType) {
        method(HttpMethod.PUT);
        return fetchResponse().getEntity(returnType);
    }

    public  T put(HttpEntity entity, Class returnType) {
        entity(entity);
        return put(returnType);
    }

    public  T delete(Class returnType) {
        method(HttpMethod.DELETE);
        return fetchResponse().getEntity(returnType);
    }

    public HttpResponse fetchResponse() {
        if (interceptor != null) {
            interceptor.preHandle(this);
        }
        HttpResponse response = executeWithRetry(maxRetryCount);
        if (interceptor != null) {
            interceptor.postHandle(response);
        }
        return response;
    }

    private HttpResponse executeWithRetry(int retryCount) {
        int count = 1;
        while (true) {
            try {
                return execute();
            } catch (IOException ex) {
                if (count >= retryCount) {
                    throw new RuntimeException("Request fail. endpoint:" + endpoint + ", error:" + ex.getMessage(), ex);
                }
                ++count;
            }
        }
    }

    private HttpResponse execute() throws IOException  {
        String url = this.endpoint;
        if (this.path != null) {
            url += this.path;
        }

        HttpUrl httpUrl = HttpUrl.parse(url);
        if (httpUrl == null) {
            throw new RuntimeException("endpoint format error. endpoint:" + endpoint);
        }
        HttpUrl.Builder urlBuilder = httpUrl.newBuilder();
        for (Map.Entry> entry : queryParams.entrySet()) {
            for (Object o : entry.getValue()) {
                String realValue = String.valueOf(o);
                urlBuilder.addQueryParameter(entry.getKey(), realValue);
            }
        }

        Request.Builder reqBuilder = new Request.Builder()
                .url(urlBuilder.build().toString());
        for (Map.Entry header : headers.entrySet()) {
            reqBuilder.addHeader(header.getKey(), header.getValue());
        }

        if (this.entity != null) {
            RequestBody reqBody = null;
            MediaType mediaType = MediaType.parse(this.entity.getContentType());

            if (CONTENT_JSON.equalsIgnoreCase(this.entity.getContentType())) {
                String jsonStr = JsonUtils.toJson(this.entity.getEntity());
                if (jsonStr == null) {
                    throw new RuntimeException("Serialize entity to json fail");
                }
                reqBody = RequestBody.create(mediaType, jsonStr);
            } else {
                HttpForm form = (HttpForm)this.entity.getEntity();
                String formStr = form != null ? form.toFormStr() : "";
                reqBody = RequestBody.create(mediaType, formStr);
            }

            if (this.method == HttpMethod.PUT) {
                reqBuilder.put(reqBody);
            } else if (this.method == HttpMethod.POST) {
                reqBuilder.post(reqBody);
            }
        } else {
            if (method == HttpMethod.DELETE) {
                reqBuilder.delete();
            } else if (method == HttpMethod.GET) {
                reqBuilder.get();
            } else if (method == HttpMethod.PUT) {
                reqBuilder.put(RequestBody.create(null, new byte[0]));
            }
        }

        Response response = client.newCall(reqBuilder.build()).execute();
        try {
            return new HttpResponse(this, response, response.body().string());
        } finally {
            response.close();
        }
    }
}