001package com.net2plan.examples.general.offline.metrohaul;
002
003import com.net2plan.interfaces.networkDesign.IAlgorithm;
004import com.net2plan.interfaces.networkDesign.Net2PlanException;
005import com.net2plan.interfaces.networkDesign.NetPlan;
006import com.net2plan.research.niw.networkModel.*;
007import com.net2plan.utils.InputParameter;
008import com.net2plan.utils.Triple;
009
010import java.io.File;
011import java.util.*;
012
013public class TutorialAlgorithm implements IAlgorithm
014{
015        private InputParameter linerate_Gbps            = new InputParameter("linerate_Gbps", 40.0, "Linerate (in Gbps) per ligthpath", 1.0, true, 1000.0, true);
016        private InputParameter slotsPerLightpath        = new InputParameter("slotsPerLightpath", 4, "Number of occupied slots per lightpath", 1, Integer.MAX_VALUE);
017        private InputParameter K                        = new InputParameter("K", 3, "Number of candidate shortest paths to compute per LP/SC", 1, 100);
018        private InputParameter trafficIntensityTimeSlot = new InputParameter("trafficIntensityTimeSlot", "#select# Morning Afternoon Evening", "Traffic intensity per time slot (as defined in the design/spreadsheet");
019
020        public static void main(String[] args)
021        {
022                NetPlan netPlan = NetPlan.loadFromFile(new File("Tutorial_excel.n2p"));
023                Map<String, String> parameters = new HashMap<>();
024                parameters.put("linerate_Gbps", String.valueOf(40.0));
025                parameters.put("slotsPerLightpath", String.valueOf(4));
026                parameters.put("K", String.valueOf(3));
027                parameters.put("trafficIntensityTimeSlot", "Morning");
028
029                TutorialAlgorithm tutorialAlgorithm = new TutorialAlgorithm();
030                tutorialAlgorithm.getParameters();
031                System.out.println(tutorialAlgorithm.executeAlgorithm(netPlan, parameters, null));
032                netPlan.saveToFile(new File("RESULT.n2p"));
033        }
034
035        @Override
036        public String executeAlgorithm(NetPlan netPlan, Map<String, String> algorithmParameters, Map<String, String> net2planParameters)
037        {
038                //First of all, initialize all parameters
039                InputParameter.initializeAllInputParameterFieldsOfObject(this, algorithmParameters);
040
041                final WNet wNet = new WNet(netPlan);
042                final OpticalSpectrumManager osm = OpticalSpectrumManager.createFromRegularLps(wNet);
043                //Perform here initial checks
044
045                /* Remove any existing lightpath, VNF instances and any existing service chain */
046                for(WLightpathRequest lpr : wNet.getLightpathRequests())
047                        lpr.remove(); // this removes also the lps
048
049                for(WVnfInstance vnf : wNet.getVnfInstances())
050                        vnf.remove();
051
052                for(WServiceChain sc : wNet.getServiceChains())
053                        sc.remove();
054
055                /* Add full mesh of lightpaths and IP links */
056                for(WNode node1 : wNet.getNodes())
057                {
058                        for(WNode node2 : wNet.getNodes())
059                        {
060                                if(node1.equals(node2)) continue;
061                                List<List<WFiber>> paths = wNet.getKShortestWdmPath(K.getInt(), node1, node2, Optional.empty());
062                                Optional<SortedSet<Integer>> slotsRange = Optional.empty();
063                                List<WFiber> selectedPath = null;
064                                for(List<WFiber> path : paths)
065                                {
066                                        slotsRange = osm.spectrumAssignment_firstFit(path, slotsPerLightpath.getInt(), Optional.empty());
067                                        if(slotsRange.isPresent())
068                                        {
069                                                selectedPath = path;
070                                                break;
071                                        }
072                                }
073                                if(! slotsRange.isPresent()) throw new Net2PlanException("No wavelengths found to allocate a lightpath between " + node1.getName() + " and " + node2.getName());
074                                WLightpathRequest lpr = wNet.addLightpathRequest(node1, node2, linerate_Gbps.getDouble(), false);
075                                WLightpathUnregenerated lp = lpr.addLightpathUnregenerated(selectedPath, slotsRange.get(), false);
076                                osm.allocateOccupation(lp, selectedPath, slotsRange.get());
077
078                                // Create IP link and couple it with the LP
079                                WIpLink ipLink = wNet.addIpLink(node1, node2, linerate_Gbps.getDouble(), false).getFirst();
080                                lpr.coupleToIpLink(ipLink);
081                        }
082                }
083
084                /* Create one VNF per type in all the nodes */
085                for(WNode n : wNet.getNodes())
086                        for(WVnfType vnfType : wNet.getVnfTypes())
087                        {
088                                if(vnfType.isConstrainedToBeInstantiatedOnlyInUserDefinedNodes())
089                                        if(! vnfType.getValidMetroNodesForInstantiation().contains(n.getName()))
090                                                continue;
091                                wNet.addVnfInstance(n, vnfType.getVnfTypeName(), vnfType);
092                        }
093
094                /* Deploy service chain */
095                for(WServiceChainRequest serviceChainRequest : wNet.getServiceChainRequests())
096                {
097                        final Optional<Double> ti = serviceChainRequest.getTrafficIntensityInfo(trafficIntensityTimeSlot.getString());
098                        if(! ti.isPresent())
099                        {
100                                System.out.println("No traffic intensity defined (" + trafficIntensityTimeSlot.getInt() + ") for SC " + serviceChainRequest.getId());
101                                continue;
102                        }
103                        final SortedSet<WNode> potentialOrigins = serviceChainRequest.getPotentiallyValidOrigins();
104                        final SortedSet<WNode> potentialDestinations = serviceChainRequest.getPotentiallyValidDestinations();
105                        final List<String> vnfsToTraverse = serviceChainRequest.getSequenceVnfTypes();
106
107                        boolean isSCAllocated = false;
108                        for(WNode origin : potentialOrigins)
109                        {
110                                for(WNode destination : potentialDestinations)
111                                {
112                                        final List<List<? extends WAbstractNetworkElement>> paths = wNet.getKShortestServiceChainInIpLayer(K.getInt(), origin, destination, vnfsToTraverse, Optional.empty(), Optional.empty());
113                                        if(paths.isEmpty()) continue;
114                                        isSCAllocated = true;
115                                        WServiceChain serviceChain = serviceChainRequest.addServiceChain(paths.get(0), ti.get());
116                                }
117                                if(isSCAllocated) break;
118                        }
119                }
120
121                /* Dimension the VNF instances, consuming the resources CPU, HD, RAM */
122                for(WVnfInstance vnf : wNet.getVnfInstances())
123                        vnf.scaleVnfCapacityAndConsumptionToBaseInstanceMultiple();
124
125                /* Remove those VNF instances that have zero capacity */
126                for(WVnfInstance vnf : wNet.getVnfInstances())
127                        if(vnf.getOccupiedCapacityInGbps() == 0)
128                                vnf.remove();
129
130                // Extra: consider service chain injected traffic as the worst case among the morning/afternoon/night
131
132                // Extra: make each lightpath be 1+1 protected with a link disjoint lightpath if possible [e.g. choose the main path as now, and the backup choose it as the one in the k-ranking with less common links, and among them, the one of lower length]
133
134                // Extra: some nodes may have consumed more CPUs/RAM/HD than they have... what to do with them
135
136                // Extra: some IP links may have more traffic than they can carry... what to do with them
137
138                return "Ok";
139        }
140
141        @Override
142        public String getDescription()
143        {
144                return null;
145        }
146
147        @Override
148        public List<Triple<String, String, String>> getParameters()
149        {
150                return InputParameter.getInformationAllInputParameterFieldsOfObject(this);
151        }
152}