package com.marcosbarbero.zuul.filters.pre.ratelimit.config.redis;

import com.marcosbarbero.zuul.filters.pre.ratelimit.config.Policy;
import com.marcosbarbero.zuul.filters.pre.ratelimit.config.Rate;
import com.marcosbarbero.zuul.filters.pre.ratelimit.config.RateLimiter;

import org.springframework.data.redis.core.RedisTemplate;

import static java.util.concurrent.TimeUnit.SECONDS;

/**
 * @author Marcos Barbero
 */
public class RedisRateLimiter implements RateLimiter {
    private RedisTemplate template;

    public RedisRateLimiter(RedisTemplate template) {
        this.template = template;
    }

    @Override
    @SuppressWarnings("unchecked")
    public Rate consume(final Policy policy, final String key) {
        final Long limit = policy.getLimit();
        final Long refreshInterval = policy.getRefreshInterval();
        final Long current = this.template.boundValueOps(key).increment(1L);
        Long expire = this.template.getExpire(key);
        if (expire == null || expire == -1) {
            this.template.expire(key, refreshInterval, SECONDS);
            expire = refreshInterval;
        }
        return new Rate(limit, Math.max(-1, limit - current), SECONDS.toMillis(expire));
    }
}

@@ -323,16 +323,56 @@
 emplate;
+%0Aimport org.springframework.util.Assert;
 %0A%0Aimport
@@ -520,16 +520,22 @@
 private 
+final 
 RedisTem
@@ -579,16 +579,22 @@
 Limiter(
+final 
 RedisTem
@@ -607,24 +607,90 @@
 template) %7B%0A
+        Assert.notNull(template, %22RedisTemplate cannot be null%22);%0A
         this

Make RedisTemplate final and validate not null construction