cdiDataHandle.cxx

00001 //*************************************************************************************
00002 //
00003 //   cdiDataHandle.cxx
00004 //   ----------
00005 //   Implementation of the cdiDataHandle class.
00006 //   
00007 //   Luis Pedro     -  November 2003
00008 //   Sergei Kolos   -  May 2004
00009 //   Dinis Klose    -  July 2004
00010 //   Nuno Barros    -  September 2004
00011 //
00012 /*************************************************************************************/
00013 
00014 // STD includes
00015 #include <sstream>
00016 #include <algorithm>
00017 #include <cstdlib>
00018 #include <iostream>
00019 extern "C" {
00020 #include <unistd.h>
00021 };
00022 
00023 // CDI specific includes
00024 #include "cdi/cdiDataHandle.h"
00025 #include "cdi/cdiAux.h"
00026 
00027 // OnlineSW includes
00028 #include <is/info.h>
00029 #include <is/infoany.h>
00030 #include <rc/Conditions.h>
00031 #include <is/serveriterator.h>
00032 #include <is/infoiterator.h>
00033 
00034 
00035 // include of boos regex libraries
00036 #include <boost/regex.hpp>
00037 
00038 const std::string cdiDataHandle::configuration_name = "RunParams.Conditions";
00039 
00040 template <class T>
00041 void convert( ISInfoAny & isa, std::vector<std::string> & to )
00042 {
00043     if ( isa.isAttributeArray() )
00044     {
00045     std::vector<T> val;
00046     isa >> val;
00047     for ( size_t i = 0; i < val.size() ; i++ )
00048     {
00049         std::ostringstream out;
00050         out << val[i];
00051         to.push_back( out.str() );
00052     }
00053     }
00054     else
00055     {
00056     T val;
00057     isa >> val;
00058     std::ostringstream out;
00059     out << val;
00060     to.push_back( out.str() );
00061     }
00062 }
00063 
00064 void convertTime ( ISInfoAny & isa, std::vector<std::string> & to )
00065 {
00066      if ( isa.isAttributeArray() )
00067      {
00068          std::vector<OWLTime> val;
00069          isa >> val;
00070          for ( size_t i = 0; i < val.size() ; i++ )
00071          {
00072              OWLTime t = val[i];
00073              long unixTime = t.c_time();
00074              std::ostringstream out;
00075              out << unixTime;
00076              to.push_back( out.str() );
00077          }
00078      }
00079      else
00080      {
00081         OWLTime t;
00082     isa >> t;
00083         long unixTime = t.c_time();
00084         std::ostringstream out;
00085         out << unixTime;
00086         to.push_back( out.str() );
00087      }      
00088 }   
00089 
00090 void cdiDataHandle::getConfig( std::vector<std::string> & names )
00091 {
00092   // first let's get the dictionary for the partition
00093   // This will allow to retrieve any object that might be needed (RunParams.Conditions)
00094   ISInfoDictionary dictionary(partition);
00095   
00096   //let's retrieve the conditions object that contains the list of subscribed objeccts 
00097   Conditions conditions;
00098   ISInfo::Status status = dictionary.findValue( configuration_name.c_str(), conditions );
00099   
00100   mout.info( std::string("Getting Informations to subscribe"), 2);
00101   
00102   names.clear();
00103   
00104   if ( status == ISInfo::Success)
00105     names = conditions.isservers;
00106 
00107   // The RunParams.RunParams object ismandatory
00108   if ( std::find( names.begin(), names.end(), std::string( "RunParams.RunParams" ) ) == names.end() ) {
00109     mout.info( std::string("cdiDataHandle::getConfig> Adding [RunParams.RunParams] to names"),3);
00110     names.push_back( "RunParams.RunParams" );
00111   }
00112  
00113   //The RunParams.Conditions object shall also be stored to keep
00114   // track of the subscription commands issued by the users
00115   if ( std::find( names.begin(), names.end(), configuration_name ) == names.end() ) {
00116     mout.info( std::string("cdiDataHandle::getConfig> Adding [" + configuration_name+ "] to names"),3);
00117     names.push_back( configuration_name );  
00118   }
00119 
00120   // Here we need to proceed to two different issues
00121   // We need to move the time consuming tasks to the initialisation (here)
00122   // Time consuming tasks: (folder verification and creation, attributelist generation)
00123   
00124   // we also need to store the values existing in the object at the moment of the
00125   // subscription and not only after the first update
00126 
00127   
00128   //  std::vector<std::string>::const_iterator it = names.begin();
00129   std::vector<std::string>::const_iterator itEnd = names.end();
00130 
00131   // a new container is needed to store the real names of the objects to be stored
00132   std::vector<std::string> pNames;
00133   
00134   // The object of the name
00135   std::string objName;
00136   // To avoid the overloading of the IS I'm just going to cycle once through
00137   // The whole list of servers and objects
00138   
00139   ISServerIterator ISit(partition);
00140   while( ISit() ){
00141     objName = ISit.name();
00142     mout.verbose(std::string("Checking the sever [" + objName + "]"));
00143     
00144     ISInfoIterator ii(partition,ISit.name());
00145     while( ii() ){
00146       // let's finally iterate under all the subscribed names from the user
00147       //objName += ".";
00148       objName = ii.name();
00149       mout.verbose(std::string("getConfig -> Starting to check object [" + objName + "]"));
00150       for (  std::vector<std::string>::const_iterator it = names.begin(); it != itEnd; ++it){
00151     boost::regex expression((*it).c_str());
00152     boost::cmatch what;
00153     // using the boost regex library let's see if the current object matches any of the 
00154     // user defined elements in the names list
00155     if (boost::regex_match(objName.c_str(),expression)){
00156       mout.verbose(std::string("getConfig -> [" + objName + "] matches the expression [" + (*it) + "]"));
00157       pNames.push_back(objName);
00158       
00159       // let's proceed to storage of the object with its current contents
00160       ISInfoAny isa;
00161       ii.value(isa);
00162       storeObject(objName, isa);
00163     }
00164     else {
00165       mout.verbose(std::string("getConfig -> [" + objName + "] does not match the expression [" + (*it) + "]"));
00166     }
00167     
00168       }
00169     }
00170   }
00171     mout.info( std::string("cdiDataHandle::getConfig> Returning without problems"),3);
00172 }
00173 
00174 std::string cdiDataHandle::getProfile()
00175 {
00176     char * tmp = getenv( "TDAQ_COND_DB_PROFILE" );
00177   
00178     if ( tmp == 0 )
00179     {
00180     mout.info( std::string("Environment variable TDAQ_COND_DB_PROFILE must be defined!") );
00181     mout.info( std::string("CDI will exit now.") );
00182     exit(1);
00183     }
00184     
00185     return std::string(tmp);
00186 }
00187 
00188 cdiDataHandle::cdiDataHandle( int verbosity, const IPCPartition & p )
00189   : partition( p ),
00190     mout( verbosity )
00191 {
00192   mout.info(std::string("Initializing CDI Data Handle.."), 3);
00193  
00194   // Simple types
00195   types.insert( std::make_pair( ISType::Boolean,    ICondDBTable::cdbBool ) );
00196   types.insert( std::make_pair( ISType::S16,    ICondDBTable::cdbInt ) );
00197   types.insert( std::make_pair( ISType::U16,    ICondDBTable::cdbInt ) );
00198   types.insert( std::make_pair( ISType::S32,    ICondDBTable::cdbLongLong ) );
00199   types.insert( std::make_pair( ISType::U32,    ICondDBTable::cdbLongLong ) );
00200   types.insert( std::make_pair( ISType::Float,  ICondDBTable::cdbFloat ) );
00201   types.insert( std::make_pair( ISType::Double, ICondDBTable::cdbDouble ) );
00202   types.insert( std::make_pair( ISType::S8, ICondDBTable::cdbString ) );
00203   types.insert( std::make_pair( ISType::U8, ICondDBTable::cdbString ) );
00204   types.insert( std::make_pair( ISType::String, ICondDBTable::cdbString ) );
00205   types.insert( std::make_pair( ISType::Date,   ICondDBTable::cdbLongLong ) );
00206   types.insert( std::make_pair( ISType::Time,   ICondDBTable::cdbLongLong ) );
00207   
00208   // Array types
00209   a_types.insert( std::make_pair( ISType::Boolean,  ICondDBTable::cdbArrayBool ) );
00210   a_types.insert( std::make_pair( ISType::S16,  ICondDBTable::cdbArrayInt ) );
00211   a_types.insert( std::make_pair( ISType::U16,  ICondDBTable::cdbArrayInt ) );
00212   a_types.insert( std::make_pair( ISType::S32,  ICondDBTable::cdbArrayLongLong ) );
00213   a_types.insert( std::make_pair( ISType::U32,  ICondDBTable::cdbArrayLongLong ) );
00214   a_types.insert( std::make_pair( ISType::Float,    ICondDBTable::cdbArrayFloat ) );
00215   a_types.insert( std::make_pair( ISType::Double,   ICondDBTable::cdbArrayDouble ) );
00216   a_types.insert( std::make_pair( ISType::S8,   ICondDBTable::cdbArrayString ) );
00217   a_types.insert( std::make_pair( ISType::U8,   ICondDBTable::cdbArrayString ) );
00218   a_types.insert( std::make_pair( ISType::String,   ICondDBTable::cdbArrayString ) );
00219   a_types.insert( std::make_pair( ISType::Date, ICondDBTable::cdbArrayLongLong ) );
00220   a_types.insert( std::make_pair( ISType::Time, ICondDBTable::cdbArrayLongLong ) );
00221   
00222   
00223   try
00224   {
00225     init( getProfile() );
00226   }
00227   catch (CondDBException &e)
00228   {
00229     std::cerr  << e.getMessage() << "   " << e.getErrorCode() << std::endl;
00230     exit( 1 );
00231   }
00232 }
00233 
00234 void cdiDataHandle::init( const std::string & profile )
00235 {
00236   mout.info(std::string("Initializing ConditionsDB Objects.."), 3); 
00237   
00238   mout.info(std::string("Performing CondDBMySQLMgrFactory::createCondDBMgr..."), 3);
00239   condDBmgr = CondDBMySQLMgrFactory::createCondDBMgr();
00240   
00241   mout.info(std::string("Performing condDBmgr->init()"), 3);
00242   condDBmgr->init(profile);
00243   
00244   mout.info(std::string("Performing condDBMgr->createCondDB()"), 3);
00245   condDBmgr->createCondDB();
00246   
00247   mout.info(std::string("Performing condDBMgr->openDatabase()"), 3);
00248   condDBmgr->openDatabase();
00249   
00250   mout.info(std::string("Performing condDBMgr-getCondDBDataAccess()"), 3);
00251   condDataAccess = condDBmgr->getCondDBDataAccess();
00252   
00253   mout.info(std::string("Performing condDBMgr->getCondDBFolderMgr()"), 3);
00254   condFolderMgr  = condDBmgr->getCondDBFolderMgr(); 
00255 }
00256 
00257 bool cdiDataHandle::is_table_exist ( const std::string & name )
00258 {
00259   mout.info(std::string("Entering <cdiDataHandle::is_table_exist>"), 2);
00260   std::map <std::string, ICondDBTable*>::iterator it = tables.begin();
00261   for( ; it != tables.end(); ++it )
00262   {
00263     if ( it->first == name )
00264       return true;
00265   }
00266   return false;
00267 }
00268 
00269 void cdiDataHandle::add_table ( ICondDBTable * table, const std::string & name )
00270 {
00271   mout.info(std::string("Entering <cdiDataHandle::add_table>"), 2);
00272   table->resize( 1 );
00273   tables.insert( std::make_pair( name, table ) );
00274 }
00275 
00276 void cdiDataHandle::create_folder ( const std::string & name, ISInfoAny & isa )
00277 {  
00278   mout.info( std::string( "Entering <cdiDataHandle::create_folder> " + name ), 2 );
00279 
00280   if ( is_table_exist( name ) )
00281   {
00282     mout.info(std::string("Entering <cdiDataHandle::create_folder> Folder already exist"), 3);
00283     return;
00284   }
00285   
00286   ICondDBTable * table = CondDBMySQLTableFactory::createCondDBTable();
00287   
00288   std::string fname = std::string("/tdaq/" + partition.name() + "/" + name);
00289   
00290   try
00291   {
00292     condDataAccess->getTableSchema( fname, table );
00293     add_table( table, name );
00294     mout.info(std::string("<cdiDataHandle::create_folder> Read table schema from the database") );
00295     return;
00296   }
00297   catch (CondDBException &e)
00298   {
00299     mout.info( std::string("<cdiDataHandle::create_folder> Folder does not exist in the database "), 1 );
00300   }
00301   
00302   table->Initialize( isa.countAttributes() );
00303   
00304   ISInfoDocument isd( partition, isa );
00305   
00306   if ( isd.status() == ISInfo::Success )
00307   {
00308     mout.info(std::string("<cdiDataHandle::create_folder> isd.name: " + isd.name() + " isd.description: " + isd.description() ) , 3 );
00309   }
00310   else
00311   {
00312     if (isd.status() == ISInfo::CommFailure) {
00313       mout.error(std::string("<cdiDataHandle::create_folder> The IS types descriptions repository is not available"));
00314       // exit (0);
00315     }
00316     else {
00317       mout.info(std::string("<cdiDataHandle::create_folder> IS description for the " + isd.name() + " is not available" ) , 3 );
00318       // exit(0);
00319     }
00320   }
00321   
00322   for ( size_t i = 0; i < isa.countAttributes(); i++ )
00323     {
00324       // nbarros - just a small try
00325       const ISInfoDocument::Attribute *attr = 0;
00326       if (isd.status() == ISInfo::Success) {
00327     attr = isd.attribute( i );
00328       }
00329       table->setType( i, isa.isAttributeArray() ? a_types[isa.getAttributeType()] 
00330               : types[isa.getAttributeType()] );
00331       std::ostringstream out;
00332       out << "column_" << i;
00333       table->setName( i, attr ? attr->name() : out.str() ); 
00334       
00335       std::ostringstream msg, msg2;
00336       //let's put the data in the payloadSpec
00337       //      msg << "Attribute name: [" << attr->name() << "] Attribute type: [" 
00338       //      <<  types[isa.getAttributeType()] << "] <-> [" << isa.getAttributeType()
00339       //      << "]"; 
00340       //mout.verbose(msg.str());
00341       
00342       std::vector<std::string> cell;
00343       switch ( isa.getAttributeType() )
00344       { 
00345       case ISType::Boolean: { convert<bool>( isa, cell ); break; }
00346       case ISType::S16: { convert<short>( isa, cell ); break; }
00347     case ISType::U16: { convert<unsigned short>( isa, cell ); break; }
00348     case ISType::S32: { convert<long>( isa, cell ); break; }
00349     case ISType::U32: { convert<unsigned long>( isa, cell ); break; }
00350     case ISType::Float: { convert<float>( isa, cell ); break; }
00351     case ISType::Double: { convert<double>( isa, cell ); break; }
00352     case ISType::S8: { convert<char>( isa, cell ); break; }
00353     case ISType::U8: { convert<unsigned char>( isa, cell ); break; }
00354     case ISType::String: { convert<string>( isa, cell ); break; }
00355     case ISType::Date: { convertTime( isa, cell ); break; }
00356     case ISType::Time: { convertTime( isa, cell ); break; }
00357     case ISType::Error:
00358     default: { mout.info( string( "IS Attribute Error " ) ); break; }
00359       }
00360 
00361   }
00362    
00363   isa.reset();
00364 
00365   try
00366   {
00367     //Creating the folder in the database
00368     mout.info(std::string("<cdiDataHandle::create_folder> Proceeding to folder " + name + " creation (if needed)... ") , 3);
00369         
00370     if ( !condFolderMgr->exist( fname ) )
00371     {
00372     mout.info( std::string("<cdiDataHandle::create_folder> folder " + fname + " does not exist " ) );
00373     condFolderMgr->createCondDBFolder( fname, table, "", "", true );
00374     mout.info(std::string("<cdiDataHandle::create_folder> Folder " + fname + " created." ) );
00375     }
00376     else
00377     {
00378     mout.info(std::string("<cdiDataHandle::create_folder> Folder " + fname + " already exists.") );
00379     }
00380     add_table( table, name );
00381   }
00382   catch (CondDBException &e)
00383   {
00384     mout.error( std::string(" ConditionsDB exception : " + (std::string)e.getMessage() ) );
00385   }
00386 }
00387 
00388 void cdiDataHandle::process_data ( const std::string & name, ISCallbackInfo * isc )
00389 {
00390   mout.info(std::string("Entering <cdiDataHandle::process_data>"), 2);
00391   ISInfoAny isa;
00392   isc->value( isa );
00393 
00394 
00395 
00396   std::string rVersion = RELEASE_NAME;
00397   std::string fSuffix;
00398   std::string::size_type beg = rVersion.find("-");
00399   
00400   if (beg != std::string::npos) // there is a version name
00401     fSuffix = rVersion.substr(beg);
00402   else // the cmtrealease is a nighlty
00403     fSuffix = "-" + rVersion;
00404   
00405   std::string foldName = name + fSuffix; //"-01-00-00"; 
00406   
00407   create_folder ( foldName, isa );
00408   
00409   // fianlly process to object storage
00410   storeObject( name, isa);
00411 }
00412 
00413 
00414 void cdiDataHandle::storeObject( const std::string& name, ISInfoAny &isa) {
00415   
00416   
00417   std::string rVersion = RELEASE_NAME;
00418   std::string fSuffix;
00419   std::string::size_type beg = rVersion.find("-");
00420   
00421   if (beg != std::string::npos) // there is a version name
00422     fSuffix = rVersion.substr(beg);
00423   else // the cmtrealease is a nighlty
00424     fSuffix = "-" + rVersion;
00425   
00426   std::string foldName = name + fSuffix; //"-01-00-00"; 
00427 
00428   create_folder ( foldName, isa );
00429   
00430   ICondDBTable * table = tables[foldName];
00431   
00432   if ( !table )
00433   {
00434     mout.error(std::string("<cdiDataHandle::writeData> table " + name + " does not exist") );
00435     return;
00436   }
00437     
00438   mout.info(std::string("<cdiDataHandle::writeData> processing data with structure description"), 2);
00439     
00440   for( size_t n = 0; n < isa.countAttributes(); n++ )
00441   {
00442       std::vector<std::string> cell;
00443       bool is_array = isa.isAttributeArray();
00444       switch ( isa.getAttributeType() )
00445       {
00446     case ISType::Boolean: { 
00447       std::ostringstream msg;
00448       msg << "Parameter [" << n << "]: ["
00449           << "bool" << "]" ;
00450       mout.verbose(msg.str());
00451       convert<bool>( isa, cell ); break; }
00452     case ISType::S16: { 
00453       std::ostringstream msg;
00454       msg << "Parameter [" << n << "]: ["
00455           << "S16" << "]" ;
00456       mout.verbose(msg.str());
00457       convert<short>( isa, cell ); break; }
00458     case ISType::U16: {       std::ostringstream msg;
00459       msg << "Parameter [" << n << "]: ["
00460           << "U16" << "]" ;
00461       mout.verbose(msg.str());
00462       convert<unsigned short>( isa, cell ); break; }
00463     case ISType::S32: { 
00464       std::ostringstream msg;
00465       msg << "Parameter [" << n << "]: ["
00466           << "S32" << "]" ;
00467       mout.verbose(msg.str());
00468       convert<long>( isa, cell ); break; }
00469     case ISType::U32: { 
00470       std::ostringstream msg;
00471       msg << "Parameter [" << n << "]: ["
00472           << "U32" << "]" ;
00473       mout.verbose(msg.str());
00474       convert<unsigned long>( isa, cell ); break; }
00475     case ISType::Float: { 
00476       std::ostringstream msg;
00477       msg << "Parameter [" << n << "]: ["
00478           << "FLoat" << "]" ;
00479       mout.verbose(msg.str());
00480       convert<float>( isa, cell ); break; }
00481     case ISType::Double: { 
00482       std::ostringstream msg;
00483       msg << "Parameter [" << n << "]: ["
00484           << "Double" << "]" ;
00485       mout.verbose(msg.str());
00486       convert<double>( isa, cell ); break; }
00487     case ISType::S8: { 
00488       std::ostringstream msg;
00489       msg << "Parameter [" << n << "]: ["
00490           << "S8" << "]" ;
00491       mout.verbose(msg.str());
00492       convert<char>( isa, cell ); break; }
00493     case ISType::U8: { 
00494       std::ostringstream msg;
00495       msg << "Parameter [" << n << "]: ["
00496           << "U8" << "]" ;
00497       mout.verbose(msg.str());
00498       convert<unsigned char>( isa, cell ); break; }
00499     case ISType::String: { 
00500       std::ostringstream msg;
00501       msg << "Parameter [" << n << "]: ["
00502           << "String" << "]" ;
00503       mout.verbose(msg.str());
00504       convert<string>( isa, cell ); break; }
00505     case ISType::Date: { 
00506       std::ostringstream msg;
00507       msg << "Parameter [" << n << "]: ["
00508           << "Date" << "]" ;
00509       mout.verbose(msg.str());
00510       convertTime( isa, cell ); break; }
00511     case ISType::Time: { 
00512       std::ostringstream msg;
00513       msg << "Parameter [" << n << "]: ["
00514           << "Time" << "]" ;
00515       mout.verbose(msg.str());
00516       convertTime( isa, cell ); break; }
00517     case ISType::Error:
00518     default: { mout.info( string( "IS Attribute Error " ) ); break; }
00519       }
00520 
00521       try
00522       {
00523     if ( is_array )
00524       table->setCell( n, 0, cell );
00525     else
00526       table->setCell( n, 0, cell[0] );
00527       }
00528       catch (CondDBException &e)
00529       {
00530     std::cerr << e.getMessage() << " " << e.getErrorCode() << std::endl; 
00531       }
00532   }  
00533   // Now we have the table with the the values in memmory,
00534   // Lets assign an interval of validity to the rows in the table
00535       
00536   OWLTime t = isa.time();
00537 
00538   SimpleTime since ( t.c_time() );
00539   SimpleTime till;
00540   till.setPlusInf();
00541     
00542   table->changeSinceTime( 0, since );
00543   table->changeTillTime( 0, till );
00544   
00545   mout.info(std::string("<cdiDataHandle::writeData> Storing Table ...") );
00546 
00547   std::string folder( "/tdaq/" + partition.name() + "/" + foldName);
00548   
00549   try
00550   {
00551     condDataAccess->storeCondDBObject( folder, table );
00552   }
00553   catch (CondDBException &e)
00554   {
00555     std::cerr << e.getMessage() << " " << e.getErrorCode() << std::endl; 
00556   }
00557   
00558   mout.info(std::string("<cdiDataHandle::writeData> Table stored") );
00559 }

Generated on Mon Feb 6 14:01:17 2006 for SCT DAQ/DCS Software - C++ by  doxygen 1.4.6