/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package demo.throttling.server; import com.codahale.metrics.MetricRegistry; import org.apache.cxf.metrics.MetricsContext; import org.apache.cxf.metrics.codahale.CodahaleMetricsContext; import org.apache.cxf.throttling.ThrottleResponse; /** * */ public abstract class Customer { protected final String name; protected volatile CodahaleMetricsContext metrics; public Customer(String n) { name = n; } MetricsContext getMetricsContext(MetricRegistry registry) { if (metrics == null) { metrics = new CodahaleMetricsContext("demo.server:customer=" + name + ",type=Customer,", registry); } return metrics; } public abstract void throttle(ThrottleResponse r); public static class PremiumCustomer extends Customer { public PremiumCustomer(String n) { super(n); } public void throttle(ThrottleResponse m) { //Premium customers are unthrottled } } public static class PreferredCustomer extends Customer { public PreferredCustomer(String n) { super(n); } public void throttle(ThrottleResponse m) { //System.out.println("p " + metrics.getTotals().getOneMinuteRate() // + " " + metrics.getTotals().getCount()); //Preferred customers are unthrottled until they hit 100req/sec, then start delaying by .05 seconds //(drops to max of 50req/sec until below the 100req/sec rate) if (metrics.getTotals().getOneMinuteRate() > 100) { m.setDelay(20); } } } public static class RegularCustomer extends Customer { public RegularCustomer(String n) { super(n); } public void throttle(ThrottleResponse m) { //Regular customers are unthrottled until they hit 25req/sec, then start delaying by 0.25 seconds //(drops to max of 4req/sec until below the 25req/sec rate) if (metrics.getTotals().getOneMinuteRate() > 25) { m.setDelay(250); } //They also get throttled more if they are over 10req/sec over a 5 minute period //(drops to max of 2req/sec until below the 10req/sec rate) if (metrics.getTotals().getFiveMinuteRate() > 10) { m.setDelay(500); } } } public static class CheapCustomer extends Customer { public CheapCustomer(String n) { super(n); } public void throttle(ThrottleResponse m) { //System.out.println("ch " + metrics.getTotals().getOneMinuteRate() // + " " + metrics.getTotals().getCount()); //Cheap customers are always get a .1 sec delay long delay = 100; //Then they get futher throttled dependending on rates if (metrics.getTotals().getOneMinuteRate() > 5) { delay += 1000; } //They also get throttled after 5 minutes of more than if (metrics.getTotals().getFiveMinuteRate() > 1) { delay += 1000; } m.setDelay(delay); } } public static class TrialCustomer extends Customer { long lastTime = System.currentTimeMillis(); public TrialCustomer(String n) { super(n); } public void throttle(ThrottleResponse m) { //Trial customers only get 10 requests, then rejected if (metrics.getTotals().getCount() >= 10) { m.setResponseCode(429, "Exceeded"); } m.addResponseHeader("X-RateLimit-Limit", "10"); m.addResponseHeader("X-RateLimit-Remaining", Long.toString(10 - metrics.getTotals().getCount())); m.setDelay(100); } } }