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.core.JsonProcessingException;
11 import com.fasterxml.jackson.core.type.TypeReference;
12 import com.fasterxml.jackson.databind.ObjectWriter;
13 import okhttp3.MediaType;
14 import okhttp3.HttpUrl;
15 import okhttp3.HttpUrl.Builder;
16 import okhttp3.Request;
17 import okhttp3.RequestBody;
18 import org.arvados.client.exception.ArvadosApiException;
19 import org.arvados.client.api.model.Item;
20 import org.arvados.client.api.model.ItemList;
21 import org.arvados.client.api.model.argument.ListArgument;
22 import org.arvados.client.config.ConfigProvider;
23 import org.slf4j.Logger;
25 import java.io.IOException;
28 public abstract class BaseStandardApiClient<T extends Item, L extends ItemList> extends BaseApiClient {
30 protected static final MediaType JSON = MediaType.parse(com.google.common.net.MediaType.JSON_UTF_8.toString());
31 private final Logger log = org.slf4j.LoggerFactory.getLogger(BaseStandardApiClient.class);
33 BaseStandardApiClient(ConfigProvider config) {
37 public L list(ListArgument listArguments) {
38 log.debug("Get list of {}", getType().getSimpleName());
39 Builder urlBuilder = getUrlBuilder();
40 addQueryParameters(urlBuilder, listArguments);
41 HttpUrl url = urlBuilder.build();
42 Request request = getRequestBuilder().url(url).build();
43 return callForList(request);
47 return list(ListArgument.builder().build());
50 public T get(String uuid) {
51 log.debug("Get {} by UUID {}", getType().getSimpleName(), uuid);
52 HttpUrl url = getUrlBuilder().addPathSegment(uuid).build();
53 Request request = getRequestBuilder().get().url(url).build();
54 return callForType(request);
57 public T create(T type) {
58 log.debug("Create {}", getType().getSimpleName());
59 String json = mapToJson(type);
60 RequestBody body = RequestBody.create(JSON, json);
61 Request request = getRequestBuilder().post(body).build();
62 return callForType(request);
65 public T delete(String uuid) {
66 log.debug("Delete {} by UUID {}", getType().getSimpleName(), uuid);
67 HttpUrl url = getUrlBuilder().addPathSegment(uuid).build();
68 Request request = getRequestBuilder().delete().url(url).build();
69 return callForType(request);
72 public T update(T type) {
73 String uuid = type.getUuid();
74 log.debug("Update {} by UUID {}", getType().getSimpleName(), uuid);
75 String json = mapToJson(type);
76 RequestBody body = RequestBody.create(JSON, json);
77 HttpUrl url = getUrlBuilder().addPathSegment(uuid).build();
78 Request request = getRequestBuilder().put(body).url(url).build();
79 return callForType(request);
83 Request.Builder getRequestBuilder() {
84 return super.getRequestBuilder().url(getUrlBuilder().build());
87 HttpUrl.Builder getUrlBuilder() {
88 return new HttpUrl.Builder()
89 .scheme(config.getApiProtocol())
90 .host(config.getApiHost())
91 .port(config.getApiPort())
92 .addPathSegment("arvados")
94 .addPathSegment(getResource());
97 <TL> TL call(Request request, Class<TL> cls) {
98 String bodyAsString = newCall(request);
100 return mapToObject(bodyAsString, cls);
101 } catch (IOException e) {
102 throw new ArvadosApiException("A problem occurred while parsing JSON data", e);
106 private <TL> TL mapToObject(String content, Class<TL> cls) throws IOException {
107 return MAPPER.readValue(content, cls);
110 protected <TL> String mapToJson(TL type) {
111 ObjectWriter writer = MAPPER.writer().withDefaultPrettyPrinter();
113 return writer.writeValueAsString(type);
114 } catch (JsonProcessingException e) {
115 log.error(e.getMessage());
120 T callForType(Request request) {
121 return call(request, getType());
124 L callForList(Request request) {
125 return call(request, getListType());
128 abstract String getResource();
130 abstract Class<T> getType();
132 abstract Class<L> getListType();
134 Request getNoArgumentMethodRequest(String method) {
135 HttpUrl url = getUrlBuilder().addPathSegment(method).build();
136 return getRequestBuilder().get().url(url).build();
139 RequestBody getJsonRequestBody(Object object) {
140 return RequestBody.create(JSON, mapToJson(object));
143 void addQueryParameters(Builder urlBuilder, Object object) {
144 Map<String, Object> queryMap = MAPPER.convertValue(object, new TypeReference<Map<String, Object>>() {});
145 queryMap.keySet().forEach(key -> {
146 Object type = queryMap.get(key);
147 if (!(type instanceof String)) {
148 type = mapToJson(type);
150 urlBuilder.addQueryParameter(key, (String) type);