Skip to content
HttpClientWrapper.java 3.42 KiB
Newer Older
package it.inaf.ia2.gms.client.call;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpRequest.Builder;
import java.net.http.HttpResponse;
import java.util.Base64;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class HttpClientWrapper {

    private final String baseGmsUri;
    private final HttpClient client;

    private String rapBaseUrl;
    private String clientId;
    private String clientSecret;

    private String accessToken;

    public HttpClientWrapper(String baseGmsUri) {
        String uri = baseGmsUri;
        if (!uri.endsWith("/")) {
            uri += "/";
        }
        this.baseGmsUri = uri;

        this.client = HttpClient.newBuilder()
                .followRedirects(HttpClient.Redirect.ALWAYS)
                .build();
    }

    public HttpClientWrapper setAccessToken(String accessToken) {
        this.accessToken = accessToken;
        return this;
    }

    public HttpClientWrapper setRapBaseUrl(String rapBaseUrl) {
        if (!rapBaseUrl.endsWith("/")) {
            rapBaseUrl += "/";
        }
        this.rapBaseUrl = rapBaseUrl;
        return this;
    }

    public HttpClientWrapper setClientId(String clientId) {
        this.clientId = clientId;
        return this;
    }

    public HttpClientWrapper setClientSecret(String clientSecret) {
        this.clientSecret = clientSecret;
        return this;
    }

    Builder newHttpRequest(String endpoint) {
        if (accessToken == null) {
            accessToken = getAccessTokenFromClientCredentials();
        }
        return HttpRequest.newBuilder()
                .uri(URI.create(baseGmsUri + endpoint))
                .header("Authorization", "Bearer " + accessToken);
    }

    private String getAccessTokenFromClientCredentials() {
        if (rapBaseUrl == null || clientId == null || clientSecret == null) {
            throw new IllegalStateException("Access token is null and client credentials are not configured");
        }

        String basicAuthHeader = clientId + ":" + clientSecret;

        HttpRequest tokenRequest = HttpRequest.newBuilder()
                .uri(URI.create(rapBaseUrl + "auth/oauth2/token"))
                .header("Authorization", "Basic " + Base64.getEncoder().encodeToString(basicAuthHeader.getBytes()))
                .header("Accept", "application/json")
                .header("Content-Type", "application/x-www-form-urlencoded")
                .POST(HttpRequest.BodyPublishers.ofString("grant_type=client_credentials"))
                .build();

        return client.sendAsync(tokenRequest, HttpResponse.BodyHandlers.ofString())
                .thenApply(response -> {
                    if (response.statusCode() == 200) {
                        return getAccessTokenFromResponse(response.body());
                    }
                    BaseGmsCall.logServerError(tokenRequest, response);

                    throw new IllegalStateException("Unable to retrieve access token");
                }).join();
    }

    protected String getAccessTokenFromResponse(String body) {
        Pattern codePattern = Pattern.compile(".*\"access_token\":\\s*\"([^\"]+).*");
        Matcher matcher = codePattern.matcher(body);
        if (matcher.find()) {
            return matcher.group(1);
        }
        throw new IllegalStateException("Unable to extract access token from body");
    }

    HttpClient getClient() {
        return client;
    }
}