Virtlab:Řídící server/Mapping.php.inc
Z VirtlabWiki
< Virtlab:Řídící server(Rozdíly mezi verzemi)
Verze z 10:16, 22. 10. 2007 Vav166 (Diskuse | příspěvky) ← Předchozí porovnání |
Aktuální verze Vav166 (Diskuse | příspěvky) |
||
Řádka 1: | Řádka 1: | ||
- | Tato třída implementuje vlastní namapování laboratorních prvků na prvky v logické topologii, tak aby byly splněny všechny podmínky. | + | Tato třída (virtlabMapping) implementuje vlastní namapování laboratorních prvků na prvky v logické topologii, tak aby byly splněny všechny podmínky. |
- | '''Zatím není plně dokončeno - pokud mapovaní nelze provést je proveden jen vypis oznamení.''' | + | '''Poznámka: podrobné výpisy z průběhu algoritmu, jsou [[Virtlab:Řídící server/Mapovací algoritmus|zde]].''' |
- | + | ||
- | == Proměnné == | + | |
- | ; equipment : odkaz na objekt <tt>virtlabParserEquipment</tt>, který poskytuje data o laboratorních prvcích | + | |
- | ; topology : odkaz na objekt <tt>virtlabParserTopology</tt>, který poskytuje data o logické topologii | + | |
- | + | ||
- | == Metody == | + | |
- | ; function __construct(virtlabParserEquipment $equip, virtlabParserTopology $topol) : konstruktor třídy v PHP5. Jako parametry očekává objekty jednotlivých parseru - [[Virtlab:ParserTopology.php.inc|virtuální topologie]] a [[Virtlab:ParserEquipment.php.inc|vybavení]] | + | |
- | ; public function Evaluate($device) : vrátí vypočtenou hodnotu (tu ovlivnňuje typ laboratorního prvku, počet rozhrani, ...) zadaného lab. prvku. Nastavení konstant třídy [[Virtlab:Values.php.inc|virtlabValues]] ovlivní výslednou hodnotu. | + | |
- | ; public function DevicesValue() : vrátí pole všech laboratorních prvků s jejich vypočtenou hodnotou | + | |
- | ; public function Availability($device, $vertex) : zjistí, zda-li může být zadaný laboratorní prvek, zařízením v logické topologii. Pokud '''ano''', vrátí pole s určením, která rozhraní mohou být použita, na kterých linkách logické topologie. Pokud '''ne''', vrátí číslo chyby - definováno ve třídě [[Virtlab:Values.php.inc|virtlabValues]]. | + | |
- | ; private function Mapping($map2, &$vysledek) : '''rekurzivní''' funkce, která se snaží mapovat. Ve dvojrozměrné poli <tt>$map2</tt> je uloženo, který ''vertex'' může být realizován jakými ''device''. Případný vysledek mapovaní je uložen do proměnné <tt>$vysledek</tt>. (viz příklady) ''Pozn.: tato funkce je psána obecně, takže je ve druhém kroku je znovu použita na mapovaní LINKA-ROZHRANÍ.'' Podrobnější informace k algoritmu rekuzivní funkce jsou [[Virtlab:Mapovací algoritmus|zde]]. | + | |
- | ; public function Map() : funkce obstarávající [[Virtlab:Mapovací algoritmus|celý algoritmus mapování]]. | + | |
- | + | ||
- | == Příklady == | + | |
- | Výsledný výstup: | + | |
- | '''$mapper->Map();''' | + | |
- | r21:s0/0 r11:s0/0 | + | |
- | r21:s0/1 r10:s0/0 | + | |
- | r42:gi7 r21:fa3 | + | |
- | r41:gi7 r21:fa2 | + | |
- | r41:gi6 r11:gi1 | + | |
- | r42:gi6 r10:gi1 | + | |
- | r42:gi5 r11:gi0 | + | |
- | r41:gi5 r10:gi0 | + | |
- | + | ||
- | '''Poznámka: podrobné výpisy z průběhu algoritmu, jsou [[Virtlab:Mapovací algoritmus|zde]].''' | + | |
== Zdrojový kód == | == Zdrojový kód == | ||
- | <pre> | + | Aktuální verze se nachází [https://vl-test.cs.vsb.cz/websvn/filedetails.php?repname=virtlab&path=%2FDISTR%2Fweb%2Fclass%2FvirtlabMapping.php.inc&rev=0&sc=0 zde] |
- | <?php | + | |
- | + | ||
- | class virtlabMapping { | + | |
- | private $equipment = NULL; | + | |
- | private $topology = NULL; | + | |
- | + | ||
- | function __construct(virtlabParserEquipment $equip, virtlabParserTopology $topol) { | + | |
- | $this->equipment = $equip; | + | |
- | $this->topology = $topol; | + | |
- | }//konstruktor | + | |
- | + | ||
- | public function Evaluate($device) { | + | |
- | $hodnota = 0; | + | |
- | $eq = $this->equipment; //pointer to equipment | + | |
- | + | ||
- | $temp = $eq->getDeviceFeatures($device); | + | |
- | $hodnota += count($temp) * virtlabValues::DeviceFeature; | + | |
- | + | ||
- | $temp = $eq->getDeviceInterfacesFeatures($device); | + | |
- | $hodnota += count($temp) * virtlabValues::InterfaceFeature; | + | |
- | + | ||
- | for($i = $eq->getDeviceInterfacesCount($device) - 1; $i >= 0; $i--) { | + | |
- | $technology = $eq->getDeviceInterfaceTechnology($device, $i); | + | |
- | + | ||
- | if($technology == "ethernet") { | + | |
- | $inf = virtlabValues::InterfaceTechnologyEthernet; | + | |
- | $ether_type = $eq->getDeviceInterfaceEthertype($device, $i); | + | |
- | if($ether_type == "legacy") | + | |
- | $inf *= virtlabValues::EthertypeMultiplerLegacy; | + | |
- | else if($ether_type == "fast") | + | |
- | $inf *= virtlabValues::EthertypeMultiplerFast; | + | |
- | else if($ether_type == "gigabit") | + | |
- | $inf *= virtlabValues::EthertypeMultiplerGigabit; | + | |
- | else $inf *= 0; //error | + | |
- | + | ||
- | $hodnota += $inf; | + | |
- | }//if:ethernet | + | |
- | else if($technology == "serial") { | + | |
- | $inf = virtlabValues::InterfaceTechnologySerial; | + | |
- | $bps = $eq->getDeviceInterfaceMaxbps($device, $i); | + | |
- | + | ||
- | if(is_null($bps)) $bps = virtlabValues::defaultMaxbps; //error | + | |
- | + | ||
- | if((int)$bps < virtlabValues::bpsDefault) | + | |
- | $inf = (int)((double)$inf * virtlabValues::bpsLower); | + | |
- | else if((int)$bps > virtlabValues::bpsDefault) | + | |
- | $inf = (int)((double)$inf * virtlabValues::bpsBigger); | + | |
- | + | ||
- | $hodnota += $inf; | + | |
- | }//else-if:serial | + | |
- | }//for-interfaces | + | |
- | return $hodnota; | + | |
- | }//function-Evaluate | + | |
- | + | ||
- | + | ||
- | public function DevicesValue() { | + | |
- | $tmp = array(); | + | |
- | $devices = $this->equipment->getDevicesList(); | + | |
- | foreach($devices as $device) { | + | |
- | $tmp[$device] = $this->Evaluate($device); | + | |
- | }//foreach | + | |
- | return $tmp; | + | |
- | }//function-DevicesValue | + | |
- | + | ||
- | + | ||
- | public function Availability($device, $vertex) { | + | |
- | $device_idx = NULL; | + | |
- | $eq = $this->equipment; //pointer to equipment | + | |
- | $to = $this->topology; //pointer to topology | + | |
- | + | ||
- | $eq->getDeviceByName($device, &$device_idx); | + | |
- | + | ||
- | + | ||
- | //type | + | |
- | $tmp_e = $eq->getDeviceType($device_idx); | + | |
- | $tmp_t = $to->getVertexType($vertex); | + | |
- | if($tmp_e != $tmp_t) return virtlabValues::badType; | + | |
- | //print("Same type\n"); | + | |
- | + | ||
- | + | ||
- | //platform | + | |
- | $tmp_e = $eq->getDevicePlatform($device_idx); | + | |
- | $tmp_t = $to->getVertexPlatforms($vertex, 1); | + | |
- | $tmp_platf = 0; | + | |
- | if(!is_null($tmp_t)) { | + | |
- | foreach($tmp_t as $hodnota) { | + | |
- | $pattern = "/" . $hodnota . "/"; | + | |
- | if(preg_match($pattern, $tmp_e)) { | + | |
- | $tmp_platf = 1; | + | |
- | break; | + | |
- | }//if-preg_match | + | |
- | }//foreach | + | |
- | if(!$tmp_platf) return virtlabValues::badPlatform; | + | |
- | }//if-compare | + | |
- | unset($tmp_platf); | + | |
- | //print("Good platform\n"); | + | |
- | + | ||
- | + | ||
- | //OS | + | |
- | $tmp_e = $eq->getDeviceOS($device, 1); | + | |
- | $tmp_t = $to->getVertexOS($vertex, 1); | + | |
- | $pattern = "/" . $tmp_t . "/"; | + | |
- | if(!preg_match($pattern, $tmp_e)) return virtlabValues::badOS; | + | |
- | unset($pattern); | + | |
- | //print("Good OS\n"); | + | |
- | + | ||
- | + | ||
- | //device features | + | |
- | $tmp_e = $eq->getDeviceFeatures($device); | + | |
- | $tmp_t = $to->getVertexFeatures($vertex); | + | |
- | if(count(array_diff((array)$tmp_t,(array)$tmp_e)) > 0) return virtlabValues::noDeviceFeature; | + | |
- | //print("Device features-OK\n"); | + | |
- | + | ||
- | + | ||
- | //enough interfaces | + | |
- | $tmp_t_if = array(); | + | |
- | $tmp_e_if = array(); | + | |
- | $tmp_t = $to->getEdgesByVertex($vertex); | + | |
- | foreach($tmp_t as $edge_idx => $edge) { | + | |
- | $tmp_tech = $to->getEdgeTechnology($edge_idx); | + | |
- | array_push($tmp_t_if, $tmp_tech); | + | |
- | }//foreach | + | |
- | for($i = $eq->getDeviceInterfacesCount($device) - 1; $i>=0; $i--) { | + | |
- | $tmp_tech = $eq->getDeviceInterfaceTechnology($device, $i); | + | |
- | array_push($tmp_e_if, $tmp_tech); | + | |
- | }//for | + | |
- | $tmp_res = array_porovnej($tmp_t_if, $tmp_e_if); //intersect of multisets | + | |
- | if(count($tmp_res) != 0) return virtlabValues::notEnoughInterfaces; | + | |
- | unset($tmp_t_if, $tmp_e_if, $tmp_res); | + | |
- | + | ||
- | + | ||
- | //interfaces | + | |
- | $tmp_t = $to->getEdgesByVertex($vertex); | + | |
- | $result = array(); | + | |
- | foreach($tmp_t as $idx => $edge) { | + | |
- | $result[$edge] = array(); | + | |
- | + | ||
- | for($i = $eq->getDeviceInterfacesCount($device) - 1; $i >= 0; $i--) { | + | |
- | + | ||
- | $tmp_e_fea = $eq->getDeviceInterfaceFeatures($device, $i); | + | |
- | if(is_null($tmp_e_fea)) $tmp_e_fea = array(); | + | |
- | $tmp_t_fea = $to->getEdgeFeatures($idx); | + | |
- | if(is_null($tmp_t_fea)) $tmp_t_fea = array(); | + | |
- | if(array_diff($tmp_t_fea, $tmp_e_fea)) continue; //uncompatible interface features -> next interface | + | |
- | + | ||
- | if($eq->getDeviceInterfaceTechnology($device, $i) == $to->getEdgeTechnology($idx)) { | + | |
- | if($to->getEdgeTechnology($idx) == "serial") { | + | |
- | if(is_null($to->getEdgeMinbps($idx))) { | + | |
- | $result[$edge][$i] = $eq->getDeviceInterfaceName($device, $i); | + | |
- | continue; | + | |
- | }//if-minbps=NULL | + | |
- | + | ||
- | if(is_null($eq->getDeviceInterfaceMaxbps($device, $i))) | + | |
- | $tmp_maxbps = virtlabValues::defaultMaxbps; //error avoidance | + | |
- | else $tmp_maxbps = $eq->getDeviceInterfaceMaxbps($device, $i); | + | |
- | if($to->getEdgeMinbps($idx) > $tmp_maxbps) continue; //slow serial interface -> next inteface | + | |
- | + | ||
- | $result[$edge][$i] = $eq->getDeviceInterfaceName($device, $i); | + | |
- | + | ||
- | }//if-technology=serial | + | |
- | else if($to->getEdgeTechnology($idx) == "ethernet") { | + | |
- | if(is_null($to->getEdgeEthertype($idx))) { | + | |
- | $result[$edge][$i] = $eq->getDeviceInterfaceName($device, $i); | + | |
- | continue; | + | |
- | }//if-ethertype-topology=NULL | + | |
- | + | ||
- | if(is_null($eq->getDeviceInterfaceEthertype($device, $i))) | + | |
- | $tmp_e_ethertype = virtlabValues::defaultEthertype; //error avoidance | + | |
- | else $tmp_e_ethertype = $eq->getDeviceInterfaceEthertype($device, $i); | + | |
- | + | ||
- | $tmp_t_ethertype = $to->getEdgeEthertype($idx); | + | |
- | + | ||
- | //if slower ethernet -> next interface | + | |
- | if($tmp_t_ethertype == "fast" && $tmp_e_ethertype == "legacy") continue; | + | |
- | else if($tmp_t_ethertype == "gigabit" && $tmp_e_ethertype == "legacy") continue; | + | |
- | else if($tmp_t_ethertype == "gigabit" && $tmp_e_ethertype == "fast") continue; | + | |
- | + | ||
- | $result[$edge][$i] = $eq->getDeviceInterfaceName($device, $i); | + | |
- | }//if-technology=ethernet | + | |
- | }//if-same technology | + | |
- | }//for - interfaces | + | |
- | }//foreach | + | |
- | + | ||
- | foreach($result as $hodnota) { | + | |
- | if(!$hodnota) return virtlabValues::VertexDeviceMismatch; //some edge has no compatible interface | + | |
- | }//foreach | + | |
- | + | ||
- | return $result; | + | |
- | }//function | + | |
- | + | ||
- | private function Mapping($map2, &$vysledek) {//recursive | + | |
- | foreach($map2 as $vertex => $devices) { | + | |
- | if(count($devices) == 0) return 0; //some vertex cannot be mapped | + | |
- | }//foreach | + | |
- | + | ||
- | if(count($map2) == 1) { | + | |
- | foreach($map2 as $vertex => $devices) { | + | |
- | if(count($devices) == 0) return 0; //cannot be mapped | + | |
- | foreach($devices as $device => $cena) { | + | |
- | $tmp["vertex"] = $vertex; | + | |
- | $tmp["device"] = $device; | + | |
- | array_push($vysledek, $tmp); | + | |
- | return 1; | + | |
- | }//foreach | + | |
- | }//foreach | + | |
- | }//if - count=1 | + | |
- | else { | + | |
- | foreach($map2 as $vertex => $devices) { //exist vertex with one possibly device | + | |
- | if(count($devices) == 1) { | + | |
- | foreach($devices as $device => $cena) { | + | |
- | MatrixClear($map2, $vertex, $device); | + | |
- | if($this->Mapping($map2, $vysledek)) { //if mapping $vertex to $device is good | + | |
- | $tmp["vertex"] = $vertex; | + | |
- | $tmp["device"] = $device; | + | |
- | array_push($vysledek, $tmp); | + | |
- | return 1; | + | |
- | }//if | + | |
- | else return 0; //bad choice | + | |
- | }//foreach | + | |
- | }//if | + | |
- | }//foreach-vertex with one poss device | + | |
- | + | ||
- | foreach($map2 as $vertex => $devices) { | + | |
- | foreach($devices as $device => $cena) { | + | |
- | MatrixClear($map2,$vertex,$device); | + | |
- | if($this->Mapping($map2, $vysledek)) { | + | |
- | $tmp["vertex"] = $vertex; | + | |
- | $tmp["device"] = $device; | + | |
- | array_push($vysledek, $tmp); | + | |
- | return 1; | + | |
- | }//if | + | |
- | }//foreach | + | |
- | return 0; //no mapping is possible | + | |
- | }//general | + | |
- | }//else | + | |
- | }//function | + | |
- | + | ||
- | + | ||
- | public function Map() { | + | |
- | $devices = $this->equipment->getDevicesList(); | + | |
- | $vertexes = $this->topology->getVertexesList(); | + | |
- | + | ||
- | $map = array(); | + | |
- | foreach($vertexes as $vertex) { | + | |
- | foreach($devices as $device) { | + | |
- | $vysledek = $this->Availability($device,$vertex); | + | |
- | + | ||
- | if(is_array($vysledek)) $map[$vertex][$device] = $vysledek; | + | |
- | else $map[$vertex][$device] = 0; | + | |
- | }//foreach | + | |
- | }//foreach | + | |
- | + | ||
- | //print("<pre> "); print_r($map); print(" </pre>"); | + | |
- | + | ||
- | $map2 = array(); | + | |
- | foreach($map as $vertex => $devices) { | + | |
- | foreach($devices as $device => $infs) { | + | |
- | if(is_array($infs)) | + | |
- | $map2[$vertex][$device] = $this->Evaluate($device); | + | |
- | }//foreach | + | |
- | }//foreach | + | |
- | + | ||
- | foreach($map2 as $idx => $devices) { | + | |
- | asort($devices,SORT_NUMERIC); | + | |
- | reset($devices); | + | |
- | $map2[$idx] = $devices; | + | |
- | }//foreach - sort | + | |
- | + | ||
- | //print("<pre> "); print_r($map2); print(" </pre>"); | + | |
- | + | ||
- | + | ||
- | $ahoj = array(); | + | |
- | if($this->Mapping($map2,$ahoj)) { | + | |
- | //print("<pre> "); print_r($ahoj); print(" </pre>"); | + | |
- | } | + | |
- | else print("Smula"); | + | |
- | + | ||
- | + | ||
- | $hotovo = array(); | + | |
- | foreach($ahoj as $spojeni) { | + | |
- | $ahoj2 = array(); | + | |
- | if($this->Mapping($map[$spojeni["vertex"]][$spojeni["device"]],$ahoj2)) {//map interfaces | + | |
- | $hotovo[$spojeni["vertex"]]["device"] = $spojeni["device"]; | + | |
- | foreach($ahoj2 as $linka) { | + | |
- | $hotovo[$spojeni["vertex"]]["links"][$linka["vertex"]] = $this->equipment->getDeviceInterfaceName($spojeni["device"], $linka["device"]); | + | |
- | }//foreach | + | |
- | }//if | + | |
- | else print("Smula"); | + | |
- | }//foreach | + | |
- | + | ||
- | //print("<pre> "); print_r($hotovo); print(" </pre>"); | + | |
- | + | ||
- | + | ||
- | print("<pre>"); | + | |
- | $tmp = $this->topology->getEdgesList(); | + | |
- | foreach($tmp as $edge_idx => $edge) { | + | |
- | $vertexes = $this->topology->getEdgeVertexes($edge_idx); | + | |
- | foreach($vertexes as $vertex) { | + | |
- | print($hotovo[$vertex]["device"] . ":" . $hotovo[$vertex]["links"][$edge] . " "); | + | |
- | } | + | |
- | print("\n"); | + | |
- | } | + | |
- | print("</pre>"); | + | |
- | }//function | + | |
- | }//class | + | |
- | ?> | + | |
- | + | ||
- | </pre> | + | |
+ | [[Kategorie:Komponenty virtlabu]] | ||
+ | [[Kategorie:Server]] | ||
+ | [[Kategorie:Řídící server]] | ||
[[Kategorie:PHP]] | [[Kategorie:PHP]] | ||
[[Kategorie:Třída]] | [[Kategorie:Třída]] |
Aktuální verze
Tato třída (virtlabMapping) implementuje vlastní namapování laboratorních prvků na prvky v logické topologii, tak aby byly splněny všechny podmínky.
Poznámka: podrobné výpisy z průběhu algoritmu, jsou zde.
[editovat]
Zdrojový kód
Aktuální verze se nachází zde
Kategorie: Komponenty virtlabu | Server | Řídící server | PHP | Třída