Skip to content

Commit eff5285

Browse files
author
Gerald Unterrainer
committed
done drafting the API
1 parent 2aee76d commit eff5285

File tree

14 files changed

+324
-199
lines changed

14 files changed

+324
-199
lines changed

pom.xml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
<modelVersion>4.0.0</modelVersion>
1212
<artifactId>rest-client</artifactId>
13-
<version>0.0.2</version>
13+
<version>0.0.3</version>
1414
<name>RestClient</name>
1515
<packaging>jar</packaging>
1616

@@ -22,10 +22,15 @@
2222
</properties>
2323

2424
<dependencies>
25+
<dependency>
26+
<groupId>info.unterrainer.commons</groupId>
27+
<artifactId>http-server</artifactId>
28+
<version>0.2.21</version>
29+
</dependency>
2530
<dependency>
2631
<groupId>info.unterrainer.commons</groupId>
2732
<artifactId>serialization</artifactId>
28-
<version>0.1.3</version>
33+
<version>0.1.4</version>
2934
</dependency>
3035
<dependency>
3136
<groupId>com.squareup.okhttp3</groupId>
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
package info.unterrainer.commons.restclient;
2+
3+
import java.util.HashMap;
4+
import java.util.Map;
5+
6+
import com.fasterxml.jackson.core.type.TypeReference;
7+
import com.fasterxml.jackson.databind.JavaType;
8+
9+
import info.unterrainer.commons.httpserver.jsons.ListJson;
10+
import info.unterrainer.commons.restclient.RestClient.HttpGetCall;
11+
import lombok.AccessLevel;
12+
import lombok.RequiredArgsConstructor;
13+
14+
@RequiredArgsConstructor(access = AccessLevel.PACKAGE)
15+
public abstract class BaseBuilder<T, R extends BaseBuilder<T, R>> {
16+
17+
protected enum Retry {
18+
ONCE,
19+
SHORT,
20+
ENDURING
21+
}
22+
23+
protected final RestClient client;
24+
protected final Class<?> type;
25+
26+
protected String url;
27+
protected JavaType javaType;
28+
protected TypeReference<?> typeReference;
29+
protected Map<String, String> headers = new HashMap<>();
30+
protected Retry retry = Retry.ONCE;
31+
32+
@SuppressWarnings("unchecked")
33+
public R url(final String url) {
34+
this.url = url;
35+
return (R) this;
36+
}
37+
38+
@SuppressWarnings("unchecked")
39+
public R isListJson() {
40+
javaType = client.jsonMapper.getTypeFactory().constructParametricType(ListJson.class, type);
41+
return (R) this;
42+
}
43+
44+
@SuppressWarnings("unchecked")
45+
public R addHeader(final String key, final String value) {
46+
headers.put(key, value);
47+
return (R) this;
48+
}
49+
50+
@SuppressWarnings("unchecked")
51+
public R retryShort() {
52+
retry = Retry.SHORT;
53+
return (R) this;
54+
}
55+
56+
@SuppressWarnings("unchecked")
57+
public R retryEnduring() {
58+
retry = Retry.ENDURING;
59+
return (R) this;
60+
}
61+
62+
protected abstract HttpGetCall<T> provideCall(String url, Class<T> type, Map<String, String> headers);
63+
64+
protected abstract HttpGetCall<T> provideJavaTypeCall(String url, JavaType javaType, Map<String, String> headers);
65+
66+
public T execute() {
67+
switch (retry) {
68+
case SHORT:
69+
return client.retryShort(provide(url, type, javaType, headers));
70+
case ENDURING:
71+
return client.retryEnduring(provide(url, type, javaType, headers));
72+
default:
73+
return client.once(provide(url, type, javaType, headers));
74+
}
75+
}
76+
77+
@SuppressWarnings("unchecked")
78+
private HttpGetCall<T> provide(final String url, final Class<?> type, final JavaType javaType,
79+
final Map<String, String> headers) {
80+
if (javaType != null)
81+
return provideJavaTypeCall(url, javaType, headers);
82+
return provideCall(url, (Class<T>) type, headers);
83+
}
84+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package info.unterrainer.commons.restclient;
2+
3+
import java.util.Map;
4+
5+
import com.fasterxml.jackson.databind.JavaType;
6+
7+
import info.unterrainer.commons.restclient.RestClient.HttpGetCall;
8+
9+
public class BaseGetBuilder<T, R> extends BaseBuilder<T, BaseGetBuilder<T, R>> {
10+
11+
BaseGetBuilder(final RestClient client, final Class<?> type) {
12+
super(client, type);
13+
}
14+
15+
@SuppressWarnings("unchecked")
16+
@Override
17+
protected HttpGetCall<T> provideCall(final String url, final Class<T> type, final Map<String, String> headers) {
18+
return client -> {
19+
String r = client.getPlain(url, StringParam.builder().parameters(headers).build());
20+
if (String.class.isAssignableFrom(type))
21+
return (T) r;
22+
return client.jsonMapper.fromStringTo(type, r);
23+
};
24+
}
25+
26+
@Override
27+
protected HttpGetCall<T> provideJavaTypeCall(final String url, final JavaType javaType,
28+
final Map<String, String> headers) {
29+
return client -> {
30+
String r = client.getPlain(url, StringParam.builder().parameters(headers).build());
31+
return client.jsonMapper.fromStringTo(javaType, r);
32+
};
33+
}
34+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package info.unterrainer.commons.restclient;
2+
3+
public abstract class BaseKeycloakBuilder<T, R extends BaseKeycloakBuilder<T, R>> extends BaseBuilder<T, R> {
4+
5+
private final KeycloakContext kcc;
6+
7+
BaseKeycloakBuilder(final RestClient client, final Class<?> type, final KeycloakContext kcc) {
8+
super(client, type);
9+
this.kcc = kcc;
10+
}
11+
12+
@Override
13+
public T execute() {
14+
kcc.update(client);
15+
return super.execute();
16+
}
17+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package info.unterrainer.commons.restclient;
2+
3+
import java.util.Map;
4+
5+
import com.fasterxml.jackson.databind.JavaType;
6+
7+
import info.unterrainer.commons.restclient.RestClient.HttpGetCall;
8+
9+
public class BasePostBuilder<T, R> extends BaseBuilder<T, BasePostBuilder<T, R>> {
10+
11+
protected String mediaType;
12+
protected String body;
13+
14+
BasePostBuilder(final RestClient client, final Class<?> type) {
15+
super(client, type);
16+
}
17+
18+
@SuppressWarnings("unchecked")
19+
public R mediaType(final String mediaType) {
20+
this.mediaType = mediaType;
21+
return (R) this;
22+
}
23+
24+
@SuppressWarnings("unchecked")
25+
public R body(final String body) {
26+
this.body = body;
27+
return (R) this;
28+
}
29+
30+
@SuppressWarnings("unchecked")
31+
@Override
32+
protected HttpGetCall<T> provideCall(final String url, final Class<T> type, final Map<String, String> headers) {
33+
return client -> {
34+
String r = client.postPlain(url, StringParam.builder().parameters(headers).build(), mediaType, body);
35+
if (String.class.isAssignableFrom(type))
36+
return (T) r;
37+
return client.jsonMapper.fromStringTo(type, r);
38+
};
39+
}
40+
41+
@Override
42+
protected HttpGetCall<T> provideJavaTypeCall(final String url, final JavaType javaType,
43+
final Map<String, String> headers) {
44+
return client -> {
45+
String r = client.postPlain(url, StringParam.builder().parameters(headers).build(), mediaType, body);
46+
return client.jsonMapper.fromStringTo(javaType, r);
47+
};
48+
}
49+
}
Lines changed: 3 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,8 @@
11
package info.unterrainer.commons.restclient;
22

3-
import java.io.IOException;
4-
import java.util.HashMap;
5-
import java.util.Map;
3+
public class GetBuilder<T> extends BaseGetBuilder<T, GetBuilder<T>> {
64

7-
import lombok.AccessLevel;
8-
import lombok.RequiredArgsConstructor;
9-
10-
@RequiredArgsConstructor(access = AccessLevel.PACKAGE)
11-
public class GetBuilder<T> {
12-
13-
private enum Retry {
14-
ONCE,
15-
SHORT,
16-
ENDURING
17-
}
18-
19-
private final RestClient client;
20-
private final KeycloakContext kcc;
21-
22-
private String url;
23-
private Class<T> type;
24-
private Map<String, String> headers = new HashMap<>();
25-
private Retry retry = Retry.ONCE;
26-
27-
public GetBuilder<T> url(final String url) {
28-
this.url = url;
29-
return this;
30-
}
31-
32-
public GetBuilder<T> type(final Class<T> type) {
33-
this.type = type;
34-
return this;
35-
}
36-
37-
public GetBuilder<T> addHeader(final String key, final String value) {
38-
headers.put(key, value);
39-
return this;
40-
}
41-
42-
public GetBuilder<T> retryShort() {
43-
retry = Retry.SHORT;
44-
return this;
45-
}
46-
47-
public GetBuilder<T> retryEnduring() {
48-
retry = Retry.ENDURING;
49-
return this;
50-
}
51-
52-
public T execute() throws IOException {
53-
kcc.update(client);
54-
switch (retry) {
55-
case SHORT:
56-
client.retryShort(
57-
client -> client.get(url, type, StringParam.builder().parameters(headers).build()));
58-
case ENDURING:
59-
client.retryEnduring(
60-
client -> client.get(url, type, StringParam.builder().parameters(headers).build()));
61-
default:
62-
return client
63-
.once(client -> client.get(url, type, StringParam.builder().parameters(headers).build()));
64-
}
5+
GetBuilder(final RestClient client, final Class<?> type) {
6+
super(client, type);
657
}
668
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package info.unterrainer.commons.restclient;
2+
3+
public class GetKeycloakBuilder<T> extends BaseGetBuilder<T, GetKeycloakBuilder<T>> {
4+
5+
private KeycloakContext kcc;
6+
7+
GetKeycloakBuilder(final RestClient client, final Class<?> type, final KeycloakContext kcc) {
8+
super(client, type);
9+
this.kcc = kcc;
10+
}
11+
12+
@Override
13+
public T execute() {
14+
kcc.update(client);
15+
addHeader("Authorization", "Bearer " + kcc.getAccessToken());
16+
return super.execute();
17+
}
18+
}

src/main/java/info/unterrainer/commons/restclient/KeycloakContext.java

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package info.unterrainer.commons.restclient;
22

3-
import java.io.IOException;
43
import java.io.UnsupportedEncodingException;
54
import java.net.URLEncoder;
65

@@ -25,12 +24,12 @@ public class KeycloakContext {
2524
@Getter
2625
private Long refreshTimestamp;
2726

28-
public <T> GetBuilder<T> get(final RestClient client) {
29-
return new GetBuilder<>(client, this);
27+
public <T> GetKeycloakBuilder<T> get(final RestClient client, final Class<?> type) {
28+
return new GetKeycloakBuilder<>(client, type, this);
3029
}
3130

32-
public <T> PostBuilder<T> post(final RestClient client) {
33-
return new PostBuilder<>(client, this);
31+
public <T> PostKeycloakBuilder<T> post(final RestClient client, final Class<?> type) {
32+
return new PostKeycloakBuilder<>(client, type, this);
3433
}
3534

3635
void update(final RestClient client) {
@@ -73,17 +72,17 @@ void update(final RestClient client) {
7372
log.debug("body: [{}]", body);
7473

7574
TokenResponseJson response = null;
76-
try {
77-
response = client.post(keycloakUrl, TokenResponseJson.class,
78-
StringParam.builder()
79-
.parameter("Content-Type", "application/x-www-form-urlencoded")
80-
.parameter("Accept", "application/json")
81-
.build(),
82-
"application/x-www-form-urlencoded", body);
83-
} catch (IOException e) {
84-
log.error("Error getting tokens from keycloak.");
75+
response = client.<TokenResponseJson>post(TokenResponseJson.class)
76+
.addHeader("Content-Type", "application/x-www-form-urlencoded")
77+
.addHeader("Accept", "application/json")
78+
.url(keycloakUrl)
79+
.retryShort()
80+
.mediaType("application/x-www-form-urlencoded")
81+
.body(body)
82+
.execute();
83+
if (response == null)
8584
return;
86-
}
85+
8786
accessToken = response.getAccessToken();
8887
refreshToken = response.getRefreshToken();
8988
refreshTimestamp = now + response.getExpiresIn() * 1000L;

0 commit comments

Comments
 (0)