1<?php 2/***************************************************************************** 3 * 4 * CoreBackendMgmt.php - class for handling all backends 5 * 6 * Copyright (c) 2004-2016 NagVis Project (Contact: info@nagvis.org) 7 * 8 * License: 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License version 2 as 12 * published by the Free Software Foundation. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 22 * 23 *****************************************************************************/ 24 25/** 26 * @author Lars Michelsen <lm@larsmichelsen.com> 27 */ 28class CoreBackendMgmt { 29 public $BACKENDS = Array(); 30 private $aInitialized = Array(); 31 private $aQueue = Array(); 32 private $aError = Array(); 33 private $countQueries = Array( 34 'serviceState' => '', 35 'hostState' => '', 36 'hostMemberState' => '', 37 'hostgroupMemberState' => '', 38 'servicegroupMemberState' => '', 39 'DYN_GROUP_MEMBER_STATE' => '', 40 ); 41 42 43 /** 44 * Constructor 45 * 46 * Initializes all backends 47 * 48 * @param config $MAINCFG 49 * @author Lars Michelsen <lm@larsmichelsen.com> 50 */ 51 public function __construct() { 52 $this->loadBackends(); 53 } 54 55 public function getBackend($id) { 56 // Only try to initialize once per request 57 if(!isset($this->aInitialized[$id]) && !isset($this->aError[$id])) 58 $this->initializeBackend($id); 59 60 // Re-throw the stored backend exception for this request 61 if(isset($this->aError[$id])) 62 throw $this->aError[$id]; 63 64 return $this->BACKENDS[$id]; 65 } 66 67 /** 68 * PUBLIC queue() 69 * 70 * Add a backend query to the queue 71 * 72 * @param Array Queries to be added to the queue 73 * @param Object Map object to fetch the informations for 74 * @author Lars Michelsen <lm@larsmichelsen.com> 75 */ 76 public function queue($query, $OBJ) { 77 $backendIds = $OBJ->getBackendIds(); 78 foreach($backendIds as $backendId) 79 if(!isset($this->aQueue[$backendId])) 80 $this->aQueue[$backendId] = Array(); 81 82 foreach($query AS $query => $_unused) { 83 foreach($backendIds as $backendId) 84 if(!isset($this->aQueue[$backendId][$query])) 85 $this->aQueue[$backendId][$query] = Array(); 86 87 // Gather the object name 88 if($query == 'serviceState') 89 $name = $OBJ->getName().'~~'.$OBJ->getServiceDescription(); 90 else 91 $name = $OBJ->getName(); 92 93 // Options is a mask which tells the backend how to handle this object 94 $options = $this->parseOptions($OBJ); 95 96 // Each object can have individual filter options. For example the 97 // member filters 98 $objFilters = $this->parseObjFilters($query, $OBJ); 99 100 // Only query the backend once per object+options+filter 101 // If the object is queued several times with the same options+filters 102 // add it to the list of objects. The backend result will be added to 103 // all objects in that list later 104 foreach($backendIds as $backendId) 105 if(!isset($this->aQueue[$backendId][$query][$options][$objFilters])) 106 $this->aQueue[$backendId][$query][$options][$objFilters] = Array($name => Array($OBJ)); 107 elseif(!isset($this->aQueue[$backendId][$query][$options][$objFilters][$name])) 108 $this->aQueue[$backendId][$query][$options][$objFilters][$name] = Array($OBJ); 109 else 110 $this->aQueue[$backendId][$query][$options][$objFilters][$name][] = $OBJ; 111 } 112 } 113 114 private function parseObjFilters($query, $OBJ) { 115 $isMemberQuery = $query != 'serviceState' && $query != 'hostState'; 116 $isCountQuery = isset($this->countQueries[$query]); 117 118 if(!$isMemberQuery || !$OBJ->hasExcludeFilters($isCountQuery)) 119 return ''; 120 121 return $OBJ->getExcludeFilterKey($isCountQuery).'~~'.$OBJ->getExcludeFilter($isCountQuery); 122 } 123 124 private function parseOptions($OBJ) { 125 $options = 0; 126 if($OBJ->getOnlyHardStates()) 127 $options |= 1; 128 if(!$OBJ->getRecognizeServices()) 129 $options |= 2; 130 /*FIXME: Implement as optional filter: "Filter: in_notification_period = 1\n" .*/ 131 132 return $options; 133 } 134 135 /** 136 * PUBLIC clearQueue() 137 * 138 * Resets the backend queue 139 * 140 * @author Lars Michelsen <lm@larsmichelsen.com> 141 */ 142 public function clearQueue() { 143 $this->aQueue = Array(); 144 } 145 146 /** 147 * PUBLIC execute() 148 * 149 * Executes all backend queries and assigns the gathered information 150 * to the objects 151 * 152 * @author Lars Michelsen <lm@larsmichelsen.com> 153 */ 154 public function execute() { 155 // Loop all backends 156 foreach($this->aQueue AS $backendId => $types) { 157 // Loop all different query types 158 foreach($types AS $type => $options) { 159 // Now loop the different options (Splitting by only_hard_state options etc.) 160 foreach($options AS $option => $filters) { 161 foreach($filters AS $filter => $aObjs) { 162 switch($type) { 163 case 'serviceState': 164 case 'hostState': 165 case 'hostMemberState': 166 case 'hostgroupMemberState': 167 case 'servicegroupMemberState': 168 case 'AGGR_MEMBER_STATE': 169 $this->fetchStateCounts($backendId, $type, $option, $aObjs); 170 break; 171 case 'DYN_GROUP_MEMBER_STATE': 172 // Can not use the generic fetchStateCounts() method. It uses summarized queries 173 // to reduce the number of backend queries, but this is not possible for member 174 // states as this makes use of individual filter queries per objects. 175 $this->fetchDynGroupMemberCounts($backendId, $option, $aObjs); 176 break; 177 178 case 'hostMemberDetails': 179 $this->fetchHostMemberDetails($backendId, $option, $aObjs); 180 break; 181 case 'hostgroupMemberDetails': 182 $this->fetchHostgroupMemberDetails($backendId, $option, $aObjs); 183 break; 184 case 'servicegroupMemberDetails': 185 $this->fetchServicegroupMemberDetails($backendId, $option, $aObjs); 186 break; 187 case 'DYN_GROUP_MEMBER_DETAILS': 188 $this->fetchDynGroupMemberDetails($backendId, $option, $aObjs); 189 break; 190 case 'AGGR_MEMBER_DETAILS': 191 $this->fetchAggrMemberDetails($backendId, $option, $aObjs); 192 break; 193 } 194 } 195 } 196 } 197 } 198 199 // Clear the queue after processing 200 $this->clearQueue(); 201 } 202 203 /** 204 * Loops all queued aggregation and executes the queries for each group. 205 * Gets all members of the aggregation and saves them to the members array 206 * 207 * This is trimmed to reduce the number of queries to the backend: 208 * 1.) fetch states for all objects 209 * 2.) fetch state counts for all objects 210 */ 211 private function fetchAggrMemberDetails($backendId, $options, $aObjs) { 212 foreach($aObjs AS $name => $OBJS) { 213 foreach($OBJS AS $OBJ) { 214 try { 215 $filters = Array(Array('key' => 'aggr_name', 'op' => '>=', 'val' => 'name')); 216 $aServices = $this->getBackend($backendId)->getServiceState(Array($OBJ->getName() => Array($OBJ)), $options, $filters, MEMBER_QUERY); 217 } catch(BackendException $e) { 218 $aServices = Array(); 219 $OBJ->setBackendProblem(l('Connection Problem (Backend: [BACKENDID]): [MSG]', 220 Array('BACKENDID' => $backendId, 'MSG' => $e->getMessage())), $backendId); 221 } 222 223 // Regular member adding loop 224 $members = Array(); 225 foreach($aServices AS $host => $serviceList) { 226 foreach($serviceList AS $aService) { 227 $members[] = $this->createServiceObject($backendId, $host, $aService[DESCRIPTION], 228 $aService, $OBJ->getObjectConfiguration()); 229 } 230 } 231 $OBJ->addMembers($members); 232 } 233 } 234 } 235 236 private function fetchDynGroupMemberCounts($backendId, $options, $aObjs) { 237 foreach($aObjs AS $name => $OBJS) { 238 foreach($OBJS AS $OBJ) { 239 try { 240 if($OBJ->object_types == 'service') { 241 if (!$this->checkBackendFeature($backendId, 'getServiceListCounts', false)) { 242 $counts = array(); 243 $OBJ->setBackendProblem(l('This type of object is not supportd by this backend ([BACKENDID]).', 244 Array('BACKENDID' => $backendId)), $backendId); 245 } 246 else { 247 $counts = $this->getBackend($backendId)->getServiceListCounts( 248 $options, $OBJ->getObjectFilter()); 249 } 250 } else { 251 if (!$this->checkBackendFeature($backendId, 'getHostAndServiceCounts', false)) { 252 $counts = array(); 253 $OBJ->setBackendProblem(l('This type of object is not supportd by this backend ([BACKENDID]).', 254 Array('BACKENDID' => $backendId)), $backendId); 255 } 256 else { 257 $counts = $this->getBackend($backendId)->getHostAndServiceCounts( 258 $options, $OBJ->getObjectFilter(), $OBJ->getObjectFilter(), false); 259 } 260 } 261 } catch(BackendException $e) { 262 $counts = Array(); 263 $OBJ->setBackendProblem(l('Connection Problem (Backend: [BACKENDID]): [MSG]', 264 Array('BACKENDID' => $backendId, 'MSG' => $e->getMessage())), $backendId); 265 } 266 267 $OBJ->addStateCounts($counts); 268 } 269 } 270 } 271 272 /** 273 * Fetches details for all given dynamic groups 274 * Sending "array()" as filter construct to the backend since the backend uses the filters which are 275 * already compiled in the object and ignores the given array() parameter 276 */ 277 private function fetchDynGroupMemberDetails($backendId, $options, $aObjs) { 278 foreach($aObjs AS $name => $OBJS) { 279 foreach($OBJS AS $OBJ) { 280 $members = Array(); 281 if ($OBJ->object_types == 'service') { 282 // Fist get the states for all the members 283 try { 284 $aServices = $this->getBackend($backendId)->getServiceState( 285 Array($OBJ->getName() => Array($OBJ)), $options, array(), MEMBER_QUERY); 286 } catch(BackendException $e) { 287 $aServices = Array(); 288 $OBJ->setBackendProblem(l('Connection Problem (Backend: [BACKENDID]): [MSG]', 289 Array('BACKENDID' => $backendId, 'MSG' => $e->getMessage())), $backendId); 290 } 291 292 // Regular member adding loop 293 foreach($aServices AS $host => $serviceList) { 294 foreach($serviceList AS $aService) { 295 $members[] = $this->createServiceObject($backendId, $host, $aService[DESCRIPTION], 296 $aService, $OBJ->getObjectConfiguration()); 297 } 298 } 299 300 } else { 301 // First get the host states 302 try { 303 $aHosts = $this->getBackend($backendId)->getHostState(Array($OBJ->getName() => Array($OBJ)), 304 $options, array(), MEMBER_QUERY); 305 } catch(BackendException $e) { 306 $aHosts = Array(); 307 $OBJ->setBackendProblem(l('Connection Problem (Backend: [BACKENDID]): [MSG]', 308 Array('BACKENDID' => $backendId, 'MSG' => $e->getMessage())), $backendId); 309 } 310 311 // Now fetch the service state counts for all hosts 312 $aServiceState = Array(); 313 if($OBJ->getRecognizeServices()) { 314 try { 315 $aServiceStateCounts = $this->getBackend($backendId)->getHostMemberCounts( 316 Array($OBJ->getName() => Array($OBJ)), $options, array()); 317 } catch(BackendException $e) {} 318 } 319 320 $members = Array(); 321 foreach($aHosts AS $name => $aHost) { 322 if(isset($aServiceStateCounts[$name]) && isset($aServiceStateCounts[$name]['counts'])) 323 $service_states = $aServiceStateCounts[$name]['counts']; 324 else 325 $service_states = null; 326 $members[] = $this->createHostObject($backendId, $name, $aHost, 327 $OBJ->getObjectConfiguration(), $service_states); 328 } 329 330 } 331 $OBJ->addMembers($members); 332 } 333 } 334 } 335 336 private function createServiceObject($backendId, $host, $descr, $state, $config) { 337 $OBJ = new NagVisService($backendId, $host, $state[DESCRIPTION]); 338 $OBJ->setState($state); 339 340 // The services have to know how they should handle hard/soft 341 // states. This is a little dirty but the simplest way to do this 342 // until the hard/soft state handling has moved from backend to the 343 // object classes. 344 $OBJ->setConfiguration($config); 345 return $OBJ; 346 } 347 348 private function createHostObject($backendId, $name, $state, $config, $service_states) { 349 $OBJ = new NagVisHost($backendId, $name); 350 $OBJ->setState($state); 351 352 // The services have to know how they should handle hard/soft 353 // states. This is a little dirty but the simplest way to do this 354 // until the hard/soft state handling has moved from backend to the 355 // object classes. 356 $OBJ->setConfiguration($config); 357 358 // Put state counts to the object 359 if ($service_states !== null) { 360 $OBJ->addStateCounts($service_states); 361 } 362 363 // Fetch summary state and output 364 $OBJ->fetchSummariesFromCounts(); 365 366 return $OBJ; 367 } 368 369 /** 370 * PRIVATE fetchServicegroupMemberDetails() 371 * 372 * Loops all queued servicegroups and executes the queries for each group. 373 * Gets all services of the servicegroup and saves them to the members array 374 * 375 * This is trimmed to reduce the number of queries to the backend: 376 * 1.) fetch states for all services 377 * 2.) fetch state counts for all services 378 * 379 * @author Lars Michelsen <lm@larsmichelsen.com> 380 */ 381 private function fetchServicegroupMemberDetails($backendId, $options, $aObjs) { 382 foreach($aObjs AS $name => $OBJS) { 383 foreach($OBJS AS $OBJ) { 384 // Fist get the host states for all the servicegroup members 385 try { 386 $filters = Array(Array('key' => 'service_groups', 'op' => '>=', 'val' => 'name')); 387 $aServices = $this->getBackend($backendId)->getServiceState(Array($OBJ->getName() => Array($OBJ)), $options, $filters, MEMBER_QUERY); 388 } catch(BackendException $e) { 389 $aServices = Array(); 390 $OBJ->setBackendProblem(l('Connection Problem (Backend: [BACKENDID]): [MSG]', 391 Array('BACKENDID' => $backendId, 'MSG' => $e->getMessage())), $backendId); 392 } 393 394 // Regular member adding loop 395 $members = Array(); 396 foreach($aServices AS $host => $serviceList) { 397 foreach($serviceList AS $aService) { 398 $members[] = $this->createServiceObject($backendId, $host, $aService[DESCRIPTION], 399 $aService, $OBJ->getObjectConfiguration()); 400 } 401 } 402 $OBJ->addMembers($members); 403 } 404 } 405 } 406 407 /** 408 * PRIVATE fetchHostgroupMemberDetails() 409 * 410 * Loops all queued objects. 411 * Gets all hosts of the hostgroup and saves them to the members array 412 * 413 * This is trimmed to reduce the number of queries to the backend: 414 * 1.) fetch states for all hosts 415 * 2.) fetch state counts for all hosts 416 * 417 * @author Lars Michelsen <lm@larsmichelsen.com> 418 */ 419 private function fetchHostgroupMemberDetails($backendId, $options, $aObjs) { 420 // And then apply them to the objects 421 foreach($aObjs AS $name => $OBJS) { 422 foreach($OBJS AS $OBJ) { 423 // First get the host states for all the hostgroup members 424 try { 425 $filters = Array(Array('key' => 'host_groups', 'op' => '>=', 'val' => 'name')); 426 $aHosts = $this->getBackend($backendId)->getHostState(Array($OBJ->getName() => Array($OBJ)), $options, $filters, MEMBER_QUERY); 427 } catch(BackendException $e) { 428 $aHosts = Array(); 429 $OBJ->setBackendProblem(l('Connection Problem (Backend: [BACKENDID]): [MSG]', 430 Array('BACKENDID' => $backendId, 'MSG' => $e->getMessage())), $backendId); 431 } 432 433 // Now fetch the service state counts for all hostgroup members 434 $aServiceState = Array(); 435 if($OBJ->getRecognizeServices()) { 436 try { 437 $filters = Array(Array('key' => 'host_groups', 'op' => '>=', 'val' => 'name')); 438 $aServiceStateCounts = $this->getBackend($backendId)->getHostMemberCounts( 439 Array($OBJ->getName() => Array($OBJ)), $options, $filters); 440 } catch(BackendException $e) {} 441 } 442 443 $members = Array(); 444 foreach($aHosts AS $name => $aHost) { 445 if(isset($aServiceStateCounts[$name]) && isset($aServiceStateCounts[$name]['counts'])) 446 $service_states = $aServiceStateCounts[$name]['counts']; 447 else 448 $service_states = null; 449 $members[] = $this->createHostObject($backendId, $name, $aHost, 450 $OBJ->getObjectConfiguration(), $service_states); 451 } 452 453 $OBJ->addMembers($members); 454 } 455 } 456 } 457 458 private function fetchStateCounts($backendId, $type, $options, $aObjs) { 459 try { 460 switch($type) { 461 case 'servicegroupMemberState': 462 $filters = Array(Array('key' => 'groups', 'op' => '>=', 'val' => 'name')); 463 $aResult = $this->getBackend($backendId)->getServicegroupStateCounts($aObjs, $options, $filters); 464 break; 465 case 'hostgroupMemberState': 466 $filters = Array(Array('key' => 'groups', 'op' => '>=', 'val' => 'name')); 467 $aResult = $this->getBackend($backendId)->getHostgroupStateCounts($aObjs, $options, $filters); 468 break; 469 case 'serviceState': 470 $filters = Array( 471 Array('key' => 'host_name', 'op' => '=', 'val' => 'name'), 472 Array('key' => 'service_description', 'op' => '=', 'service_description') 473 ); 474 $aResult = $this->getBackend($backendId)->getServiceState($aObjs, $options, $filters); 475 break; 476 case 'hostState': 477 $filters = Array(Array('key' => 'host_name', 'op' => '=', 'val' => 'name')); 478 $aResult = $this->getBackend($backendId)->getHostState($aObjs, $options, $filters); 479 break; 480 case 'hostMemberState': 481 $filters = Array(Array('key' => 'host_name', 'op' => '=', 'val' => 'name')); 482 $aResult = $this->getBackend($backendId)->getHostMemberCounts($aObjs, $options, $filters); 483 break; 484 case 'AGGR_MEMBER_STATE': 485 if (!$this->checkBackendFeature($backendId, 'getAggrStateCounts', false)) { 486 throw new BackendException(l('This type of object is not supported by this backend ([BACKENDID]).', 487 Array('BACKENDID' => $backendId)), $backendId); 488 } else { 489 $filters = Array(Array('key' => 'aggr_name', 'op' => '=', 'val' => 'name')); 490 $aResult = $this->getBackend($backendId)->getAggrStateCounts($aObjs, $options, $filters); 491 } 492 break; 493 } 494 } catch(BackendException $e) { 495 $aResult = Array(); 496 $msg = $e->getMessage(); 497 } 498 499 foreach($aObjs AS $name => $OBJS) { 500 if(isset($aResult[$name])) { 501 if($type == 'serviceState' || $type == 'hostState') 502 foreach($OBJS AS $OBJ) 503 $OBJ->setState($aResult[$name]); 504 else 505 foreach($OBJS AS $OBJ) { 506 if(isset($aResult[$name]['details'])) 507 $OBJ->setState($aResult[$name]['details']); 508 if(isset($aResult[$name]['attrs'])) 509 $OBJ->setObjectInformation($aResult[$name]['attrs']); 510 if(isset($aResult[$name]['counts'])) 511 $OBJ->addStateCounts($aResult[$name]['counts']); 512 } 513 } else { 514 if($type != 'hostMemberState') 515 foreach($OBJS AS $OBJ) 516 if(isset($msg)) 517 $OBJ->setBackendProblem($msg, $backendId); 518 else 519 $OBJ->setBackendProblem(l('The object "[OBJ]" does not exist ([TYPE]).', 520 Array('OBJ' => $name, 'TYPE' => $OBJ->getType())), $backendId); 521 } 522 } 523 } 524 525 private function fetchHostMemberDetails($backendId, $options, $aObjs) { 526 try { 527 $filters = Array(Array('key' => 'host_name', 'op' => '=', 'val' => 'name')); 528 $aMembers = $this->getBackend($backendId)->getServiceState($aObjs, $options, $filters, MEMBER_QUERY); 529 } catch(BackendException $e) { 530 $aMembers = Array(); 531 } 532 533 foreach($aObjs AS $name => $OBJS) { 534 if(isset($aMembers[$name])) { 535 foreach($OBJS AS $OBJ) { 536 $members = Array(); 537 foreach($aMembers[$name] AS $service => $details) { 538 $MOBJ = new NagVisService($backendId, $OBJ->getName(), $details[DESCRIPTION]); 539 $MOBJ->setState($details); 540 $members[] = $MOBJ; 541 } 542 $OBJ->addMembers($members); 543 } 544 } 545 } 546 } 547 548 /** 549 * Loads all backends and prints an error when no backend defined 550 * 551 * @author Lars Michelsen <lm@larsmichelsen.com> 552 */ 553 private function loadBackends() { 554 global $CORE; 555 $aBackends = $CORE->getDefinedBackends(); 556 557 if(!count($aBackends)) 558 throw new NagVisException(l('noBackendDefined')); 559 } 560 561 /** 562 * Checks for existing backend file 563 * 564 * @param Boolean $printErr 565 * @return Boolean Is Successful? 566 * @author Lars Michelsen <lm@larsmichelsen.com> 567 */ 568 public function checkBackendExists($backendId, $printErr) { 569 global $CORE; 570 if($CORE->checkExisting(cfg('paths','class').'GlobalBackend'.cfg('backend_'.$backendId,'backendtype').'.php', false)) 571 return true; 572 573 if($printErr == 1) 574 throw new NagVisException(l('backendNotExists', Array('BACKENDID' => $backendId, 575 'BACKENDTYPE' => cfg('backend_'.$backendId,'backendtype')))); 576 return false; 577 } 578 579 /** 580 * Checks if a backend host is status using status 581 * information from another backend 582 * 583 * @author Lars Michelsen <lm@larsmichelsen.com> 584 */ 585 private function backendAlive($backendId, $statusHost) { 586 list($statusBackend, $statusHost) = explode(':', $statusHost, 2); 587 588 if($statusBackend == $backendId) 589 $this->aError[$backendId] = new BackendConnectionProblem(l('Configuration Error: The statusHost ([STATUSHOST]) is in same backend as the one to check.', Array('STATUSHOST' => $statusHost))); 590 591 try { 592 $filters = Array(Array('key' => 'host_name', 'op' => '=', 'val' => 'name')); 593 $aObjs = Array($statusHost => Array(new NagVisHost($statusBackend, $statusHost))); 594 $aCounts = $this->getBackend($statusBackend)->getHostState($aObjs, 1, $filters); 595 } catch(BackendException $e) { 596 return true; 597 } 598 599 if($aCounts[$statusHost][STATE] == UP) 600 return true; 601 else 602 return false; 603 } 604 605 /** 606 * Initializes a backend 607 * 608 * @return Boolean Is Successful? 609 * @author Lars Michelsen <lm@larsmichelsen.com> 610 */ 611 private function initializeBackend($backendId) { 612 if(!$this->checkBackendExists($backendId, false)) { 613 $this->aError[$backendId] = new BackendConnectionProblem(l('backendNotDefined', 614 Array('BACKENDID' => $backendId))); 615 return false; 616 } 617 /** 618 * The status host can be used to prevent annoying timeouts when a backend is not 619 * reachable. This is only useful in multi backend setups. 620 * 621 * It works as follows: The assumption is that there is a "local" backend which 622 * monitors the host of the "remote" backend. When the remote backend host is 623 * reported as UP the backend is queried as normal. 624 * When the remote backend host is reported as "DOWN" or "UNREACHABLE" NagVis won't 625 * try to connect to the backend anymore until the backend host gets available again. 626 */ 627 $statusHost = cfg('backend_' . $backendId, 'statushost'); 628 if($statusHost != '' && !$this->backendAlive($backendId, $statusHost)) { 629 $this->aError[$backendId] = new BackendConnectionProblem(l('The backend is reported as dead by the statusHost ([STATUSHOST]).', Array('STATUSHOST' => $statusHost))); 630 return false; 631 } 632 633 try { 634 $backendClass = 'GlobalBackend' . cfg('backend_' . $backendId, 'backendtype'); 635 $this->BACKENDS[$backendId] = new $backendClass($backendId); 636 637 // Mark backend as initialized 638 $this->aInitialized[$backendId] = true; 639 640 return true; 641 } catch(BackendException $e) { 642 $this->aError[$backendId] = $e; 643 return false; 644 } 645 } 646 647 /** 648 * Checks for an initialized backend 649 * 650 * @param Boolean $printErr 651 * @return Boolean Is Successful? 652 * @author Lars Michelsen <lm@larsmichelsen.com> 653 * @deprecated Please don't use this function anymore 654 */ 655 public function checkBackendInitialized($backendId, $printErr) { 656 if(isset($this->aInitialized[$backendId])) { 657 return true; 658 } else { 659 if($printErr == 1) { 660 throw new NagVisException(l('backendNotInitialized', Array('BACKENDID' => $backendId, 661 'BACKENDTYPE' => cfg('backend_'.$backendId,'backendtype')))); 662 } 663 return false; 664 } 665 } 666 667 /** 668 * Checks if the given feature is provided by the given backend 669 * 670 * @param Boolean $printErr 671 * @return Boolean Is Successful? 672 * @author Lars Michelsen <lm@larsmichelsen.com> 673 */ 674 public function checkBackendFeature($backendId, $feature, $printErr = 1) { 675 $backendClass = 'GlobalBackend'.cfg('backend_'.$backendId, 'backendtype'); 676 if(method_exists($backendClass, $feature)) { 677 return true; 678 } else { 679 if($printErr == 1) { 680 throw new NagVisException(l('The requested feature [FEATURE] is not provided by the backend (Backend-ID: [BACKENDID], Backend-Type: [BACKENDTYPE]). The requested view may not be available using this backend.', 681 Array('FEATURE' => htmlentities($feature, ENT_COMPAT, 'UTF-8'), 682 'BACKENDID' => $backendId, 683 'BACKENDTYPE' => cfg('backend_'.$backendId,'backendtype')))); 684 } 685 return false; 686 } 687 } 688} 689?> 690