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

com.github.gcauchis.scalablepress4j.api.AbstractRestApi Maven / Gradle / Ivy

/**
 * The MIT License (MIT)
 *
 * Copyright (c) 2016 Gabriel Cauchis
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
package com.github.gcauchis.scalablepress4j.api;

import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import org.apache.commons.codec.binary.Base64;
import org.apache.http.Header;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicHeader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.DefaultResponseErrorHandler;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.gcauchis.scalablepress4j.ScalablePressBadRequestException;
import com.github.gcauchis.scalablepress4j.model.Error;
import com.github.gcauchis.scalablepress4j.model.ErrorResponse;
import com.github.gcauchis.scalablepress4j.model.PaginatedResult;

public abstract class AbstractRestApi {

    /** The default items per page number. */
    public static final int DEFAULT_LIMIT = 50;
    protected final Logger log = LoggerFactory.getLogger(getClass());

    /** The base url */
    private String baseUrl;
    /** The basic auth */
    private String basicAuth;
    /** The rest template */
    private RestTemplate restTemplate;
    /** The json object mapper */
    private ObjectMapper objectMapper = new ObjectMapper();
    /** Items per page. Defaults to 50. */
    private int limit = DEFAULT_LIMIT;

    private RestTemplate getRestTemplate() {
        if (restTemplate == null) {
            restTemplate = new RestTemplate(new HttpComponentsClientHttpRequestFactory(HttpClientBuilder.create()
                                    .setDefaultHeaders(Arrays.asList(getBasicAuthenticateHeader()))
                                    .build()));
            restTemplate.setErrorHandler(new DefaultResponseErrorHandler() {

                @Override
                public void handleError(ClientHttpResponse response) throws IOException {
                    log.error("Response error: {} {}", response.getStatusCode(), response.getStatusText());
                    ErrorResponse errorResponse = null;
                    try {
                        errorResponse = objectMapper.readValue(response.getBody(), ErrorResponse.class);
                    } catch (IOException ioe) {
                        log.error("Fail to parse error", ioe);
                    }
                    if (errorResponse != null) {
                        log.error("Response error object: {}", errorResponse);
                        throw new ScalablePressBadRequestException(errorResponse);
                    }

                    super.handleError(response);
                }
            });
        }
        return restTemplate;
    }

    private Header getBasicAuthenticateHeader() {
        if (basicAuth != null) {
            byte[] encodedAuth = Base64.encodeBase64(basicAuth.getBytes(Charset.forName("US-ASCII")));
            return new BasicHeader("Authorization", "Basic " + new String(encodedAuth));
        }
        return null;
    }

    public String getBaseUrl() {
        return baseUrl;
    }

    public void setBaseUrl(String baseUrl) {
        this.baseUrl = baseUrl;
    }

    public String getBasicAuth() {
        return basicAuth;
    }

    public void setBasicAuth(String basicAuth) {
        this.basicAuth = basicAuth;
        restTemplate = null;
    }

    public ObjectMapper getObjectMapper() {
        return objectMapper;
    }

    public void setObjectMapper(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }

    public int getLimit() {
        return limit;
    }

    public void setLimit(int limit) {
        this.limit = limit;
    }
    
    private String preparePaginatedUrl(String url, int page) {
        if (page < 1) {
            ErrorResponse errorResponse = new ErrorResponse();
            errorResponse.setStatusCode("500");
            Error error = new Error();
            error.setCode("");
            error.setMessage("Page number cannot be less than 1.");
            errorResponse.setIssues(Arrays.asList(error));
            throw new ScalablePressBadRequestException(errorResponse);
        }
        int argSeparatorIndex = url.indexOf("?");
        if (argSeparatorIndex < 0) {
            url += "?";
        } else if (argSeparatorIndex < url.length() - 1) {
            url += "&";
        }
        url += "page=" + page;
        if (limit != DEFAULT_LIMIT) {
            url += "&limit=" + limit;
        }
        return url;
    }
    
    private  PaginatedResult buildPaginatedResult(ResponseEntity resultEntity, int page) {
        PaginatedResult paginatedResult = new PaginatedResult();
        paginatedResult.setResult(resultEntity.getBody());
        paginatedResult.setPageNumber(page);
        paginatedResult.setLimit(limit);
        HttpHeaders headers = resultEntity.getHeaders();
        List xspPages = headers.get("X-SP-Pages");
        if (xspPages != null && !xspPages.isEmpty())
            paginatedResult.setPagesCount(Integer.parseInt(xspPages.get(0).toString()));
        List xspCount = headers.get("X-SP-Count");
        if (xspCount != null && !xspCount.isEmpty())
            paginatedResult.setItemsCount(Integer.parseInt(xspCount.get(0).toString()));
        return paginatedResult;
    }

    protected  T get(String url, Class responseType) throws RestClientException {
        log.trace("Call GET for: {}, to url: {}", responseType.toString(), url);
        return getRestTemplate().getForEntity(baseUrl + url, responseType).getBody();
    }
    
    protected  PaginatedResult get(String url, int page, Class responseType) throws RestClientException {
        log.trace("Call GET page {} for: {}, to url: {}", page, responseType.toString(), url);
        return buildPaginatedResult(getRestTemplate().getForEntity(preparePaginatedUrl(baseUrl + url, page), responseType), page);
    }

    protected  T get(String url, Class responseType, Map urlVariables) throws RestClientException {
        log.trace("Call GET for: {}, to url: {}, with var: {}", responseType.toString(), url, urlVariables);
        return getRestTemplate().getForEntity(baseUrl + url, responseType, urlVariables).getBody();
    }
    
    protected  PaginatedResult get(String url, int page, Class responseType, Map urlVariables) throws RestClientException {
        log.trace("Call GET page {} for: {}, to url: {}, with var: {}", page, responseType.toString(), url, urlVariables);
        return buildPaginatedResult(getRestTemplate().getForEntity(preparePaginatedUrl(baseUrl + url, page), responseType, urlVariables), page);
    }

    protected  T post(String url, Object request, Class responseType) throws RestClientException {
        log.trace("Call POST for: {}, to url: {}, with req {}", responseType.toString(), url, request);
        return getRestTemplate().postForEntity(baseUrl + url, request, responseType).getBody();
    }

    protected  PaginatedResult post(String url, int page, Object request, Class responseType) throws RestClientException {
        log.trace("Call POST page {} for: {}, to url: {}, with req {}", page, responseType.toString(), url, request);
        return buildPaginatedResult(getRestTemplate().postForEntity(preparePaginatedUrl(baseUrl + url, page), request, responseType), page);
    }

    protected  T delete(String url, Class responseType) throws RestClientException {
        log.trace("Call DELETE for: {}, to url: {}", responseType.toString(), url);
        return getRestTemplate().exchange(baseUrl + url, HttpMethod.DELETE, null, responseType).getBody();
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy