Redesign OkHttpClientFactory:
[arvados.git] / sdk / java-v2 / src / main / java / org / arvados / client / api / client / BaseApiClient.java
1 /*
2  * Copyright (C) The Arvados Authors. All rights reserved.
3  *
4  * SPDX-License-Identifier: AGPL-3.0 OR Apache-2.0
5  *
6  */
7
8 package org.arvados.client.api.client;
9
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;
20
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;
26
27 abstract class BaseApiClient {
28
29     static final ObjectMapper MAPPER = new ObjectMapper().findAndRegisterModules();
30
31     final OkHttpClient client;
32     final ConfigProvider config;
33     private final Logger log = org.slf4j.LoggerFactory.getLogger(BaseApiClient.class);
34
35     BaseApiClient(ConfigProvider config) {
36         this.config = config;
37         this.client = OkHttpClientFactory.INSTANCE.create(config.isApiHostInsecure());
38     }
39
40     Request.Builder getRequestBuilder() {
41         return new Request.Builder()
42                 .addHeader("authorization", String.format("OAuth2 %s", config.getApiToken()))
43                 .addHeader("cache-control", "no-cache");
44     }
45
46     String newCall(Request request) {
47         return (String) getResponseBody(request, body -> body.string().trim());
48     }
49
50     byte[] newFileCall(Request request) {
51         return (byte[]) getResponseBody(request, ResponseBody::bytes);
52     }
53
54     private Object getResponseBody(Request request, Command command) {
55         try {
56             log.debug(URLDecoder.decode(request.toString(), StandardCharsets.UTF_8.name()));
57         } catch (UnsupportedEncodingException e) {
58             throw new ArvadosApiException(e);
59         }
60
61         try (Response response = client.newCall(request).execute()) {
62             ResponseBody responseBody = response.body();
63
64             if (!response.isSuccessful()) {
65                 String errorBody = Objects.requireNonNull(responseBody).string();
66                 if (errorBody == null || errorBody.length() == 0) {
67                     throw new ArvadosApiException(String.format("Error code %s with message: %s", response.code(), response.message()));
68                 }
69                 ApiError apiError = MAPPER.readValue(errorBody, ApiError.class);
70                 throw new ArvadosApiException(String.format("Error code %s with messages: %s", response.code(), apiError.getErrors()));
71             }
72             return command.readResponseBody(responseBody);
73         } catch (IOException e) {
74             throw new ArvadosApiException(e);
75         }
76     }
77
78     private interface Command {
79         Object readResponseBody(ResponseBody body) throws IOException;
80     }
81 }