00001 #include "StatsServerAlg.h"
00002
00003 #include "StatisticsSvc/IStatisticsSvc.h"
00004 #include "TSocket.h"
00005 #include "TServerSocket.h"
00006 #include "TMap.h"
00007 #include "TList.h"
00008 #include "TMonitor.h"
00009 #include "TObjString.h"
00010 #include "TObjArray.h"
00011 #include "TMessage.h"
00012
00013 StatsServerAlg::StatsServerAlg(const std::string& name,
00014 ISvcLocator* pSvcLocator)
00015 : GaudiAlgorithm(name,pSvcLocator),
00016 m_statsSvc(0),
00017 m_server(0),
00018 m_monitor(0),
00019 m_clients(0)
00020 {
00021 declareProperty("ProcessInterval",
00022 m_processInterval=1,
00023 "Interval for processing requests to server");
00024 declareProperty("PortNumber",
00025 m_portNumber=9090,
00026 "Port Number for server");
00027 }
00028
00029 StatsServerAlg::~StatsServerAlg()
00030 {
00031 }
00032
00033 StatusCode StatsServerAlg::initialize()
00034 {
00035
00036 StatusCode sc = this->service("StatisticsSvc",m_statsSvc,true);
00037 if(sc.isFailure()){
00038 error() << "Failed to get StatisticsSvc" << endreq;
00039 return sc;
00040 }
00041
00042
00043 sc = startServer();
00044 return sc;
00045 }
00046
00047 StatusCode StatsServerAlg::execute()
00048 {
00049 static int currentCycle = 0;
00050 currentCycle += 1;
00051 StatusCode sc = StatusCode::SUCCESS;
00052
00053 if( currentCycle % m_processInterval == 0 ){
00054 info() << "Processing requests to server" << endreq;
00055 sc = processRequests();
00056 }
00057 return StatusCode::SUCCESS;
00058 }
00059
00060 StatusCode StatsServerAlg::finalize()
00061 {
00062 if( m_statsSvc ) m_statsSvc->release();
00063 StatusCode sc = stopServer();
00064 return sc;
00065 }
00066
00068
00069 StatusCode StatsServerAlg::startServer(){
00070
00071
00072 m_server = new TServerSocket(m_portNumber, kTRUE);
00073 if (!m_server->IsValid()){
00074 error() << "Failed to start server on port " << m_portNumber << endreq;
00075 return StatusCode::FAILURE;
00076 }
00077 m_monitor = new TMonitor;
00078 m_monitor->Add( m_server );
00079 m_clients = new TList;
00080
00081 return StatusCode::SUCCESS;
00082 }
00083
00084 StatusCode StatsServerAlg::stopServer(){
00085
00086 m_clients->Delete();
00087 delete m_clients;
00088 delete m_server;
00089 delete m_monitor;
00090 return StatusCode::SUCCESS;
00091 }
00092
00093 StatusCode StatsServerAlg::processRequests(){
00094
00095 int timeout = 20;
00096 TSocket* s = m_monitor->Select(timeout);
00097 if( !s ){
00098 error() << "Failure in client socket monitor." << endreq;
00099 return StatusCode::FAILURE;
00100 }
00101 if( s == (TSocket*)-1 ){
00102
00103 return StatusCode::SUCCESS;
00104 }
00105
00106
00107 if( s->IsA() == TServerSocket::Class() ){
00108
00109 TSocket* sock = ((TServerSocket*)s)->Accept();
00110 m_monitor->Add(sock);
00111 m_clients->Add(sock);
00112 info() << "Accepted connection from client: "
00113 << sock->GetInetAddress().GetHostName() << endreq;
00114 return StatusCode::SUCCESS;
00115 }
00116
00117
00118 char request[1024];
00119 if (s->Recv(request, sizeof(request)) <= 0) {
00120
00121 m_monitor->Remove(s);
00122 m_clients->Remove(s);
00123 info() << "Closed connection from client: "
00124 << s->GetInetAddress().GetHostName() << endreq;
00125 delete s;
00126 return StatusCode::SUCCESS;
00127 }
00128
00129 info() << "Received request: " << request << endreq;
00130
00131
00132
00133
00134 TMap itemMap;
00135 TList cleanupList;
00136 cleanupList.SetOwner();
00137 TObjString* nullObject = new TObjString("NULL");
00138 cleanupList.Add( nullObject );
00139
00140 TString reqStr( request );
00141 TObjArray* paths = reqStr.Tokenize( " " );
00142 info() << "Number of requested paths: " << paths->GetEntriesFast() << endreq;
00143 for(int pathIdx=0; pathIdx<paths->GetEntriesFast(); pathIdx++){
00144
00145 TObjString* path = new TObjString( *(dynamic_cast<TObjString*>(paths->At(pathIdx))));
00146 cleanupList.Add( path );
00147 std::string pathStr( path->GetName() );
00148 info() << "Retrieving path: \"" << pathStr << "\"" << endreq;
00149
00150
00151 if(! m_statsSvc->exists( pathStr ) ){
00152 warning() << "Request for invalid path: " << pathStr << endreq;
00153 itemMap.Add( path, nullObject );
00154 continue;
00155 }
00156
00157
00158 TObject* object = m_statsSvc->get( pathStr );
00159 if( object ){
00160 info() << "Found object at path: " << pathStr << endreq;
00161 itemMap.Add( path, object );
00162 continue;
00163 }
00164
00165
00166 std::vector<std::string> subFolds = m_statsSvc->getSubFolders( pathStr );
00167 TList* subFolders = new TList();
00168 subFolders->SetName("subFolders");
00169 subFolders->SetOwner();
00170 for(size_t idx=0; idx<subFolds.size(); idx++){
00171 subFolders->Add( new TObjString( subFolds[idx].c_str() ) );
00172 }
00173
00174 std::vector<std::string> conts = m_statsSvc->getContents( pathStr );
00175 TList* contents = new TList();
00176 contents->SetName("contents");
00177 contents->SetOwner();
00178 for(size_t idx=0; idx<conts.size(); idx++){
00179 contents->Add( new TObjString( conts[idx].c_str() ) );
00180 }
00181
00182 TMap* directory = new TMap();
00183 directory->SetName("directory");
00184 directory->SetOwner();
00185 directory->Add(new TObjString("subFolders"),subFolders);
00186 directory->Add(new TObjString("contents"),contents);
00187 itemMap.Add( path, directory );
00188 cleanupList.Add( directory );
00189 }
00190 delete paths;
00191
00192
00193 TMessage answer(kMESS_OBJECT);
00194 answer.WriteObject( &itemMap );
00195 s->Send(answer);
00196
00197 cleanupList.Delete();
00198
00199 return StatusCode::SUCCESS;
00200 }