00001 #ifndef _ots_ConfigurationInterface_h_
00002 #define _ots_ConfigurationInterface_h_
00003
00004 #include "otsdaq-core/ConfigurationDataFormats/ConfigurationGroupKey.h"
00005 #include "otsdaq-core/ConfigurationDataFormats/ConfigurationVersion.h"
00006 #include "otsdaq-core/Macros/CoutHeaderMacros.h"
00007 #include "otsdaq-core/ConfigurationDataFormats/ConfigurationBase.h"
00008
00009 #include "otsdaq-core/PluginMakers/MakeInterfaceConfiguration.h"
00010 #include <memory>
00011 #include <set>
00012 #include <sstream>
00013
00014 namespace ots
00015 {
00016
00017 class ConfigurationHandlerBase;
00018
00019 class ConfigurationInterface
00020 {
00021 friend class ConfigurationManagerRW;
00022 friend class ConfigurationManager;
00023
00024 public:
00025 virtual ~ConfigurationInterface(){;}
00026
00027 static ConfigurationInterface* getInstance(bool mode);
00028 static bool isVersionTrackingEnabled();
00029 static void setVersionTrackingEnabled(bool setValue);
00030
00031 static const std::string GROUP_METADATA_TABLE_NAME;
00032
00033
00034
00035
00036
00037
00038 void get(ConfigurationBase*& configuration,
00039 const std::string configurationName,
00040 std::shared_ptr<const ConfigurationGroupKey> groupKey = 0,
00041 const std::string* groupName = 0,
00042 bool dontFill = false,
00043 ConfigurationVersion version = ConfigurationVersion(),
00044 bool resetConfiguration = true,
00045 bool looseColumnMatching = false)
00046 {
00047 if(configuration == 0)
00048 {
00049
00050 try
00051 {
00052 configuration = makeInterfaceConfiguration(configurationName);
00053 }
00054 catch(...)
00055 {}
00056
00057 if(configuration == 0)
00058 {
00059
00060
00061
00062
00063 try
00064 {
00065 configuration = new ConfigurationBase(configurationName);
00066 }
00067 catch(...)
00068 {
00069 __COUT_WARN__ << "Failed to even use ConfigurationBase!" << std::endl;
00070 if(configuration)
00071 delete configuration;
00072 configuration = 0;
00073 throw;
00074 }
00075
00076 }
00077
00078 }
00079
00080 if(groupKey != 0 && groupName != 0)
00081 {
00082
00083 __SS__ << "FATAL ERROR: new ConfigurationGroup and ConfigurationGroupKey should be used!" << std::endl;
00084 throw std::runtime_error(ss.str());
00085 }
00086 else if(!dontFill)
00087 {
00088
00089 if(version == ConfigurationVersion::INVALID &&
00090 (version=findLatestVersion(configuration)) == ConfigurationVersion::INVALID)
00091 {
00092 __COUT__ << "FATAL ERROR: Can't ask to fill a configuration object with a negative version! " <<
00093 configurationName << std::endl;
00094 __SS__ << "FATAL ERROR: Invalid latest version." <<
00095 std::endl << std::endl << std::endl <<
00096 "*******************" << std::endl <<
00097 "Suggestion: If you expect a version to exist for this configuration, perhaps this is your first time running with the artdaq database. (and your old configurations have not been transferred?) " <<
00098 std::endl << "Try running this once:\n\n\totsdaq_database_migrate" <<
00099 std::endl << std::endl << "This will migrate the old ots file system configuration to the artdaq database approach." <<
00100 std::endl << std::endl << std::endl;
00101 throw std::runtime_error(ss.str());
00102 }
00103 }
00104
00105 if(resetConfiguration)
00106 {
00107 configuration->deactivate();
00108 std::set<ConfigurationVersion> versions =
00109 configuration->getStoredVersions();
00110 for(auto &version:versions)
00111 if(!version.isTemporaryVersion())
00112 configuration->eraseView(version);
00113 }
00114
00115 if(dontFill)
00116 return;
00117
00118
00119
00120
00121 if(configuration->isStored(version))
00122 {
00123
00124
00125
00126 if(!configuration->isActive() || version != configuration->getViewVersion())
00127 configuration->setActiveView(version);
00128
00129 configuration->getViewP()->setLastAccessTime();
00130 return;
00131 }
00132
00133 try
00134 {
00135 if(version.isTemporaryVersion())
00136 {
00137 __COUT_ERR__ << "FATAL ERROR: Can not use interface to fill a configuration object with a temporary version!" << std::endl;
00138 __SS__ << "FATAL ERROR: Invalid temporary version v" << version << std::endl;
00139 throw std::runtime_error(ss.str());
00140 }
00141
00142 configuration->setupMockupView(version);
00143 configuration->setActiveView(version);
00144
00145
00146 configuration->getViewP()->setLooseColumnMatching(looseColumnMatching);
00147 fill(configuration,version);
00148 if(looseColumnMatching) configuration->getViewP()->setLooseColumnMatching(false);
00149 configuration->getViewP()->setLastAccessTime();
00150
00152
00153 if(configuration->getViewP()->getVersion() != version)
00154 {
00155 __COUT__ << "Version mismatch!! " <<
00156 configuration->getViewP()->getVersion() <<
00157 " vs " << version << std::endl;
00158 throw;
00159 }
00160
00161
00162 bool nameIsMatch = true;
00163 unsigned int nameIsMatchIndex,nameIsMatchStorageIndex;
00164 for(nameIsMatchIndex=0, nameIsMatchStorageIndex=0;
00165 nameIsMatchIndex<configuration->getViewP()->getTableName().size();
00166 ++nameIsMatchIndex)
00167 {
00168 if(configuration->getMockupViewP()->getTableName()[nameIsMatchStorageIndex] == '_')
00169 ++nameIsMatchStorageIndex;
00170 if(configuration->getViewP()->getTableName()[nameIsMatchIndex] == '_')
00171 continue;
00172
00173
00174 if(nameIsMatchStorageIndex >= configuration->getMockupViewP()->getTableName().size() ||
00175 configuration->getViewP()->getTableName()[nameIsMatchIndex] !=
00176 configuration->getMockupViewP()->getTableName()[nameIsMatchStorageIndex])
00177 {
00178
00179 nameIsMatch = false;
00180 break;
00181 }
00182 ++nameIsMatchStorageIndex;
00183 }
00184
00185 if(nameIsMatch)
00186 configuration->getViewP()->setTableName(configuration->getMockupViewP()->getTableName());
00187 else
00188 {
00189 __COUT__ << "View Table Name mismatch!! " <<
00190 configuration->getViewP()->getTableName() <<
00191 " vs " << configuration->getMockupViewP()->getTableName() << std::endl;
00192 throw;
00193 }
00194 configuration->getViewP()->init();
00195
00196
00198 }
00199 catch(...)
00200 {
00201 __COUT__ << "Error occurred while getting and filling Configuration \"" <<
00202 configurationName << "\" version:" << version << std::endl;
00203 __COUT__ << "\t-Configuration interface mode=" << theMode_ << std::endl;
00204 throw;
00205 }
00206
00207
00208 }
00209
00210
00211 virtual std::set<std::string > getAllConfigurationNames() const throw(std::runtime_error) { __SS__; throw std::runtime_error(ss.str() + "ConfigurationInterface::... Must only call findAllGlobalConfigurations in a mode with this functionality implemented (e.g. DatabaseConfigurationInterface).");}
00212 virtual std::set<ConfigurationVersion> getVersions (const ConfigurationBase* configuration) const = 0;
00213 const bool& getMode () const {return theMode_;}
00214 ConfigurationVersion saveNewVersion (ConfigurationBase* configuration, ConfigurationVersion temporaryVersion, ConfigurationVersion newVersion = ConfigurationVersion());
00215
00216
00217
00218 virtual std::set<std::string > getAllConfigurationGroupNames(const std::string &filterString = "") const throw(std::runtime_error) { __SS__; throw std::runtime_error(ss.str() + "ConfigurationInterface::... Must only call findAllGlobalConfigurations in a mode with this functionality implemented (e.g. DatabaseConfigurationInterface).");}
00219 virtual std::set<ConfigurationGroupKey> getKeys(const std::string &groupName) const { __SS__; throw std::runtime_error(ss.str() + "ConfigurationInterface::... Must only call findAllGlobalConfigurations in a mode with this functionality implemented (e.g. DatabaseConfigurationInterface).");}
00220 virtual std::map<std::string , ConfigurationVersion > getConfigurationGroupMembers(std::string const& , bool includeMetaDataTable = false) const throw(std::runtime_error) { __SS__; throw std::runtime_error(ss.str() + "ConfigurationInterface::... Must only call findAllGlobalConfigurations in a mode with this functionality implemented (e.g. DatabaseConfigurationInterface).");}
00221 virtual void saveConfigurationGroup(std::map<std::string /*name*/, ConfigurationVersion /*version*/> const& , std::string const& ) const throw(std::runtime_error) { __SS__; throw std::runtime_error(ss.str() + "ConfigurationInterface::... Must only call findAllGlobalConfigurations in a mode with this functionality implemented (e.g. DatabaseConfigurationInterface).");};
00222
00223 protected:
00224 ConfigurationInterface(void);
00225
00226 virtual void fill ( ConfigurationBase* configuration, ConfigurationVersion version) const = 0;
00227 virtual ConfigurationVersion findLatestVersion (const ConfigurationBase* configuration) const = 0;
00228
00229 public:
00230 virtual void saveActiveVersion (const ConfigurationBase* configuration, bool overwrite = false) const = 0;
00231
00232 protected:
00233
00234 ConfigurationHandlerBase* theConfigurationHandler_;
00235
00236 private:
00237 static ConfigurationInterface* theInstance_;
00238 static bool theMode_;
00239 static bool theVersionTrackingEnabled_;
00240 };
00241
00242 }
00243 #endif
00244
00245
00246