001package com.net2plan.examples.general.onlineSim;
002/*******************************************************************************
003 * Copyright (c) 2017 Pablo Pavon Marino and others.
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the 2-clause BSD License 
006 * which accompanies this distribution, and is available at
007 * https://opensource.org/licenses/BSD-2-Clause
008 *
009 * Contributors:
010 *     Pablo Pavon Marino and others - initial API and implementation
011 *******************************************************************************/
012
013
014import com.net2plan.examples.ocnbook.onlineSim.Online_evGen_generalGenerator;
015import com.net2plan.interfaces.networkDesign.Net2PlanException;
016import com.net2plan.interfaces.networkDesign.NetPlan;
017import com.net2plan.interfaces.networkDesign.NetworkLayer;
018import com.net2plan.interfaces.simulation.SimEvent;
019import com.net2plan.libraries.SRGUtils;
020import com.net2plan.utils.InputParameter;
021import com.net2plan.utils.Triple;
022
023import java.text.SimpleDateFormat;
024import java.util.Calendar;
025import java.util.HashMap;
026import java.util.List;
027import java.util.Map;
028
029
030
031/** 
032 * Generates events for an IP over WDM multilayer network, with an IP/OSPF layer on top of a WDM layer where lightpaths are carried in a fixed grid of wavelengths
033 * 
034 * This class extends the {@code Online_evGen_generalGenerator} generator (see its Javadoc for further details), and is basically used to:
035 * <ul>
036 * <li>Send events to the IP layer to create used-defined IP traffic fluctuations (fast/slow), according to the general operation of the {@code Online_evGen_generalGenerator} module.</li>
037 * <li>Send events related to node/link failures and repairs, also according to how the {@code Online_evGen_generalGenerator} module operates.</li>
038 * </ul>
039 *  
040 * See the technology conventions used in Net2Plan built-in algorithms and libraries to represent IP and WDM networks. 
041 * @net2plan.keywords IP/OSPF, WDM, Multilayer, Network recovery: protection, Network recovery: restoration, Multihour optimization
042 * @net2plan.inputParameters 
043 * @author Pablo Pavon-Marino, Jose-Luis Izquierdo-Zaragoza
044 */
045public class Online_evGen_ipOverWdm extends Online_evGen_generalGenerator
046{
047        private final static String DATE_FORMAT = "MM/dd/YY HH:mm:ss";
048
049        private InputParameter ipOverWdmFailureModel = new InputParameter ("ipOverWdmFailureModel", "#select# perBidirectionalLinkBundle none SRGfromNetPlan perNode perLink perDirectionalLinkBundle" , "Failure model selection: SRGfromNetPlan, perNode, perLink, perDirectionalLinkBundle, perBidirectionalLinkBundle");
050        private InputParameter ipOverWdmFailureDefaultMTTFInHours = new InputParameter ("ipOverWdmFailureDefaultMTTFInHours", (double) 10 , "Default value for Mean Time To Fail (hours) (unused when failureModel=SRGfromNetPlan)" , 0 , false , Double.MAX_VALUE , true);
051        private InputParameter ipOverWdmFailureDefaultMTTRInHours = new InputParameter ("ipOverWdmFailureDefaultMTTRInHours", (double) 12 , "Default value for Mean Time To Repair (hours) (unused when failureModel=SRGfromNetPlan)" , 0 , false , Double.MAX_VALUE , true);
052        private InputParameter ipOverWDmFailureStatisticalPattern = new InputParameter ("ipOverWDmFailureStatisticalPattern", "#select# exponential-iid" , "Type of failure and repair statistical pattern");
053        private InputParameter randomSeed = new InputParameter ("randomSeed", (long) 1 , "Seed for the random generator (-1 means random)");
054        private InputParameter ipTFFastFluctuationType = new InputParameter ("ipTFFastFluctuationType", "#select# none random-truncated-gaussian" , "");
055        private InputParameter ipTFFastTimeBetweenDemandFluctuationsHours = new InputParameter ("ipTFFastTimeBetweenDemandFluctuationsHours", (double) 0.1 , "Average time between two changes of demand offered traffic in a demand (demands behave independently)" , 0 , false , Double.MAX_VALUE , true);
056        private InputParameter ipTFFastFluctuationCoefficientOfVariation = new InputParameter ("ipTFFastFluctuationCoefficientOfVariation", (double) 1.0 , "Average time between two changes of demand offered traffic in a demand (demands behave independently)" , 0 , false , Double.MAX_VALUE , true);
057        private InputParameter ipTFFastMaximumFluctuationRelativeFactor = new InputParameter ("ipTFFastMaximumFluctuationRelativeFactor", (double) 1.0 , "The fluctuation of a demand cannot exceed this percentage from the media" , 0 , true , Double.MAX_VALUE , true);
058        private InputParameter ipTFSlowStartDate = new InputParameter ("ipTFSlowStartDate", new SimpleDateFormat(DATE_FORMAT).format(Calendar.getInstance().getTime()) , "Initial date and time of the simulation");
059        private InputParameter ipTFSlowTimeBetweenDemandFluctuationsHours = new InputParameter ("ipTFSlowTimeBetweenDemandFluctuationsHours", (double) 1.0 , "Average time between two changes of demand offered traffic in a demand (demands behave independently)" , 0 , false , Double.MAX_VALUE , true);
060        private InputParameter ipTFSlowDefaultTimezone = new InputParameter ("ipTFSlowDefaultTimezone", (int) 0 , "Default timezone with respect to UTC (in range [-12, 12])" , -12 , 12);
061        private InputParameter ipTFSlowFluctuationType = new InputParameter ("ipTFSlowFluctuationType", "#select# none time-zone-based" , "");
062
063        @Override
064        public String getDescription()
065        {
066                return "Generates events for an IP over WDM multilayer network, with an IP/OSPF layer on top of a WDM layer where lightpaths are carried in a fixed grid of wavelengths";
067        }
068
069        @Override
070        public List<Triple<String, String, String>> getParameters()
071        {
072                /* Returns the parameter information for all the InputParameter objects defined in this object (uses Java reflection) */
073                return InputParameter.getInformationAllInputParameterFieldsOfObject(this);
074        }
075
076        @Override
077        public void initialize(NetPlan initialNetPlan, Map<String, String> algorithmParameters, Map<String, String> simulationParameters, Map<String, String> net2planParameters)
078        {
079                /* Initialize all InputParameter objects defined in this object (this uses Java reflection) */
080                InputParameter.initializeAllInputParameterFieldsOfObject(this, algorithmParameters);
081
082                final NetworkLayer ipLayer = initialNetPlan.getNetworkLayer("IP"); if (ipLayer == null) throw new Net2PlanException ("IP layer not found");
083                final NetworkLayer wdmLayer = initialNetPlan.getNetworkLayer("WDM"); if (wdmLayer == null) throw new Net2PlanException ("WDM layer not found");
084                if ((ipLayer == wdmLayer) || (initialNetPlan.getNumberOfLayers() != 2)) throw new Net2PlanException ("Wrong layer Ids (or the design does not have two layers)");
085
086                /* Initialize slow changing traffic */
087                if (!ipOverWdmFailureModel.getString ().equalsIgnoreCase("none"))
088                {
089                        switch (ipOverWdmFailureModel.getString ())
090                        {
091                                case "SRGfromNetPlan":
092                                        break;
093                                case "perNode":
094                                        SRGUtils.configureSRGs(initialNetPlan, ipOverWdmFailureDefaultMTTFInHours.getDouble(), ipOverWdmFailureDefaultMTTRInHours.getDouble(), SRGUtils.SharedRiskModel.PER_NODE, true , wdmLayer);
095                                        break;
096                                case "perLink":
097                                        SRGUtils.configureSRGs(initialNetPlan, ipOverWdmFailureDefaultMTTFInHours.getDouble(), ipOverWdmFailureDefaultMTTRInHours.getDouble(), SRGUtils.SharedRiskModel.PER_LINK, true , wdmLayer);
098                                        break;
099                                case "perDirectionalLinkBundle":
100                                        SRGUtils.configureSRGs(initialNetPlan, ipOverWdmFailureDefaultMTTFInHours.getDouble(), ipOverWdmFailureDefaultMTTRInHours.getDouble(), SRGUtils.SharedRiskModel.PER_DIRECTIONAL_LINK_BUNDLE, true , wdmLayer);
101                                        break;
102                                case "perBidirectionalLinkBundle":
103                                        SRGUtils.configureSRGs(initialNetPlan, ipOverWdmFailureDefaultMTTFInHours.getDouble(), ipOverWdmFailureDefaultMTTRInHours.getDouble(), SRGUtils.SharedRiskModel.PER_BIDIRECTIONAL_LINK_BUNDLE, true , wdmLayer);
104                                        break;
105                                default:
106                                        throw new Net2PlanException("Failure model not valid. Please, check algorithm parameters description");
107                        }
108                }
109
110                Map<String,String> generalEventGeneratorParam = new HashMap<String,String> ();
111                generalEventGeneratorParam.put ("_fail_failureModel" , ipOverWdmFailureModel.getString ().equalsIgnoreCase("none")? "none" : "SRGfromNetPlan"); // I create the SRGs here
112                generalEventGeneratorParam.put ("_tfFast_fluctuationType" , ipTFFastFluctuationType.getString ()); 
113                generalEventGeneratorParam.put ("_trafficType" , "non-connection-based"); 
114                generalEventGeneratorParam.put ("_tfSlow_fluctuationType" , ipTFSlowFluctuationType.getString ()); 
115                generalEventGeneratorParam.put ("_tfFast_fluctuationType" , ipTFFastFluctuationType.getString ()); 
116                generalEventGeneratorParam.put ("cac_arrivalsPattern" , "deterministic"); 
117                generalEventGeneratorParam.put ("trafficLayerId" , "" + wdmLayer.getId ()); 
118                generalEventGeneratorParam.put ("randomSeed" , "" + randomSeed.getLong()); 
119                generalEventGeneratorParam.put ("cac_avHoldingTimeHours" , "" + 1.0); 
120                generalEventGeneratorParam.put ("cac_defaultConnectionSizeTrafficUnits" , "" + 1.0); 
121                generalEventGeneratorParam.put ("tfFast_timeBetweenDemandFluctuationsHours" , "" + ipTFFastTimeBetweenDemandFluctuationsHours.getDouble()); 
122                generalEventGeneratorParam.put ("tfFast_fluctuationCoefficientOfVariation" , "" + ipTFFastFluctuationCoefficientOfVariation.getDouble()); 
123                generalEventGeneratorParam.put ("tfFast_maximumFluctuationRelativeFactor" , "" + ipTFFastMaximumFluctuationRelativeFactor.getDouble()); 
124                generalEventGeneratorParam.put ("tfSlow_startDate" , ipTFSlowStartDate.getString()); 
125                generalEventGeneratorParam.put ("tfSlow_timeBetweenDemandFluctuationsHours" , "" + ipTFSlowTimeBetweenDemandFluctuationsHours.getDouble()); 
126                generalEventGeneratorParam.put ("tfSlow_defaultTimezone" , "" + ipTFSlowDefaultTimezone.getInt()); 
127                generalEventGeneratorParam.put ("fail_defaultMTTFInHours" , "" + ipOverWdmFailureDefaultMTTFInHours.getDouble()); 
128                generalEventGeneratorParam.put ("fail_defaultMTTRInHours" , "" + ipOverWdmFailureDefaultMTTRInHours.getDouble()); 
129                generalEventGeneratorParam.put ("fail_statisticalPattern" , ipOverWDmFailureStatisticalPattern.getString ()); 
130                super.initialize(initialNetPlan , generalEventGeneratorParam , simulationParameters , net2planParameters);
131
132
133        
134        }
135
136        @Override
137        public void processEvent(NetPlan currentNetPlan, SimEvent event)
138        {
139//              this.generalEventGenerator.processEvent(currentNetPlan , event);
140                super.processEvent(currentNetPlan , event);
141        }
142
143}