<commit_before>package eu.netide.configuration.generator

import Topology.Connector
import Topology.Controller
import Topology.Host
import Topology.NetworkElement
import Topology.NetworkEnvironment
import Topology.Switch
import eu.netide.configuration.utils.fsa.FileSystemAccess
import org.eclipse.emf.ecore.resource.Resource

/**
 * Generates a Mininet configuration based on the specified topology model
 * 
 * @author <NAME>
 */
class ConfigurationGenerator  {

	var nodemap = newHashMap()

	def doGenerate(Resource input, FileSystemAccess fsa) {
		var ne = input.allContents.filter(typeof(NetworkEnvironment)).next

		populateNodeMap(ne)

		fsa.generateFile("mininet/" + ne.envName + ".py", ne.compileTopo)
		fsa.generateFile("mininet/" + ne.envName + "_run.py", ne.compileRunscript)
	}

	def populateNodeMap(NetworkEnvironment ne) {
		var scounter = 1
		var switches = ne.networks.map[networkelements].flatten.filter(typeof(Switch))
		var all_sdpid = switches.map[dpid]
		for (s : switches) {
			if (s.dpid != "-1" && Integer.decode("0x"+s.dpid) > 0) {
				nodemap.put(s.fullname, s.dpid)
			} else {
				while (all_sdpid.toSet.contains(scounter))
					scounter++
				nodemap.put(s.fullname, scounter++)
			}

		}

		var hcounter = 1
		var hosts = ne.networks.map[networkelements].flatten.filter(typeof(Host))
		var all_hdpid = switches.map[dpid]
		for (h : hosts) {
			if (h.dpid != "-1" && Integer.decode("0x"+h.dpid) > 0) {
				nodemap.put(h.fullname, h.dpid)
			} else {
				while (all_hdpid.toSet.contains(hcounter))
					hcounter++
				nodemap.put(h.fullname, hcounter++)
			}

		}

		var ccounter = 1
		for (c : ne.controllers)
			nodemap.put(c.name, ccounter++)

	}

	def compileTopo(NetworkEnvironment ne) {

		var switches = ne.networks.map[networkelements].flatten.filter(typeof(Switch))
		var hosts = ne.networks.map[networkelements].flatten.filter(typeof(Host))
		var connectors = ne.networks.map[connectors].flatten.filter(typeof(Connector))
		var hasIPs = switches.exists[x|x.ip != null && x.ip != ""] || hosts.exists[x|x.ip != null && x.ip != ""]

		return '''
			from mininet.topo import Topo
			from mininet.node import Controller, RemoteController
			
			
			def int2dpid( dpid ):
			   try:
			      dpid = hex( dpid )[ 2: ]
			      dpid = '0' * ( 16 - len( dpid ) ) + dpid
			      return dpid
			   except IndexError:
			      raise Exception( 'Unable to derive default datapath ID - '
			                       'please either specify a dpid or use a '
			               'canonical switch name such as s23.' )
			
			class «ne.envName» (Topo):
			    
			    def __init__( self ):
			    
			        Topo.__init__(self)
			    
			        # Adding Switches
			        «FOR Switch s : switches»
			        	self.«s.fullname» = self.addSwitch('«s.fullname»', dpid='«nodemap.get(s.fullname)»'«IF !(s.mac == null || s.mac.empty)», mac='«s.mac»'«ENDIF»)
			        «ENDFOR»
			        
			        # Adding Hosts
			        «FOR Host h : hosts»
			        	self.«h.fullname» = self.addHost('«h.fullname»'«IF !(h.ip == null || h.ip.empty)», ip='«h.ip»'«ENDIF»«IF !(h.mac == null || h.mac.empty)», mac='«h.mac»'«ENDIF»)
			        «ENDFOR»
			        
			        # Adding Links
			        «FOR Connector c : connectors»
			        	self.addLink(self.«c.connectedports.get(0).networkelement.fullname», self.«c.connectedports.get(1).networkelement.fullname»)
			        «ENDFOR»
			        
«««			    «IF hasIPs»
«««			    def SetIPConfiguration(self, net):
«««			        «FOR s : switches»
«««			        «IF s.ip != null && s.ip != ""»
«««			            net.get("«s.fullname»").setIP("«s.ip»"«IF s.prefix > 0», "«s.prefix»"«ENDIF»)
«««			        «ENDIF»
«««			        «ENDFOR»
«««			        «FOR h : hosts»
«««			        «IF h.ip != null && h.ip != ""»<commit_msg>int2dpid call for configuration generator<commit_after>package eu.netide.configuration.generator

import Topology.Connector
import Topology.Controller
import Topology.Host
import Topology.NetworkElement
import Topology.NetworkEnvironment
import Topology.Switch
import eu.netide.configuration.utils.fsa.FileSystemAccess
import org.eclipse.emf.ecore.resource.Resource

/**
 * Generates a Mininet configuration based on the specified topology model
 * 
 * @author <NAME>
 */
class ConfigurationGenerator  {

	var nodemap = newHashMap()

	def doGenerate(Resource input, FileSystemAccess fsa) {
		var ne = input.allContents.filter(typeof(NetworkEnvironment)).next

		populateNodeMap(ne)

		fsa.generateFile("mininet/" + ne.envName + ".py", ne.compileTopo)
		fsa.generateFile("mininet/" + ne.envName + "_run.py", ne.compileRunscript)
	}

	def populateNodeMap(NetworkEnvironment ne) {
		var scounter = 1
		var switches = ne.networks.map[networkelements].flatten.filter(typeof(Switch))
		var all_sdpid = switches.map[dpid]
		for (s : switches) {
			if (s.dpid != "-1" && Integer.decode("0x"+s.dpid) > 0) {
				nodemap.put(s.fullname, s.dpid)
			} else {
				while (all_sdpid.toSet.contains(scounter))
					scounter++
				nodemap.put(s.fullname, scounter++)
			}

		}

		var hcounter = 1
		var hosts = ne.networks.map[networkelements].flatten.filter(typeof(Host))
		var all_hdpid = switches.map[dpid]
		for (h : hosts) {
			if (h.dpid != "-1" && Integer.decode("0x"+h.dpid) > 0) {
				nodemap.put(h.fullname, h.dpid)
			} else {
				while (all_hdpid.toSet.contains(hcounter))
					hcounter++
				nodemap.put(h.fullname, hcounter++)
			}

		}

		var ccounter = 1
		for (c : ne.controllers)
			nodemap.put(c.name, ccounter++)

	}

	def compileTopo(NetworkEnvironment ne) {

		var switches = ne.networks.map[networkelements].flatten.filter(typeof(Switch))
		var hosts = ne.networks.map[networkelements].flatten.filter(typeof(Host))
		var connectors = ne.networks.map[connectors].flatten.filter(typeof(Connector))
		var hasIPs = switches.exists[x|x.ip != null && x.ip != ""] || hosts.exists[x|x.ip != null && x.ip != ""]

		return '''
			from mininet.topo import Topo
			from mininet.node import Controller, RemoteController
			
			
			def int2dpid( dpid ):
			   try:
			      dpid = hex( dpid )[ 2: ]
			      dpid = '0' * ( 16 - len( dpid ) ) + dpid
			      return dpid
			   except IndexError:
			      raise Exception( 'Unable to derive default datapath ID - '
			                       'please either specify a dpid or use a '
			               'canonical switch name such as s23.' )
			
			class «ne.envName» (Topo):
			    
			    def __init__( self ):
			    
			        Topo.__init__(self)
			    
			        # Adding Switches
			        «FOR Switch s : switches»
			        	self.«s.fullname» = self.addSwitch('«s.fullname»', dpid=int2dpid(«nodemap.get(s.fullname)»)«IF !(s.mac == null || s.mac.empty)», mac='«s.mac»'«ENDIF»)
			        «ENDFOR»
			        
			        # Adding Hosts
			        «FOR Host h : hosts»
			        	self.«h.fullname» = self.addHost('«h.fullname»'«IF !(h.ip == null || h.ip.empty)», ip='«h.ip»'«ENDIF»«IF !(h.mac == null || h.mac.empty)», mac='«h.mac»'«ENDIF»)
			        «ENDFOR»
			        
			        # Adding Links
			        «FOR Connector c : connectors»
			        	self.addLink(self.«c.connectedports.get(0).networkelement.fullname», self.«c.connectedports.get(1).networkelement.fullname»)
			        «ENDFOR»
			        
«««			    «IF hasIPs»
«««			    def SetIPConfiguration(self, net):
«««			        «FOR s : switches»
«««			        «IF s.ip != null && s.ip != ""»
«««			            net.get("«s.fullname»").setIP("«s.ip»"«IF s.prefix > 0», "«s.prefix»"«ENDIF»)
«««			        «ENDIF»
«««			        «ENDFOR»
«««			        «FOR h : hosts»
«««			        «IF h.ip != null && h.ip != ""»
{'fraction_non_alphanumeric': 0.15101289134438306, 'fraction_numerical': 0.005261773217574322, 'mean_word_length': 2.6500240038406147, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3146909', 'n_tokens_mistral': 3101, 'n_tokens_neox': 2648, 'n_words': 750}