Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-08-13 23:26:41

0001 #ifndef CondCore_CondDB_Utils_h
0002 #define CondCore_CondDB_Utils_h
0003 
0004 #include "CondCore/CondDB/interface/Exception.h"
0005 //
0006 #include <string>
0007 #include <cxxabi.h>
0008 #include <algorithm>
0009 #include <iostream>
0010 #include <tuple>
0011 #include <fstream>
0012 #include <unistd.h>
0013 #include <pwd.h>
0014 #include <climits>
0015 #include <regex>
0016 
0017 namespace cond {
0018 
0019   namespace {
0020 
0021     inline std::string demangledName(const std::type_info& typeInfo) {
0022       int status = 0;
0023       std::string ret("");
0024       char* realname = abi::__cxa_demangle(typeInfo.name(), nullptr, nullptr, &status);
0025       if (status == 0 && realname) {
0026         ret = realname;
0027         free(realname);
0028       }
0029       // clean up the spaces... ( to be removed after getting rid of reflex - that does not have spaces...)
0030       ret.erase(std::remove(ret.begin(), ret.end(), ' '), ret.end());
0031       return ret;
0032     }
0033 
0034     inline std::string currentCMSSWVersion() {
0035       std::string version("");
0036       const char* envVersion = std::getenv("CMSSW_VERSION");
0037       if (envVersion) {
0038         version += envVersion;
0039       }
0040       return version;
0041     }
0042 
0043     inline std::string currentArchitecture() {
0044       std::string arch("");
0045       const char* archEnv = std::getenv("SCRAM_ARCH");
0046       if (archEnv) {
0047         arch += archEnv;
0048       }
0049       return arch;
0050     }
0051 
0052     inline std::string getUserName() {
0053       struct passwd* user_creds = getpwuid(getuid());
0054       if (user_creds == nullptr)
0055         return std::string("USER_NOT_AVAILABLE");
0056       return std::string(user_creds->pw_name);
0057     }
0058 
0059     inline std::string getHostName() {
0060       char hostname[HOST_NAME_MAX];
0061       int retcode = gethostname(hostname, HOST_NAME_MAX);
0062       if (retcode)
0063         return "";
0064       return std::string(hostname);
0065     }
0066 
0067     inline std::string getCommand() {
0068       std::string commName("");
0069       try {
0070         std::ifstream comm("/proc/self/cmdline");
0071         std::getline(comm, commName);
0072         size_t ind = commName.find('\0');
0073         while (ind != std::string::npos) {
0074           commName.replace(ind, 1, 1, ' ');
0075           ind = commName.find('\0');
0076         }
0077       } catch (std::ifstream::failure const&) {
0078         commName = "unknown";
0079       }
0080       return commName;
0081     }
0082   }  // namespace
0083 
0084   namespace persistency {
0085 
0086     inline std::string getConnectionProtocol(const std::string& connectionString) {
0087       size_t techEnd = connectionString.find(':');
0088       if (techEnd == std::string::npos)
0089         throwException("Could not resolve the connection protocol on " + connectionString + ".",
0090                        "getConnectionProtocol");
0091       std::string technology = connectionString.substr(0, techEnd);
0092       return technology;
0093     }
0094 
0095     inline std::tuple<std::string, std::string, std::string> parseConnectionString(const std::string& connectionString) {
0096       std::string protocol = getConnectionProtocol(connectionString);
0097       std::string serviceName("");
0098       std::string databaseName("");
0099       if (protocol == "sqlite" || protocol == "sqlite_file" || protocol == "sqlite_fip") {
0100         databaseName = connectionString.substr(protocol.size() + 1);
0101       } else if (protocol == "oracle" || protocol == "frontier") {
0102         size_t ptr = protocol.size() + 1;
0103         if (connectionString.substr(ptr, 2) != "//")
0104           throwException(
0105               "Connection string " + connectionString + " is invalid format for technology \"" + protocol + "\".",
0106               "parseConnectionString");
0107         ptr += 2;
0108         size_t serviceEnd = connectionString.find('/', ptr);
0109         if (serviceEnd == std::string::npos)
0110           throwException("Connection string " + connectionString + " is invalid.", "parseConnectionString");
0111         serviceName = connectionString.substr(ptr, serviceEnd - ptr);
0112         ptr = serviceEnd + 1;
0113         databaseName = connectionString.substr(ptr);
0114       } else
0115         throwException("Technology " + protocol + " is not known.", "parseConnectionString");
0116 
0117       return std::make_tuple(protocol, serviceName, databaseName);
0118     }
0119 
0120     inline std::string convertoToOracleConnection(const std::string& input) {
0121       // leave the connection string unmodified for sqlite
0122       if (input.find("sqlite") == 0 || input.find("oracle") == 0)
0123         return input;
0124 
0125       //static const std::regex trivial("oracle://(cms_orcon_adg|cms_orcoff_prep)/([_[:alnum:]]+?)");
0126       static const std::regex short_frontier("frontier://([[:alnum:]]+?)/([_[:alnum:]]+?)");
0127       static const std::regex long_frontier("frontier://((\\([-[:alnum:]]+?=[^\\)]+?\\))+)/([_[:alnum:]]+?)");
0128       static const std::regex long_frontier_serverurl("\\(serverurl=[^\\)]+?/([[:alnum:]]+?)\\)");
0129 
0130       static const std::map<std::string, std::string> frontierMap = {
0131           {"PromptProd", "cms_orcon_adg"},
0132           {"FrontierProd", "cms_orcon_adg"},
0133           {"FrontierArc", "cms_orcon_adg"},
0134           {"FrontierOnProd", "cms_orcon_adg"},
0135           {"FrontierPrep", "cms_orcoff_prep"},
0136       };
0137 
0138       std::smatch matches;
0139 
0140       static const std::string technology("oracle://");
0141       std::string service("");
0142       std::string account("");
0143 
0144       bool match = false;
0145       if (std::regex_match(input, matches, short_frontier)) {
0146         service = matches[1];
0147         account = matches[2];
0148         match = true;
0149       } else if (std::regex_match(input, matches, long_frontier)) {
0150         std::string frontier_config(matches[1]);
0151         std::smatch matches2;
0152         if (not std::regex_search(frontier_config, matches2, long_frontier_serverurl))
0153           throwException("No serverurl in matched long frontier", "convertoToOracleConnection");
0154         service = matches2[1];
0155         account = matches[3];
0156         match = true;
0157       }
0158 
0159       if (!match)
0160         throwException("Connection string " + input + " can't be converted to oracle connection.",
0161                        "convertoToOracleConnection");
0162 
0163       if (service == "FrontierArc") {
0164         size_t len = account.size() - 5;
0165         account = account.substr(0, len);
0166       }
0167 
0168       auto it = frontierMap.find(service);
0169       if (it == frontierMap.end())
0170         throwException("Connection string can't be converted.", "convertoToOracleConnection");
0171       service = it->second;
0172 
0173       return technology + service + "/" + account;
0174     }
0175 
0176   }  // namespace persistency
0177 
0178 }  // namespace cond
0179 
0180 #endif