/* * Title: CloudSimSDN * Description: SDN extension for CloudSim * Licence: GPL - http://www.gnu.org/copyleft/gpl.html * * Copyright (c) 2017, The University of Melbourne, Australia */ package org.cloudbus.cloudsim.sdn.parsers; import java.io.FileNotFoundException; import java.io.FileReader; import java.math.BigDecimal; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Map; import org.cloudbus.cloudsim.sdn.HostFactory; import org.cloudbus.cloudsim.sdn.HostFactorySimple; import org.cloudbus.cloudsim.sdn.nos.NetworkOperatingSystem; import org.cloudbus.cloudsim.sdn.nos.NetworkOperatingSystemSimple; import org.cloudbus.cloudsim.sdn.physicalcomponents.Link; import org.cloudbus.cloudsim.sdn.physicalcomponents.Node; import org.cloudbus.cloudsim.sdn.physicalcomponents.SDNHost; import org.cloudbus.cloudsim.sdn.physicalcomponents.switches.AggregationSwitch; import org.cloudbus.cloudsim.sdn.physicalcomponents.switches.CoreSwitch; import org.cloudbus.cloudsim.sdn.physicalcomponents.switches.EdgeSwitch; import org.cloudbus.cloudsim.sdn.physicalcomponents.switches.GatewaySwitch; import org.cloudbus.cloudsim.sdn.physicalcomponents.switches.IntercloudSwitch; import org.cloudbus.cloudsim.sdn.physicalcomponents.switches.Switch; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.json.simple.JSONValue; import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; /** * This class parses Physical Topology JSON file. * It supports multiple data centers. * * @author Jungmin Son * @since CloudSimSDN 1.0 */ public class PhysicalTopologyParser { private String filename; private Multimap<String, SDNHost> sdnHosts; private Multimap<String, Switch> switches; private List<Link> links = new ArrayList<Link>(); private Hashtable<String, Node> nameNodeTable = new Hashtable<String, Node>(); private HostFactory hostFactory = null; public PhysicalTopologyParser(String jsonFilename, HostFactory hostFactory) { sdnHosts = HashMultimap.create(); switches = HashMultimap.create(); this.hostFactory = hostFactory; this.filename = jsonFilename; } public static Map<String, NetworkOperatingSystem> loadPhysicalTopologyMultiDC(String physicalTopologyFilename) { PhysicalTopologyParser parser = new PhysicalTopologyParser(physicalTopologyFilename, new HostFactorySimple()); Map<String, String> dcNameType = parser.parseDatacenters(); // DC Name -> DC Type Map<String, NetworkOperatingSystem> netOsList = new HashMap<String, NetworkOperatingSystem>(); for(String dcName: dcNameType.keySet()) { NetworkOperatingSystem nos; nos = new NetworkOperatingSystemSimple("NOS_"+dcName); netOsList.put(dcName, nos); parser.parseNode(dcName); } parser.parseLink(); for(String dcName: dcNameType.keySet()) { if(!"network".equals(dcNameType.get(dcName))) { NetworkOperatingSystem nos = netOsList.get(dcName); nos.configurePhysicalTopology(parser.getHosts(dcName), parser.getSwitches(dcName), parser.getLinks()); } } for(String dcName: dcNameType.keySet()) { if("network".equals(dcNameType.get(dcName))) { NetworkOperatingSystem nos = netOsList.get(dcName); nos.configurePhysicalTopology(parser.getHosts(dcName), parser.getSwitches(dcName), parser.getLinks()); } } return netOsList; } public static void loadPhysicalTopologySingleDC(String physicalTopologyFilename, NetworkOperatingSystem nos, HostFactory hostFactory) { PhysicalTopologyParser parser = new PhysicalTopologyParser(physicalTopologyFilename, hostFactory); parser.parse(nos); nos.configurePhysicalTopology(parser.getHosts(), parser.getSwitches(), parser.getLinks()); } public Collection<SDNHost> getHosts() { return this.sdnHosts.values(); } public Collection<SDNHost> getHosts(String dcName) { return this.sdnHosts.get(dcName); } public Collection<Switch> getSwitches() { return this.switches.values(); } public Collection<Switch> getSwitches(String dcName) { return this.switches.get(dcName); } public List<Link> getLinks() { return this.links; } public Map<String, String> parseDatacenters() { HashMap<String, String> dcNameType = new HashMap<String, String>(); try { JSONObject doc = (JSONObject) JSONValue.parse(new FileReader(this.filename)); JSONArray datacenters = (JSONArray) doc.get("datacenters"); @SuppressWarnings("unchecked") Iterator<JSONObject> iter = datacenters.iterator(); while(iter.hasNext()){ JSONObject node = iter.next(); String dcName = (String) node.get("name"); String type = (String) node.get("type"); dcNameType.put(dcName, type); } } catch (FileNotFoundException e) { e.printStackTrace(); } return dcNameType; } private void parse(NetworkOperatingSystem nos) { parseNode(null); parseLink(); } public void parseNode(String datacenterName) { try { JSONObject doc = (JSONObject) JSONValue.parse(new FileReader(this.filename)); // Get Nodes (Switches and Hosts) JSONArray nodes = (JSONArray) doc.get("nodes"); @SuppressWarnings("unchecked") Iterator<JSONObject> iter =nodes.iterator(); while(iter.hasNext()){ JSONObject node = iter.next(); String nodeType = (String) node.get("type"); String nodeName = (String) node.get("name"); String dcName = (String) node.get("datacenter"); if(datacenterName != null && !datacenterName.equals(dcName)) { continue; } if(nodeType.equalsIgnoreCase("host")){ //////////////////////////////////////// // Host //////////////////////////////////////// long pes = (Long) node.get("pes"); long mips = (Long) node.get("mips"); int ram = new BigDecimal((Long)node.get("ram")).intValueExact(); long storage = (Long) node.get("storage"); long bw = new BigDecimal((Long)node.get("bw")).intValueExact(); int num = 1; if (node.get("nums")!= null) num = new BigDecimal((Long)node.get("nums")).intValueExact(); for(int n = 0; n< num; n++) { String nodeName2 = nodeName; if(num >1) nodeName2 = nodeName + n; SDNHost sdnHost = hostFactory.createHost(ram, bw, storage, pes, mips, nodeName); nameNodeTable.put(nodeName2, sdnHost); //hostId++; this.sdnHosts.put(dcName, sdnHost); } } else { //////////////////////////////////////// // Switch //////////////////////////////////////// int MAX_PORTS = 256; long bw = new BigDecimal((Long)node.get("bw")).longValueExact(); long iops = (Long) node.get("iops"); int upports = MAX_PORTS; int downports = MAX_PORTS; if (node.get("upports")!= null) upports = new BigDecimal((Long)node.get("upports")).intValueExact(); if (node.get("downports")!= null) downports = new BigDecimal((Long)node.get("downports")).intValueExact(); Switch sw = null; if(nodeType.equalsIgnoreCase("core")) { sw = new CoreSwitch(nodeName, bw, iops, upports, downports); } else if (nodeType.equalsIgnoreCase("aggregate")){ sw = new AggregationSwitch(nodeName, bw, iops, upports, downports); } else if (nodeType.equalsIgnoreCase("edge")){ sw = new EdgeSwitch(nodeName, bw, iops, upports, downports); } else if (nodeType.equalsIgnoreCase("intercloud")){ sw = new IntercloudSwitch(nodeName, bw, iops, upports, downports); } else if (nodeType.equalsIgnoreCase("gateway")){ // Find if this gateway is already created? If so, share it! if(nameNodeTable.get(nodeName) != null) sw = (Switch)nameNodeTable.get(nodeName); else sw = new GatewaySwitch(nodeName, bw, iops, upports, downports); } else { throw new IllegalArgumentException("No switch found!"); } if(sw != null) { nameNodeTable.put(nodeName, sw); this.switches.put(dcName, sw); } } } } catch (FileNotFoundException e) { e.printStackTrace(); } } public void parseLink() { try { JSONObject doc = (JSONObject) JSONValue.parse(new FileReader(this.filename)); JSONArray links = (JSONArray) doc.get("links"); @SuppressWarnings("unchecked") Iterator<JSONObject> linksIter =links.iterator(); while(linksIter.hasNext()){ JSONObject link = linksIter.next(); String src = (String) link.get("source"); String dst = (String) link.get("destination"); double lat = (Double) link.get("latency"); Node srcNode = nameNodeTable.get(src); Node dstNode = nameNodeTable.get(dst); Link l = new Link(srcNode, dstNode, lat, -1); // Temporary Link (blueprint) to create the real one in NOS this.links.add(l); } } catch (FileNotFoundException e) { e.printStackTrace(); } } public Hashtable<String, Node> getNameNode() { return nameNodeTable; } }