/* * Data Hub Service (DHuS) - For Space data distribution. * Copyright (C) 2013,2014,2015 GAEL Systems * * This file is part of DHuS software sources. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package fr.gael.dhus.network; import java.util.concurrent.TimeUnit; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import fr.gael.dhus.database.object.User; import fr.gael.dhus.database.object.config.network.ChannelType; import fr.gael.dhus.database.object.config.network.ClassifierCriteriaType; import fr.gael.dhus.database.object.config.network.ClassifierType; import fr.gael.dhus.database.object.config.network.NetworkConfiguration; import fr.gael.dhus.database.object.config.network.PeriodicalPositiveInt; import fr.gael.dhus.database.object.config.network.PeriodicalPositiveLong; import fr.gael.dhus.database.object.config.network.UserQuotasType; import fr.gael.dhus.spring.context.ApplicationContextProvider; import fr.gael.dhus.system.config.ConfigurationManager; /** * TODO Documentation */ class Regulator { /** * A logger for this class. */ private static final Logger LOGGER = LogManager.getLogger(Regulator.class); /** * The a single instance default network regulator. */ private static Regulator defaultRegulator = null; private final ChannelQueue outboundChannel; private final ChannelQueue inboundChannel; Regulator() { this.outboundChannel = new ChannelQueue("OutboundChannel"); this.inboundChannel = new ChannelQueue("InboundChannel"); } public Channel getChannel(ConnectionParameters parameters) throws IllegalArgumentException, RegulationException { // Check parameter if (parameters == null) { throw new IllegalArgumentException( "Cannot get a channel without connection parameters."); } // Return channel according to the traffic direction if (parameters.getDirection() == TrafficDirection.OUTBOUND) { return this.outboundChannel.getChannel(parameters); } else { return this.inboundChannel.getChannel(parameters); } } public void releaseChannel(final Channel channel) { // For the moment just detach the channel from its parent // TODO This method may be moved to the flow itself if (channel.getParent() != null) { ((ChannelQueue) channel.getParent()).removeChannel(channel); } } /** * TODO Documentation * * @return * @throws IllegalStateException */ public static synchronized Regulator getDefaultRegulator() throws IllegalStateException { // Creates a new default regulator if not already done if (defaultRegulator == null) { // Create a new regulator Regulator regulator = new Regulator(); try { regulator.configure(((ConfigurationManager) ApplicationContextProvider.getBean (ConfigurationManager.class)) .getNetworkConfiguration ()); } catch (Exception exception) { throw new IllegalStateException( "Cannot configure default regulator.", exception); } // Assign new regulator as the default one defaultRegulator = regulator; } LOGGER.debug(defaultRegulator); // Return the default regulator return defaultRegulator; } // End getDefaultRegulator() /** * TODO Documentation * * @param config_stream * @throws IllegalArgumentException */ private void configure(NetworkConfiguration network) throws IllegalArgumentException, IllegalStateException { // Check parameter if (network == null) { throw new IllegalArgumentException( "Cannot configure regulator with empty network configuration."); } // Configure outbound channels if (network.getOutbound() != null) { for (ChannelType channel_type : network.getOutbound().getChannel()) { this.outboundChannel.addChannel(configureChannel(channel_type)); } } // Configure inbound channels if (network.getInbound() != null) { for (ChannelType channel_type : network.getInbound().getChannel()) { this.inboundChannel.addChannel(configureChannel(channel_type)); } } } // End configure(InputStream) /** * TODO Documentation * * @param channel_type * @return * @throws IllegalArgumentException */ private static Channel configureChannel(ChannelType channel_type) throws IllegalArgumentException { // Check parameter if (channel_type == null) { throw new IllegalArgumentException( "Cannot configure a network channel from a null type."); } // Create a new channel queue ChannelQueue channel = new ChannelQueue(channel_type.getName()); // Set channel weight with respect to its siblings channel.setWeight(channel_type.getWeight()); // Configure channel classifier ClassifierType classifier_type = channel_type.getClassifier(); if (classifier_type != null) { ChannelClassifier classifier = new ChannelClassifier(); // Parse include rules if (classifier_type.getIncludes() != null) { for (ClassifierCriteriaType include_type : classifier_type .getIncludes().getInclude()) { ChannelClassifierRules rules = new ChannelClassifierRules(); rules.setEmailPattern(include_type.getUserEmailPattern()); rules.setServiceName(include_type.getService()); classifier.addIncludeRules(rules); } } // Parse exclude rules if (classifier_type.getExcludes() != null) { for (ClassifierCriteriaType exclude_type : classifier_type .getExcludes().getExclude()) { ChannelClassifierRules rules = new ChannelClassifierRules(); rules.setEmailPattern(exclude_type.getUserEmailPattern()); rules.setServiceName(exclude_type.getService()); classifier.addExcludeRules(rules); } } // Assign classifier channel.setClassifier(classifier); } // Configure user default quotas UserQuotasType user_quota_type = channel_type.getDefaultUserQuotas(); if (user_quota_type != null) { // Initialize a UserQuota builder UserQuotas.Builder quota_builder = new UserQuotas.Builder(); // Set maxConcurrent if provided if (user_quota_type.getMaxConcurrent() != null) { quota_builder.maxConcurrent(user_quota_type.getMaxConcurrent() .intValue()); } // Set maxCount if provided if (user_quota_type.getMaxCount() != null) { PeriodicalPositiveInt max_count = user_quota_type.getMaxCount(); quota_builder.maxCount(max_count.getValue(), max_count.getPeriod(), TimeUnit.valueOf(max_count.getPeriodUnit().value())); } // Set maxSize if provided if (user_quota_type.getMaxSize() != null) { quota_builder.maxSize(user_quota_type.getMaxSize().longValue()); } // Set maxCumulativeSize if provided if (user_quota_type.getMaxCumulativeSize() != null) { PeriodicalPositiveLong max_cumul_size = user_quota_type.getMaxCumulativeSize(); quota_builder.maxCumulativeSize(max_cumul_size.getValue(), max_cumul_size.getPeriod(), TimeUnit.valueOf(max_cumul_size.getPeriodUnit().value())); } // Set maxBandwidth if provided if (user_quota_type.getMaxBandwidth() != null) { quota_builder.maxBandwidth(user_quota_type.getMaxBandwidth() .intValue()); } // Assign user quotas to the channel channel.setDefaultUserQuotas(quota_builder.build()); } // Configure sub-channels for (ChannelType sub_channel_type : channel_type.getChannel()) { channel.addChannel(configureChannel(sub_channel_type)); } // Return channel return channel; } // End configureChannel(ChannelType) /** * @param user * @param direction * @return */ public int countUserChannels(final User user, final TrafficDirection direction) { if (direction == null) { throw new IllegalArgumentException("Invalid null direction."); } if (direction == TrafficDirection.OUTBOUND) { return this.outboundChannel.countUserChannels(user); } return this.inboundChannel.countUserChannels(user); } @Override public String toString() { return "Newtork Regulator Configuration:\n" + this.outboundChannel.toString() + "\n" + this.inboundChannel.toString(); } } // End Regulator class