ATLAS Offline Software
Loading...
Searching...
No Matches
DBReplicaSvc Class Reference

#include <DBReplicaSvc.h>

Inheritance diagram for DBReplicaSvc:
Collaboration diagram for DBReplicaSvc:

Public Member Functions

virtual StatusCode initialize () override
void sort (std::vector< const coral::IDatabaseServiceDescription * > &replicaSet) override

Private Types

typedef std::pair< std::string, int > ServerPair

Private Member Functions

StatusCode readConfig ()

Private Attributes

Gaudi::Property< std::string > m_configfile {this, "ConfigFile", "dbreplica.config"}
Gaudi::Property< std::string > m_testhost {this, "TestHost", ""}
Gaudi::Property< std::string > m_coolsqlitepattern {this, "COOLSQLiteVetoPattern", ""}
Gaudi::Property< bool > m_usecoolsqlite {this, "UseCOOLSQLite", true}
Gaudi::Property< bool > m_usecoolfrontier {this, "UseCOOLFrontier", true}
Gaudi::Property< bool > m_usegeomsqlite {this, "UseGeomSQLite", true}
Gaudi::Property< bool > m_nofailover {this, "DisableFailover", false}
bool m_frontiergen {false}
std::string m_hostname
std::vector< ServerPairm_servermap

Detailed Description

Definition at line 16 of file DBReplicaSvc.h.

Member Typedef Documentation

◆ ServerPair

typedef std::pair<std::string, int> DBReplicaSvc::ServerPair
private

Definition at line 38 of file DBReplicaSvc.h.

Member Function Documentation

◆ initialize()

StatusCode DBReplicaSvc::initialize ( )
overridevirtual

Definition at line 16 of file DBReplicaSvc.cxx.

16 {
17
18 // determine the hostname (or override if from joboption)
20 // if nothing set on job-options, try environment variable ATLAS_CONDDB
21 if (m_hostname.empty()) {
22 const char* chost=getenv("ATLAS_CONDDB");
23 if (chost) m_hostname=chost;
24 }
25 // if ATLAS_CONDDB not set, try environment variable HOSTNAME
26 if (m_hostname.empty()) {
27 const char* chost=getenv("HOSTNAME");
28 if (chost) m_hostname=chost;
29 // check if the returned host has a .
30 if (m_hostname.find('.')==std::string::npos) {
31 ATH_MSG_DEBUG("HOSTNAME " << m_hostname
32 << " has no domain - try hostname --fqdn");
33 m_hostname="unknown";
34#ifndef __APPLE__
35 system("hostname --fqdn > hostnamelookup.tmp");
36#else
37 // Unfortunately Leopard doesn't understand the -f option to hostname, only Snow Leopard does
38 system("hostname > hostnamelookup.tmp");
39#endif
40 std::ifstream infile;
41 infile.open("hostnamelookup.tmp");
42 if (infile) {
44 ATH_MSG_DEBUG ("HOSTNAME from fqdn: " << m_hostname);
45 } else {
46 m_hostname="unknown";
47 }
48 }
49 }
50 // check if FRONTIER_SERVER is set, if so, allow generic replicas
51 const char* cfrontier=getenv("FRONTIER_SERVER");
52 if (m_usecoolfrontier && cfrontier && strcmp(cfrontier,"")!=0) {
53 ATH_MSG_INFO ("Frontier server at " << cfrontier
54 << " will be considered for COOL data");
55 m_frontiergen=true;
56 }
58 if (!m_usecoolsqlite) {
59 ATH_MSG_INFO ("COOL SQLite replicas will be excluded");
60 } else if (m_coolsqlitepattern!="") {
61 ATH_MSG_INFO ("COOL SQLite replicas will be excluded if matching pattern "
63 }
65 ATH_MSG_INFO ("COOL Frontier replicas will be excluded");
66 if (!m_usegeomsqlite)
67 ATH_MSG_INFO ("Geometry SQLite replicas will be excluded");
68 if (m_nofailover)
69 ATH_MSG_INFO ("Failover to secondary replicas disabled");
70 return sc;
71}
#define ATH_MSG_INFO(x)
#define ATH_MSG_DEBUG(x)
static Double_t sc
std::string m_hostname
Gaudi::Property< std::string > m_testhost
Gaudi::Property< bool > m_usegeomsqlite
Gaudi::Property< bool > m_usecoolsqlite
Gaudi::Property< bool > m_nofailover
Gaudi::Property< std::string > m_coolsqlitepattern
StatusCode readConfig()
Gaudi::Property< bool > m_usecoolfrontier
::StatusCode StatusCode
StatusCode definition for legacy code.
std::string getenv(const std::string &variableName)
get an environment variable
str infile
Definition run.py:13

◆ readConfig()

StatusCode DBReplicaSvc::readConfig ( )
private

Definition at line 74 of file DBReplicaSvc.cxx.

74 {
75
76 // try to locate the file using pathresolver
77 std::string file=PathResolver::find_file(m_configfile,"DATAPATH");
78 if (file.empty()) {
79 ATH_MSG_ERROR ("Cannot locate configuration file " << m_configfile);
80 return StatusCode::FAILURE;
81 }
82 // open and read the file
83 ATH_MSG_INFO ("Read replica configuration from " << file);
84 FILE* p_inp=fopen(file.c_str(),"r");
85 if (p_inp==nullptr) {
86 ATH_MSG_ERROR ("Cannot open configuration file");
87 return StatusCode::FAILURE;
88 }
89 // buffer for reading line
90 const unsigned int bufsize=999;
91 char p_buf[bufsize];
92 while (!feof(p_inp)) {
93 char* p_line=fgets(p_buf,bufsize,p_inp);
94 if (p_line!=NULL && p_line[0]!='#') {
95 std::string buf=std::string(p_line);
96 std::string::size_type iofs1=0;
97 // analyse based on spaces as separator
98 bool sequal=false;
99 std::vector<std::string> domains;
100 std::vector<std::string> servers;
101 while (iofs1<buf.size()) {
102 std::string::size_type iofs2=buf.find(' ',iofs1);
103 // allow for trailing linefeed
104 if (iofs2==std::string::npos) iofs2=buf.size()-1;
105 std::string token=buf.substr(iofs1,iofs2-iofs1);
106 // skip empty or space tokens
107 if (token!="" && token!=" ") {
108 if (token=="=") {
109 sequal=true;
110 } else if (!sequal) {
111 // token is a domain name
112 domains.push_back(std::move(token));
113 } else {
114 // token is a server name
115 if (!m_nofailover || servers.size()==0 || token=="atlas_dd")
116 servers.push_back(std::move(token));
117 }
118 }
119 iofs1=iofs2+1;
120 }
121 // check the list of domains against the hostname to see if this
122 // set of servers is appropriate
123 bool useit=false;
124 unsigned int bestlen=0;
125 for (const std::string& d : domains) {
126 std::string::size_type len=d.size();
127 std::string::size_type hlen=m_hostname.size();
128 if (hlen>=len && d==m_hostname.substr(hlen-len,len)) {
129 if (len>bestlen) {
130 useit=true;
131 bestlen=len;
132 }
133 }
134 // for 'default' domain name, add the servers as a last resort
135 // if nothing has been found so far
136 if ("default"==d && m_servermap.empty()) {
137 ATH_MSG_INFO ("No specific match for domain found - use default fallback");
138 useit=true;
139 bestlen=0;
140 }
141 }
142 if (useit) {
143 // assign these servers, priority based on position in list
144 // and length of match of domain name
145 for (unsigned int i=0;i<servers.size();++i) {
146 int priority=i*5-100*bestlen;
147 // only add ATLF Frontier generic servers if allowed
148 if (servers[i]!="ATLF" || m_frontiergen) {
149 // give generic Frontier server higher (more negative) priority
150 // so it will be preferred over DBRelaese SQLite file
151 if (servers[i]=="ATLF") priority-=2000;
152 m_servermap.push_back(ServerPair(servers[i],priority));
153 ATH_MSG_DEBUG ("Candidate server " << servers[i] <<
154 " (priority " << priority << ")");
155 }
156 }
157 }
158 }
159 }
160 fclose(p_inp);
161 msg() << MSG::INFO << "Total of " << m_servermap.size() <<
162 " servers found for host " << m_hostname << " [";
163 for (const auto& [name, pri] : m_servermap) {
164 msg() << name << " ";
165 }
166 msg() << "]" << endmsg;
167 return StatusCode::SUCCESS;
168}
#define endmsg
#define ATH_MSG_ERROR(x)
std::pair< std::string, int > ServerPair
std::vector< ServerPair > m_servermap
Gaudi::Property< std::string > m_configfile
static std::string find_file(const std::string &logical_file_name, const std::string &search_path)
MsgStream & msg
Definition testRead.cxx:32
TFile * file

◆ sort()

void DBReplicaSvc::sort ( std::vector< const coral::IDatabaseServiceDescription * > & replicaSet)
override

Definition at line 170 of file DBReplicaSvc.cxx.

170 {
171 // if only one replica offered, return immediately
172 // this helps for online, where explicit configuration file is given
173 // that does not match any of the standard dbreplica.config entries
174 if (replicaSet.size()<=1) return;
175
176 // loop through all the offered replicas
177 std::map<int,const coral::IDatabaseServiceDescription*> primap;
178 for (const coral::IDatabaseServiceDescription* dbdescr : replicaSet) {
179
180 const std::string conn=dbdescr->connectionString();
181 ATH_MSG_DEBUG ("Replica connection string: " << conn);
182 if (conn.find("sqlite_file")!=std::string::npos) {
183 // include SQLite files unless they are vetoed
184 // COOL SQLIte files recognised by ALLP in connection string
185 // vetoed if use-SQlite flag not set, or pattern is found in
186 // SQLite filename
187 // Geometry SQLite files recognised by geomDB in connection string
188 if (!( ((m_usecoolsqlite==false ||
189 (m_coolsqlitepattern!="" &&
190 conn.find(m_coolsqlitepattern)!=std::string::npos))
191 && conn.find("ALLP")!=std::string::npos)
192 || ((m_usegeomsqlite==false ||
193 (m_coolsqlitepattern!="" &&
194 conn.find(m_coolsqlitepattern)!=std::string::npos))
195 && conn.find("geomDB")!=std::string::npos))) {
196 // local sqlite files get -9999, DB release ones
197 // (identified with path starting / or containing DBRelease)
198 // get -999, so local one will be tried first if present
199 if (conn.find("sqlite_file:/")!=std::string::npos ||
200 conn.find("DBRelease")!=std::string::npos) {
201 primap[-999]=dbdescr;
202 } else {
203 primap[-9999]=dbdescr;
204 }
205 }
206 } else {
207 // define priority for technologies with this server (lower = better)
208 bool veto=false;
209 int spri=5; // default for Oracle
210 if (conn.find("frontier:")!=std::string::npos) {
211 spri=3; // use frontier before oracle
212 // dont use frontier servers if disabled, or generic Frontier server
213 // is specified (via '()' in server definition) and FRONTIER_SERVER
214 // env variable is not set
215 if (!m_usecoolfrontier ||
216 (conn.find("()")!=std::string::npos && m_frontiergen==false))
217 veto=true;
218 }
219 // extract the server name (assuming URLs "techno://server/schema")
220 std::string::size_type ipos1=conn.find("://");
221 std::string::size_type ipos2=conn.find('/',ipos1+3);
222 // for Frontier, have to remove the (..) part after the server name
223 // e.g. frontier://ATLAS_COOLPROD/(serverurl=http://xyzfrontier.cern.ch:8000/atlr)/schema
224 std::string::size_type ipos3=conn.find('(',ipos1+3);
225 if (ipos3!=std::string::npos && ipos3<ipos2) ipos2=ipos3;
226 if (ipos1!=std::string::npos && ipos2!=std::string::npos && !veto) {
227 const std::string server=conn.substr(ipos1+3,ipos2-ipos1-3);
228 // check if this server is on list of replicas to use for domain
229 // if so, add it with its associated priority
230 for (const auto& [name, pri] : m_servermap) {
231 if (name==server) {
232 primap[pri+spri]=dbdescr;
233 }
234 }
235 }
236 }
237 }
238 // now create sorted list
239 replicaSet.clear();
240 for (const auto& [pri, db] : primap) {
241 replicaSet.push_back(db);
242 ATH_MSG_DEBUG ("Allowed replica to try (priority " << pri << ") : " << db->connectionString());
243 }
244 if (replicaSet.empty()) {
245 ATH_MSG_ERROR ("No matching replicas found");
246 }
247 ATH_MSG_DEBUG ("Retained total of " << replicaSet.size() << " replicas");
248}
std::vector< std::string > veto
these patterns are anded
Definition listroot.cxx:191

Member Data Documentation

◆ m_configfile

Gaudi::Property<std::string> DBReplicaSvc::m_configfile {this, "ConfigFile", "dbreplica.config"}
private

Definition at line 28 of file DBReplicaSvc.h.

28{this, "ConfigFile", "dbreplica.config"};

◆ m_coolsqlitepattern

Gaudi::Property<std::string> DBReplicaSvc::m_coolsqlitepattern {this, "COOLSQLiteVetoPattern", ""}
private

Definition at line 30 of file DBReplicaSvc.h.

30{this, "COOLSQLiteVetoPattern", ""};

◆ m_frontiergen

bool DBReplicaSvc::m_frontiergen {false}
private

Definition at line 36 of file DBReplicaSvc.h.

36{false};

◆ m_hostname

std::string DBReplicaSvc::m_hostname
private

Definition at line 37 of file DBReplicaSvc.h.

◆ m_nofailover

Gaudi::Property<bool> DBReplicaSvc::m_nofailover {this, "DisableFailover", false}
private

Definition at line 34 of file DBReplicaSvc.h.

34{this, "DisableFailover", false};

◆ m_servermap

std::vector<ServerPair> DBReplicaSvc::m_servermap
private

Definition at line 39 of file DBReplicaSvc.h.

◆ m_testhost

Gaudi::Property<std::string> DBReplicaSvc::m_testhost {this, "TestHost", ""}
private

Definition at line 29 of file DBReplicaSvc.h.

29{this, "TestHost", ""};

◆ m_usecoolfrontier

Gaudi::Property<bool> DBReplicaSvc::m_usecoolfrontier {this, "UseCOOLFrontier", true}
private

Definition at line 32 of file DBReplicaSvc.h.

32{this, "UseCOOLFrontier", true};

◆ m_usecoolsqlite

Gaudi::Property<bool> DBReplicaSvc::m_usecoolsqlite {this, "UseCOOLSQLite", true}
private

Definition at line 31 of file DBReplicaSvc.h.

31{this, "UseCOOLSQLite", true};

◆ m_usegeomsqlite

Gaudi::Property<bool> DBReplicaSvc::m_usegeomsqlite {this, "UseGeomSQLite", true}
private

Definition at line 33 of file DBReplicaSvc.h.

33{this, "UseGeomSQLite", true};

The documentation for this class was generated from the following files: