00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "ConsumerList.h"
00017
00018 #include "time.h"
00019
00020 #include <fstream>
00021 #include <string>
00022 #include <strstream>
00023 #include <algorithm>
00024
00025 #include "TSocket.h"
00026 #include "TServerSocket.h"
00027 #include "TMonitor.h"
00028
00029 using std::cout;
00030 using std::endl;
00031 using std::ends;
00032 using std::string;
00033 using std::istrstream;
00034 using std::ostrstream;
00035 using std::ios;
00036
00037 ConsumerList::ConsumerList(TString sitename) : _websitename(sitename)
00038 {
00039 _statusnames[Unknown] = "Unknown";
00040 _statusnames[Dead] = "Dead";
00041 _statusnames[Running] = "Running";
00042 _statusnames[Stopped] = "Stopped";
00043 _statusnames[Crashed] = "Crashed";
00044 _statusnames[Finished] = "Finished";
00045 }
00046
00047 ConsumerList::~ConsumerList()
00048 {
00049 }
00050
00051 ConsumerList::ConsumerList(const ConsumerList& )
00052 {
00053 }
00054
00055 int ConsumerList::nEntries() const
00056 {
00057 return _consumerlist.size();
00058 }
00059
00060 const TString& ConsumerList::consumername(int i) const
00061 {
00062 return _consumerlist[i].name;
00063 }
00064
00065 const TString& ConsumerList::hostname(int i) const
00066 {
00067 return _consumerlist[i].hostname;
00068 }
00069
00070 int ConsumerList::port(int i) const
00071 {
00072 return _consumerlist[i].port;
00073 }
00074
00075 int ConsumerList::nevents(int i) const
00076 {
00077 return _consumerlist[i].nevents;
00078 }
00079
00080 int ConsumerList::runnumber(int i) const
00081 {
00082 return _consumerlist[i].runnumber;
00083 }
00084
00085 int ConsumerList::status(int i) const
00086 {
00087 return _consumerlist[i].status;
00088 }
00089
00090 const char *ConsumerList::statusString(int i) const
00091 {
00092 return _statusnames[_consumerlist[i].status];
00093 }
00094
00095 const TString& ConsumerList::updateTime(int i) const
00096 {
00097 return _consumerlist[i].time;
00098 }
00099
00100 void ConsumerList::setPort(int i, int port)
00101 {
00102 _consumerlist[i].port = port;
00103 }
00104
00105 void ConsumerList::setNevents(int i, int nev)
00106 {
00107 _consumerlist[i].nevents = nev;
00108 }
00109
00110 void ConsumerList::setStatus(int i , int status)
00111 {
00112 _consumerlist[i].status = status;
00113 }
00114
00115 void ConsumerList::setRunnumber(int i, int runn)
00116 {
00117 _consumerlist[i].runnumber = runn;
00118 }
00119
00120 void ConsumerList::setUpdateTime(int i, char *tm)
00121 {
00122 _consumerlist[i].time = tm;
00123 }
00124
00125
00126 void ConsumerList::removeEntry(const char *hostname,int port)
00127 {
00128 std::vector<ConsumerEntry>::iterator pos =
00129 _consumerlist.end();
00130 for(std::vector<ConsumerEntry>::iterator iter = _consumerlist.begin();
00131 iter != _consumerlist.end(); ++iter)
00132 if((iter->hostname == hostname)&&(iter->port == port)) pos = iter;
00133 if(pos!=_consumerlist.end()) _consumerlist.erase(pos);
00134 }
00135
00136 int ConsumerList::watchServers(const int port,const char*filename )
00137 {
00138
00139
00140 TServerSocket ss(port,kTRUE);
00141 if(!(ss.IsValid()))
00142 {
00143 cout << "ConsumerList::watchServers: serversocket not valid" << endl;
00144 return 0;
00145 }
00146 writeWebPage(filename);
00147 while(1)
00148 {
00149
00150 TSocket *sock = ss.Accept();
00151
00152 char buffer[1000];
00153 string word;
00154 sock->RecvRaw(buffer,1000);
00155 istrstream message(buffer);
00156
00157 message >> word;
00158 if(word=="ConsumerList")
00159 {
00160 message >> word;
00161 while((word != "END") && message)
00162 {
00163
00164
00165 ConsumerEntry entry;
00166 entry.name = word.c_str();
00167 message >> entry.hostname;
00168 message >> entry.port;
00169 message >> entry.runnumber;
00170 message >> entry.nevents;
00171 message >> entry.status;
00172 message >> word;
00173
00174 removeEntry(entry.hostname,entry.port);
00175 const time_t zeit = time(0);
00176 entry.time = ctime(&zeit);
00177 if((entry.status==Running)||(entry.status==Crashed)||
00178 (entry.status==Unknown) && message) _consumerlist.push_back(entry);
00179
00180 }
00181
00182 writeWebPage(filename);
00183 }
00184
00185 sock->Close();
00186 delete sock;
00187 }
00188 }
00189
00190
00191 void ConsumerList::test()
00192 {
00193
00194
00195
00196
00197
00198
00199
00200 }
00201
00202 int ConsumerList::readWebPage()
00203 {
00204 ostrstream message;
00205 string page,temp;
00206 unsigned int pos,last,pos2=0;
00207 char buffer[5000];
00208 TUrl website(_websitename);
00209
00210 TSocket sock(website.GetHost(),website.GetPort());
00211 if(!(sock.IsValid())) return 0;
00212
00213 message << "GET " << website.GetFile() << " HTTP/1.0\rHost:"
00214 << website.GetHost() << ":" << website.GetPort()
00215 << "\n\rAccept: */*\n\r\n\r" << ends;
00216
00217 temp = message.str();
00218 if (sock.SendRaw(temp.c_str(),temp.length()) != (Int_t)temp.length())
00219 return 0;
00220 sock.RecvRaw(buffer,5000);
00221 sock.Close();
00222
00223 page = buffer;
00224 pos = page.find("<title>")+7;
00225 temp = page.substr(pos,page.find("</title>")-pos);
00226 if (temp != "Consumer Status Page") return 0;
00227
00228 _consumerlist.erase(_consumerlist.begin(),_consumerlist.end());
00229 pos = page.find("<tr>");
00230 last = page.rfind("</tr>");
00231 if (pos==page.rfind("<tr>")) return 0;
00232 pos = page.find("<tr>",pos+3);
00233 while(pos<last)
00234 {
00235
00236 ConsumerEntry ent;
00237 pos = page.find("<td>",pos) + 4;
00238 temp = page.substr(pos,page.find("</td>",pos)-pos).c_str();
00239 pos2 = temp.find(">");
00240 cout << temp << " " << pos2 << endl;
00241 if(pos2 > 0)
00242 ent.name = temp.substr(pos2 + 1,temp.rfind("</font>")-pos2-1).c_str();
00243 else ent.name = temp.c_str();
00244 pos = page.find("<td>",pos) + 4;
00245 temp = page.substr(pos,page.find("</td>",pos)-pos).c_str();
00246 pos2 = temp.find(">");cout << temp << " " << pos2 << endl;
00247 if(pos2 > 0)
00248 ent.hostname = temp.substr(pos2 + 1,temp.rfind("</font>")-pos2-1).c_str();
00249 else ent.hostname = temp.c_str();
00250 pos = page.find("<td>",pos) + 4;
00251 ent.port = atoi(page.substr(pos,page.find("</td>",pos)-pos).c_str());
00252 pos = page.find("<td>",pos) + 4;
00253 ent.runnumber = atoi(page.substr(pos,page.find("</td>",pos)-pos).c_str());
00254 pos = page.find("<td>",pos) + 4;
00255 ent.nevents = atoi(page.substr(pos,page.find("</td>",pos)-pos).c_str());
00256 pos = page.find("<td>",pos) + 4;
00257 temp = page.substr(pos,page.find("</td>",pos)-pos);
00258 pos2 = temp.find(">") ;cout << temp << " " << pos2 << endl;
00259 if(pos2 > 0)
00260 temp = temp.substr(pos2 + 1,temp.rfind("</font>") - pos2 - 1).c_str();
00261 for(int i = 0; i < 6; i++)
00262 if (strcmp(temp.c_str(),_statusnames[i])==0)
00263 {
00264 ent.status = i;
00265 break;
00266 }
00267 pos = page.find("</tr>",pos);
00268 _consumerlist.push_back(ent);
00269 }
00270 return 1;
00271 }
00272
00273 int ConsumerList::writeWebPage(const char * filename)
00274 {
00275
00276 std::sort(_consumerlist.begin(),_consumerlist.end(),sortbyName);
00277
00278 const time_t zeit = time(0);
00279
00280
00281 std::ofstream page(filename);
00282 if (!page) return 0;
00283
00284 page << "<html> \n <head> \n <title>Consumer Status Page</title>" << endl;;
00285 page << "<meta http-equiv=\"cache-control\" content=\"no-cache\">" << endl;
00286 page << "<meta http-equiv=\"pragma\" content=\"no-cache\">" << endl;
00287 page << "<meta http-equiv=\"Refresh\" content=\"30;url=" << _websitename
00288 << "\" >" << endl;
00289 page << "<br><br><br><center><h1><u><font color=\"#FF0000\"> Consumer Status Page</center></font></u></h1> \n";
00290 page << "\n </head> \n <body background=\"home/cdfii_ybgr.jpg\"> \n ";
00291 page << "<img src=\"home/cdfii_logo.gif\" align=right alt=\"CDF II\" height=100 width=100> \n";
00292 page << "<br><br><br><br><br><br><br><br><br> \n Status of Consumer Processes: \n";
00293 page << "<br> \n <center> <table BORDER COLS=7 WIDTH=\"100%\" NOSAVE> \n";
00294 page << "<tr> \n <td> Consumer </td> \n \n";
00295 page << "<td>Hostname</td> \n \n <td>Port</td> \n \n";
00296 page << "<td>Run number</td> \n \n" ;
00297 page << "<td># of Events processed</td> \n \n <td>Status</td>";
00298 page << "\n \n <td>Time</td> \n </tr> \n";
00299
00300
00301 for(std::vector<ConsumerEntry>::const_iterator iter = _consumerlist.begin();
00302 iter != _consumerlist.end(); ++iter)
00303 {
00304 if(iter->status == Crashed)
00305 page << "<tr> \n <td>" << "<font color=\"#FF0000\">"
00306 << iter->name << "</font></td><td>" << "<font color=\"#FF0000\">"
00307 << iter->hostname << "</font>"
00308 << "</td><td>" << iter->port << "</td><td>"
00309 << iter->runnumber << "</td><td>"
00310 << iter->nevents << "</td><td>" << "<font color=\"#FF0000\">"
00311 <<_statusnames[iter->status] << "</font>"
00312 << "</td><td>" << iter->time << "</td></tr>\n";
00313 else
00314 page << "<tr> \n <td>" << iter->name << "</td><td>" << iter->hostname
00315 << "</td><td>" << iter->port << "</td><td>"
00316 << iter->runnumber << "</td><td>"
00317 << iter->nevents << "</td><td>" << _statusnames[iter->status]
00318 << "</td><td>" << iter->time << "</td></tr>\n";
00319 }
00320
00321 page << "</center> </table>\n";
00322 page << "<br> <br> <br> \n Last Update:" << ctime(&zeit) << "<br> \n";
00323 page << "</body>\n </html> \n";
00324 page.close();
00325 return 1;
00326 }
00327
00328 void ConsumerList::print(std::ostream& output) const
00329 {
00330 output << "ConsumerList:" << endl;
00331 output.width(15);
00332 output.setf(ios::left,ios::adjustfield);
00333 output << "name";
00334 output.width(30);
00335 output.setf(ios::left,ios::adjustfield);
00336 output << "hostname";
00337 output.width(6);
00338 output.setf(ios::right,ios::adjustfield);
00339 output << "port";
00340 output.width(7);
00341 output.setf(ios::right,ios::adjustfield);
00342 output << " runn";
00343 output.width(8);
00344 output.setf(ios::right,ios::adjustfield);
00345 output << "events";
00346 output.width(10);
00347 output.setf(ios::right,ios::adjustfield);
00348 output << " status" << endl;
00349 for(std::vector<ConsumerEntry>::const_iterator iter = _consumerlist.begin();
00350 iter != _consumerlist.end(); ++iter)
00351 {
00352 output.width(15);
00353 output.setf(ios::left,ios::adjustfield);
00354 output << iter->name;
00355 output.width(30);
00356 output.setf(ios::left,ios::adjustfield);
00357 output << iter->hostname;
00358 output.width(6);
00359 output.setf(ios::right,ios::adjustfield);
00360 output << iter->port;
00361 output.width(7);
00362 output.setf(ios::right,ios::adjustfield);
00363 output << iter->runnumber;
00364 output.width(8);
00365 output.setf(ios::right,ios::adjustfield);
00366 output << iter->nevents;
00367 output.width(10);
00368 output.setf(ios::right,ios::adjustfield);
00369 output << _statusnames[iter->status] << endl;
00370 }
00371 }
00372
00373 int ConsumerList::sendList(const char *host,const int port)
00374 {
00375 ostrstream message;
00376 string temp;
00377
00378 TSocket sock(host,port);
00379 if (!(sock.IsValid()))
00380 {
00381 cout << "ConsumerList::sendList: socket not valid" << endl;
00382 return 0;
00383 }
00384 message << "ConsumerList" << endl;
00385 for(std::vector<ConsumerEntry>::const_iterator iter = _consumerlist.begin();
00386 iter != _consumerlist.end(); ++iter)
00387 message << iter->name << endl << iter->hostname << endl
00388 << iter->port << endl << iter->runnumber << endl
00389 << iter->nevents << endl << iter->status << endl;
00390 message << "END" << endl;
00391 temp = message.str();
00392 if (sock.SendRaw(temp.c_str(),temp.length()) != (Int_t)temp.length())
00393 {
00394 sock.Close();
00395 return 0;
00396 }
00397 sock.Close();
00398 return 1;
00399 }
00400
00401
00402 void ConsumerList::addEntry(TString nam, TString hostnam,
00403 int port,int nev,int runn,int stat,TString tm)
00404 {
00405
00406 removeEntry(hostnam,port);
00407 _consumerlist.push_back(ConsumerEntry(nam,hostnam,port,nev,runn,stat,tm));
00408 }
00409
00410 ConsumerList::ConsumerEntry::ConsumerEntry(TString nam,TString hostnam,
00411 int p,int nev,int runn, int stat,
00412 TString tm)
00413 : name(nam), hostname(hostnam) , port(p), nevents(nev), runnumber(runn) ,
00414 status(stat) , time(tm)
00415 {
00416 }
00417
00418 ConsumerList::ConsumerEntry::ConsumerEntry()
00419 : name(""), hostname(""), port(0), nevents(0), runnumber(0)
00420 , status(0) ,time("")
00421 {
00422 }
00423
00424 bool ConsumerList::sortbyName(const ConsumerList::ConsumerEntry a,
00425 const ConsumerList::ConsumerEntry b)
00426 {
00427 return a.name < b.name;
00428 }