25
25
*/
26
26
public class RestTool {
27
27
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
+
28
33
// root/parent instance that holds the OAuthToken and Configuration instance
29
34
private MangoPayApi root ;
30
35
@@ -438,50 +443,51 @@ private SSLContext getSSLContext() throws NoSuchAlgorithmException, KeyManagemen
438
443
}
439
444
440
445
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 ();
444
447
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 <>();
446
451
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
+ }
448
456
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 ;
452
463
}
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 ;
462
467
}
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 ;
472
471
}
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 ;
478
474
}
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
+
479
483
if (k .getKey ().equals ("X-Number-Of-Pages" ) || k .getKey ().equals ("X-Number-Of-Pages" .toLowerCase ())) {
480
484
this .pagination .setTotalPages (Integer .parseInt (v ));
481
485
}
486
+
482
487
if (k .getKey ().equals ("X-Number-Of-Items" ) || k .getKey ().equals ("X-Number-Of-Items" .toLowerCase ())) {
483
488
this .pagination .setTotalItems (Integer .parseInt (v ));
484
489
}
490
+
485
491
if (k .getKey ().equals ("Link" ) || k .getKey ().equals ("Link" .toLowerCase ())) {
486
492
String linkValue = v ;
487
493
String [] links = linkValue .split ("," );
@@ -505,17 +511,56 @@ private void readResponseHeaders(HttpURLConnection conn) {
505
511
}
506
512
}
507
513
}
508
- if (updatedRateLimits != null ) {
509
- root .setRateLimits (updatedRateLimits );
510
- }
514
+
515
+ setRateLimits (rateLimitResetValues , rateLimitRemainingValues , rateLimitValues );
511
516
}
512
517
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
+ }
519
564
}
520
565
521
566
public <T > T castResponseToEntity (Class <T > classOfT , JsonObject response ) {
0 commit comments