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

io.github.juniqlim.apicall.http.RestTemplateHttpApiCall Maven / Gradle / Ivy

There is a newer version: 0.0.14
Show newest version
package io.github.juniqlim.apicall.http;

import com.fasterxml.jackson.databind.ObjectMapper;
import io.github.juniqlim.apicall.http.logging.HttpLogging;
import io.github.juniqlim.apicall.http.logging.HttpLogging.SystemOutPrintHttpLogging;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;

/**
 * interface
 */
@Slf4j
public class RestTemplateHttpApiCall implements HttpApiCall {
    private final RestTemplate restTemplate;
    private final ObjectMapper objectMapper;
    private final HttpLogging httpLogging;

    private RestTemplateHttpApiCall(RestTemplate restTemplate, ObjectMapper objectMapper, HttpLogging httpLogging) {
        this.restTemplate = restTemplate;
        this.objectMapper = objectMapper;
        this.httpLogging = httpLogging;
    }

    public static RestTemplateHttpApiCall of(RestTemplate restTemplate, ObjectMapper objectMapper) {
        return new RestTemplateHttpApiCall(restTemplate, objectMapper, new SystemOutPrintHttpLogging());
    }

    public static RestTemplateHttpApiCall of(RestTemplate restTemplate, ObjectMapper objectMapper, HttpLogging httpLogging) {
        return new RestTemplateHttpApiCall(restTemplate, objectMapper, httpLogging);
    }

    @Override
    public  S callApi(HttpRequest request) {
        return run(request.httpMethod(), request.url(), request.header(), request.request(), request.responseType());
    }

    @Override
    public  void callApi(HttpRequestWithoutResponse response) {
        runWithoutResponse(response.httpMethod(), response.url(), response.header(), response.request());
    }

    private  S run(HttpMethod httpMethod, String url, Map header, Q request, Class clazz) {
        HttpResponse response = sendHttpRequest(httpMethod, url, header, request);
        log(HttpApiCallResult.of(httpMethod, url, header, request, response));
        return parseResponseBody(response.body(), clazz);
    }

    private  void runWithoutResponse(HttpMethod httpMethod, String url, Map header, Q request) {
        HttpResponse response = sendHttpRequest(httpMethod, url, header, request);
        log(HttpApiCallResult.of(httpMethod, url, header, request, response));
    }

    private void log(HttpApiCallResult httpMethod) {
        if (httpMethod.response().isError()) {
            httpLogging.errorLog(httpMethod);
            throw new HttpApiCallException(httpMethod.response(),
                "Http request call exception - status: " + httpMethod.response().httpStatus() + ", response: "
                    + httpMethod.response().body());
        }
        httpLogging.infoLog(httpMethod);
    }

    private HttpResponse sendHttpRequest(HttpMethod httpMethod, String url, Map header,
        Object request) {
        try {
            ResponseEntity response = restTemplate.exchange(url, httpMethod,
                new HttpEntity<>(request, makeHeader(header)), String.class);
            return HttpResponse.of(response.getStatusCode(), response.getBody());
        } catch (HttpClientErrorException e) {
            return HttpResponse.of(e.getStatusCode(), e.getResponseBodyAsString());
        }
    }

    private MultiValueMap makeHeader(Map header) {
        MultiValueMap result = new LinkedMultiValueMap<>();
        result.setAll(header);
        return result;
    }

    @SuppressWarnings("unchecked")
    private  S parseResponseBody(String responseBody, Class clazz) {
        if (clazz == String.class) {
            return (S) responseBody;
        }
        return ResponseBodyParser.of(objectMapper).parse(responseBody, clazz);
    }
}