bool cAlarmServer::loadAlarmDefinitions(const UtlString& alarmFile) { OsSysLog::add(FAC_ALARM, PRI_DEBUG, "Loading alarm def file '%s'", alarmFile.data()); TiXmlDocument doc(alarmFile); TiXmlHandle docHandle( &doc ); if (!doc.LoadFile()) { UtlString errorMsg; XmlErrorMsg( doc, errorMsg ); OsSysLog::add(FAC_ALARM, PRI_ERR, "Failed to load alarm file: %s", errorMsg.data()); return false; } TiXmlHandle docH( &doc ); //load alarm definitions TiXmlElement* alarmDefElement = docH.FirstChildElement("alarm_server"). FirstChildElement("definitions").Element(); if (alarmDefElement) { TiXmlElement* element = alarmDefElement->FirstChildElement(); cAlarmData* pAlarmData; for (; element; element=element->NextSiblingElement() ) { pAlarmData = new cAlarmData(); if (loadAlarmData(element, pAlarmData)) { UtlString* idStr = new UtlString(pAlarmData->getId()); if (!mAlarmMap.insertKeyAndValue(idStr, pAlarmData)) { OsSysLog::add(FAC_ALARM, PRI_ERR, "Alarm id '%s' is already defined", pAlarmData->getId().data()); delete pAlarmData; } } else { OsSysLog::add(FAC_ALARM, PRI_ERR, "Alarm element '%s' is incorrectly defined", (char *)element->ToText()); delete pAlarmData; } } } return true; }
bool cAlarmServer::loadAlarmStringsFile(const UtlString& stringsFile) { OsSysLog::add(FAC_ALARM, PRI_DEBUG, " load alarm strings file %s", stringsFile.data()); TiXmlDocument doc(stringsFile); TiXmlHandle docHandle( &doc ); if (!doc.LoadFile()) { UtlString errorMsg; XmlErrorMsg( doc, errorMsg ); OsSysLog::add(FAC_ALARM, PRI_ERR, "failed to load alarm strings file: %s", errorMsg.data()); return false; } TiXmlHandle docH( &doc ); TiXmlHandle alarmServerHandle = docH.FirstChildElement("alarm_server"); TiXmlElement* settingsElement = alarmServerHandle.FirstChildElement("settings").Element(); if (settingsElement) { //load alarm action strings TiXmlElement* alarmActionsElement = settingsElement->FirstChildElement("actions"); if (alarmActionsElement) { TiXmlElement* element = alarmActionsElement->FirstChildElement("log"); if (mpNotifiers[cAlarmData::eActionLog]) { mpNotifiers[cAlarmData::eActionLog]->initStrings(element); } element = alarmActionsElement->FirstChildElement("email"); if (mpNotifiers[cAlarmData::eActionEmail]) { mpNotifiers[cAlarmData::eActionEmail]->initStrings(element); } element = alarmActionsElement->FirstChildElement("sms"); if (mpNotifiers[cAlarmData::eActionSms]) { mpNotifiers[cAlarmData::eActionSms]->initStrings(element); } /* Not implemented as Strings are not needed for TrapNotifier. element = alarmActionsElement->FirstChildElement("trap"); if (mpNotifiers[cAlarmData::eActionTrap]) { mpNotifiers[cAlarmData::eActionTrap]->initStrings(element); } */ } } else { OsSysLog::add(FAC_ALARM, PRI_DEBUG, "no <settings> element in alarm config file '%s'", stringsFile.data()); } //load alarm description strings TiXmlElement* alarmDefElement = alarmServerHandle. FirstChildElement("definitions").Element(); if (alarmDefElement) { TiXmlElement* element = alarmDefElement->FirstChildElement(); UtlString idStr; UtlString descStr; UtlString resStr; for (; element; element=element->NextSiblingElement() ) { idStr = element->Attribute("id"); if (idStr.isNull()) { OsSysLog::add(FAC_ALARM, PRI_ERR,"Parsing alarm strings file %s: alarm ID is required", stringsFile.data()); continue; } cAlarmData* alarmData = lookupAlarm(idStr); if (!alarmData) { OsSysLog::add(FAC_ALARM, PRI_ERR,"unknown alarm ID %s", idStr.data()); continue; } TiXmlElement* codeElement = element->FirstChildElement("shorttitle"); if (codeElement) { textContentShallow(descStr, codeElement); if (!descStr.isNull()) { UtlString tempStr; XmlUnEscape(tempStr, descStr); alarmData->setShortTitle(tempStr); } } codeElement = element->FirstChildElement("description"); if (codeElement) { textContentShallow(descStr, codeElement); if (!descStr.isNull()) { UtlString tempStr; XmlUnEscape(tempStr, descStr); alarmData->setDescription(tempStr); } } codeElement = element->FirstChildElement("resolution"); if (codeElement) { textContentShallow(resStr, codeElement); if (!resStr.isNull()) { UtlString tempStr; XmlUnEscape(tempStr, resStr); alarmData->setResolution(tempStr); } } } } return true; }
bool cAlarmServer::loadAlarmConfig(const UtlString& alarmFile, const UtlString& groupFile) { // load global alarm config from alarm-config.xml OsSysLog::add(FAC_ALARM, PRI_DEBUG, "Loading alarm config files '%s' '%s'", alarmFile.data(), groupFile.data()); // Load the alarm configuration file TiXmlDocument alarmDoc(alarmFile); TiXmlHandle alarmDocHandle( &alarmDoc ); if (!alarmDoc.LoadFile()) { UtlString errorMsg; XmlErrorMsg( alarmDoc, errorMsg ); OsSysLog::add(FAC_ALARM, PRI_ERR, "Failed to load alarm config file: %s", errorMsg.data()); return false; } TiXmlHandle alarmDocH( &alarmDoc ); TiXmlHandle alarmServerHandle = alarmDocH.FirstChildElement("alarm_server"); // Load the alarm group configuration file TiXmlDocument groupDoc(groupFile); TiXmlHandle groupDocHandle( &groupDoc ); if (!groupDoc.LoadFile()) { UtlString errorMsg; XmlErrorMsg( groupDoc, errorMsg ); OsSysLog::add(FAC_ALARM, PRI_ERR, "Failed to load alarm group config file: %s", errorMsg.data()); return false; } TiXmlHandle groupDocH( &groupDoc ); TiXmlHandle groupServerHandle = groupDocH.FirstChildElement("alarm_groups"); // Continue to process the alarm configuration file TiXmlElement* settingsElement = alarmServerHandle.FirstChildElement("settings").Element(); if (!settingsElement) { OsSysLog::add(FAC_ALARM, PRI_ERR, "No <settings> element in alarm config file '%s'", alarmFile.data()); return false; } TiXmlElement* langElement = settingsElement->FirstChildElement("language"); if (langElement) { textContentShallow(mLanguage, langElement); OsSysLog::add(FAC_ALARM, PRI_INFO, "Language for alarm notifications: %s", mLanguage.data()); } //load alarm action settings TiXmlElement* alarmActionsElement = settingsElement->FirstChildElement("actions"); if (alarmActionsElement) { TiXmlElement* element = alarmActionsElement->FirstChildElement("log"); if (getBoolAttribute(element, "enabled")) { LogNotifier* pLogNotifier = new LogNotifier(); if (mpNotifiers[cAlarmData::eActionLog]) { delete mpNotifiers[cAlarmData::eActionLog]; } mpNotifiers[cAlarmData::eActionLog] = pLogNotifier; if (pLogNotifier) { pLogNotifier->init(element, NULL); gbActions[cAlarmData::eActionLog] = true; } } // Alarm email notifications element = alarmActionsElement->FirstChildElement("email"); if (getBoolAttribute(element, "enabled")) { EmailNotifier* pEmailNotifier = new EmailNotifier(); if (mpNotifiers[cAlarmData::eActionEmail]) { delete mpNotifiers[cAlarmData::eActionEmail]; } mpNotifiers[cAlarmData::eActionEmail] = pEmailNotifier; if (pEmailNotifier) { TiXmlElement* groupElement = groupServerHandle.FirstChildElement("definitions").Element(); pEmailNotifier->init(element, groupElement); gbActions[cAlarmData::eActionEmail] = true; } } element = alarmActionsElement->FirstChildElement("sms"); if (getBoolAttribute(element, "enabled")) { SmsNotifier* pSmsNotifier = new SmsNotifier(); if (mpNotifiers[cAlarmData::eActionSms]) { delete mpNotifiers[cAlarmData::eActionSms]; } mpNotifiers[cAlarmData::eActionSms] = pSmsNotifier; if (pSmsNotifier) { TiXmlElement* groupElement = groupServerHandle.FirstChildElement("definitions").Element(); pSmsNotifier->init(element, groupElement); gbActions[cAlarmData::eActionSms] = true; } } // Alarm SNMPv2 trap notifications element = alarmActionsElement->FirstChildElement("trap"); if (getBoolAttribute(element, "enabled")) { TrapNotifier* pTrapNotifier = new TrapNotifier(); if (mpNotifiers[cAlarmData::eActionTrap]) { delete mpNotifiers[cAlarmData::eActionTrap]; } mpNotifiers[cAlarmData::eActionTrap] = pTrapNotifier; if (pTrapNotifier) { TiXmlElement* groupElement = groupServerHandle.FirstChildElement("definitions").Element(); pTrapNotifier->init(element, groupElement); gbActions[cAlarmData::eActionTrap] = true; } } else { // The trap notification of alarms is disabled. // So, delete the notifier if (mpNotifiers[cAlarmData::eActionTrap]) { delete mpNotifiers[cAlarmData::eActionTrap]; mpNotifiers[cAlarmData::eActionTrap] = 0; } gbActions[cAlarmData::eActionTrap] = false; } } return true; }
/// Parses attributes common to all SipxResource classes. bool SipxResource::parseAttribute(const TiXmlDocument& document, const TiXmlAttribute* attribute, SipxProcess* currentProcess ) { /**< * This method should be called for each attribute child of a 'resource' type node. * @returns true iff the attribute was recognized and handled by the SipxResource class. * If this returns false, then the subclass must attempt to parse the attribute * as one specific to its subclass. */ bool attributeIsValid = false; UtlString attributeName(attribute->Name()); UtlString attributeValue(attribute->Value()); UtlString errorMsg; if (0==attributeName.compareTo(RequiredAttributeName, UtlString::matchCase)) { if (0==attributeValue.compareTo("true", UtlString::ignoreCase)) { attributeIsValid = true; } else if (0==attributeValue.compareTo("false", UtlString::ignoreCase)) { currentProcess->resourceIsOptional(this); attributeIsValid = true; } else { XmlErrorMsg(document, errorMsg); OsSysLog::add(FAC_SUPERVISOR, PRI_ERR, "SipxResource::parseAttribute " "invalid value '%s' for '%s' attribute %s", attributeValue.data(), RequiredAttributeName, errorMsg.data()); } } else if (0==attributeName.compareTo(ConfigAccessAttributeName, UtlString::matchCase)) { if (0==attributeValue.compareTo("read-write", UtlString::ignoreCase)) { mWritableImplicit = false; mWritable = true; attributeIsValid = true; } else if (0==attributeValue.compareTo("read-only", UtlString::ignoreCase)) { if (mWritableImplicit && mFirstDefinition) { mWritableImplicit = false; mWritable = false; } attributeIsValid = true; } else { XmlErrorMsg(document, errorMsg); OsSysLog::add(FAC_SUPERVISOR, PRI_ERR, "SipxResource::parseAttribute " "invalid value '%s' for '%s' attribute %s", attributeValue.data(), ConfigAccessAttributeName, errorMsg.data()); } } else { OsSysLog::add(FAC_SUPERVISOR, PRI_DEBUG, "SipxResource::parseAttribute " "unrecognized attribute '%s'", attributeName.data()); } return attributeIsValid; }
// Factory method that parses a 'directory' resource description element. bool DirectoryResource::parse(const TiXmlDocument& directoryDefinitionDoc, ///< process definition document TiXmlElement* resourceElement, // 'directory' element SipxProcess* currentProcess // whose resources are being read. ) { /* * This is called by SipxResource::parse with any 'directory' child of * the 'resources' element in a process definition. * * @returns NULL if the element was in any way invalid. */ UtlString errorMsg; bool resourceIsValid = true; bool validResourceParm; TiXmlElement* dbElement; UtlString path; UtlSList resources; // holding list for resources until we're done DirectoryResource* dirWithoutPatternResource = NULL; DirectoryResource* directoryResource = NULL; DirectoryResourceManager* directoryManager = DirectoryResourceManager::getInstance(); dbElement = resourceElement->FirstChildElement(); if (dbElement) { if (0 == strcmp("path",dbElement->Value())) { validResourceParm = textContent(path, dbElement); if (validResourceParm && !path.isNull()) { // Initialize the resource for the directory path name alone (null pattern) // used for 'required' processing. if (!(directoryResource = directoryManager->find(path, ""))) // does this combination exist? { directoryResource = new DirectoryResource(path, "", ""); } // get the attribute values for the directory for ( const TiXmlAttribute* attribute = resourceElement->FirstAttribute(); resourceIsValid && attribute; attribute = attribute->Next() ) { if (!(resourceIsValid = directoryResource->SipxResource::parseAttribute(directoryDefinitionDoc, attribute, currentProcess) )) { Os::Logger::instance().log(FAC_SUPERVISOR, PRI_ERR, "DirectoryResource::parse " "invalid attribute '%s': directory path '%s' ignored", attribute->Name(), path.data()); } } // end of attribute loop if (resourceIsValid) { dirWithoutPatternResource = directoryResource; resources.append(directoryResource); // save until parsing is complete directoryResource = NULL; } // advance to the next element, if any. dbElement = dbElement->NextSiblingElement(); } else { resourceIsValid = false; XmlErrorMsg(directoryDefinitionDoc, errorMsg); Os::Logger::instance().log(FAC_SUPERVISOR, PRI_ERR, "DirectoryResource::parse " "'path' element is empty or invalid %s", errorMsg.data() ); } } else { // first child is not 'path' resourceIsValid = false; XmlErrorMsg(directoryDefinitionDoc, errorMsg); Os::Logger::instance().log(FAC_SUPERVISOR, PRI_ERR, "DirectoryResource::parse " "expected path element, found %s", dbElement->Value() ); } } else { resourceIsValid = false; XmlErrorMsg(directoryDefinitionDoc, errorMsg); Os::Logger::instance().log(FAC_SUPERVISOR, PRI_ERR, "DirectoryResource::parse " "no elements are present: path element is required %s", errorMsg.data() ); } /* * Loop over all filePattern elements, creating a DirectoryResource for each, * and saving them on the 'resources' list. */ while (resourceIsValid && dbElement) { if (0 == strcmp("filePattern", dbElement->Value())) { TiXmlElement* filePatternDocElement = dbElement; UtlString pattern; validResourceParm = textContent(pattern, dbElement); if (validResourceParm && !pattern.isNull()) { if (!(directoryResource = directoryManager->find(path, pattern))) // does this combination exist? { // No - this is a new path/pattern combination // Convert the file pattern into a regular expression UtlString patternExpression; if ( pattern2RegEx(pattern, patternExpression) ) { directoryResource = new DirectoryResource(path, pattern, patternExpression); for ( const TiXmlAttribute* attribute = filePatternDocElement->FirstAttribute(); resourceIsValid && attribute; attribute = attribute->Next() ) { if (directoryResource-> SipxResource::isAttribute(attribute, SipxResource::RequiredAttributeName)) { resourceIsValid = false ; Os::Logger::instance().log(FAC_SUPERVISOR, PRI_ERR, "DirectoryResource::parse " "invalid attribute '%s' on filePattern '%s'", attribute->Name(), path.data()) ; } else if (!(resourceIsValid = directoryResource-> SipxResource::parseAttribute(directoryDefinitionDoc, attribute, currentProcess) )) { Os::Logger::instance().log(FAC_SUPERVISOR, PRI_ERR, "DirectoryResource::parse " "invalid attribute '%s': filePattern '%s' ignored", attribute->Name(), pattern.data()); } } if (resourceIsValid) { if (directoryResource->mImplicitAccess) { directoryResource->mImplicitAccess = dirWithoutPatternResource->mImplicitAccess; directoryResource->mAccess = dirWithoutPatternResource->mAccess; } } else { delete directoryResource; } } else { resourceIsValid = false; Os::Logger::instance().log(FAC_SUPERVISOR, PRI_ERR, "DirectoryResource::parse " "path '%s' " "filePattern '%s' did not translate to a regular expression", path.data(), pattern.data() ); } } else { // existing path/pattern combination // parse the attributes so that the required and access attributes are set correctly for ( const TiXmlAttribute* attribute = filePatternDocElement->FirstAttribute(); resourceIsValid && attribute; attribute = attribute->Next() ) { if (directoryResource-> SipxResource::isAttribute(attribute, SipxResource::RequiredAttributeName)) { resourceIsValid = false ; Os::Logger::instance().log(FAC_SUPERVISOR, PRI_ERR, "DirectoryResource::parse " "invalid attribute '%s' on filePattern '%s'", attribute->Name(), path.data()) ; } else if (!(resourceIsValid = directoryResource-> SipxResource::parseAttribute(directoryDefinitionDoc, attribute, currentProcess) )) { Os::Logger::instance().log(FAC_SUPERVISOR, PRI_ERR, "DirectoryResource::parse " "invalid attribute '%s': filePattern '%s' ignored", attribute->Name(), pattern.data()); } } if (resourceIsValid) { if (directoryResource->mImplicitAccess) { directoryResource->mImplicitAccess = dirWithoutPatternResource->mImplicitAccess; directoryResource->mAccess = dirWithoutPatternResource->mAccess; } Os::Logger::instance().log(FAC_SUPERVISOR, PRI_INFO, "DirectoryResource::parse " "shared directory '%s' pattern '%s'", path.data(), pattern.data() ); } } // advance to the next element, if any. dbElement = dbElement->NextSiblingElement(); } else { resourceIsValid = false; XmlErrorMsg(directoryDefinitionDoc, errorMsg); Os::Logger::instance().log(FAC_SUPERVISOR, PRI_ERR, "DirectoryResource::parse " "'filePattern' element is empty" ); } } else { resourceIsValid = false; XmlErrorMsg(directoryDefinitionDoc, errorMsg); Os::Logger::instance().log(FAC_SUPERVISOR, PRI_ERR, "DirectoryResource::parse " "expected 'filePattern' element; found '%s'", dbElement->Value() ); } if (resourceIsValid) { resources.append(directoryResource); } directoryResource = NULL; } // while loop over filePattern elements if (resourceIsValid && resources.entries() < 2) // no filePattern elements were found { // the directory resource was created, but no filePattern elements resourceIsValid = false; Os::Logger::instance().log(FAC_SUPERVISOR, PRI_ERR, "DirectoryResource::parse " "no 'filePattern' elements found for path '%s'", path.data() ); } if (resourceIsValid) // have all elements been parsed successfully? { // everything was valid - so transfer the resulting resources to the DirectoryResourceManager while ((directoryResource=dynamic_cast<DirectoryResource*>(resources.get()))) { directoryResource->usedBy(currentProcess); if (! directoryResource->mFilePattern.isNull()) { // pattern resources are not allowed to be required currentProcess->resourceIsOptional(directoryResource); } if (directoryResource->mFirstDefinition) { directoryResource->mFirstDefinition = false; directoryManager->save(directoryResource); UtlString description; directoryResource->appendDescription(description); Os::Logger::instance().log(FAC_SUPERVISOR, PRI_INFO, "DirectoryResource::parse add %s", description.data() ); } } } else { /* * Something was invalid - discard any of these resources that are not shared * * Note: this could still have modified the access of some shared resources, * but that's too difficult to fix. */ while ((directoryResource=dynamic_cast<DirectoryResource*>(resources.get()))) { if (directoryResource->mFirstDefinition) { delete directoryResource; } } } return resourceIsValid; }
// Factory method that parses a 'imdb' resource description element. bool ImdbResource::parse(const TiXmlDocument& imdbDefinitionDoc, ///< imdb definition document TiXmlElement* resourceElement, // 'imdb' element SipxProcess* currentProcess // whose resources are being read. ) { /* * This is called by SipxResource::parse with any 'imdb' child of * the 'resources' element in a imdb definition. * * @returns NULL if the element was in any way invalid. */ UtlString errorMsg; bool resourceIsValid; UtlString tableName; resourceIsValid = textContent(tableName, resourceElement); if (resourceIsValid) { if (!tableName.isNull()) { ImdbResourceManager* imdbResourceMgr = ImdbResourceManager::getInstance(); ImdbResource* imdbResource; if (!(imdbResource = imdbResourceMgr->find(tableName))) { imdbResource = new ImdbResource(tableName); } imdbResource->usedBy(currentProcess); for ( const TiXmlAttribute* attribute = resourceElement->FirstAttribute(); resourceIsValid && attribute; attribute = attribute->Next() ) { if (!(resourceIsValid = imdbResource->SipxResource::parseAttribute(imdbDefinitionDoc, attribute, currentProcess) )) { OsSysLog::add(FAC_SUPERVISOR, PRI_ERR, "ImdbResource::parse " "invalid attribute '%s'", attribute->Name()); } } if ( imdbResource->mFirstDefinition ) // existing resources are in the manager already { if (resourceIsValid) { imdbResource->mFirstDefinition = false; imdbResourceMgr->save(imdbResource); } else { delete imdbResource; } } } else { resourceIsValid = false; XmlErrorMsg(imdbDefinitionDoc, errorMsg); OsSysLog::add(FAC_SUPERVISOR, PRI_ERR, "ImdbResource::parse " "imdb element is empty %s", errorMsg.data()); } } else { XmlErrorMsg(imdbDefinitionDoc, errorMsg); OsSysLog::add(FAC_SUPERVISOR, PRI_ERR, "ImdbResource::parse " "invalid content in imdb element %s", errorMsg.data()); } return resourceIsValid; }
// Factory method that parses a 'file' or 'osconfig' resource description element. bool FileResource::parse(const TiXmlDocument& fileDefinitionDoc, ///< process definition document TiXmlElement* resourceElement, // 'file' or 'osconfig' element SipxProcess* currentProcess // whose resources are being read. ) { /* * This is called by SipxResource::parse with any 'file' or 'osconfig' child of * the 'resources' element in a process definition. * * @returns NULL if the element was in any way invalid. */ UtlString errorMsg; bool resourceIsValid; UtlString path; resourceIsValid = textContent(path, resourceElement); if (resourceIsValid) { if (!path.isNull()) { FileResourceManager* fileResourceMgr = FileResourceManager::getInstance(); FileResource* fileResource; if (!(fileResource = fileResourceMgr->find(path, FileResourceManager::RequireExactFileMatch))) { fileResource = new FileResource(path); } fileResource->usedBy(currentProcess); for ( const TiXmlAttribute* attribute = resourceElement->FirstAttribute(); resourceIsValid && attribute; attribute = attribute->Next() ) { if (!(resourceIsValid = fileResource->SipxResource::parseAttribute(fileDefinitionDoc, attribute, currentProcess) )) { Os::Logger::instance().log(FAC_SUPERVISOR, PRI_ERR, "FileResource::parse " "invalid attribute '%s'", attribute->Name()); } } if ( fileResource->mFirstDefinition ) // existing resources are in the manager already { if (resourceIsValid) { fileResource->mFirstDefinition = false; fileResourceMgr->save(fileResource); } else { currentProcess->resourceIsOptional(fileResource); // get off the required list delete fileResource; fileResource = NULL; } } } else { resourceIsValid = false; XmlErrorMsg(fileDefinitionDoc, errorMsg); Os::Logger::instance().log(FAC_SUPERVISOR, PRI_ERR, "FileResource::parse " "file element is empty %s", errorMsg.data()); } } else { XmlErrorMsg(fileDefinitionDoc, errorMsg); Os::Logger::instance().log(FAC_SUPERVISOR, PRI_ERR, "FileResource::parse " "invalid content in file element %s", errorMsg.data()); } return resourceIsValid; }
// Factory method that parses a 'process' resource description element. bool SipxProcessResource::parse(const TiXmlDocument& processDefinitionDoc, ///< process definition document TiXmlElement* resourceElement, // 'process' element SipxProcess* currentProcess // whose resources are being read. ) { /* * This is called by SipxResource::parse with any 'process' child of * the 'resources' element in a process definition. * * @returns NULL if the element was in any way invalid. */ UtlString errorMsg; bool resourceIsValid; UtlString processName; resourceIsValid = textContent(processName, resourceElement); if (resourceIsValid) { if (!processName.isNull()) { SipxProcessResourceManager* processResourceMgr = SipxProcessResourceManager::getInstance(); SipxProcessResource* processResource; if (!(processResource = processResourceMgr->find(processName))) { processResource = new SipxProcessResource(processName); } // do not register this resource as used by itself if( processResource->compareTo( currentProcess ) != 0 ) { processResource->usedBy( currentProcess ); } for ( const TiXmlAttribute* attribute = resourceElement->FirstAttribute(); resourceIsValid && attribute; attribute = attribute->Next() ) { if (!(resourceIsValid = processResource->SipxResource::parseAttribute(processDefinitionDoc, attribute, currentProcess) )) { OsSysLog::add(FAC_SUPERVISOR, PRI_ERR, "SipxProcessResource::parse " "invalid attribute '%s'", attribute->Name()); } } if ( processResource->mFirstDefinition ) // existing resources are in the manager already { if (resourceIsValid) { processResource->mFirstDefinition = false; processResourceMgr->save(processResource); } else { delete processResource; } } } else { resourceIsValid = false; XmlErrorMsg(processDefinitionDoc, errorMsg); OsSysLog::add(FAC_SUPERVISOR, PRI_ERR, "SipxProcessResource::parse " "process element is empty %s", errorMsg.data()); } } else { XmlErrorMsg(processDefinitionDoc, errorMsg); OsSysLog::add(FAC_SUPERVISOR, PRI_ERR, "SipxProcessResource::parse " "invalid content in process element %s", errorMsg.data()); } return resourceIsValid; }
// Factory method that parses a 'sqldb' resource description element. bool SqldbResource::parse(const TiXmlDocument& sqldbDefinitionDoc, ///< sqldb definition document TiXmlElement* resourceElement, // 'sqldb' element SipxProcess* currentProcess // whose resources are being read. ) { /* * This is called by SipxResource::parse with any 'sqldb' child of * the 'resources' element in a sqldb definition. * * @returns NULL if the element was in any way invalid. */ UtlString errorMsg; bool resourceIsValid = true; bool validResourceParm; TiXmlElement* dbElement; UtlString databaseName; UtlString serverName; UtlString userName; UtlString dbDriver; UtlString userPassword; SqldbResource* sqldbResource; SqldbResourceManager* sqldbManager = SqldbResourceManager::getInstance(); dbElement = resourceElement->FirstChildElement(); if (dbElement) { if (0 == strcmp("server",dbElement->Value())) { validResourceParm = textContent(serverName, dbElement); if (validResourceParm && !serverName.isNull()) { // advance to the next element, if any. dbElement = dbElement->NextSiblingElement(); } else { resourceIsValid = false; XmlErrorMsg(sqldbDefinitionDoc, errorMsg); OsSysLog::add(FAC_SUPERVISOR, PRI_ERR, "SqldbResource::parse " "'server' element is empty" " - if present, it must be a machine name or localhost %s", errorMsg.data() ); } } else { // 'server' is an optional element. Setup the server to use the default of localhost serverName = "localhost"; } } else { resourceIsValid = false; XmlErrorMsg(sqldbDefinitionDoc, errorMsg); OsSysLog::add(FAC_SUPERVISOR, PRI_ERR, "SqldbResource::parse " "no elements are present %s", errorMsg.data() ); } if (resourceIsValid && dbElement) { if (0 == strcmp("dbname",dbElement->Value())) { validResourceParm = textContent(databaseName, dbElement); if (validResourceParm && !databaseName.isNull()) { // advance to the next element, if any. dbElement = dbElement->NextSiblingElement(); } else { resourceIsValid = false; XmlErrorMsg(sqldbDefinitionDoc, errorMsg); OsSysLog::add(FAC_SUPERVISOR, PRI_ERR, "SqldbResource::parse " "'dbname' element is empty" " - if present it must contain a valid sql database name" ); } } else { resourceIsValid = false; XmlErrorMsg(sqldbDefinitionDoc, errorMsg); OsSysLog::add(FAC_SUPERVISOR, PRI_ERR, "SqldbResource::parse " "'dbname' element is missing %s", errorMsg.data() ); } } if (resourceIsValid) { if (dbElement && (0 == strcmp("username",dbElement->Value()))) { validResourceParm = textContent(userName, dbElement); if (validResourceParm && !userName.isNull()) { // advance to the next element, if any. dbElement = dbElement->NextSiblingElement(); } else { resourceIsValid = false; XmlErrorMsg(sqldbDefinitionDoc, errorMsg); OsSysLog::add(FAC_SUPERVISOR, PRI_ERR, "SqldbResource::parse " "'username' element is empty" " - if present, it must be a valid database user name %s", errorMsg.data() ); } } else { // 'username' is an optional element. Setup the username to use the default of postgres userName = "******"; } } if (resourceIsValid) { if (dbElement && (0 == strcmp("dbdriver",dbElement->Value()))) { validResourceParm = textContent(dbDriver, dbElement); if (validResourceParm && !dbDriver.isNull()) { // advance to the next element, if any. dbElement = dbElement->NextSiblingElement(); } else { resourceIsValid = false; XmlErrorMsg(sqldbDefinitionDoc, errorMsg); OsSysLog::add(FAC_SUPERVISOR, PRI_ERR, "SqldbResource::parse " "'dbdriver' element is empty" " - if present, it must be a valid database driver name %s", errorMsg.data() ); } } else { /* 'dbdriver' is an optional element. * Setup the database driver to use the default of {PostgreSQL} */ dbDriver = "{PostgreSQL}"; } } if (resourceIsValid) { if (dbElement && (0 == strcmp("userpassword",dbElement->Value()))) { validResourceParm = textContent(userPassword, dbElement); if (!validResourceParm || userPassword.isNull()) { resourceIsValid = false; XmlErrorMsg(sqldbDefinitionDoc, errorMsg); OsSysLog::add(FAC_SUPERVISOR, PRI_ERR, "SqldbResource::parse " "'userpassword' element is empty" " - if present, it must be a valid password string %s", errorMsg.data() ); } } else { // 'userpassword' is an optional element. Setup the password to be an empty string userPassword = ""; } } if (resourceIsValid) { if (!(sqldbResource = sqldbManager->find(databaseName + serverName + userName))) { sqldbResource = new SqldbResource(databaseName + serverName + userName ); } sqldbResource->usedBy(currentProcess); for ( const TiXmlAttribute* attribute = resourceElement->FirstAttribute(); resourceIsValid && attribute; attribute = attribute->Next() ) { if (!(resourceIsValid = sqldbResource->SipxResource::parseAttribute(sqldbDefinitionDoc, attribute, currentProcess) )) { OsSysLog::add(FAC_SUPERVISOR, PRI_ERR, "SqldbResource::parse " "invalid attribute '%s'", attribute->Name()); } } if ( sqldbResource->mFirstDefinition ) // existing resources are in the manager already { if (resourceIsValid) { sqldbResource->mFirstDefinition = false; sqldbResource->mUser = userName; sqldbResource->mPassword = userPassword; sqldbResource->mDbDriver = dbDriver; sqldbResource->mServer = serverName; sqldbResource->mDbName = databaseName; OsSysLog::add(FAC_SUPERVISOR, PRI_NOTICE, "SqldbResource::parse " "databaseName = %s, username = %s, password = %s, driver = %s, server = %s", sqldbResource->mDbName.data(), sqldbResource->mUser.data(), sqldbResource->mPassword.data(), sqldbResource->mDbDriver.data(), sqldbResource->mServer.data() ); sqldbManager->save(sqldbResource); } } else { delete sqldbResource; } } return resourceIsValid; }
void upgradeFrom3_0() { // 3.0 had process definition files in /etc/sipxpbx/process.d UtlString oldProcessDefinitionDirectory = SipXecsService::Path(SipXecsService::ConfigurationDirType, "process-old.d"); OsSysLog::add(FAC_SUPERVISOR, PRI_DEBUG,"upgradeFrom3_0: searching '%s'", oldProcessDefinitionDirectory.data() ); if ( !OsFileSystem::exists( oldProcessDefinitionDirectory) ) { return; } OsFileIterator definitions(oldProcessDefinitionDirectory); OsPath oldProcessDefinitionFile; bool okToRemoveDir = true; // set to false if any pre-4.0 process file cannot be upgraded for ( OsStatus iteratorStatus = definitions.findFirst(oldProcessDefinitionFile, OLD_PROCESS_DEFINITION_NAME_PATTERN, OsFileIterator::FILES); OS_SUCCESS == iteratorStatus; iteratorStatus = definitions.findNext(oldProcessDefinitionFile) ) { OsPath oldProcessDefinitionPath( oldProcessDefinitionDirectory +OsPath::separator +oldProcessDefinitionFile ); OsSysLog::add(FAC_SUPERVISOR, PRI_INFO,"upgradeFrom3_0: reading pre-4.0 process def '%s'", oldProcessDefinitionPath.data() ); // read the process name and the watchdog enable setting, // and enable the process if necessary TiXmlDocument processDefinitionDoc(oldProcessDefinitionPath); bool definitionValid = true; UtlString errorMsg; if ( processDefinitionDoc.LoadFile() ) { TiXmlElement *subroot = processDefinitionDoc.RootElement(); if (subroot != NULL) { bool bEnabled=false; const char *enableString = subroot->Attribute("enable"); if (enableString == NULL || strcmp(enableString, "true")==0) { bEnabled=true; } TiXmlElement* processDefElement = subroot->FirstChildElement("process_definitions"); if (processDefElement) { TiXmlNode *pGroupNode = processDefElement->FirstChild("group"); if (pGroupNode) { TiXmlElement *processElement = pGroupNode->FirstChildElement("process"); if (processElement) { const char *pMsg = processElement->Attribute("name"); UtlString processName = pMsg; // enable or disable process based on setting in old process def file SipxProcess* newProcess; if ((newProcess=SipxProcessManager::getInstance()->findProcess(processName))) { if (bEnabled) { OsSysLog::add(FAC_SUPERVISOR, PRI_NOTICE, "upgradeFrom3_0: enabling process '%s'", processName.data()); newProcess->enable(); } else { OsSysLog::add(FAC_SUPERVISOR, PRI_NOTICE, "upgradeFrom3_0: disabling process '%s'", processName.data()); newProcess->disable(); } if (OS_SUCCESS == OsFileSystem::remove(oldProcessDefinitionPath)) { OsSysLog::add(FAC_SUPERVISOR, PRI_NOTICE, "upgradeFrom3_0: removing pre-4.0 process def file '%s'", oldProcessDefinitionPath.data()); } else { OsSysLog::add(FAC_SUPERVISOR, PRI_ERR, "upgradeFrom3_0: failed to remove pre-4.0 process def file '%s'", oldProcessDefinitionPath.data()); } } else { OsSysLog::add(FAC_SUPERVISOR, PRI_ERR, "upgradeFrom3_0: could not find process '%s'", processName.data()); okToRemoveDir = false; } } else { definitionValid = false; } } else { definitionValid = false; } } else { definitionValid = false; } } else { definitionValid = false; } } else { definitionValid = false; } if ( !definitionValid ) { // Invalid document format. Log the issue and continue to the next process xml file. XmlErrorMsg(processDefinitionDoc, errorMsg); OsSysLog::add(FAC_SUPERVISOR, PRI_ERR, "upgradeFrom3_0: ignoring invalid pre-4.0 process xml file '%s' (%s)", oldProcessDefinitionFile.data(), errorMsg.data()); okToRemoveDir = false; } } // remove the old process defn directory (succeeds only if it is empty) if (OS_SUCCESS == OsFileSystem::remove(oldProcessDefinitionDirectory)) { OsSysLog::add(FAC_SUPERVISOR, PRI_NOTICE, "upgradeFrom3_0: all process data has been migrated from " "pre-4.0 process def directory '%s', " "and the directory has been deleted.", oldProcessDefinitionDirectory.data()); } else { // rmdir may fail because files still exist (e.g. editor backup files). // Log whether upgrade succeeded or not. if ( okToRemoveDir ) { OsSysLog::add(FAC_SUPERVISOR, PRI_NOTICE, "upgradeFrom3_0: all process data has been migrated from " "pre-4.0 process def directory '%s', " "and the directory may safely be deleted.", oldProcessDefinitionDirectory.data()); } else { OsSysLog::add(FAC_SUPERVISOR, PRI_WARNING, "upgradeFrom3_0: some process data could not be migrated from " "pre-4.0 process def directory '%s'. ", oldProcessDefinitionDirectory.data()); } } }