Uploaded image for project: 'Camel'
  1. Camel
  2. CAMEL-17486

camel-core - ThrottlePermit compareTo cast to int causes issues

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Resolved
    • Minor
    • Resolution: Fixed
    • None
    • 3.11.6, 3.14.1, 3.15.0
    • camel-core
    • None
    • Patch Available
    • Novice

    Description

      When a Throttler has not been used for longer than Integer#MAX_VALUE, casting the result of the ThrottlePermit comparison to an int causes a bit overflow.

      Using a value comparison prevents this issue.
       
      Current :

      private static class ThrottlePermit implements Delayed {
      
          @Override
          public int compareTo(final Delayed o) {
              return (int) (getDelay(TimeUnit.MILLISECONDS) - o.getDelay(TimeUnit.MILLISECONDS));
          }
      }
      

      Proposal :

      private static class ThrottlePermit implements Delayed {
      
              @Override
              public int compareTo(final Delayed o) {
                  return Long.compare(getDelay(TimeUnit.MILLISECONDS), o.getDelay(TimeUnit.MILLISECONDS));
              }
      }
      

      Unit Test :

      public class ThrottlerPermitTest {
      
          /**
           *   When a Throttler has not been used for longer than {@link java.lang.Integer#MAX_VALUE},
           *   casting the result of the {@link ThrottlePermit} comparison to an int causes a bit overflow.
           *   Using a value comparison prevents this issue.
           **/
          @Test
          public void testThrottlerPermitWithOldScheduledTime() {
              long timeMillis = System.currentTimeMillis();
              // 30 days in the past
              ThrottlePermit throttlePermitOld = new ThrottlePermit(timeMillis -2592000000L);
              // Now
              ThrottlePermit throttlePermitNow = new ThrottlePermit(timeMillis);
              ThrottlePermit throttlePermitNow2 = new ThrottlePermit(timeMillis);
              // Future
              ThrottlePermit throttlePermitFuture = new ThrottlePermit(timeMillis + 1000);
      
              assertEquals(-1, throttlePermitOld.compareTo(throttlePermitNow));
              assertEquals(0, throttlePermitNow.compareTo(throttlePermitNow2));
              assertEquals(1, throttlePermitFuture.compareTo(throttlePermitNow));
          }
      
          private final class ThrottlePermit implements Delayed {
              private volatile long scheduledTime;
      
              ThrottlePermit(final long delayMs) {
                  setDelayMs(delayMs);
              }
      
              public void setDelayMs(final long delayMs) {
                  this.scheduledTime = System.currentTimeMillis() + delayMs;
              }
      
              @Override
              public long getDelay(final TimeUnit unit) {
                  return unit.convert(scheduledTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
              }
      
              @Override
              public int compareTo(final Delayed o) {
                  return Long.compare(getDelay(TimeUnit.MILLISECONDS), o.getDelay(TimeUnit.MILLISECONDS));
              }
          }
      }
      

      Attachments

        Activity

          People

            davsclaus Claus Ibsen
            bmarc MARC BOULANGER
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: