org.restlet.ext.apispark.internal.firewall.rule.counter.PeriodicCounter.java Source code

Java tutorial

Introduction

Here is the source code for org.restlet.ext.apispark.internal.firewall.rule.counter.PeriodicCounter.java

Source

/**
 * Copyright 2005-2014 Restlet
 * 
 * The contents of this file are subject to the terms of one of the following
 * open source licenses: Apache 2.0 or or EPL 1.0 (the "Licenses"). You can
 * select the license that you prefer but you may not use this file except in
 * compliance with one of these Licenses.
 * 
 * You can obtain a copy of the Apache 2.0 license at
 * http://www.opensource.org/licenses/apache-2.0
 * 
 * You can obtain a copy of the EPL 1.0 license at
 * http://www.opensource.org/licenses/eclipse-1.0
 * 
 * See the Licenses for the specific language governing permissions and
 * limitations under the Licenses.
 * 
 * Alternatively, you can obtain a royalty free commercial license with less
 * limitations, transferable or non-transferable, directly at
 * http://restlet.com/products/restlet-framework
 * 
 * Restlet is a registered trademark of Restlet S.A.S.
 */

package org.restlet.ext.apispark.internal.firewall.rule.counter;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.logging.Level;

import org.restlet.Context;
import org.restlet.ext.apispark.internal.firewall.rule.CounterResult;

import com.google.common.base.Stopwatch;

/**
 * {@link Counter} which counts requests on a given period.
 * 
 * @author Guillaume Blondeau
 */
public class PeriodicCounter extends Counter {

    /** The counter value. */
    protected final AtomicInteger counter;

    /** Next counter reset time */
    private final AtomicLong counterReset;

    /** The period associated to the Counter. */
    private final long period;

    /** Calculates periods duration and resets them. */
    private final Stopwatch stopwatch;

    /**
     * Constructor.
     * 
     * @param period
     *            The period associated to the counter.
     */
    public PeriodicCounter(long period) {
        this.counter = new AtomicInteger();
        this.period = period;
        this.stopwatch = Stopwatch.createStarted();
        this.counterReset = new AtomicLong();
    }

    @Override
    public void decrement() {
    }

    @Override
    public CounterResult increment() {
        long elapsed;
        long reset;

        // if counter time is elapsed, reset it.
        synchronized (stopwatch) {
            elapsed = stopwatch.elapsed(TimeUnit.SECONDS);
            if (elapsed > period) {
                Context.getCurrentLogger().log(Level.FINE, "Period reinitialized.");
                stopwatch.reset();
                stopwatch.start();
                counter.getAndSet(0);
                reset = System.currentTimeMillis() / 1000L + period;
                counterReset.getAndSet(reset);
                elapsed = 0;
            } else {
                reset = counterReset.get();
            }
        }

        int consumed = counter.incrementAndGet();
        CounterResult counterResult = new CounterResult();
        counterResult.setConsumed(consumed);
        counterResult.setElapsed(elapsed);
        counterResult.setReset(reset);
        return counterResult;
    }

}