4d4adb364ff581be8a4c0c7a67afce1221b7d99f
[u/mrichter/AliRoot.git] / STORAGE / AliStorageAdministratorPanel.cxx
1 #include "AliStorageAdministratorPanel.h"
2 #include "AliStorageAdministratorPanelMarkEvent.h"
3 #include "AliStorageAdministratorPanelListEvents.h"
4 #include "AliStorageAdministratorPanelSetStorageParams.h"
5 #include "AliESDEvent.h"
6
7 #include "zmq.hpp"
8 #include <iostream>
9 #include <fstream>
10
11 #include <TGMenu.h>
12
13 using namespace std;
14 using namespace zmq;
15
16 ClassImp(AliStorageAdministratorPanel);
17
18 #define WINDOWS_WIDTH 500
19 #define WINDOWS_HEIGHT 350
20
21 enum TOOLBUTTON{
22         TOOLBUTTON_START=1,
23         TOOLBUTTON_STOP,
24         TOOLBUTTON_PREFERENCES,
25         TOOLBUTTON_EXIT         
26 };
27
28 enum MENUBAR{
29         MENUBAR_CLIENT_SET_PARAMS=1,
30         MENUBAR_SERVER_LIST_EVENTS,
31         MENUBAR_SERVER_MARK_EVENT,
32         MENUBAR_SERVER_GET_EVENT,
33         MENUBAR_SERVER_GET_NEXT_EVENT,
34         MENUBAR_SERVER_GET_LAST_EVENT
35 };
36
37 enum FRAME{
38         CLIENT_FRAME=1,
39         SERVER_FRAME
40 };
41
42 AliStorageAdministratorPanel::AliStorageAdministratorPanel() :
43         TGMainFrame(gClient->GetRoot(), 400, 400),
44         fPanelQuited(false),
45         fConnectionLabel(0),
46         fDataLabel(0),
47         fSavingLabel(0),
48         fCurrentSizeLabel(0),
49         fMaxSizeLabel(0),
50         fMaxOccupationLabel(0),
51         fRemoveEventsLabel(0),
52         fEventsInChunkLabel(0),
53         fMaxStorageSize(0),
54         fMaxOccupation(0),
55         fRemoveEvents(0),
56         fEventsInChunk(0),
57         fCommunicationThread(0),
58         fCommunicationContext(0),
59         fCommunicationSocket(0),
60         fStorageServer(""),
61         fServerContext(0),
62         fServerSocket(0),
63         fEventManager(0)
64 {
65         InitWindow();
66
67     //read config file
68     TThread::Lock();
69         ifstream configFile (Form("%s/STORAGE/setupStorageDatabase.sh",
70                               gSystem->Getenv("ALICE_ROOT")));
71     
72         if (configFile.is_open())
73         {
74                 string line;
75                 int from,to;
76                 while(configFile.good())
77                 {
78                         getline(configFile,line);
79                         from = line.find("\"")+1;
80                         to = line.find_last_of("\"");
81                         if(line.find("STORAGE_SERVER=")==0)
82                         {
83                                 fStorageServer=line.substr(from,to-from);
84                         }
85                 }
86                 if(configFile.eof())
87                 {
88                         configFile.clear();
89                 }
90                 configFile.close();
91         }
92         else
93         {
94                 cout<<"ADMIN -- Unable to open config file"<<endl;
95         }
96         TThread::UnLock();
97     
98         //create event manager
99         fEventManager = new AliStorageEventManager();
100         
101         //start communication with server
102         fServerContext = new context_t(1);
103         fServerSocket = new socket_t(*fServerContext,ZMQ_REQ);
104         fServerSocket->connect(Form("tcp://%s:%d",fStorageServer.c_str(),gServerCommunicationPort));
105
106         
107         int linger = 0;
108         fServerSocket->setsockopt (ZMQ_LINGER, &linger, sizeof(linger));
109         
110         if(fServerSocket)
111         {
112                 cout<<"\nADMIN -- Connected to server socket"<<endl;
113         }
114         else
115         {
116                 cout<<"ADMIN -- ERROR - could not connect to server's socket"<<endl;
117         }
118
119         //start communication with client
120         fCommunicationContext = new context_t(1);
121         fCommunicationSocket = new socket_t(*fCommunicationContext,ZMQ_REQ);
122         fCommunicationSocket->connect(Form("tcp://%s:%d",fStorageServer.c_str(), gClientCommunicationPort));
123         if(fCommunicationSocket)
124         {
125                 cout<<"\nADMIN -- Connected to client communication socket:"<<Form("tcp://%s:%d",fStorageServer.c_str(), gClientCommunicationPort)<<endl;
126         }
127         else
128         {
129                 cout<<"ADMIN -- ERROR - could not connect to client's communication socket"<<endl;
130         }
131         fCommunicationThread = new TThread("fCommunicationThread",
132                                            AliStorageAdministratorPanel::CheckStateHandler,(void*)this);
133         fCommunicationThread->Run();
134         
135
136 }
137
138 AliStorageAdministratorPanel::~AliStorageAdministratorPanel()
139 {
140         cout<<"ADMIN -- AliStorageAdministratorPanel descructor called";
141         cout<<" --- OK"<<endl;
142 }
143
144 void* AliStorageAdministratorPanel::CheckStateHandler(void *arg)//ask client about its state
145 {
146         AliStorageAdministratorPanel *panelInstance = static_cast<AliStorageAdministratorPanel*>(arg);
147
148
149         while(!(panelInstance->fPanelQuited))
150         {
151                 panelInstance->CheckClientState(REQUEST_CONNECTION);
152                 sleep(1);
153                 panelInstance->CheckClientState(REQUEST_RECEIVING);
154                 sleep(1);
155                 panelInstance->CheckClientState(REQUEST_SAVING);
156                 sleep(1);
157                 panelInstance->CheckClientState(REQUEST_CURRENT_SIZE);
158                 sleep(1);
159                 panelInstance->CheckClientState(REQUEST_GET_PARAMS);
160                 sleep(1);
161         }
162         return NULL;
163 }
164
165 void AliStorageAdministratorPanel::CheckClientState(int option)
166 {
167         pollitem_t items[1] =  {{*fCommunicationSocket,0,ZMQ_POLLIN,0}} ;
168
169         struct clientRequestStruct *request = new struct clientRequestStruct;
170         request->messageType = option;
171
172         char *buffer  = (char*)(request);
173         message_t *message = new message_t((void*)buffer,
174                                            sizeof(struct clientRequestStruct),0);
175         fCommunicationSocket->send(*message);
176         if(poll (&items[0], 1, 10000)==0)
177         {
178                 SetLabel(fConnectionLabel,STATUS_DOWN);
179                 SetLabel(fDataLabel,STATUS_DOWN);
180                 SetLabel(fSavingLabel,STATUS_DOWN);
181                 cout<<"ADMIN -- CLIENT IS DOWN"<<endl;
182         }
183
184         message_t *responseMessage = new message_t;
185         long response = -1;
186         fCommunicationSocket->recv(responseMessage);    
187         struct clientRequestStruct *responseParams = NULL;
188         if(option == REQUEST_GET_PARAMS)
189         {
190                 responseParams = static_cast<struct clientRequestStruct*>(responseMessage->data());
191         }
192         else
193         {
194                 response = atoi(static_cast<char*>(responseMessage->data()));
195         }
196         switch(option)
197         {
198         case REQUEST_CONNECTION:
199                 SetLabel(fConnectionLabel,response);
200                 break;
201         case REQUEST_RECEIVING:
202                 SetLabel(fDataLabel,response);
203                 break;
204         case REQUEST_SAVING:
205                 SetLabel(fSavingLabel,response);
206                 break;
207         case REQUEST_CURRENT_SIZE:
208                 SetLabelValue(fCurrentSizeLabel,response,1);
209                 break;
210         case REQUEST_GET_PARAMS:
211                 fMaxStorageSize = responseParams->maxStorageSize;
212                 fMaxOccupation = responseParams->maxOccupation;
213                 fRemoveEvents = responseParams->removeEvents;
214                 fEventsInChunk = responseParams->eventsInChunk;
215                 
216                 SetLabelValue(fMaxSizeLabel,fMaxStorageSize,1);
217                 SetLabelValue(fMaxOccupationLabel,fMaxOccupation,2);
218                 SetLabelValue(fRemoveEventsLabel,fRemoveEvents,2);
219                 SetLabelValue(fEventsInChunkLabel,fEventsInChunk,3);
220                 break;
221         default:break;  
222         }
223 }
224
225 void AliStorageAdministratorPanel::InitWindow()
226 {
227         SetCleanup(kDeepCleanup);
228         // add main manubar on top of the window
229         SetupFixedMenuBar();
230         AddFrame(new TGHorizontal3DLine(this),
231                  new TGLayoutHints(kLHintsNormal | kLHintsExpandX));
232         // add toolbar with pictured buttons
233         /*SetupToolbar();
234         AddFrame(new TGHorizontal3DLine(this),
235                  new TGLayoutHints(kLHintsNormal | kLHintsExpandX));
236         // add dockable toolbar
237         SetupDockableMenuBar();
238         AddFrame(new TGHorizontal3DLine(this),
239                  new TGLayoutHints(kLHintsNormal | kLHintsExpandX));
240         */
241         
242         // add frame with two segments for client and server
243         SetupThreadsFrame();
244         SetWindowName("ALICE Storage Manager");
245         MapSubwindows();
246         Resize(WINDOWS_WIDTH,WINDOWS_HEIGHT);
247         MapWindow();
248 }
249
250 void AliStorageAdministratorPanel::SetupThreadsFrame()
251 {
252         // create frame for both client and server
253         TGHorizontalFrame *threadsFrame = new TGHorizontalFrame(this);
254
255         //create client frame and add components to it
256         TGCompositeFrame *clientThreadFrame = new TGCompositeFrame(threadsFrame,CLIENT_FRAME);
257         fConnectionLabel = new TGLabel(clientThreadFrame,"======Waiting======");
258         fDataLabel = new TGLabel(clientThreadFrame,"======Waiting======");
259         fSavingLabel = new TGLabel(clientThreadFrame,"======Waiting======");
260         fCurrentSizeLabel = new TGLabel(clientThreadFrame,"=========Waiting=========");
261         fMaxSizeLabel = new TGLabel(clientThreadFrame,"==========Waiting=========");
262         fMaxOccupationLabel = new TGLabel(clientThreadFrame,"==========Waiting=========");
263         fRemoveEventsLabel = new TGLabel(clientThreadFrame,"==========Waiting=========");
264         fEventsInChunkLabel = new TGLabel(clientThreadFrame,"==========Waiting=========");
265         
266         clientThreadFrame->AddFrame(new TGLabel(clientThreadFrame,
267                                                 "ALICE Storage Client"),
268                                     new TGLayoutHints(kLHintsCenterX));
269
270         //connection label
271         clientThreadFrame->AddFrame(new TGLabel(clientThreadFrame,
272                                                 "Connection:"),
273                                     new TGLayoutHints(kLHintsCenterX));
274         clientThreadFrame->AddFrame(fConnectionLabel,
275                                     new TGLayoutHints(kLHintsCenterX));
276
277         //data receiving label
278         clientThreadFrame->AddFrame(new TGLabel(clientThreadFrame,
279                                                 "Receiving data:"),
280                                     new TGLayoutHints(kLHintsCenterX));
281         clientThreadFrame->AddFrame(fDataLabel,
282                                     new TGLayoutHints(kLHintsCenterX));
283
284         //saving label
285         clientThreadFrame->AddFrame(new TGLabel(clientThreadFrame,
286                                                 "Saving:"),
287                                     new TGLayoutHints(kLHintsCenterX));
288         clientThreadFrame->AddFrame(fSavingLabel,
289                                     new TGLayoutHints(kLHintsCenterX));
290
291         //current size label
292         clientThreadFrame->AddFrame(new TGLabel(clientThreadFrame,
293                                                 "Current storage size:"),
294                                     new TGLayoutHints(kLHintsCenterX));
295         clientThreadFrame->AddFrame(fCurrentSizeLabel,
296                                     new TGLayoutHints(kLHintsCenterX));
297
298         //max size label
299         clientThreadFrame->AddFrame(new TGLabel(clientThreadFrame,
300                                                 "Max storage size:"),
301                                     new TGLayoutHints(kLHintsCenterX));
302         clientThreadFrame->AddFrame(fMaxSizeLabel,
303                                     new TGLayoutHints(kLHintsCenterX));
304
305         //max occupation label
306         clientThreadFrame->AddFrame(new TGLabel(clientThreadFrame,
307                                                 "Max occupation percent:"),
308                                     new TGLayoutHints(kLHintsCenterX));
309         clientThreadFrame->AddFrame(fMaxOccupationLabel,
310                                     new TGLayoutHints(kLHintsCenterX));
311
312         //remove events label
313         clientThreadFrame->AddFrame(new TGLabel(clientThreadFrame,
314                                                 "Remove events percentage:"),
315                                     new TGLayoutHints(kLHintsCenterX));
316         clientThreadFrame->AddFrame(fRemoveEventsLabel,
317                                     new TGLayoutHints(kLHintsCenterX));
318
319         //events in chunk label
320         clientThreadFrame->AddFrame(new TGLabel(clientThreadFrame,
321                                                 "Number of events in chunk:"),
322                                     new TGLayoutHints(kLHintsCenterX));
323         clientThreadFrame->AddFrame(fEventsInChunkLabel,
324                                     new TGLayoutHints(kLHintsCenterX));
325
326         //create server frame and add components to it
327         TGCompositeFrame *serverThreadFrame = new TGCompositeFrame(threadsFrame,SERVER_FRAME);
328         serverThreadFrame->AddFrame(new TGLabel(serverThreadFrame,
329                                                  "ALICE Storage Server"),
330                                      new TGLayoutHints(kLHintsCenterX));
331
332         //add client and server frames to threads frame
333         threadsFrame->AddFrame(clientThreadFrame,
334                                 new TGLayoutHints(kLHintsLeft | kLHintsExpandX));
335         threadsFrame->AddFrame(new TGVertical3DLine(threadsFrame),
336                  new TGLayoutHints(kLHintsNormal | kLHintsExpandY));
337         threadsFrame->AddFrame(serverThreadFrame,
338                                 new TGLayoutHints(kLHintsRight | kLHintsExpandX));
339
340         //add threads frame to main window
341         AddFrame(threadsFrame,new TGLayoutHints(kLHintsExpandX | kLHintsExpandY));
342 }
343
344 void AliStorageAdministratorPanel::SetupFixedMenuBar()
345 {
346         //create popup menu for client
347         TGPopupMenu *clientPopup = new TGPopupMenu(fClient->GetRoot());
348         clientPopup->AddEntry("&Set storage params",MENUBAR_CLIENT_SET_PARAMS);
349         clientPopup->Associate(this);
350
351         //create popup menu for server
352         TGPopupMenu *serverPopup = new TGPopupMenu(fClient->GetRoot());
353         serverPopup->AddEntry("&Get Events List",MENUBAR_SERVER_LIST_EVENTS);
354         serverPopup->AddEntry("&Mark Event",MENUBAR_SERVER_MARK_EVENT);
355         serverPopup->AddEntry("&Get Event (test)",MENUBAR_SERVER_GET_EVENT);
356         serverPopup->AddEntry("&Get Next Event (test)",MENUBAR_SERVER_GET_NEXT_EVENT);
357         serverPopup->AddEntry("&Get Last Event (test)",MENUBAR_SERVER_GET_LAST_EVENT);
358         serverPopup->Associate(this);
359
360         //create menubar
361         TGMenuBar *menuBar = new TGMenuBar(this,1,1,kHorizontalFrame);
362         menuBar->AddPopup("&Client",clientPopup,
363                           new TGLayoutHints(kLHintsTop | kLHintsLeft, 0, 4, 0, 0));
364         menuBar->AddPopup("&Server", serverPopup,
365                           new TGLayoutHints(kLHintsTop | kLHintsLeft, 0, 4, 0, 0));
366
367         AddFrame(menuBar,new TGLayoutHints(kLHintsTop | kLHintsExpandX));
368 }
369
370 //handle GUI actions
371 Bool_t AliStorageAdministratorPanel::ProcessMessage(Long_t msg, Long_t parm1, Long_t)
372 {
373         switch (GET_MSG(msg))
374         {
375
376         case kC_COMMAND:
377                 switch (GET_SUBMSG(msg))
378                 {
379                 case kCM_BUTTON://when button is pressed
380                         break;
381                 case kCM_MENUSELECT://when mouse is over menu entry
382                         break;
383                 case kCM_MENU://when menu entry was clicked
384                         switch (parm1)
385                         {
386                         case MENUBAR_CLIENT_SET_PARAMS:onClientSetParams();break;
387                         case MENUBAR_SERVER_LIST_EVENTS:onServerListEvents();break;
388                         case MENUBAR_SERVER_MARK_EVENT:onServerMarkEvent();break;
389                         case MENUBAR_SERVER_GET_EVENT:onServerGetEvent();break;
390                         case MENUBAR_SERVER_GET_NEXT_EVENT:onServerGetNextEvent();break;
391                         case MENUBAR_SERVER_GET_LAST_EVENT:onServerGetLastEvent();break;
392                         default:break;
393                         }
394                         break;
395                 default:break;
396                 }
397                 break;
398         default:break;
399         }
400
401         return false;
402 }
403
404 void AliStorageAdministratorPanel::onServerListEvents()
405 {
406         AliStorageAdministratorPanelListEvents *listEventsWindow =
407                 AliStorageAdministratorPanelListEvents::GetInstance();
408
409         listEventsWindow->SetSocket(fServerSocket);
410 }
411
412 void AliStorageAdministratorPanel::onServerMarkEvent()
413 {
414         AliStorageAdministratorPanelMarkEvent *markEventWindow =
415                 AliStorageAdministratorPanelMarkEvent::GetInstance();
416
417         markEventWindow->SetSocket(fServerSocket);
418 }
419
420 void AliStorageAdministratorPanel::onClientSetParams()
421 {
422         AliStorageAdministratorPanelSetStorageParams *setParamsWindow =
423                 AliStorageAdministratorPanelSetStorageParams::GetInstance();
424
425         setParamsWindow->Setup(fCommunicationSocket,
426                                fMaxStorageSize/1000000,
427                                fMaxOccupation,
428                                fRemoveEvents,
429                                fEventsInChunk);
430 }
431
432 void AliStorageAdministratorPanel::onServerGetEvent()
433 {
434         //this method is just for tests
435         int runNumber=197669;
436         int eventNumber=168;
437         
438         struct serverRequestStruct *requestMessage = new struct serverRequestStruct;
439         struct eventStruct mark;
440         mark.runNumber = runNumber;
441         mark.eventNumber = eventNumber;
442         requestMessage->messageType = REQUEST_GET_EVENT;
443         requestMessage->event = mark;
444
445         fEventManager->Send(requestMessage,fServerSocket);
446         AliESDEvent *resultEvent = fEventManager->GetEvent(fServerSocket);
447         
448         if(resultEvent)
449         {
450                 cout<<"ADMIN -- received event. Run no:"<<resultEvent->GetRunNumber()<<"\tEvent no in file:"<<resultEvent->GetEventNumberInFile()<<endl;
451         }
452         else
453         {
454                 cout<<"ADMIN -- received no event"<<endl;
455         }
456 }
457
458
459 void AliStorageAdministratorPanel::onServerGetNextEvent()
460 {
461         //this method is just for tests
462         int runNumber=197669;
463         int eventNumber=33;
464         
465         struct serverRequestStruct *requestMessage = new struct serverRequestStruct;
466         struct eventStruct mark;
467         mark.runNumber = runNumber;
468         mark.eventNumber = eventNumber;
469         requestMessage->messageType = REQUEST_GET_NEXT_EVENT;
470         requestMessage->event = mark;
471
472         fEventManager->Send(requestMessage,fServerSocket);
473         AliESDEvent* resultEvent= fEventManager->GetEvent(fServerSocket);       
474         if(resultEvent)
475         {
476                 cout<<"ADMIN -- received event. Run no:"<<resultEvent->GetRunNumber()<<"\tEvent no in file:"<<resultEvent->GetEventNumberInFile()<<endl;
477         }
478         else
479         {
480                 cout<<"ADMIN -- received no event"<<endl;
481         }
482 }
483
484
485 void AliStorageAdministratorPanel::onServerGetLastEvent()
486 {       
487         struct serverRequestStruct *requestMessage = new struct serverRequestStruct;
488         requestMessage->messageType = REQUEST_GET_LAST_EVENT;
489
490         fEventManager->Send(requestMessage,fServerSocket);
491         AliESDEvent* resultEvent= fEventManager->GetEvent(fServerSocket);
492
493         if(resultEvent)
494         {
495                 cout<<"ADMIN -- received event. Run no:"<<resultEvent->GetRunNumber()<<"\tEvent no in file:"<<resultEvent->GetEventNumberInFile()<<endl;
496         }
497         else
498         {
499                 cout<<"ADMIN -- received no event"<<endl;
500         }
501 }
502
503 void AliStorageAdministratorPanel::onExit()
504 {
505         cout<<"ADMIN -- Quiting ALICE Storage Admin Panel"<<endl;
506         fPanelQuited=true;
507         gSystem->ExitLoop();
508 }
509
510 void AliStorageAdministratorPanel::CloseWindow(){onExit();}
511
512
513 //methods to change labels:
514 void AliStorageAdministratorPanel::SetLabel(TGLabel *label, int option)
515 {
516         switch(option)
517         {
518         case STATUS_WAITING:
519                 label->SetText("Waiting");
520                 label->SetTextColor(kBlack);
521                 break;
522         case STATUS_OK:
523                 label->SetText("OK");
524                 label->SetTextColor(kBlack);
525                 break;
526         case STATUS_ERROR:
527                 label->SetText("ERROR");
528                 label->SetTextColor(kBlack);
529                 break;
530         case STATUS_DOWN:
531                 label->SetText("CLIENT IS DOWN");
532                 label->SetTextColor(kRed);
533                 break;
534         default:break;
535         }
536         gClient->HandleInput();
537 }
538
539 void AliStorageAdministratorPanel::SetLabelValue(TGLabel *label, long value,int option)
540 {
541         // options:
542         // 1 - MB
543         // 2 - percentage
544         // 3 - number
545
546         switch(option)
547         {
548         case 1:
549                 label->SetText(Form("%lu B (%.2f MB)",value,(float)value/(1000.*1000.)));
550                 break;
551         case 2:
552                 label->SetText(Form("%d %%",(int)value));
553                 break;
554         case 3:
555                 label->SetText(Form("%d",(int)value));
556                 break;
557         default:break;
558         }
559         label->SetTextColor(kBlack);
560         gClient->HandleInput();
561 }
562 //other methods that can be useful later
563
564 /*
565 void AliStorageAdministratorPanel::SetupToolbar()
566 {
567         TGToolBar* toolBar = new TGToolBar(this);
568         toolBar->AddButton(this,new TGPictureButton(toolBar,
569                                                      Form("%s/MONITOR/icons/start.png",
570                                                      gSystem->Getenv("ALICE_ROOT")),
571                                                      TOOLBUTTON_START ) );
572         toolBar->AddButton(this, new TGPictureButton(toolBar,
573                                                       Form("%s/MONITOR/icons/stop.png",
574                                                       gSystem->Getenv("ALICE_ROOT")),
575                                                       TOOLBUTTON_STOP) ); 
576         
577         AddFrame(toolBar, new TGLayoutHints(kLHintsNormal | kLHintsExpandX));
578 }
579
580 void AliStorageAdministratorPanel::SetupDockableMenuBar()
581 {
582         TGDockableFrame *menuDock = new TGDockableFrame(this);
583         AddFrame(menuDock,new TGLayoutHints(kLHintsExpandX,0,0,1,0));
584         menuDock->SetWindowName("ALICE Storage Dockable  MenuBar");
585         menuDock->EnableUndock(kTRUE);
586         menuDock->EnableHide(kTRUE);
587
588         TGPopupMenu *popup1 = new TGPopupMenu(fClient->GetRoot());
589         popup1->AddEntry("&Check client state",MENUBAR_1_OPTION_1);
590         popup1->AddSeparator();
591         popup1->AddEntry("&BBB",MENUBAR_1_OPTION_2);
592         popup1->AddEntry("&CCC",MENUBAR_1_OPTION_3);
593
594         popup1->DisableEntry(MENUBAR_1_OPTION_2);
595         popup1->Associate(this);
596
597         
598         TGMenuBar *menuBar = new TGMenuBar(menuDock,1,1,kHorizontalFrame);
599         menuBar->AddPopup("&File",
600                           popup1,
601                           new TGLayoutHints(kLHintsTop | kLHintsLeft, 0, 4, 0, 0));
602
603         menuDock->AddFrame(menuBar,
604                            new TGLayoutHints(kLHintsTop | kLHintsExpandX));
605                            }*/