//
//
// Copyright (C) 2004 SIPfoundry Inc.
// Licensed by SIPfoundry under the LGPL license.
//
// Copyright (C) 2004 Pingtel Corp.
// Licensed to SIPfoundry under a Contributor Agreement.
//
// $$
//////////////////////////////////////////////////////////////////////////////
// SYSTEM INCLUDES
#include <iostream>
// APPLICATION INCLUDES
#include "utl/UtlInt.h"
#include "net/Url.h"
#include "net/NetMd5Codec.h"
#include "xmlparser/tinyxml.h"
#include "os/OsDateTime.h"
#include "sipdb/SIPDBManager.h"
#include "sipdb/ResultSet.h"
#include "sipdb/AliasDB.h"
#include "sipdb/HuntgroupDB.h"
#include "sipdb/ExtensionDB.h"
#include "sipdb/PermissionDB.h"
#include "sipdb/SubscriptionDB.h"
#include "sipdb/DialByNameDB.h"
#include "sipdb/CredentialDB.h"
#include "sipdb/SIPXAuthHelper.h"
#include "IMDBTaskMonitor.h"
#include "ImportTask.h"
extern UtlString uriKey;
extern UtlString extensionKey;
extern UtlString callidKey;
extern UtlString contactKey;
extern UtlString realmKey;
extern UtlString useridKey;
extern UtlString passtokenKey;
extern UtlString pintokenKey;
extern UtlString authtypeKey;
extern UtlString identityKey;
extern UtlString permissionKey;
extern UtlString qvalueKey;
extern UtlString expiresKey;
extern UtlString timenowKey;
extern UtlString subscribecseqKey;
extern UtlString eventtypeKey;
extern UtlString idKey;
extern UtlString toKey;
extern UtlString cseqKey;
extern UtlString fromKey;
extern UtlString keyKey;
extern UtlString recordrouteKey;
extern UtlString notifycseqKey;
extern UtlString np_identityKey;
extern UtlString np_contactKey;
extern UtlString np_digitsKey;
using namespace std;
ImportTask::ImportTask (
const UtlString& rArgument, OsMsgQ& rMsgQ, OsEvent& rCommandEvent) :
IMDBWorkerTask( rArgument, rMsgQ, rCommandEvent )
{}
ImportTask::~ImportTask()
{}
int
ImportTask::run( void* runArg )
{
OsSysLog::add(LOG_FACILITY, PRI_DEBUG, "Starting Import Thread %s\n", mArgument.data());
// Indicate that we're finished, the monitor thread
// reads this flag and if it's still set
setBusy (TRUE);
importTableRows ( mArgument );
UtlString databaseInfo;
getDatabaseInfo ( databaseInfo );
OsSysLog::add(LOG_FACILITY, PRI_DEBUG, databaseInfo.data());
setBusy (FALSE);
cleanupIMDBResources();
OsSysLog::add(LOG_FACILITY, PRI_DEBUG, "Stopping Thread\n");
// send a success message to the sleeping monitor
notifyMonitor( USER_IMPORT_SUCCESS_EVENT );
return( TRUE );
}
int
ImportTask::importTableRows ( const UtlString& rImportFilename ) const
{
int exitCode = EXIT_SUCCESS;
if (rImportFilename.contains("registration"))
{
cout << "Loading the registration database is no longer supported" << endl;
return EXIT_UNSUPPORTEDDB;
}
// Load all rows from an external XML Script
if ( loadDB( rImportFilename ) == OS_SUCCESS )
{
cout << "Database loaded" << endl;
// Checkpoint each of the DBs
if ( CredentialDB::getInstance()->store() != OS_SUCCESS )
{
cout << "Problem storing CredentialDB to local XML file" << endl;
}
// Checkpoint each of the DBs
if ( HuntgroupDB::getInstance()->store() != OS_SUCCESS )
{
cout << "Problem storing HuntgroupDB to local XML file" << endl;
}
if ( AliasDB::getInstance()->store() != OS_SUCCESS )
{
cout << "Problem storing AliasDB to local XML file" << endl;
}
if ( PermissionDB::getInstance()->store() != OS_SUCCESS )
{
cout << "Problem storing AliasDB to local XML file" << endl;
}
if ( DialByNameDB::getInstance()->store() != OS_SUCCESS )
{
cout << "Problem storing DialByNameDB to local XML file" << endl;
}
if ( SubscriptionDB::getInstance()->store() != OS_SUCCESS )
{
cout << "Problem storing SubscriptionDB to local XML file" << endl;
}
if ( ExtensionDB::getInstance()->store() != OS_SUCCESS )
{
cout << "Problem storing ExtensionDB to local XML file" << endl;
}
} else
{
exitCode = EXIT_FILENOTFOUND;
cout << "Could not import the XML file" << endl;
}
return exitCode;
}
// Populate the DB from the XML sections
OsStatus
ImportTask::loadDB( const UtlString& rFileName ) const
{
// Critical Section here
OsStatus result = OS_SUCCESS;
TiXmlDocument doc ( rFileName );
// Verify that we can load the file (i.e it must exist)
if( doc.LoadFile() )
{
TiXmlNode *dbNode = doc.FirstChild( "items" );
if ( dbNode )
{
UtlString tableName = dbNode->ToElement()->Attribute( "type" );
for( ;
dbNode;
dbNode = dbNode->NextSibling( "items" ) )
{
// Clear out this table as we've got a new version in this file
// Note dialbyname is an implied database
if ( tableName.compareTo("alias" , UtlString::ignoreCase)==0 ) {
AliasDB::getInstance()->removeAllRows();
} else if ( tableName.compareTo("credential" , UtlString::ignoreCase)==0 ) {
CredentialDB::getInstance()->removeAllRows();
} else if ( tableName.compareTo("extension" , UtlString::ignoreCase)==0 ) {
ExtensionDB::getInstance()->removeAllRows();
} else if ( tableName.compareTo("huntgroup" , UtlString::ignoreCase)==0 ) {
HuntgroupDB::getInstance()->removeAllRows();
} else if ( tableName.compareTo("permission" , UtlString::ignoreCase)==0 ) {
PermissionDB::getInstance()->removeAllRows();
} else if ( tableName.compareTo("subscription" , UtlString::ignoreCase)==0 ) {
SubscriptionDB::getInstance()->removeAllRows();
}
// the folder node contains at least the name/displayname/
// and autodelete elements, it may contain others
for( TiXmlNode *itemNode = dbNode->FirstChild( "item" );
itemNode;
itemNode = itemNode->NextSibling( "item" ) )
{
// Create a hash dictionary for element attributes
UtlHashMap nvPairs;
for( TiXmlNode *elementNode = itemNode->FirstChild();
elementNode;
elementNode = elementNode->NextSibling() )
{
// Bypass comments and other element types only interested
// in parsing element attributes
if ( elementNode->Type() == TiXmlNode::ELEMENT )
{
UtlString elementName = elementNode->Value();
UtlString elementValue;
result = getAttributeValue (*itemNode, elementName, elementValue);
if (result == OS_SUCCESS)
{
UtlString* collectableKey =
new UtlString( elementName );
UtlString* collectableValue =
new UtlString( elementValue );
nvPairs.insertKeyAndValue (
collectableKey, collectableValue );
} else if ( elementNode->FirstChild() == NULL )
{
// Null Element value creaete a special
// char string we have key and value so insert
UtlString* collectableKey =
new UtlString( elementName );
UtlString* collectableValue =
new UtlString( SPECIAL_IMDB_NULL_VALUE );
nvPairs.insertKeyAndValue (
collectableKey, collectableValue );
}
}
}
// Insert the item row into the IMDB
insertRow ( nvPairs, tableName );
}
}
}
else
{
osPrintf( "No items element found\n");
result = OS_FAILED;
}
}
else
{
osPrintf( "Import load failed for '%s'\n", rFileName.data() );
result = OS_FAILED;
}
return result;
}
OsStatus
ImportTask::getAttributeValue (
const TiXmlNode& rNode,
const UtlString& rKey,
UtlString& value ) const
{
OsStatus result = OS_SUCCESS;
TiXmlNode* configNode = (TiXmlNode*)rNode.FirstChild( rKey );
if ( (configNode != NULL) && (configNode->Type() == TiXmlNode::ELEMENT) )
{
// convert the node to an element
TiXmlElement* elem = configNode->ToElement();
if ( elem != NULL )
{
TiXmlNode* childNode = elem->FirstChild();
if( childNode && childNode->Type() == TiXmlNode::TEXT )
{
TiXmlText* elementValue = childNode->ToText();
if (elementValue)
{
value = elementValue->Value();
} else
{
result = OS_FAILED;
}
} else
{
result = OS_FAILED;
}
} else
{
result = OS_FAILED;
}
} else
{
result = OS_FAILED;
}
return result;
}
void
ImportTask::insertRow (
const UtlHashMap& rNVPairs,
const UtlString& rTableName ) const
{
OsSysLog::add(LOG_FACILITY, PRI_DEBUG, "ImportTask::insertRow %s"
,rTableName.data()
);
// check the table
if ( rTableName.compareTo("credential" , UtlString::ignoreCase)==0 )
{
Url uri(*((UtlString*)rNVPairs.findValue(&uriKey)));
UtlString realm = *((UtlString*)rNVPairs.findValue(&realmKey));
UtlString userid = *((UtlString*)rNVPairs.findValue(&useridKey));
UtlString authtype = *((UtlString*)rNVPairs.findValue(&authtypeKey));
UtlString passtoken = *((UtlString*)rNVPairs.findValue(&passtokenKey));
if ( authtype.compareTo("NONE", UtlString::ignoreCase) == 0 )
{
UtlString passtokenPlain = passtoken;
passtoken.remove(0);
UtlString textToEncode = userid + ":" + realm + ":" + passtokenPlain;
NetMd5Codec::encode(textToEncode, passtoken);
}
// if this is an old credentials file, there may not be a pintoken
UtlString pintoken;
if (rNVPairs.contains(&pintokenKey))
{
pintoken = *(UtlString*)rNVPairs.findValue(&pintokenKey);
}
else
{
// old file - duplicate the passtoken value for the pintoken
pintoken = *(UtlString*)rNVPairs.findValue(&passtokenKey);
}
// Always create digest passtokens
CredentialDB::getInstance()->
insertRow ( uri, realm, userid, passtoken, pintoken, "DIGEST" );
} else if ( rTableName.compareTo("huntgroup" , UtlString::ignoreCase)==0 )
{
HuntgroupDB::getInstance()->
insertRow (
Url( *((UtlString*)rNVPairs.findValue(&identityKey))));
} else if ( rTableName.compareTo("alias" , UtlString::ignoreCase)==0 )
{
AliasDB::getInstance()->
insertRow (
Url( *((UtlString*)rNVPairs.findValue(&identityKey))),
Url( *((UtlString*)rNVPairs.findValue(&contactKey))));
} else if ( rTableName.compareTo("permission" , UtlString::ignoreCase)==0 )
{
PermissionDB::getInstance()->
insertRow (
Url( *((UtlString*)rNVPairs.findValue(&identityKey))),
*((UtlString*)rNVPairs.findValue(&permissionKey)));
} else if ( rTableName.compareTo("subscription" , UtlString::ignoreCase)==0 )
{
int iNotifycseq = ((UtlInt*)rNVPairs.findValue(¬ifycseqKey))->getValue();
int iExpiresKey = ((UtlInt*)rNVPairs.findValue(&expiresKey))->getValue();
int iSubscribeKey= ((UtlInt*)rNVPairs.findValue(&subscribecseqKey))->getValue();
SubscriptionDB::getInstance()->
insertRow(
*((UtlString*)rNVPairs.findValue(&uriKey)),
*((UtlString*)rNVPairs.findValue(&callidKey)),
*((UtlString*)rNVPairs.findValue(&contactKey)),
iExpiresKey,
iSubscribeKey,
*((UtlString*)rNVPairs.findValue(&eventtypeKey)),
*((UtlString*)rNVPairs.findValue(&idKey)),
*((UtlString*)rNVPairs.findValue(&toKey)),
*((UtlString*)rNVPairs.findValue(&fromKey)),
*((UtlString*)rNVPairs.findValue(&keyKey)),
*((UtlString*)rNVPairs.findValue(&recordrouteKey)),
iNotifycseq) ;
} else if ( rTableName.compareTo("extension" , UtlString::ignoreCase)==0 )
{
ExtensionDB::getInstance()->
insertRow(
Url( *((UtlString*)rNVPairs.findValue(&uriKey))),
*((UtlString*)rNVPairs.findValue(&extensionKey)));
} else
{
cout << "unknown database type: " << rTableName.data() << endl;
}
}
syntax highlighted by Code2HTML, v. 0.9.1