ATLAS Offline Software
Database/CoolConvUtilities/src/ReplicaSorter.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 // ReplicaSorter.cxx
6 // Richard Hawkings, 26/11/07
7 
8 #include "ReplicaSorter.h"
9 #include "RelationalAccess/IDatabaseServiceDescription.h"
10 #include <cstdlib>
11 #include <cstring>
12 #include <fstream>
13 #include <iostream>
14 #include <map>
15 
17  m_frontiergen(false) {
18  readConfig();
19 }
20 
21 void ReplicaSorter::sort(std::vector<
22  const coral::IDatabaseServiceDescription*>& replicaSet) {
23  // loop through all the offered replicas
24  std::map<int,const coral::IDatabaseServiceDescription*> primap;
25  for (std::vector<const coral::IDatabaseServiceDescription*>::const_iterator
26  itr=replicaSet.begin();itr!=replicaSet.end();++itr) {
27  const std::string conn=(**itr).connectionString();
28  // do not use SQLite files
29  if (conn.find("sqlite_file")==std::string::npos) {
30  // extract the server name (assuming URLs "techno://server/schema")
31  std::string::size_type ipos1=conn.find("://");
32  std::string::size_type ipos2=conn.find('/',ipos1+3);
33  if (ipos1!=std::string::npos && ipos2!=std::string::npos) {
34  const std::string_view server=std::string_view(conn).substr(ipos1+3,ipos2-ipos1-3);
35  // check if this server is on list of replicas to use for domain
36  // if so, add it with its associated priority
37  for (ServerMap::const_iterator sitr=m_servermap.begin();
38  sitr!=m_servermap.end();++sitr) {
39  if (sitr->first==server)
40  primap[sitr->second]=*itr;
41  }
42  }
43  }
44  }
45  // now create sorted list
46  replicaSet.clear();
47  for (std::map<int,const coral::IDatabaseServiceDescription*>::const_iterator
48  itr=primap.begin();itr!=primap.end();++itr) {
49  replicaSet.push_back(itr->second);
50  std::cout << "Allowed replica to try (priority " << itr->first
51  << ") : " << (itr->second)->connectionString() << std::endl;
52  }
53  if (replicaSet.empty())
54  std::cout << "No matching replicas found" << std::endl;
55 }
56 
58  // determine the hostname from ATLAS_CONDDB, HOSTNAME or hostname -fqdn
59  m_hostname="";
60  const char* chost=getenv("ATLAS_CONDDB");
61  if (chost) m_hostname=chost;
62  if (m_hostname.empty()) {
63  const char* chost=getenv("HOSTNAME");
64  if (chost) m_hostname=chost;
65  // check if the returned host has a .
66  if (m_hostname.find('.')==std::string::npos) {
67  m_hostname="unknown";
68  system("hostname --fqdn > hostnamelookup.tmp");
69  std::ifstream infile;
70  infile.open("hostnamelookup.tmp");
71  if (infile) {
72  infile >> m_hostname;
73  } else {
74  m_hostname="unknown";
75  }
76  }
77  }
78  std::cout << "Using machine hostname " << m_hostname <<
79  " for DB replica resolution" << std::endl;
80  // check if FRONTIER_SERVER is set, if so, allow generic replicas
81  const char* cfrontier=getenv("FRONTIER_SERVER");
82  if (cfrontier && strcmp(cfrontier,"")!=0) {
83  std::cout << "Frontier server at " << cfrontier << " will be considered"
84  << std::endl;
85  m_frontiergen=true;
86  }
87 
88  // try to locate configuration file using pathresolver
89  FILE* p_inp=nullptr;
90  const char* datapath=getenv("DATAPATH");
91  if (datapath!=nullptr) p_inp=findFile("dbreplica.config",datapath);
92  if (p_inp==nullptr) {
93  std::cout << "Cannot open/locate configuration file dbreplica.config"
94  << std::endl;
95  return false;
96  }
97  // buffer for reading line
98  unsigned int bufsize=999;
99  char* p_buf=new char[bufsize];
100  while (!feof(p_inp)) {
101  char* p_line=fgets(p_buf,bufsize,p_inp);
102  if (p_line!=nullptr && p_line[0]!='#') {
103  std::string buf=std::string(p_line);
104  std::string::size_type iofs1=0;
105  // analyse based on spaces as seperator
106  bool sequal=false;
107  std::vector<std::string> domains;
108  std::vector<std::string> servers;
109  while (iofs1<buf.size()) {
110  std::string::size_type iofs2=buf.find(' ',iofs1);
111  // allow for trailing linefeed
112  if (iofs2==std::string::npos) iofs2=buf.size()-1;
113  std::string token=buf.substr(iofs1,iofs2-iofs1);
114  // skip empty or space tokens
115  if (!token.empty() && token!=" ") {
116  if (token=="=") {
117  sequal=true;
118  } else if (!sequal) {
119  // token is a domain name
120  domains.push_back(token);
121  } else {
122  // token is a server name
123  // only add Frontier ATLF server if FRONTIER_CLIENT set
124  if (token!="ATLF" || m_frontiergen) servers.push_back(token);
125  }
126  }
127  iofs1=iofs2+1;
128  }
129  // check the list of domains against the hostname to see if this
130  // set of servers is appropriate
131  bool useit=false;
132  unsigned int bestlen=0;
133  for (std::vector<std::string>::const_iterator itr=domains.begin();
134  itr!=domains.end();++itr) {
135  std::string::size_type len=(itr->size());
136  std::string::size_type hlen=m_hostname.size();
137  if (hlen>=len && *itr==m_hostname.substr(hlen-len,len)) {
138  if (len>bestlen) {
139  useit=true;
140  bestlen=len;
141  }
142  }
143  // for 'default' domain name, add the servers as a last resort
144  // if nothing has been found so far
145  if ("default"==*itr && m_servermap.empty()) {
146  std::cout <<
147  "No specific match for domain found - use default fallback"
148  << std::endl;
149  useit=true;
150  bestlen=0;
151  }
152  }
153  if (useit) {
154  // assign these servers, priority based on position in list
155  // and length of match of domain name
156  for (unsigned int i=0;i<servers.size();++i) {
157  int priority=i-100*bestlen;
158  m_servermap.push_back(ServerPair(servers[i],priority));
159  }
160  }
161  }
162  }
163  fclose(p_inp);
164  delete [] p_buf;
165  std::cout << "Total of " << m_servermap.size() <<
166  " servers found for host " << m_hostname << std::endl;
167  return true;
168 }
169 
170 FILE* ReplicaSorter::findFile(const std::string& filename,
171  const std::string& pathvar) {
172  // behave like pathresolver
173  std::string::size_type iofs1,iofs2,len;
174  FILE* fptr=nullptr;
175  iofs1=0;
176  len=pathvar.size();
177  std::string name;
178  while (!fptr && iofs1<len) {
179  iofs2=pathvar.find(':',iofs1);
180  if (iofs2==std::string::npos) iofs2=len;
181  name=pathvar.substr(iofs1,iofs2-iofs1);
182  name+='/';
183  name+=filename;
184  fptr=fopen(name.c_str(),"r");
185  iofs1=iofs2+1;
186  }
187  return fptr;
188 }
checkCorrelInHIST.conn
conn
Definition: checkCorrelInHIST.py:25
run.infile
string infile
Definition: run.py:13
ReplicaSorter::ReplicaSorter
ReplicaSorter()
Definition: Database/CoolConvUtilities/src/ReplicaSorter.cxx:16
python.selector.AtlRunQuerySelectorLhcOlc.priority
priority
Definition: AtlRunQuerySelectorLhcOlc.py:611
ReplicaSorter::findFile
static FILE * findFile(const std::string &filename, const std::string &pathvar)
Definition: Database/CoolConvUtilities/src/ReplicaSorter.cxx:170
ReplicaSorter::m_hostname
std::string m_hostname
Definition: Database/CoolConvUtilities/src/ReplicaSorter.h:20
ReplicaSorter.h
ReplicaSorter::ServerPair
std::pair< std::string, int > ServerPair
Definition: Database/CoolConvUtilities/src/ReplicaSorter.h:21
ReplicaSorter::readConfig
bool readConfig()
Definition: Database/CoolConvUtilities/src/ReplicaSorter.cxx:57
lumiFormat.i
int i
Definition: lumiFormat.py:92
python.html.AtlRunQueryDQSummary.datapath
datapath
Definition: AtlRunQueryDQSummary.py:1205
fptr
std::vector< TFile * > fptr
Definition: hcg.cxx:48
ReplicaSorter::sort
void sort(std::vector< const coral::IDatabaseServiceDescription * > &replicaSet)
Definition: Database/CoolConvUtilities/src/ReplicaSorter.cxx:21
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
SCT_ConditionsAlgorithms::CoveritySafe::getenv
std::string getenv(const std::string &variableName)
get an environment variable
Definition: SCT_ConditionsUtilities.cxx:17
CaloCellTimeCorrFiller.filename
filename
Definition: CaloCellTimeCorrFiller.py:24
python.html.AtlRunQueryDQSummary.server
server
Definition: AtlRunQueryDQSummary.py:22
ReplicaSorter::m_servermap
ServerMap m_servermap
Definition: Database/CoolConvUtilities/src/ReplicaSorter.h:23
ReplicaSorter::m_frontiergen
bool m_frontiergen
Definition: Database/CoolConvUtilities/src/ReplicaSorter.h:24