2 * Copyright (C) The Arvados Authors. All rights reserved.
4 * SPDX-License-Identifier: AGPL-3.0 OR Apache-2.0
8 package org.arvados.client.api.client;
10 import com.fasterxml.jackson.databind.ObjectMapper;
11 import org.arvados.client.exception.ArvadosApiException;
12 import org.arvados.client.api.client.factory.OkHttpClientFactory;
13 import org.arvados.client.api.model.ApiError;
14 import org.arvados.client.config.ConfigProvider;
15 import okhttp3.OkHttpClient;
16 import okhttp3.Request;
17 import okhttp3.Response;
18 import okhttp3.ResponseBody;
19 import org.slf4j.Logger;
21 import java.io.IOException;
22 import java.io.UnsupportedEncodingException;
23 import java.net.URLDecoder;
24 import java.nio.charset.StandardCharsets;
25 import java.util.Objects;
27 abstract class BaseApiClient {
29 static final ObjectMapper MAPPER = new ObjectMapper().findAndRegisterModules();
31 final OkHttpClient client;
32 final ConfigProvider config;
33 private final Logger log = org.slf4j.LoggerFactory.getLogger(BaseApiClient.class);
35 BaseApiClient(ConfigProvider config) {
37 client = OkHttpClientFactory.builder()
39 .create(config.isApiHostInsecure());
42 Request.Builder getRequestBuilder() {
43 return new Request.Builder()
44 .addHeader("authorization", String.format("OAuth2 %s", config.getApiToken()))
45 .addHeader("cache-control", "no-cache");
48 String newCall(Request request) {
49 return (String) getResponseBody(request, body -> body.string().trim());
52 byte[] newFileCall(Request request) {
53 return (byte[]) getResponseBody(request, ResponseBody::bytes);
56 private Object getResponseBody(Request request, Command command) {
58 log.debug(URLDecoder.decode(request.toString(), StandardCharsets.UTF_8.name()));
59 } catch (UnsupportedEncodingException e) {
60 throw new ArvadosApiException(e);
63 try (Response response = client.newCall(request).execute()) {
64 ResponseBody responseBody = response.body();
66 if (!response.isSuccessful()) {
67 String errorBody = Objects.requireNonNull(responseBody).string();
68 if (errorBody == null || errorBody.length() == 0) {
69 throw new ArvadosApiException(String.format("Error code %s with message: %s", response.code(), response.message()));
71 ApiError apiError = MAPPER.readValue(errorBody, ApiError.class);
72 throw new ArvadosApiException(String.format("Error code %s with messages: %s", response.code(), apiError.getErrors()));
74 return command.readResponseBody(responseBody);
75 } catch (IOException e) {
76 throw new ArvadosApiException(e);
80 private interface Command {
81 Object readResponseBody(ResponseBody body) throws IOException;