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

io.alapierre.ksef.client.http.HttpApiClient Maven / Gradle / Ivy

There is a newer version: 2.0.24
Show newest version
package io.alapierre.ksef.client.http;

import io.alapierre.io.IOUtils;
import io.alapierre.ksef.client.AbstractApiClient;
import io.alapierre.ksef.client.ApiException;
import io.alapierre.ksef.client.JsonSerializer;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.jetbrains.annotations.NotNull;

import javax.xml.bind.JAXBException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.*;

/**
 * @author Karol Bryzgiel {@literal [email protected]}
 * Copyrights by original author 2022.04.24
 */
@Slf4j
public class HttpApiClient extends AbstractApiClient {

    private final HttpClient client = HttpClient.newHttpClient();

    public HttpApiClient(JsonSerializer serializer) {
        super(serializer);
    }

    public HttpApiClient(String url, JsonSerializer serializer) {
        super(serializer, url);
    }

    @Override
    public  Optional getJson(@NotNull String endpoint, @NotNull Class classOfR, @NotNull String token) throws ApiException {
        HttpRequest request = prepareGetRequest(endpoint, Map.of(TOKEN_HEADER_NAME, token));
        return callAndReturnJson(classOfR, request);
    }

    @Override
    public  Optional getJson(@NotNull String endpoint, @NotNull Class classOfR) throws ApiException {
        HttpRequest request = prepareGetRequest(endpoint, Collections.emptyMap());
        return callAndReturnJson(classOfR, request);
    }

    @Override
    public  Optional postJson(@NotNull String endpoint, @NotNull B body, @NotNull Class classOfR) throws ApiException {
        HttpRequest request = preparePostRequest(endpoint, Collections.emptyMap(), HttpRequest.BodyPublishers.ofString(serializer.toJson(body)), true);
        return callAndReturnJson(classOfR, request);
    }

    @Override
    public  Optional postJson(@NotNull String endpoint, @NotNull B body, @NotNull Class classOfR, @NotNull String token) throws ApiException {
        HttpRequest request = preparePostRequest(endpoint, Map.of(TOKEN_HEADER_NAME, token), HttpRequest.BodyPublishers.ofString(serializer.toJson(body)), true);
        return callAndReturnJson(classOfR, request);
    }

    @Override
    public  Optional putJson(@NotNull String endpoint, @NotNull B body, @NotNull Class classOfR, @NotNull String token) throws ApiException {
        HttpRequest request = preparePostRequest(endpoint, Map.of(TOKEN_HEADER_NAME, token), HttpRequest.BodyPublishers.ofString(serializer.toJson(body)), false);
        return callAndReturnJson(classOfR, request);
    }

    @Override
    public  Optional postXMLFromBytes(@NotNull String endpoint, byte[] body, @NotNull Class classOfR) throws ApiException {
        HttpRequest request = preparePostRequest(endpoint, Collections.emptyMap(), HttpRequest.BodyPublishers.ofByteArray(body), false);
        return callAndReturnJson(classOfR, request);
    }

    @Override
    public  Optional postXMLFromBytes(@NotNull String endpoint, byte[] body, @NotNull Class classOfR, @NotNull String token) throws ApiException {
        HttpRequest request = preparePostRequest(endpoint, Map.of(TOKEN_HEADER_NAME, token), HttpRequest.BodyPublishers.ofByteArray(body), false);
        return callAndReturnJson(classOfR, request);
    }

    @Override
    public  Optional postXML(@NotNull String endpoint, @NotNull Object body, @NotNull Class classOfR) throws ApiException {
        try {
            HttpRequest request = preparePostRequest(endpoint, Collections.emptyMap(), HttpRequest.BodyPublishers.ofByteArray(marshalXML(body)), false);
            return callAndReturnJson(classOfR, request);
        } catch (JAXBException e) {
            throw new ApiException("Błąd wywołania API", e);
        }
    }

    @Override
    public void getStream(@NotNull String endpoint, @NotNull String token, @NotNull OutputStream os) throws ApiException {
        HttpRequest request = prepareGetRequest(endpoint, Collections.emptyMap());

        try {
            HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofInputStream());
            if (response.body() != null) { // TODO: sprawdzić czy to jest potrzebne
                try (InputStream is = response.body()) {
                    IOUtils.copy(is, os);
                }
            }
        } catch (IOException | InterruptedException e) {
            throw new ApiException(e);
        }

        throw new IllegalStateException("Not implemented yet");
    }

    private HttpRequest prepareGetRequest(@NotNull String endpoint, @NotNull Map headers) throws ApiException {
        List headersList = prepareHeaders(headers);
        URI uri = prepareURI(endpoint);
        return HttpRequest.newBuilder()
                .uri(uri)
                .headers(headersList.toArray(new String[0]))
                .GET()
                .build();
    }


    private HttpRequest preparePostRequest(@NotNull String endpoint,
                                           @NotNull Map headers,
                                           @NotNull HttpRequest.BodyPublisher bodyPublisher,
                                           boolean post) throws ApiException {
        List headersList = prepareHeaders(headers);
        URI uri = prepareURI(endpoint);

        HttpRequest.Builder httpRequestBuilder = HttpRequest.newBuilder()
                .uri(uri)
                .headers(headersList.toArray(new String[0]));

        if (post) {
            httpRequestBuilder.POST(bodyPublisher);
        } else {
            httpRequestBuilder.PUT(bodyPublisher);
        }
        return httpRequestBuilder.build();
    }

    private URI prepareURI(@NotNull String endpoint) throws ApiException {
        String url = createUrl(endpoint);
        try {
            return new URI(url);
        } catch (URISyntaxException e) {
            log.error("URL {} is a malformed URL", url, e);
            throw new ApiException(e);
        }
    }

    private List prepareHeaders(@NotNull Map headers) {
        List headersList = new LinkedList<>();
        headers.forEach((k, v) -> {
            headersList.add(k);
            headersList.add(v);
        });
        return headersList;
    }

    private  Optional callAndReturnJson(@NotNull Class classOfR, @NotNull HttpRequest request) throws ApiException {
        try {
            HttpResponse> req = client.send(request, new JsonBodyHandler<>(classOfR, serializer));
            if (req.statusCode() != 200) {
                throw createException(req);
            }
            return req.body();
        } catch (IOException | InterruptedException e) {
            throw new ApiException(e);
        }
    }

    protected ApiException createException(@NotNull HttpResponse response) {

        val responseBody = response.body();

        String body;
        body = responseBody != null ? responseBody.toString() : null;
        log.debug("responseBody: {}", body);

        val headers = response.headers().map();
        log.debug("headers: {}", headers);

        return mapHttpResponseStatusToException(response.statusCode(), HttpStatus.valueOf(response.statusCode()).getMessage(), headers, body);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy