Skip to content

Commit 23e247f

Browse files
iulian03Iulian Masar
and
Iulian Masar
authored
[improvement] rate limits
* improvement of how the rate limits are set * small change * change the way a string is converted to integer --------- Co-authored-by: Iulian Masar <iulian.masar@codegile.com>
1 parent 076ddf0 commit 23e247f

File tree

3 files changed

+92
-43
lines changed

3 files changed

+92
-43
lines changed

src/main/java/com/mangopay/core/RestTool.java

+85-40
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@
2525
*/
2626
public class RestTool {
2727

28+
private final static int MINUTES_15 = 15;
29+
private final static int MINUTES_30 = 30;
30+
private final static int MINUTES_60 = 60;
31+
private final static int ONE_DAY_IN_MINUTES = MINUTES_60 * 24;
32+
2833
// root/parent instance that holds the OAuthToken and Configuration instance
2934
private MangoPayApi root;
3035

@@ -438,50 +443,51 @@ private SSLContext getSSLContext() throws NoSuchAlgorithmException, KeyManagemen
438443
}
439444

440445
private void readResponseHeaders(HttpURLConnection conn) {
441-
List<RateLimit> updatedRateLimits = null;
442-
for (Map.Entry<String, List<String>> k : conn.getHeaderFields().entrySet()) {
443-
for (String v : k.getValue()) {
446+
Set<Map.Entry<String, List<String>>> headers = conn.getHeaderFields().entrySet();
444447

445-
if (this.debugMode) logger.info("Response header: {}", k.getKey() + ":" + v);
448+
List<String> rateLimitResetValues = new ArrayList<>();
449+
List<String> rateLimitRemainingValues = new ArrayList<>();
450+
List<String> rateLimitValues = new ArrayList<>();
446451

447-
if (k.getKey() == null) continue;
452+
for (Map.Entry<String, List<String>> k : headers) {
453+
if (this.debugMode) {
454+
logger.info("Reading rate limit headers");
455+
}
448456

449-
if (k.getKey().equals("X-RateLimit-Remaining") || k.getKey().equals("X-RateLimit-Remaining".toLowerCase())) {
450-
if (updatedRateLimits == null) {
451-
updatedRateLimits = initRateLimits();
457+
// prepare rate limits values
458+
if (k.getKey() != null) {
459+
switch (k.getKey().toLowerCase()) {
460+
case "x-ratelimit-reset": {
461+
rateLimitResetValues = k.getValue();
462+
break;
452463
}
453-
List<String> callsRemaining = k.getValue();
454-
updatedRateLimits.get(0).setCallsRemaining(Integer.valueOf(callsRemaining.get(3)));
455-
updatedRateLimits.get(1).setCallsRemaining(Integer.valueOf(callsRemaining.get(2)));
456-
updatedRateLimits.get(2).setCallsRemaining(Integer.valueOf(callsRemaining.get(1)));
457-
updatedRateLimits.get(3).setCallsRemaining(Integer.valueOf(callsRemaining.get(0)));
458-
}
459-
if (k.getKey().equals("X-RateLimit") || k.getKey().equals("X-RateLimit".toLowerCase())) {
460-
if (updatedRateLimits == null) {
461-
updatedRateLimits = initRateLimits();
464+
case "x-ratelimit-remaining": {
465+
rateLimitRemainingValues = k.getValue();
466+
break;
462467
}
463-
List<String> callsMade = k.getValue();
464-
updatedRateLimits.get(0).setCallsMade(Integer.valueOf(callsMade.get(3)));
465-
updatedRateLimits.get(1).setCallsMade(Integer.valueOf(callsMade.get(2)));
466-
updatedRateLimits.get(2).setCallsMade(Integer.valueOf(callsMade.get(1)));
467-
updatedRateLimits.get(3).setCallsMade(Integer.valueOf(callsMade.get(0)));
468-
}
469-
if (k.getKey().equals("X-RateLimit-Reset") || k.getKey().equals("X-RateLimit-Reset".toLowerCase())) {
470-
if (updatedRateLimits == null) {
471-
updatedRateLimits = initRateLimits();
468+
case "x-ratelimit": {
469+
rateLimitValues = k.getValue();
470+
break;
472471
}
473-
List<String> resetTimes = k.getValue();
474-
updatedRateLimits.get(0).setResetTimeSeconds(Long.valueOf(resetTimes.get(3)));
475-
updatedRateLimits.get(1).setResetTimeSeconds(Long.valueOf(resetTimes.get(2)));
476-
updatedRateLimits.get(2).setResetTimeSeconds(Long.valueOf(resetTimes.get(1)));
477-
updatedRateLimits.get(3).setResetTimeSeconds(Long.valueOf(resetTimes.get(0)));
472+
default:
473+
break;
478474
}
475+
}
476+
477+
for (String v : k.getValue()) {
478+
if (this.debugMode) logger.info("Response header: {}", k.getKey() + ":" + v);
479+
if (k.getKey() == null) {
480+
continue;
481+
}
482+
479483
if (k.getKey().equals("X-Number-Of-Pages") || k.getKey().equals("X-Number-Of-Pages".toLowerCase())) {
480484
this.pagination.setTotalPages(Integer.parseInt(v));
481485
}
486+
482487
if (k.getKey().equals("X-Number-Of-Items") || k.getKey().equals("X-Number-Of-Items".toLowerCase())) {
483488
this.pagination.setTotalItems(Integer.parseInt(v));
484489
}
490+
485491
if (k.getKey().equals("Link") || k.getKey().equals("Link".toLowerCase())) {
486492
String linkValue = v;
487493
String[] links = linkValue.split(",");
@@ -505,17 +511,56 @@ private void readResponseHeaders(HttpURLConnection conn) {
505511
}
506512
}
507513
}
508-
if (updatedRateLimits != null) {
509-
root.setRateLimits(updatedRateLimits);
510-
}
514+
515+
setRateLimits(rateLimitResetValues, rateLimitRemainingValues, rateLimitValues);
511516
}
512517

513-
private List<RateLimit> initRateLimits() {
514-
return Arrays.asList(
515-
new RateLimit(15),
516-
new RateLimit(30),
517-
new RateLimit(60),
518-
new RateLimit(24 * 60));
518+
/**
519+
* set rate limits:
520+
* - if the X-RateLimit-Reset is not present, rate limits can't be set
521+
* - if all 3 headers are present, but they don't have the same structure (size), rate limits can't be set
522+
*/
523+
private void setRateLimits(
524+
List<String> rateLimitResetValues,
525+
List<String> rateLimitRemainingValues,
526+
List<String> rateLimitValues
527+
) {
528+
if (rateLimitResetValues.size() == rateLimitRemainingValues.size() && rateLimitResetValues.size() == rateLimitValues.size()) {
529+
if (this.debugMode) {
530+
logger.info("Setting rate limits");
531+
}
532+
List<RateLimit> rateLimits = new ArrayList<>();
533+
534+
// resetTime is in epoch (seconds), currentTime is in ms => convert currentTime to the same unit
535+
long currentTime = System.currentTimeMillis() / 1000;
536+
537+
for (int i = 0; i < rateLimitResetValues.size(); i++) {
538+
long numberOfMinutes = (Integer.parseInt(rateLimitResetValues.get(i)) - currentTime) / 60;
539+
RateLimit rateLimit = new RateLimit();
540+
541+
if (numberOfMinutes <= MINUTES_15) {
542+
rateLimit.setIntervalMinutes(MINUTES_15);
543+
} else if (numberOfMinutes <= MINUTES_30) {
544+
rateLimit.setIntervalMinutes(MINUTES_30);
545+
} else if (numberOfMinutes <= MINUTES_60) {
546+
rateLimit.setIntervalMinutes(MINUTES_60);
547+
} else if (numberOfMinutes <= ONE_DAY_IN_MINUTES) {
548+
rateLimit.setIntervalMinutes(ONE_DAY_IN_MINUTES);
549+
}
550+
551+
rateLimit.setResetTimeSeconds(Long.parseLong(rateLimitResetValues.get(i)));
552+
rateLimit.setCallsRemaining(Integer.parseInt(rateLimitRemainingValues.get(i)));
553+
rateLimit.setCallsMade(Integer.parseInt(rateLimitValues.get(i)));
554+
555+
rateLimits.add(rateLimit);
556+
}
557+
558+
if (!rateLimits.isEmpty()) {
559+
root.setRateLimits(rateLimits);
560+
}
561+
} else if (this.debugMode) {
562+
logger.warn("Can't set rate limits");
563+
}
519564
}
520565

521566
public <T> T castResponseToEntity(Class<T> classOfT, JsonObject response) {

src/main/java/com/mangopay/entities/RateLimit.java

+6-2
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@ public class RateLimit {
77
private int callsRemaining;
88
private long resetTimeSeconds;
99

10-
public RateLimit(int intervalMinutes) {
11-
this.intervalMinutes = intervalMinutes;
10+
public RateLimit() {
1211
}
1312

1413
/**
@@ -82,4 +81,9 @@ public long getResetTimeSeconds() {
8281
public void setResetTimeSeconds(long resetTimeSeconds) {
8382
this.resetTimeSeconds = resetTimeSeconds;
8483
}
84+
85+
public RateLimit setIntervalMinutes(int intervalMinutes) {
86+
this.intervalMinutes = intervalMinutes;
87+
return this;
88+
}
8589
}

src/test/java/com/mangopay/entities/RateLimitTest.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,6 @@ public void rateLimitsUpdateTest() throws Exception {
2323
List<RateLimit> rateLimits = this.api.getRateLimits();
2424

2525
assertNotNull(rateLimits);
26-
assertTrue(rateLimits.size() == 4);
26+
assertFalse(rateLimits.isEmpty());
2727
}
2828
}

0 commit comments

Comments
 (0)