/** * 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.agent.module; import com.google.common.base.Function; import com.google.common.collect.ListMultimap; import com.google.common.collect.Multimaps; import org.restlet.ext.apispark.FirewallConfig; import org.restlet.ext.apispark.internal.ApiSparkConfig; import org.restlet.ext.apispark.internal.agent.AgentConfigurationException; import org.restlet.ext.apispark.internal.agent.AgentUtils; import org.restlet.ext.apispark.internal.agent.bean.FirewallIpFilter; import org.restlet.ext.apispark.internal.agent.bean.FirewallRateLimit; import org.restlet.ext.apispark.internal.agent.bean.FirewallSettings; import org.restlet.ext.apispark.internal.agent.bean.ModulesSettings; import org.restlet.ext.apispark.internal.agent.resource.FirewallSettingsResource; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; /** * @author Manuel Boillod */ public class FirewallModule { public static final String MODULE_PATH = "/firewall"; public static final String SETTINGS_PATH = MODULE_PATH + "/settings"; FirewallSettings firewallSettings; public FirewallModule(ApiSparkConfig apiSparkConfig, ModulesSettings modulesSettings) { FirewallSettingsResource firewallSettingsClientResource = AgentUtils .getClientResource(apiSparkConfig, modulesSettings, FirewallSettingsResource.class, SETTINGS_PATH); try { firewallSettings = firewallSettingsClientResource.getSettings(); } catch (Exception e) { throw new AgentConfigurationException( "Could not get firewall module configuration from APISpark connector service", e); } } public void updateFirewallConfig(FirewallConfig firewallConfig) { addIpFilterRules(firewallSettings, firewallConfig); addRateLimitationRules(firewallSettings, firewallConfig); } private void addIpFilterRules(FirewallSettings firewallSettings, FirewallConfig firewallConfig) { if (firewallSettings.getIpFilters() != null) { for (FirewallIpFilter ipFilter : firewallSettings.getIpFilters()) { if (ipFilter.isWhiteList()) { firewallConfig.addIpAddressesWhiteList(ipFilter.getIps()); } else { firewallConfig.addIpAddressesBlackList(ipFilter.getIps()); } } } } private void addRateLimitationRules(FirewallSettings firewallSettings, FirewallConfig firewallConfig) { if (firewallSettings.getRateLimits() != null) { List<FirewallRateLimit> rateLimits = firewallSettings .getRateLimits(); Map<Integer, Collection<FirewallRateLimit>> rateLimitsByPeriod = sortRateLimitsByPeriod(rateLimits); for (Integer period : rateLimitsByPeriod.keySet()) { Map<String, Integer> limitsPerRole = new HashMap<>(); int defaultRateLimit = Integer.MAX_VALUE; for (FirewallRateLimit firewallRateLimit : rateLimitsByPeriod .get(period)) { if (firewallRateLimit.isDefaultRateLimit()) { defaultRateLimit = firewallRateLimit.getRateLimit(); } else { limitsPerRole.put(firewallRateLimit.getGroup(), firewallRateLimit.getRateLimit()); } } firewallConfig.addRolesPeriodicCounter(period, TimeUnit.SECONDS, limitsPerRole, defaultRateLimit); } } } private Map<Integer, java.util.Collection<FirewallRateLimit>> sortRateLimitsByPeriod( List<FirewallRateLimit> rateLimits) { ListMultimap<Integer, FirewallRateLimit> rateLimitsByPeriod = Multimaps .index(rateLimits, new Function<FirewallRateLimit, Integer>() { @Override public Integer apply(FirewallRateLimit firewallRateLimit) { return firewallRateLimit.getPeriod(); } }); return rateLimitsByPeriod.asMap(); } }