1 package fr.tiogars.chat.client;
2
3 import java.io.IOException;
4 import java.net.URI;
5 import java.net.http.HttpClient;
6 import java.net.http.HttpRequest;
7 import java.net.http.HttpResponse;
8 import java.util.List;
9 import com.fasterxml.jackson.databind.ObjectMapper;
10 import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
11
12
13 public abstract class TaxonomyClient<T, C, U> {
14 private final URI baseUri;
15 private final String path;
16 private final Class<T> type;
17 private final HttpClient httpClient;
18 private final ObjectMapper mapper;
19
20 protected TaxonomyClient(URI baseUri, String path, Class<T> type) {
21 this(baseUri, path, type, HttpClient.newHttpClient(), new ObjectMapper().registerModule(new JavaTimeModule())
22 .disable(com.fasterxml.jackson.databind.SerializationFeature.WRITE_DATES_AS_TIMESTAMPS));
23 }
24
25 protected TaxonomyClient(URI baseUri, String path, Class<T> type, HttpClient httpClient, ObjectMapper mapper) {
26 this.baseUri = baseUri;
27 this.path = path;
28 this.type = type;
29 this.httpClient = httpClient;
30 this.mapper = mapper;
31 }
32
33 public T create(C request) throws IOException, InterruptedException {
34 return mapper.readValue(send("", "POST", request, 201), type);
35 }
36
37 public T update(long id, U request) throws IOException, InterruptedException {
38 return mapper.readValue(send("/" + id, "PUT", request, 200), type);
39 }
40
41 public T findById(long id) throws IOException, InterruptedException {
42 return mapper.readValue(send("/" + id, "GET", null, 200), type);
43 }
44
45 public List<T> findAll() throws IOException, InterruptedException {
46 return mapper.readValue(send("", "GET", null, 200), mapper.getTypeFactory().constructCollectionType(List.class, type));
47 }
48
49 public void delete(long id) throws IOException, InterruptedException {
50 send("/" + id, "DELETE", null, 204);
51 }
52
53 private String send(String suffix, String method, Object body, int expectedStatus) throws IOException, InterruptedException {
54 var publisher = body == null ? HttpRequest.BodyPublishers.noBody()
55 : HttpRequest.BodyPublishers.ofString(mapper.writeValueAsString(body));
56 var request = HttpRequest.newBuilder(baseUri.resolve(path + suffix)).header("Accept", "application/json")
57 .header("Content-Type", "application/json").method(method, publisher).build();
58 var response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
59 if (response.statusCode() != expectedStatus) {
60 throw new TaskException("Expected HTTP " + expectedStatus + " but received " + response.statusCode());
61 }
62 return response.body();
63 }
64 }