Skip to content

Commit 398238b

Browse files
authored
Merge pull request #47 from pokepay/retry
Allow to retry automatically for 503 or ConnectionError.
2 parents e5ef5c1 + bc11ca8 commit 398238b

File tree

1 file changed

+53
-15
lines changed

1 file changed

+53
-15
lines changed

src/main/java/jp/pokepay/partnerapi/PartnerAPI.java

Lines changed: 53 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,16 @@
1313
import java.text.SimpleDateFormat;
1414
import java.util.Date;
1515
import java.util.UUID;
16+
import java.util.Arrays;
17+
import java.lang.reflect.Field;
1618

1719
public class PartnerAPI {
1820
private Config config;
1921
private HttpClient httpClient;
2022
private Crypto crypto;
2123
private GsonBuilder gsonBuilder;
2224
private Gson gson;
25+
private static final int MAX_RETRIES = 2;
2326

2427
public PartnerAPI(File configFile) throws ProcessingError, ConfigFileNotFoundException,
2528
P12FileNotFoundException, SSLInitializeError {
@@ -62,24 +65,59 @@ public Pong ping() throws ProcessingError, ConnectionError {
6265
return gson.fromJson(response.getBody(), Pong.class);
6366
}
6467

65-
public String encodeRequest(Request request) throws ProcessingError {
66-
String requestData = gson.toJson(request);
67-
return constructContent(request.method().toString(), requestData);
68+
private boolean isRetriable(Request request) {
69+
String[] retriableMethods = {"GET", "PATCH"};
70+
if (Arrays.asList(retriableMethods).contains(request.method().toString())) {
71+
return true;
72+
}
73+
try {
74+
Field field = request.getClass().getDeclaredField("requestId");
75+
field.setAccessible(true);
76+
boolean hasRequestId = field.get(request) != null;
77+
field.setAccessible(false);
78+
return hasRequestId;
79+
} catch (NoSuchFieldException ex) {
80+
} catch (IllegalAccessException ex) { }
81+
return false;
6882
}
6983

7084
public Response send(Request request) throws ProcessingError, ConnectionError, PartnerRequestError {
71-
HttpClient.Response response = httpClient.post(request.path(), encodeRequest(request), config.acceptLanguage);
72-
JsonResponse json = gson.fromJson(response.getBody(), JsonResponse.class);
73-
if (json.responseData == null) {
74-
ErrorResponse errorResponse = gson.fromJson(response.getBody(), ErrorResponse.class);
75-
throw new PartnerRequestError(errorResponse.type, errorResponse.message, response.getBody());
76-
}
77-
String responseData = crypto.decode(json.responseData);
78-
ErrorResponse errorResponse = gson.fromJson(responseData, ErrorResponse.class);
79-
if (!errorResponse.isValid()) {
80-
return gson.fromJson(responseData, request.getResponseClass());
81-
} else {
82-
throw new PartnerRequestError(errorResponse.type, errorResponse.message, responseData);
85+
Integer retry = 0;
86+
boolean isRetriable = isRetriable(request);
87+
String requestData = gson.toJson(request);
88+
int statusCode = 0;
89+
while (true) {
90+
try {
91+
HttpClient.Response response = httpClient.post(request.path(), constructContent(request.method().toString(), requestData), config.acceptLanguage);
92+
statusCode = response.getStatus();
93+
JsonResponse json = gson.fromJson(response.getBody(), JsonResponse.class);
94+
if (json.responseData == null) {
95+
ErrorResponse errorResponse = gson.fromJson(response.getBody(), ErrorResponse.class);
96+
throw new PartnerRequestError(errorResponse.type, errorResponse.message, response.getBody());
97+
}
98+
String responseData = crypto.decode(json.responseData);
99+
ErrorResponse errorResponse = gson.fromJson(responseData, ErrorResponse.class);
100+
if (!errorResponse.isValid()) {
101+
return gson.fromJson(responseData, request.getResponseClass());
102+
} else {
103+
throw new PartnerRequestError(errorResponse.type, errorResponse.message, responseData);
104+
}
105+
} catch (ConnectionError ex) {
106+
if (this.MAX_RETRIES <= retry || !isRetriable) {
107+
throw ex;
108+
}
109+
} catch (PartnerRequestError ex) {
110+
if (ex.getType().equals("request_id_conflict")) {
111+
throw new RequestIdConflict(ex.getType(), ex.getMessage(), ex.getRawJson());
112+
}
113+
if (!isRetriable) {
114+
throw ex;
115+
}
116+
if (!(statusCode == 503 && retry < this.MAX_RETRIES)) {
117+
throw ex;
118+
}
119+
}
120+
++retry;
83121
}
84122
}
85123

0 commit comments

Comments
 (0)