Skip to content

Commit 79ef706

Browse files
authored
Merge pull request #1 from taboola/get-response-header
Get response header
2 parents bbf5cdc + df4088a commit 79ef706

File tree

11 files changed

+151
-57
lines changed

11 files changed

+151
-57
lines changed

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
## Rest API SDK Core
22

33
[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.taboola/api-java-client-core/badge.svg?style=plastic)](https://maven-badges.herokuapp.com/maven-central/com.taboola/api-java-client-core)
4-
[![Build Status](https://travis-ci.org/taboola/api-java-client-core.svg?branch=master)](https://travis-ci.org/taboola/api-java-client-core)
4+
[![Build Status](https://travis-ci.com/taboola/api-java-client-core.svg?branch=master)](https://travis-ci.com/taboola/api-java-client-core)
55

66
### Table of Contents
77
1. [Getting Started](#1-getting-started)
@@ -17,7 +17,7 @@ Easily create Rest API clients by defining endpoint mappings and models that is
1717
First you will need _RestAPIClient.java_ object
1818
```
1919
RestAPIClient restClient = RestAPIClient.builder()
20-
.setBaseUrl('your_base_url')
20+
.setBaseUrl("your_base_url")
2121
.build();
2222
```
2323

@@ -29,9 +29,9 @@ public class EntityModelExample {
2929
private String name;
3030
3131
public String getId() { return id; }
32-
public String setId(String id) { this.id = id; }
32+
public void setId(String id) { this.id = id; }
3333
public String getName() { return name; }
34-
public String setName(String name) { this.name = name; }
34+
public void setName(String name) { this.name = name; }
3535
}
3636
3737
public interface EntityModelEndpoint {

src/main/java/com/taboola/rest/api/RestAPIClient.java

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,13 @@
1313
import com.taboola.rest.api.exceptions.factories.DefaultExceptionFactory;
1414
import com.taboola.rest.api.exceptions.factories.ExceptionFactory;
1515
import com.taboola.rest.api.internal.CommunicationFactory;
16+
import com.taboola.rest.api.internal.StringResponseFactories;
1617
import com.taboola.rest.api.internal.config.CommunicationConfig;
1718
import com.taboola.rest.api.internal.config.SerializationConfig;
1819
import com.taboola.rest.api.internal.config.UserAgentHeader;
1920
import com.taboola.rest.api.internal.serialization.SerializationMapperCreator;
2021
import com.taboola.rest.api.model.RequestHeader;
22+
import com.taboola.rest.api.model.StringResponseFactory;
2123

2224
/**
2325
* Created by vladi.m
@@ -69,6 +71,7 @@ public static class RestAPIClientBuilder {
6971
private String restAPIVersion;
7072
private ExceptionFactory exceptionFactory;
7173
private ObjectMapper objectMapper;
74+
private final StringResponseFactories stringResponseFactories = new StringResponseFactories();
7275

7376
public RestAPIClientBuilder setBaseUrl(String baseUrl) {
7477
this.baseUrl = baseUrl;
@@ -120,7 +123,7 @@ public RestAPIClientBuilder setSerializationConfig(SerializationConfig serializa
120123
return this;
121124
}
122125

123-
public RestAPIClientBuilder setHeaders(Collection<RequestHeader> headers){
126+
public RestAPIClientBuilder setHeaders(Collection<RequestHeader> headers) {
124127
this.headers = headers;
125128
return this;
126129
}
@@ -140,12 +143,17 @@ public RestAPIClientBuilder setObjectMapper(ObjectMapper objectMapper) {
140143
return this;
141144
}
142145

146+
public RestAPIClientBuilder addStringBodyResponseFactory(Class<?> clazz, StringResponseFactory stringResponseFactory) {
147+
stringResponseFactories.addFactory(clazz, stringResponseFactory);
148+
return this;
149+
}
150+
143151
public RestAPIClient build() {
144152
organizeState();
145153
String finalUserAgent = String.format("%s/%s/%s (%s)", userAgentPrefix, restAPIVersion, VERSION, userAgentSuffix);
146154
Collection<RequestHeader> headers = getAllHeaders(this.headers, finalUserAgent);
147155
CommunicationConfig config = new CommunicationConfig(baseUrl, connectionTimeoutMillis, readTimeoutMillis, writeTimeoutMillis, maxIdleConnections,
148-
keepAliveDurationMillis, headers, debug, exceptionFactory, objectMapper);
156+
keepAliveDurationMillis, headers, debug, exceptionFactory, objectMapper, stringResponseFactories);
149157
return new RestAPIClient(new CommunicationFactory(config));
150158
}
151159

@@ -189,11 +197,11 @@ private void organizeState() {
189197
userAgentSuffix = DEFAULT_USER_AGENT_SUFFIX;
190198
}
191199

192-
if(userAgentPrefix == null) {
200+
if (userAgentPrefix == null) {
193201
userAgentPrefix = DEFAULT_USER_AGENT_PREFIX;
194202
}
195203

196-
if(restAPIVersion == null) {
204+
if (restAPIVersion == null) {
197205
restAPIVersion = DEFAULT_REST_API_VERSION;
198206
}
199207

@@ -205,11 +213,11 @@ private void organizeState() {
205213
serializationConfig = DEFAULT_SERIALIZATION_CONFIG;
206214
}
207215

208-
if(exceptionFactory == null) {
216+
if (exceptionFactory == null) {
209217
exceptionFactory = DEFAULT_EXCEPTION_FACTORY;
210218
}
211219

212-
if(objectMapper == null) {
220+
if (objectMapper == null) {
213221
objectMapper = SerializationMapperCreator.createObjectMapper(serializationConfig);
214222
}
215223
}

src/main/java/com/taboola/rest/api/internal/CommunicationFactory.java

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public CommunicationFactory(CommunicationConfig communicationConfig) {
3030

3131
private HttpLoggingInterceptor createLoggingInterceptor(CommunicationConfig config) {
3232
HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(new CommunicationInterceptor());
33-
if(config.isDebug()) {
33+
if (config.isDebug()) {
3434
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
3535
loggingInterceptor.redactHeader("Authorization");
3636
loggingInterceptor.redactHeader("Cookie");
@@ -43,21 +43,21 @@ private HttpLoggingInterceptor createLoggingInterceptor(CommunicationConfig conf
4343

4444
private Retrofit.Builder createRetrofitBuilder(CommunicationConfig config) {
4545
return new Retrofit.Builder()
46-
.addConverterFactory(StringConverterFactory.create())
47-
.addConverterFactory(JacksonConverterFactory.create(config.getObjectMapper()))
48-
.addCallAdapterFactory(SynchronousCallAdapterFactory.create(config.getExceptionFactory()))
49-
.client(createOkHttpClient(config));
46+
.addConverterFactory(StringConverterFactory.create(config.getStringResponseFactories()))
47+
.addConverterFactory(JacksonConverterFactory.create(config.getObjectMapper()))
48+
.addCallAdapterFactory(SynchronousCallAdapterFactory.create(config.getExceptionFactory(), config.getStringResponseFactories()))
49+
.client(createOkHttpClient(config));
5050
}
5151

5252
private OkHttpClient createOkHttpClient(CommunicationConfig config) {
5353
return new OkHttpClient.Builder()
54-
.addInterceptor(new HeadersInterceptor(config.getHeaders()))
55-
.addInterceptor(createLoggingInterceptor(config))
56-
.readTimeout(config.getReadTimeoutMillis(), TimeUnit.MILLISECONDS)
57-
.writeTimeout(config.getWriteTimeoutMillis(), TimeUnit.MILLISECONDS)
58-
.connectTimeout(config.getConnectionTimeoutMillis(), TimeUnit.MILLISECONDS)
59-
.connectionPool(new ConnectionPool(config.getMaxIdleConnections(),
60-
config.getKeepAliveDurationMillis(), TimeUnit.MILLISECONDS))
54+
.addInterceptor(new HeadersInterceptor(config.getHeaders()))
55+
.addInterceptor(createLoggingInterceptor(config))
56+
.readTimeout(config.getReadTimeoutMillis(), TimeUnit.MILLISECONDS)
57+
.writeTimeout(config.getWriteTimeoutMillis(), TimeUnit.MILLISECONDS)
58+
.connectTimeout(config.getConnectionTimeoutMillis(), TimeUnit.MILLISECONDS)
59+
.connectionPool(new ConnectionPool(config.getMaxIdleConnections(),
60+
config.getKeepAliveDurationMillis(), TimeUnit.MILLISECONDS))
6161
.build();
6262
}
6363

src/main/java/com/taboola/rest/api/internal/StringConverterFactory.java

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
package com.taboola.rest.api.internal;
22

3+
import java.lang.annotation.Annotation;
4+
import java.lang.reflect.Type;
5+
36
import okhttp3.ResponseBody;
47
import retrofit2.Converter;
58
import retrofit2.Retrofit;
69

7-
import java.lang.annotation.Annotation;
8-
import java.lang.reflect.Type;
9-
1010
/**
1111
* Created by vladi
1212
* Date: 1/14/2018
@@ -15,15 +15,19 @@
1515
*/
1616
public class StringConverterFactory extends Converter.Factory {
1717

18-
public static StringConverterFactory create() {
19-
return new StringConverterFactory();
18+
private final StringResponseFactories stringResponseFactories;
19+
20+
public static StringConverterFactory create(StringResponseFactories stringResponseFactories) {
21+
return new StringConverterFactory(stringResponseFactories);
2022
}
2123

22-
private StringConverterFactory() { }
24+
private StringConverterFactory(StringResponseFactories stringResponseFactories) {
25+
this.stringResponseFactories = stringResponseFactories;
26+
}
2327

2428
@Override
2529
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
26-
if (String.class.equals(type)) {
30+
if (String.class.equals(type) || stringResponseFactories.isExist(type)) {
2731
return ResponseBody::string;
2832
}
2933
return null;
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.taboola.rest.api.internal;
2+
3+
import java.lang.reflect.Type;
4+
import java.util.HashMap;
5+
import java.util.Map;
6+
7+
import com.taboola.rest.api.model.StringResponseFactory;
8+
9+
public class StringResponseFactories {
10+
private final Map<Type, StringResponseFactory> typeToResponseFactory = new HashMap<>();
11+
12+
public void addFactory(Type type, StringResponseFactory stringResponseFactory) {
13+
typeToResponseFactory.put(type, stringResponseFactory);
14+
}
15+
16+
public StringResponseFactory getFactory(Type type){
17+
return typeToResponseFactory.get(type);
18+
}
19+
20+
public boolean isExist(Type type){
21+
return typeToResponseFactory.containsKey(type);
22+
}
23+
24+
@Override
25+
public String toString() {
26+
return "StringResponseFactories{" +
27+
"typeToResponseFactory=" + typeToResponseFactory +
28+
'}';
29+
}
30+
}

src/main/java/com/taboola/rest/api/internal/SynchronousCallAdapterFactory.java

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,51 @@
11
package com.taboola.rest.api.internal;
22

3+
import java.io.IOException;
4+
import java.lang.annotation.Annotation;
5+
import java.lang.reflect.Type;
6+
7+
import org.apache.logging.log4j.LogManager;
8+
import org.apache.logging.log4j.Logger;
9+
310
import com.taboola.rest.api.exceptions.RestAPIConnectivityException;
411
import com.taboola.rest.api.exceptions.RestAPIRequestException;
512
import com.taboola.rest.api.exceptions.factories.ExceptionFactory;
613

7-
import org.apache.logging.log4j.LogManager;
8-
import org.apache.logging.log4j.Logger;
914
import retrofit2.Call;
1015
import retrofit2.CallAdapter;
1116
import retrofit2.Response;
1217
import retrofit2.Retrofit;
1318

14-
import java.io.IOException;
15-
import java.lang.annotation.Annotation;
16-
import java.lang.reflect.Type;
17-
1819
/**
1920
* Created by vladi
2021
* Date: 11/19/2017
2122
* Time: 11:53 PM
2223
* By Taboola
2324
*/
24-
public class SynchronousCallAdapterFactory extends CallAdapter.Factory {
25+
public class SynchronousCallAdapterFactory extends CallAdapter.Factory {
2526

2627
private static final Logger logger = LogManager.getLogger(SynchronousCallAdapterFactory.class);
2728
private static final int UNAUTHORIZED_HTTP_STATUS_CODE = 401;
2829
private static final int BAD_REQUEST_HTTP_STATUS_CODE = 400;
2930
private static final int INTERNAL_SERVER_ERROR_HTTP_STATUS_CODE = 500;
30-
3131
private final ExceptionFactory exceptionFactory;
32+
private final StringResponseFactories stringResponseFactories;
3233

33-
public static SynchronousCallAdapterFactory create(ExceptionFactory exceptionFactory) {
34-
return new SynchronousCallAdapterFactory(exceptionFactory);
34+
public static SynchronousCallAdapterFactory create(ExceptionFactory exceptionFactory,
35+
StringResponseFactories stringResponseFactories) {
36+
return new SynchronousCallAdapterFactory(exceptionFactory, stringResponseFactories);
3537
}
3638

37-
private SynchronousCallAdapterFactory(ExceptionFactory exceptionFactory) {
39+
private SynchronousCallAdapterFactory(ExceptionFactory exceptionFactory,
40+
StringResponseFactories stringResponseFactories) {
3841
this.exceptionFactory = exceptionFactory;
42+
this.stringResponseFactories = stringResponseFactories;
3943
}
4044

4145
@Override
4246
public CallAdapter<Object, Object> get(final Type returnType, Annotation[] annotations, Retrofit retrofit) {
4347
if (returnType instanceof Call ||
44-
returnType.toString().contains("retrofit2.Call")) {
48+
returnType.toString().contains("retrofit2.Call")) {
4549

4650
return null;
4751
}
@@ -57,14 +61,18 @@ public Object adapt(Call<Object> call) {
5761
Object obj = null;
5862
try {
5963
Response<Object> response = call.execute();
60-
if(response.isSuccessful()) {
61-
obj = response.body();
64+
if (response.isSuccessful()) {
65+
if (stringResponseFactories.isExist(returnType)) {
66+
obj = stringResponseFactories.getFactory(returnType).handlerResponse(response.headers().toMultimap(), (String) response.body());
67+
} else {
68+
obj = response.body();
69+
}
6270
} else {
6371
int responseCode = response.code();
64-
if(responseCode == UNAUTHORIZED_HTTP_STATUS_CODE) {
72+
if (responseCode == UNAUTHORIZED_HTTP_STATUS_CODE) {
6573
throwIfNotNull(exceptionFactory.createUnauthorizedException(safeCreateCauseException(response)));
6674

67-
} else if(responseCode >= BAD_REQUEST_HTTP_STATUS_CODE && responseCode < INTERNAL_SERVER_ERROR_HTTP_STATUS_CODE) {
75+
} else if (responseCode >= BAD_REQUEST_HTTP_STATUS_CODE && responseCode < INTERNAL_SERVER_ERROR_HTTP_STATUS_CODE) {
6876
String message = response.message();
6977
throwIfNotNull(exceptionFactory.createRequestException(responseCode, safeGetErrorPayloadBytes(response, message, responseCode), message));
7078
}
@@ -77,7 +85,7 @@ public Object adapt(Call<Object> call) {
7785
throwIfNotNull(exceptionFactory.createConnectivityException(e));
7886
}
7987

80-
if(obj == null) {
88+
if (obj == null) {
8189
throw new RestAPIConnectivityException();
8290
}
8391

@@ -89,7 +97,7 @@ public Object adapt(Call<Object> call) {
8997
private byte[] safeGetErrorPayloadBytes(Response<Object> response, String message, int responseCode) throws IOException {
9098
try {
9199
return response.errorBody().bytes();
92-
} catch(Throwable t) {
100+
} catch (Throwable t) {
93101
logger.warn("Failed to extract byte[] from response error body", t);
94102
throw new RestAPIRequestException("message: %s, responseCode: %s", MessageHandlingUtils.normalizeErrorMsg(message), responseCode);
95103
}
@@ -105,7 +113,7 @@ private IOException safeCreateCauseException(Response<Object> response) {
105113
}
106114

107115
private void throwIfNotNull(RuntimeException e) {
108-
if(e != null) {
116+
if (e != null) {
109117
throw e;
110118
}
111119
}

src/main/java/com/taboola/rest/api/internal/config/CommunicationConfig.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
package com.taboola.rest.api.internal.config;
22

3+
34
import java.util.Collection;
45

56
import com.fasterxml.jackson.databind.ObjectMapper;
67
import com.taboola.rest.api.exceptions.factories.ExceptionFactory;
8+
import com.taboola.rest.api.internal.StringResponseFactories;
79
import com.taboola.rest.api.model.RequestHeader;
810

911
/**
@@ -24,10 +26,12 @@ public class CommunicationConfig {
2426
private final Collection<RequestHeader> headers;
2527
private final ExceptionFactory exceptionFactory;
2628
private final ObjectMapper objectMapper;
29+
private final StringResponseFactories stringResponseFactories;
2730

2831
public CommunicationConfig(String baseUrl, Long connectionTimeoutMillis, Long readTimeoutMillis,
2932
Long writeTimeoutMillis, Integer maxIdleConnections, Long keepAliveDurationMillis,
30-
Collection<RequestHeader> headers, boolean debug, ExceptionFactory exceptionFactory, ObjectMapper objectMapper) {
33+
Collection<RequestHeader> headers, boolean debug, ExceptionFactory exceptionFactory,
34+
ObjectMapper objectMapper, StringResponseFactories stringResponseFactories) {
3135
this.baseUrl = baseUrl;
3236
this.connectionTimeoutMillis = connectionTimeoutMillis;
3337
this.readTimeoutMillis = readTimeoutMillis;
@@ -38,6 +42,7 @@ public CommunicationConfig(String baseUrl, Long connectionTimeoutMillis, Long re
3842
this.debug = debug;
3943
this.exceptionFactory = exceptionFactory;
4044
this.objectMapper = objectMapper;
45+
this.stringResponseFactories = stringResponseFactories;
4146
}
4247

4348
public String getBaseUrl() {
@@ -64,7 +69,7 @@ public long getKeepAliveDurationMillis() {
6469
return keepAliveDurationMillis;
6570
}
6671

67-
public Collection<RequestHeader> getHeaders(){
72+
public Collection<RequestHeader> getHeaders() {
6873
return headers;
6974
}
7075

@@ -80,6 +85,10 @@ public ObjectMapper getObjectMapper() {
8085
return objectMapper;
8186
}
8287

88+
public StringResponseFactories getStringResponseFactories() {
89+
return stringResponseFactories;
90+
}
91+
8392
@Override
8493
public String toString() {
8594
return "CommunicationConfig{" +
@@ -93,6 +102,7 @@ public String toString() {
93102
", headers=" + headers +
94103
", exceptionFactory=" + exceptionFactory +
95104
", objectMapper=" + objectMapper +
105+
", stringResponseFactories=" + stringResponseFactories +
96106
'}';
97107
}
98108
}

0 commit comments

Comments
 (0)