GSI Object Oriented Online Offline (Go4) GO4-6.4.0
Loading...
Searching...
No Matches
TGo4HttpProxy.cpp
Go to the documentation of this file.
1// $Id$
2//-----------------------------------------------------------------------
3// The GSI Online Offline Object Oriented (Go4) Project
4// Experiment Data Processing at EE department, GSI
5//-----------------------------------------------------------------------
6// Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
7// Planckstr. 1, 64291 Darmstadt, Germany
8// Contact: http://go4.gsi.de
9//-----------------------------------------------------------------------
10// This software can be used under the license agreements as stated
11// in Go4License.txt file which is part of the distribution.
12//-----------------------------------------------------------------------
13
14#include "TGo4HttpProxy.h"
15
16#include "TROOT.h"
17#include "TClass.h"
18#include "TList.h"
19#include "TH1.h"
20#include "TH2.h"
21#include "TGraph.h"
22#include "TBufferFile.h"
23
24#include "TGo4Condition.h"
25#include "TGo4Slot.h"
26#include "TGo4Iter.h"
27#include "TGo4ObjectProxy.h"
28#include "TGo4Ratemeter.h"
29#include "TGo4AnalysisStatus.h"
30
31#include <QtNetwork>
32#include <QTimer>
33#include <QElapsedTimer>
34#include <QApplication>
35#include <QEventLoop>
36#include <QInputDialog>
37
39 QObject(),
40 qnam(),
41 fHReply(nullptr),
42 fProxy(p)
43{
44 QObject::connect(&qnam, &QNetworkAccessManager::authenticationRequired, this, &QHttpProxy::authenticationRequiredSlot);
45}
46
50
52{
53 if (!fHReply) return;
54
55 QByteArray res = fHReply->readAll();
56 fHReply->deleteLater();
57 fHReply = nullptr;
58 fProxy->GetHReply(res);
59}
60
61void QHttpProxy::httpHReqError(QNetworkReply::NetworkError code)
62{
63 if (gDebug > 0)
64 printf("QHttpProxy::httpHReqError %d %s\n", code, fHReply ? fHReply->errorString().toLatin1().constData() : "---");
65 if (fHReply) {
66 fHReply->deleteLater();
67 fHReply = nullptr;
68 }
69}
70
72{
73 if (fProxy) fProxy->ProcessUpdateTimer();
74 QTimer::singleShot(2000, this, &QHttpProxy::updateRatemeter);
75}
76
78{
79 if (fProxy) fProxy->UpdateHierarchy(kFALSE);
80}
81
83{
84 if (fProxy) fProxy->ProcessRegularMultiRequest(kTRUE);
85}
86
87void QHttpProxy::StartRequest(const char *url)
88{
89 fHReply = qnam.get(QNetworkRequest(QUrl(url)));
90
91 QObject::connect(fHReply, &QNetworkReply::finished, this, &QHttpProxy::httpFinished);
92
93#if QT_VERSION < QT_VERSION_CHECK(5,15,0)
94 QObject::connect(fHReply, (void (QNetworkReply::*)(QNetworkReply::NetworkError)) &QNetworkReply::error, this, &QHttpProxy::httpHReqError);
95#else
96 QObject::connect(fHReply, &QNetworkReply::errorOccurred, this, &QHttpProxy::httpHReqError);
97#endif
98
99 QObject::connect(fHReply, &QNetworkReply::sslErrors, [this](const QList<QSslError> &errors) { fHReply->ignoreSslErrors(errors); });
100
101 QSslConfiguration cfg = fHReply->sslConfiguration();
102 cfg.setProtocol(QSsl::AnyProtocol/*QSsl::TlsV1SslV3*/);
103 fHReply->setSslConfiguration(cfg);
104}
105
106void QHttpProxy::authenticationRequiredSlot(QNetworkReply* repl, QAuthenticator* auth)
107{
108 if (fProxy->fUserName.Length()>0) {
109 auth->setUser(fProxy->fUserName.Data());
110 auth->setPassword(fProxy->fPassword.Data());
111 return;
112 }
113
114 bool ok = false;
115 QString user_name =
116 QInputDialog::getText(nullptr, tr("Authentication required"),
117 tr("User name:"), QLineEdit::Normal,
118 "", &ok);
119 if (!ok) return;
120 QString passwd =
121 QInputDialog::getText(nullptr, tr("Authentication required"),
122 tr("User password:"), QLineEdit::Password,
123 "", &ok);
124 if (!ok) return;
125
126 fProxy->fUserName = user_name.toLatin1().constData();
127 fProxy->fPassword = passwd.toLatin1().constData();
128
129 auth->setUser(user_name);
130 auth->setPassword(passwd);
131}
132
133const char *GetHttpRootClassName(const char *kind)
134{
135 if (!kind || (*kind == 0)) return nullptr;
136 if (strncmp(kind,"ROOT.", 5) != 0) return nullptr;
137 if (strcmp(kind+5,"TGo4AnalysisWebStatus") == 0)
138 return "TGo4AnalysisStatus";
139 return kind+5;
140}
141
142// ============================================================================================
143
144TGo4HttpAccess::TGo4HttpAccess(TGo4HttpProxy *proxy, XMLNodePointer_t node, Int_t kind, const char *extra_arg) :
145 TGo4Access(),
146 fProxy(proxy),
147 fNode(node),
148 fUrlPath(),
149 fKind(kind),
150 fNameAttr(),
151 fKindAttr(),
152 fExtraArg(),
153 fReceiver(nullptr),
154 fRecvPath(),
155 fReply(nullptr)
156{
157 const char *_name = fProxy->fXML->GetAttr(fNode,"_realname");
158 if (!_name) _name = fProxy->fXML->GetAttr(fNode,"_name");
159 if (_name) fNameAttr = _name;
160
161 fUrlPath = fProxy->MakeUrlPath(node);
162
163 const char *_kind = fProxy->fXML->GetAttr(fNode,"_kind");
164 if (_kind) fKindAttr = _kind;
165 if (extra_arg) fExtraArg = extra_arg;
166}
167
169{
170 if (fKind==3) return TGraph::Class();
171 if (fKind==4) return gROOT->GetClass("TGo4ParameterStatus");
172 if (fKind==5) return gROOT->GetClass("TTree");
173 if (fKind==6) return gROOT->GetClass("TGo4AnalysisStatus");
174 if (fKind==7) return gROOT->GetClass("TList");
175 if (fKind==8) return gROOT->GetClass("TGo4HistogramStatus");
177}
178
180{
181 return fNameAttr.Data();
182}
183
185{
186 if (fKind==3) return "TGraph";
187 if (fKind==4) return "TGo4ParameterStatus";
188 if (fKind==6) return "TGo4AnalysisStatus";
189 if (fKind==7) return "TList";
190 if (fKind==8) return "TGo4HistogramStatus";
191
192 const char *clname = GetHttpRootClassName(fKindAttr.Data());
193
194 return clname ? clname : "TObject";
195}
196
198{
199 if (!rcv) return 0;
200
201 TClass *obj_cl = GetObjectClass();
202 if (!obj_cl) {
203 printf("TGo4HttpAccess fail to get class %s for object %s\n", GetObjectClassName(), path);
204 return 0;
205 }
206
207 if (obj_cl->GetBaseClassOffset(TObject::Class()) != 0) {
208 printf("TGo4HttpAccess cannot used class %s not derived from TObject\n", GetObjectClassName());
209 return 0;
210 }
211
212 fReceiver = rcv;
213 fRecvPath = path;
214
215 TString url = fProxy->fNodeName;
216 if (fUrlPath.Length()>0) { url.Append("/"); url.Append(fUrlPath); }
217
218 switch (fKind) {
219 case 0: url.Append("/h.xml?compact"); break;
220 case 1: url.Append("/root.bin.gz"); break;
221 case 2: url.Append("/get.xml"); break;
222 case 3: url.Append("/get.xml.gz?history=100&compact"); break;
223 case 4: url.Append("/exe.bin.gz?method=CreateStatus&_destroy_result_"); break;
224 case 5: url.Append("/exe.bin.gz?method=CreateSampleTree&sample=0&_destroy_result_"); break;
225 case 6: url.Append("/exe.bin.gz?method=CreateStatus&_destroy_result_"); break;
226 case 7: url.Append("/exe.bin.gz?method=Select&max=10000"); break;
227 case 8: url.Form("%s/Control/go4_sniffer/exe.bin.gz?method=CreateItemStatus&_destroy_result_&itemname=\"%s\"", fProxy->fNodeName.Data(), fUrlPath.Data()); break;
228 default: url.Append("/root.bin.gz"); break;
229 }
230
231 if (fExtraArg.Length()>0) {
232 if (url.Index("?") != kNPOS) url.Append("&"); else url.Append("?");
233 url.Append(fExtraArg);
234 }
235
236 fReply = fProxy->fComm.qnam.get(QNetworkRequest(QUrl(url.Data())));
237 QObject::connect(fReply, &QNetworkReply::finished, this, &TGo4HttpAccess::httpFinished);
238
239#if QT_VERSION < QT_VERSION_CHECK(5,15,0)
240 QObject::connect(fReply, (void (QNetworkReply::*)(QNetworkReply::NetworkError)) &QNetworkReply::error, this, &TGo4HttpAccess::httpError);
241#else
242 QObject::connect(fReply, &QNetworkReply::errorOccurred, this, &TGo4HttpAccess::httpError);
243#endif
244
245 if (gDebug > 2)
246 printf("TGo4HttpAccess::AssignObjectTo Request URL %s\n", url.Data());
247
248 return 2;
249}
250
251void TGo4HttpAccess::httpError(QNetworkReply::NetworkError)
252{
253 // may do special handling for http errors
254}
255
256
258{
259 QByteArray res = fReply->readAll();
260 fReply->deleteLater();
261 fReply = nullptr;
262
263 if (gDebug > 2)
264 printf("TGo4HttpAccess::httpFinished Get reply size %ld\n", (long) res.size());
265
266 // regular ratemeter update used to check connection status
267 if (fUrlPath == "Status/Ratemeter") {
268 Bool_t conn = res.size() > 0;
269
270 // if proxy in shutdown state - cancel all action in case of communication error
271 if (!conn && fProxy->CheckShutdown()) return;
272
273 if (!conn) DoObjectAssignement(fReceiver, fRecvPath.Data(), new TNamed("disconnected","title"), kTRUE); else
274 if (fProxy->fConnected != conn) fProxy->UpdateHierarchy(kFALSE);
275
276 fProxy->fConnected = conn;
277 }
278
279 // do nothing when nothing received
280 if (res.size() == 0) {
281 if (gDebug > 0)
282 printf("TGo4HttpAccess::httpFinished error with %s\n", fUrlPath.Data());
283 return;
284 }
285
286 if (fKind == 0) {
287
288 TXMLEngine *xml = fProxy->fXML;
289
290 XMLDocPointer_t doc = xml->ParseString(res.data());
291
292 if (!doc) return;
293
294 XMLNodePointer_t top = xml->GetChild(xml->DocGetRootElement(doc));
295
296 xml->FreeAllAttr(fNode);
297
298 XMLAttrPointer_t attr = xml->GetFirstAttr(top);
299 while (attr) {
300 xml->NewAttr(fNode, nullptr, xml->GetAttrName(attr), xml->GetAttrValue(attr));
301 attr = xml->GetNextAttr(attr);
302 }
303
304 XMLNodePointer_t chld;
305 while ((chld = xml->GetChild(top)) != nullptr) {
306 xml->UnlinkNode(chld);
307 xml->AddChild(fNode, chld);
308 }
309
310 xml->FreeDoc(doc);
311
312 if (fProxy->fxParentSlot)
313 fProxy->fxParentSlot->ForwardEvent(fProxy->fxParentSlot, TGo4Slot::evObjAssigned);
314 }
315
316 TObject *obj = nullptr;
317
318 if (fKind == 2) {
319 TXMLEngine* xml = fProxy->fXML;
320
321 XMLDocPointer_t doc = xml->ParseString(res.data());
322 if (!doc) return;
323
324 XMLNodePointer_t top = xml->DocGetRootElement(doc);
325
326 const char *_kind = xml->GetAttr(top, "_kind");
327 const char *_name = xml->GetAttr(top, "_name");
328 const char *_title = xml->GetAttr(top, "_title");
329 const char *xtitle = xml->GetAttr(top, "xtitle");
330 const char *ytitle = xml->GetAttr(top, "ytitle");
331 const char *xlabels = xml->GetAttr(top, "xlabels");
332 const char *ylabels = xml->GetAttr(top, "ylabels");
333
334 if (strcmp(_kind,"ROOT.TH1D") == 0) {
335 Int_t nbins = xml->GetIntAttr(top, "nbins");
336 Int_t left = TString(xml->GetAttr(top, "left")).Atof();
337 Int_t right = TString(xml->GetAttr(top, "right")).Atof();
338 TH1D* h1 = new TH1D(_name, _title, nbins, left, right);
339 h1->SetDirectory(nullptr);
340 const char *bins = xml->GetAttr(top, "bins") + 1;
341 for (int n =-3; n<nbins+2; n++) {
342 const char *separ = strpbrk(bins,",]");
343 if (!separ) { printf("Error parsing histogram bins\n"); break; }
344 if (n >= 0) {
345 Double_t v = TString(bins, separ-bins).Atof();
346 h1->SetBinContent(n, v);
347 }
348 bins = separ+1;
349 }
350 h1->ResetStats();
351 obj = h1;
352 } else {
353 Int_t nbins1 = xml->GetIntAttr(top, "nbins1");
354 Int_t left1 = TString(xml->GetAttr(top, "left1")).Atof();
355 Int_t right1 = TString(xml->GetAttr(top, "right1")).Atof();
356 Int_t nbins2 = xml->GetIntAttr(top, "nbins2");
357 Int_t left2 = TString(xml->GetAttr(top, "left2")).Atof();
358 Int_t right2 = TString(xml->GetAttr(top, "right2")).Atof();
359 TH2D* h2 = new TH2D(_name, _title, nbins1, left1, right1, nbins2, left2, right2);
360 h2->SetDirectory(nullptr);
361 const char *bins = xml->GetAttr(top, "bins") + 1;
362 for (int n =-6; n<(nbins1+2)*(nbins2+2); n++) {
363 const char *separ = strpbrk(bins,",]");
364 if (!separ) { printf("Error parsing histogram bins\n"); break; }
365 if (n >= 0) {
366 Double_t v = TString(bins, separ-bins).Atof();
367 h2->SetBinContent(n % (nbins1 + 2), n / (nbins1 + 2), v);
368 }
369 bins = separ+1;
370 }
371 h2->ResetStats();
372 obj = h2;
373 }
374
375 if (obj) {
376 if (xtitle)
377 ((TH1 *)obj)->GetXaxis()->SetTitle(xtitle);
378 if (ytitle)
379 ((TH1 *)obj)->GetYaxis()->SetTitle(ytitle);
380 if (xlabels) {
381 TObjArray *arr = TString(xlabels).Tokenize(",");
382 for (int n = 0; n <= (arr ? arr->GetLast() : -1); n++)
383 ((TH1 *)obj)->GetXaxis()->SetBinLabel(1 + n, arr->At(n)->GetName());
384 delete arr;
385 }
386 if (ylabels) {
387 TObjArray *arr = TString(ylabels).Tokenize(",");
388 for (int n = 0; n <= (arr ? arr->GetLast() : -1); n++)
389 ((TH1 *)obj)->GetYaxis()->SetBinLabel(1 + n, arr->At(n)->GetName());
390 delete arr;
391 }
392 }
393
394 xml->FreeDoc(doc);
395
396 } else
397
398 if (fKind == 3) {
399 TXMLEngine* xml = fProxy->fXML;
400
401 XMLDocPointer_t doc = xml->ParseString(res.data());
402 if (!doc) return;
403
404 XMLNodePointer_t top = xml->DocGetRootElement(doc);
405
406 XMLNodePointer_t chld = top;
407 Int_t cnt = 0;
408 while (chld) {
409 if (xml->GetAttr(chld, "value") && xml->GetAttr(chld, "time")) cnt++;
410 chld = (chld==top) ? xml->GetChild(top) : xml->GetNext(chld);
411 }
412
413 TGraph *gr = new TGraph(cnt);
414 gr->SetName(xml->GetAttr(top, "_name"));
415 gr->SetTitle(TString::Format("%s ratemeter", xml->GetAttr(top, "_name")).Data());
416
417 chld = top;
418 Int_t i = cnt-1;
419 while (chld) {
420 const char *time = xml->GetAttr(chld, "time");
421 const char *value = xml->GetAttr(chld, "value");
422 if (time && value) {
423 QDateTime tm = QDateTime::fromString(time, Qt::ISODate);
424 gr->SetPoint(i, tm.toMSecsSinceEpoch()/1000, TString(value).Atof());
425 i = (i+1) % cnt;
426 }
427 chld = (chld==top) ? xml->GetChild(top) : xml->GetNext(chld);
428 }
429
430 xml->FreeDoc(doc);
431 obj = gr;
432
433 gr->GetXaxis()->SetTimeDisplay(1);
434 gr->GetXaxis()->SetTimeFormat("%H:%M:%S%F1970-01-01 00:00:00");
435 } else {
436
437 TClass *obj_cl = GetObjectClass();
438
439 if (gDebug > 2) printf("TGo4HttpAccess::httpFinished Reconstruct object class %s\n", obj_cl ? obj_cl->GetName() : "---");
440
441 if (!obj_cl || (obj_cl->GetBaseClassOffset(TObject::Class()) != 0)) return;
442
443 obj = (TObject *) obj_cl->New();
444 if (!obj) {
445 printf("TGo4HttpAccess fail to create object of class %s\n", GetObjectClassName());
446 return;
447 }
448
449 TBufferFile buf(TBuffer::kRead, res.size(), res.data(), kFALSE);
450 buf.MapObject(obj, obj_cl);
451
452 obj->Streamer(buf);
453
454 // workaround - when ratemeter received, check running state
455 if (obj->IsA() == TGo4Ratemeter::Class())
456 fProxy->fbAnalysisRunning = ((TGo4Ratemeter*) obj)->IsRunning();
457
458 if (fKind == 6)
459 fProxy->SetAnalysisReady(kTRUE);
460
461 }
462
463 DoObjectAssignement(fReceiver, fRecvPath.Data(), obj, kTRUE);
464}
465
466// =========================================================================
467
469 protected:
470 TXMLEngine *fXML;
471 XMLNodePointer_t fParent;
472 XMLNodePointer_t fChild;
473
474 public:
475 TGo4HttpLevelIter(TXMLEngine* xml, XMLNodePointer_t item) :
477 fXML(xml),
478 fParent(item),
479 fChild()
480 {
481 }
482
484
485 Bool_t next() override
486 {
487 if (!fParent) return kFALSE;
488
489 while (true) {
490
491 if (!fChild) {
492 fChild = fXML->GetChild(fParent);
493 } else {
494 fChild = fXML->GetNext(fChild);
495 }
496
497 if (!fChild) return kFALSE;
498
499 if (fXML->HasAttr(fChild,"_hidden")) continue;
500
501 break;
502 }
503
504 return fChild != nullptr;
505 }
506
507 Bool_t isfolder() override
508 {
509 return fXML->GetChild(fChild) != nullptr;
510 }
511
512 Int_t getflag(const char *flagname) override
513 {
514 if (strcmp(flagname,"IsRemote") == 0) return 1;
515
516 if (strcmp(flagname,"IsDeleteProtect") == 0)
517 return fXML->HasAttr(fChild, "_can_delete") ? 0 : 1;
518
519 if (strcmp(flagname,"IsResetProtect") == 0)
520 return fXML->HasAttr(fChild, "_no_reset") ? 1 : 0;
521
522 if (strcmp(flagname,"_numargs") == 0) {
523 const char *_numargs = fXML->GetAttr(fChild,"_numargs");
524 return !_numargs ? -1 : TString(_numargs).Atoi();
525 }
526
527 return -1;
528 }
529
531 {
532 if (!isfolder()) return nullptr;
533 return new TGo4HttpLevelIter(fXML,fChild);
534 }
535
536 TGo4Slot *getslot() override { return nullptr; }
537
538 const char *name() override
539 {
540 const char *real = fXML->GetAttr(fChild,"_realname");
541 return real? real : fXML->GetAttr(fChild,"_name");
542 }
543
544 const char *info() override { return fXML->GetAttr(fChild,"_title"); }
545 Int_t sizeinfo() override { return 0; }
546
547 Int_t GetKind() override
548 {
549 if (isfolder()) return TGo4Access::kndFolder;
550
551 if (fXML->HasAttr(fChild,"_go4event")) return TGo4Access::kndEventElement;
552
553 if (fXML->HasAttr(fChild,"_more")) return TGo4Access::kndMoreFolder;
554
555 const char *_kind = fXML->GetAttr(fChild,"_kind");
556 if (_kind && strcmp(_kind,"Command") == 0) return TGo4Access::kndRootCommand;
557
558 const char *drawfunc = fXML->GetAttr(fChild,"_drawfunc");
559 if (drawfunc && !strcmp(drawfunc, "GO4.drawParameter")) return TGo4Access::kndGo4Param;
560
561 const char *classname = GetClassName();
562
563 if (!classname) return TGo4Access::kndNone;
564
565 if (strcmp(classname,"TLeafElement") == 0) return TGo4Access::kndTreeLeaf;
566
568 }
569
570 const char *GetClassName() override
571 {
572 const char *_kind = fXML->GetAttr(fChild,"_kind");
573 const char *res = GetHttpRootClassName(_kind);
574 if (res) return res;
575 if (_kind && !strcmp(_kind,"rate") && fXML->HasAttr(fChild,"_history")) return "TGraph";
576 return isfolder() ? "TFolder" : nullptr;
577 }
578};
579
580// =====================================================================
581
584 fXML(nullptr),
585 fxHierarchy(nullptr),
586 fComm(this),
587 fRateCnt(0),
588 fStatusCnt(0),
589 fDebugCnt(0),
590 fbAnalysisRunning(kFALSE),
591 fUserName(),
592 fPassword(),
593 fConnected(kTRUE),
594 fRegularReq(nullptr)
595{
596 fXML = new TXMLEngine;
597 fUserName = "anonymous";
598 // SetAccount("observer","go4view");
599 // SetAccount("controller","go4ctrl");
600}
601
603{
604 fXML->FreeDoc(fxHierarchy);
605 fxHierarchy = nullptr;
606
607 delete fXML; fXML = nullptr;
608}
609
610void TGo4HttpProxy::SetAccount(const char *username, const char *passwd)
611{
612 fUserName = username ? username : "";
613 fPassword = passwd ? passwd : "";
614}
615
617{
619
620 if (!IsGo4Analysis()) return;
621
622 TGo4Slot *subslot = new TGo4Slot(fxParentSlot, "Settings", "Analysis configuration");
623 subslot->SetProxy(new TGo4ObjectProxy());
624
625 subslot = new TGo4Slot(fxParentSlot, "Ratemeter", "Analysis ratemeter");
626 subslot->SetProxy(new TGo4ObjectProxy());
627
628 subslot = new TGo4Slot(fxParentSlot, "Loginfo", "Latest status messages");
629 subslot->SetProxy(new TGo4ObjectProxy());
630
631 subslot = new TGo4Slot(fxParentSlot, "Debugoutput", "Debug output of go4 analysis");
632 subslot->SetProxy(new TGo4ObjectProxy());
633
634 QTimer::singleShot(2000, &fComm, &QHttpProxy::updateRatemeter);
635}
636
637
638XMLNodePointer_t TGo4HttpProxy::FindItem(const char *name, XMLNodePointer_t curr) const
639{
640 if (!curr) curr = fXML->GetChild(fXML->DocGetRootElement(fxHierarchy));
641
642 if (!curr || !name || !*name) return curr;
643
644 const char *slash = strchr(name,'/');
645 bool doagain = false;
646
647 do {
648 size_t len = !slash ? strlen(name) : (slash - name);
649
650 XMLNodePointer_t chld = fXML->GetChild(curr);
651 while (chld) {
652 const char *_name = fXML->GetAttr(chld,"_realname");
653 if (!_name) _name = fXML->GetAttr(chld,"_name");
654
655 if (_name && (strlen(_name) == len) && (strncmp(_name, name, len) == 0))
656 return FindItem(slash ? slash+1 : nullptr, chld);
657
658 chld = fXML->GetNext(chld);
659 }
660
661 // we try to process situation when item name contains slashes
662 doagain = slash != nullptr;
663 if (slash) slash = strchr(slash+1,'/');
664
665 } while (doagain);
666
667 return nullptr;
668}
669
670TString TGo4HttpProxy::MakeUrlPath(XMLNodePointer_t item)
671{
672 if (!item) return TString("");
673
674 XMLNodePointer_t root = fXML->GetChild(fXML->DocGetRootElement(fxHierarchy));
675
676 TString res;
677
678 while (item != root) {
679 const char *_name = fXML->GetAttr(item,"_name");
680 if (!_name) return TString("");
681 if (res.Length()>0)
682 res = TString(_name) + "/" + res;
683 else
684 res = _name;
685
686 item = fXML->GetParent(item);
687 if (!item) return TString("");
688 }
689
690 return res;
691}
692
693
694void TGo4HttpProxy::GetHReply(QByteArray& res)
695{
696 if (res.size() == 0) return;
697 XMLDocPointer_t doc = fXML->ParseString(res.data());
698
699 if (doc) {
700 fXML->FreeDoc(fxHierarchy);
701 fxHierarchy = doc;
702 }
703
704 if (fxParentSlot)
706}
707
709{
710 TGo4ServerProxy::GetContainedObjectInfo(); // evaluate roles
711 fInfoStr +="(";
713 fInfoStr +="@";
715 fInfoStr +=")";
716 const char *analname = fXML->GetAttr(FindItem(""), "_analysis_name");
717 if (analname) {
718 fInfoStr += " name:";
719 fInfoStr += analname;
720 }
721
722 return fInfoStr.Data();
723}
724
725Bool_t TGo4HttpProxy::Connect(const char *nodename)
726{
727 fNodeName = nodename;
728
729 if ((fNodeName.Index("http://") != 0) && (fNodeName.Index("https://") != 0))
730 fNodeName = TString("http://") + fNodeName;
731
732 return UpdateHierarchy(kTRUE);
733}
734
736{
737 return fxHierarchy && !fComm.fHReply;
738}
739
741{
742 if (fComm.fHReply) return kTRUE;
743
744 TString req = fNodeName + "/h.xml?compact";
745
746 fComm.StartRequest(req.Data());
747
748 if (!sync) return kTRUE;
749
750 QElapsedTimer t;
751 t.start();
752
753 // wait several seconds
754 while (t.elapsed() < 5000) {
755 if (!fComm.fHReply) break;
756 QApplication::processEvents();
757 }
758
759 return fxHierarchy != nullptr;
760}
761
763{
764 return fxHierarchy != nullptr;
765}
766
767std::unique_ptr<TGo4Access> TGo4HttpProxy::ProvideAccess(const char *name)
768{
769 XMLNodePointer_t item = FindItem(name);
770
771 if (!item) return nullptr;
772
773 const char *_kind = fXML->GetAttr(item,"_kind");
774
775 Int_t kind = 1;
776
777 if (!strcmp(_kind, "rate") && fXML->HasAttr(item, "_history"))
778 kind = 3;
779 else if (fXML->HasAttr(item, "_dabc_hist"))
780 kind = 2;
781 else if (fXML->HasAttr(item, "_more"))
782 kind = 0;
783
784 return std::make_unique<TGo4HttpAccess>(this, item, kind);
785}
786
788{
789 if (!fxHierarchy) return nullptr;
790 XMLNodePointer_t top = fXML->GetChild(fXML->DocGetRootElement(fxHierarchy));
791
792 return !top ? nullptr : new TGo4HttpLevelIter(fXML, top);
793}
794
795void TGo4HttpProxy::WriteData(TGo4Slot *slot, TDirectory *dir, Bool_t onlyobjs)
796{
797}
798
799void TGo4HttpProxy::ReadData(TGo4Slot *slot, TDirectory *dir)
800{
801}
802
803void TGo4HttpProxy::Update(TGo4Slot *slot, Bool_t strong)
804{
805 if (strong)
806 UpdateHierarchy(kFALSE);
807}
808
810{
811 // return kTRUE when server has Restrict methods
812 // It is indication of new functionality like commands with arguments or support of POST requests
813
814 return fXML->HasAttr(FindItem(""),"_has_restrict");
815}
816
818{
819 // return kTRUE when server has ProduceMulti method
820 // One could use it to submit many requests at once
821
822 return fXML->HasAttr(FindItem(""),"_has_produce_multi");
823}
824
825
827{
828 XMLNodePointer_t item = FindItem("");
829 if (!item) return kFALSE;
830
831 const char *_kind = fXML->GetAttr(item,"_kind");
832 const char *_title = fXML->GetAttr(item,"_title");
833
834 if (!_kind || !_title) return kFALSE;
835
836 return !strcmp(_kind,"ROOT.Session") && !strcmp(_title,"GO4 analysis");
837}
838
839Bool_t TGo4HttpProxy::CheckUserName(const char *expects, Bool_t dflt) const
840{
841 XMLNodePointer_t item = FindItem("");
842 if (!item) return dflt;
843
844 const char *username = fXML->GetAttr(item,"_username");
845 if (!username) return dflt;
846
847 return strcmp(username, expects) == 0;
848}
849
850
852{
853 return UpdateHierarchy(kFALSE);
854}
855
857{
858 QTimer::singleShot(delay_sec*1000, &fComm, &QHttpProxy::updateHierarchy);
859
860 return kTRUE;
861}
862
864{
865 if (!IsGo4Analysis() || IsViewer()) return kFALSE;
866
867 return ServerHasRestrict();
868}
869
870
872{
873 if (SubmitRequest("Control/Analysis", 6, SettingsSlot()))
874 SetAnalysisSettingsReady(kTRUE); // workaround - mark as we finished with settings
875}
876
878{
879 TGo4AnalysisStatus *status = nullptr;
880 if (SettingsSlot())
881 status = dynamic_cast<TGo4AnalysisStatus*>(SettingsSlot()->GetAssignedObject());
882
883 if (status)
884 PostObject("Control/Analysis/exe.bin?method=ApplyStatus&status", status, 2);
885}
886
888{
890
891 SubmitCommand("Control/CmdClose");
892}
893
895{
896 // when command submitted without arguments, histograms and conditions folder will be cleared
897 SubmitCommand("Control/CmdClear");
898}
899
900void TGo4HttpProxy::ClearAnalysisObject(const char *fullpath)
901{
902 TString foldername, objectname;
903 TGo4Slot::ProduceFolderAndName(fullpath, foldername, objectname);
904
905 objectname = TString("\"") + objectname + TString("\"");
906
907 SubmitCommand("Control/CmdClearObject", -1, objectname.Data());
908}
909
911{
912 TString foldername, objectname;
913 TGo4Slot::ProduceFolderAndName(fullpath, foldername, objectname);
914
915 objectname = TString("\"") + objectname + TString("\"");
916
917 SubmitCommand("Control/CmdDeleteObject", -1, objectname.Data());
918}
919
920void TGo4HttpProxy::ExecuteLine(const char *line)
921{
922 // use method of TGo4AnalysisWebStatus - this works with all THttpServer versions
923 if (FindItem("Control/Analysis"))
924 SubmitURL(TString::Format("Control/Analysis/exe.json?method=ExecuteLine&cmd=\"%s\"", line));
925}
926
928{
929 SubmitCommand("Control/CmdStart");
930 fbAnalysisRunning = kTRUE;
931}
932
934{
935 SubmitCommand("Control/CmdStop");
936 fbAnalysisRunning = kFALSE;
937}
938
939Bool_t TGo4HttpProxy::RequestObjectStatus(const char *objectname, TGo4Slot *tgtslot)
940{
941 return SubmitRequest(objectname, 4, tgtslot) != nullptr;
942}
943
944Bool_t TGo4HttpProxy::SubmitURL(const char *path, Int_t waitres)
945{
946 TString url = fNodeName;
947 url.Append("/");
948 url.Append(path);
949
950 if (gDebug > 1) printf("Submit URL %s\n", url.Data());
951
952 QNetworkReply *netReply = fComm.qnam.get(QNetworkRequest(QUrl(url.Data())));
953
954 QSslConfiguration cfg = netReply->sslConfiguration();
955 cfg.setProtocol(QSsl::AnyProtocol/*QSsl::TlsV1SslV3*/);
956 netReply->setSslConfiguration(cfg);
957
958 if (waitres <= 0) {
959 QObject::connect(netReply, &QNetworkReply::finished, netReply, &QNetworkReply::deleteLater);
960 return kTRUE;
961 }
962
963 QEventLoop loop;
964 QElapsedTimer myTimer;
965 myTimer.start();
966 while (!netReply->isFinished()) {
967 loop.processEvents(QEventLoop::AllEvents,100);
968 if (myTimer.elapsed() > waitres*1000) break;
969 }
970
971 netReply->deleteLater();
972 return netReply->isFinished();
973}
974
975TString TGo4HttpProxy::FindCommand(const char *name)
976{
977 if (!name || !*name)
978 return "";
979 if (NumCommandArgs(name) >= 0)
980 return name;
981
983
984 while (iter.next()) {
985 if (iter.getflag("_numargs") < 0) continue;
986 if (strcmp(iter.getname(),name) == 0) return iter.getfullname();
987 }
988
989 return "";
990}
991
992Int_t TGo4HttpProxy::NumCommandArgs(const char *name)
993{
994 XMLNodePointer_t item = FindItem(name);
995 if (!item) return -1;
996
997 const char *_numargs = fXML->GetAttr(item,"_numargs");
998 if (!_numargs) return 0;
999
1000 return TString(_numargs).Atoi();
1001}
1002
1003Bool_t TGo4HttpProxy::SubmitCommand(const char *name, Int_t waitres, const char *arg1, const char *arg2, const char *arg3)
1004{
1005 TString url(name);
1006 url.Append("/cmd.json");
1007 if (arg1 && *arg1) {
1008 url.Append("?arg1=");
1009 url.Append(arg1);
1010 if (arg2 && *arg2) {
1011 url.Append("&arg2=");
1012 url.Append(arg2);
1013 if (arg3 && *arg3) {
1014 url.Append("&arg3=");
1015 url.Append(arg3);
1016 }
1017 }
1018 }
1019
1020 return SubmitURL(url.Data(), waitres);
1021}
1022
1023Bool_t TGo4HttpProxy::PostObject(const char *prefix, TObject *obj, Int_t waitres, Bool_t destroy_after)
1024{
1025 if (!ServerHasRestrict()) return kFALSE;
1026
1027 TBufferFile *sbuf = new TBufferFile(TBuffer::kWrite, 100000);
1028 sbuf->MapObject(obj);
1029 obj->Streamer(*sbuf);
1030
1031 QByteArray postData;
1032 postData.append(sbuf->Buffer(), sbuf->Length());
1033
1034 delete sbuf;
1035
1036 TString url = fNodeName;
1037 url.Append("/");
1038 url.Append(prefix);
1039 url.Append("=_post_object_&");
1040 if (destroy_after) url.Append("_destroy_post_&");
1041 url.Append("_post_class_=");
1042 url.Append(obj->ClassName());
1043
1044 // printf("URL %s datalen %d\n", url.Data(), postData.length());
1045
1046 QNetworkRequest req(QUrl(url.Data()));
1047
1048 QNetworkReply *netReply = fComm.qnam.post(req, postData);
1049
1050 QSslConfiguration cfg = netReply->sslConfiguration();
1051 cfg.setProtocol(QSsl::AnyProtocol/*QSsl::TlsV1SslV3*/);
1052 netReply->setSslConfiguration(cfg);
1053
1054 if (waitres <= 0) {
1055 QObject::connect(netReply, &QNetworkReply::finished, netReply, &QNetworkReply::deleteLater);
1056 return kTRUE;
1057 }
1058
1059 QEventLoop loop;
1060 QElapsedTimer myTimer;
1061 myTimer.start();
1062 while (!netReply->isFinished()) {
1063 loop.processEvents(QEventLoop::AllEvents,100);
1064 if (myTimer.elapsed() > waitres*1000) break;
1065 }
1066
1067 netReply->deleteLater();
1068 return netReply->isFinished();
1069}
1070
1071
1072Bool_t TGo4HttpProxy::UpdateAnalysisObject(const char *objectname, TObject *obj)
1073{
1074 TString url;
1075
1076 Bool_t destr = kTRUE;
1077
1078 if (*objectname == 0) {
1079 url.Append("Control/go4_sniffer/exe.bin?method=AddAnalysisObject&obj");
1080 destr = kFALSE; // object will be owned by analysis
1081 } else {
1082 url.Append(objectname);
1083 url.Append("/exe.bin?method=");
1084
1085 if (obj->InheritsFrom(TGo4Condition::Class())) {
1086 url.Append("UpdateFrom&counts=kFALSE&cond");
1087 } else {
1088 url.Append("SetStatus&status");
1089 }
1090 }
1091
1092 return PostObject(url.Data(), obj, 2, destr);
1093}
1094
1096{
1097 TGo4Slot *subslot = DebugOutputSlot();
1098 if (subslot) subslot->AssignObject(nullptr, kFALSE);
1099}
1100
1102{
1103 if (finished) {
1104 if (!fRegularReq) return;
1105
1106 QByteArray res = fRegularReq->readAll();
1107 fRegularReq->deleteLater();
1108 fRegularReq = nullptr;
1109
1110 if (res.size() <= 0) {
1111 fConnected = false;
1112
1113 // check if proxy is in shutdown phase
1114 if (CheckShutdown()) return;
1115
1116 RatemeterSlot()->AssignObject(new TNamed("disconnected","title"),kTRUE);
1117
1118 return;
1119 }
1120
1121 if (!fConnected) {
1122 UpdateHierarchy(kFALSE);
1123 fConnected = true;
1124 }
1125
1126 if (gDebug > 2)
1127 printf("TGo4HttpProxy:: get reply on multi.bin request with %ld bytes\n", (long) res.size());
1128
1129 int pos = 0;
1130
1131 for (int n = 0; n < 3; n++) {
1132 unsigned char *ptr = (unsigned char *)res.data() + pos;
1133 unsigned len = ((unsigned) ptr[0]) |
1134 (((unsigned) ptr[1]) << 8) |
1135 (((unsigned) ptr[2]) << 16) |
1136 (((unsigned) ptr[3]) << 24);
1137
1138 ptr += 4;
1139 pos += 4 + len;
1140 if (len > (unsigned) res.size()) {
1141 printf("Error decoding multi.bin buffer\n");
1142 return;
1143 }
1144
1145 if (gDebug>2) printf("Decoding portion of %d bytes\n", len);
1146
1147 TClass *obj_cl = n == 0 ? TGo4Ratemeter::Class() : TList::Class();
1148 TObject *obj = (TObject*) obj_cl->New();
1149
1150 TBufferFile buf(TBuffer::kRead, len, ptr, kFALSE);
1151 buf.MapObject(obj, obj_cl);
1152
1153 obj->Streamer(buf);
1154
1155 if (n > 0) {
1156 TGo4Slot *subslot = n==1 ? LoginfoSlot() : DebugOutputSlot();
1157 TList *curr = subslot ? dynamic_cast<TList *> (subslot->GetAssignedObject()) : nullptr;
1158 TList *next = dynamic_cast<TList *> (obj);
1159 if (curr && curr->First() && next && next->First()) {
1160 if (strcmp(curr->First()->GetName(), next->First()->GetName()) == 0) {
1161 // this is protection against sending same info many times
1162 // happend with sever snapshot
1163 delete obj;
1164 obj = nullptr;
1165 }
1166 }
1167 }
1168
1169 switch(n) {
1170 case 0:
1171 fbAnalysisRunning = ((TGo4Ratemeter*) obj)->IsRunning();
1172 RatemeterSlot()->AssignObject(obj,kTRUE);
1173 break;
1174 case 1:
1175 if (obj) LoginfoSlot()->AssignObject(obj,kTRUE);
1176 break;
1177 case 2:
1178 if (obj) DebugOutputSlot()->AssignObject(obj,kTRUE);
1179 break;
1180 }
1181 }
1182
1183 if (pos != res.size())
1184 printf("Decoding fails %d != %ld bytes\n", pos, (long) res.size());
1185
1186 return;
1187 }
1188
1189
1190 if (fRegularReq) return;
1191
1192 TString req;
1193
1194 req.Append("Ratemeter/root.bin\n");
1195
1196 req.Append("Msg/exe.bin?method=Select&max=10000");
1197 TGo4Slot *subslot = LoginfoSlot();
1198 TList *curr = subslot ? dynamic_cast<TList *> (subslot->GetAssignedObject()) : nullptr;
1199 if (curr && curr->First()) {
1200 req.Append("&id=");
1201 req.Append(curr->First()->GetName());
1202
1203 }
1204 req.Append("\n");
1205
1206 req.Append("Log/exe.bin?method=Select&max=10000");
1207 subslot = DebugOutputSlot();
1208 curr = subslot ? dynamic_cast<TList *> (subslot->GetAssignedObject()) : nullptr;
1209 if (curr && curr->First()) {
1210 req.Append("&id=");
1211 req.Append(curr->First()->GetName());
1212
1213 }
1214 req.Append("\n");
1215
1216 QByteArray postData;
1217 postData.append(req.Data(), req.Length());
1218 if (gDebug>2) printf("Sending multi.bin request\n%s", req.Data());
1219
1220 TString url = fNodeName;
1221 url.Append("/Status/multi.bin.gz?number=3");
1222
1223 fRegularReq = fComm.qnam.post(QNetworkRequest(QUrl(url.Data())), postData);
1224
1225 QSslConfiguration cfg = fRegularReq->sslConfiguration();
1226 cfg.setProtocol(QSsl::AnyProtocol/*QSsl::TlsV1SslV3*/);
1227 fRegularReq->setSslConfiguration(cfg);
1228
1229 QObject::connect(fRegularReq, &QNetworkReply::finished, &fComm, &QHttpProxy::regularRequestFinished);
1230}
1231
1233{
1234 if (force || (fShutdownCnt>0)) {
1235 if (fxParentSlot) fxParentSlot->Delete();
1236 fxParentSlot = nullptr;
1237 return kTRUE;
1238 }
1239 return kFALSE;
1240}
1241
1243{
1244 if ((fShutdownCnt > 0) && (--fShutdownCnt == 0)) {
1245 CheckShutdown(kTRUE);
1246 return;
1247 }
1248
1249 if (ServerHasMulti() || fRegularReq) {
1251 return;
1252 }
1253
1254 TGo4Slot *subslot = RatemeterSlot();
1255 if (subslot) {
1256 // no new update since last call
1257 if (!subslot->GetAssignedObject() || (fRateCnt != subslot->GetAssignCnt())) {
1258 fRateCnt = subslot->GetAssignCnt();
1259 SubmitRequest("Status/Ratemeter", 1, subslot);
1260 }
1261 }
1262
1263 subslot = LoginfoSlot();
1264 if (subslot && IsConnected()) {
1265 TList *curr = dynamic_cast<TList *> (subslot->GetAssignedObject());
1266 if (!curr || (fStatusCnt != subslot->GetAssignCnt())) {
1267 TString arg;
1268 if (curr && curr->First()) {
1269 arg = "id=";
1270 arg += curr->First()->GetName();
1271 }
1272 fStatusCnt = subslot->GetAssignCnt();
1273 SubmitRequest("Status/Msg", 7, subslot, arg);
1274 }
1275 }
1276
1277 subslot = DebugOutputSlot();
1278 if (subslot && IsConnected()) {
1279 TList *curr = dynamic_cast<TList *> (subslot->GetAssignedObject());
1280 if (!curr || (fDebugCnt != subslot->GetAssignCnt())) {
1281 TString arg;
1282 if (curr && curr->First()) {
1283 arg = "id=";
1284 arg += curr->First()->GetName();
1285 }
1286 fDebugCnt = subslot->GetAssignCnt();
1287 SubmitRequest("Status/Log", 7, subslot, arg);
1288 }
1289 }
1290}
1291
1292void TGo4HttpProxy::RemoteTreeDraw(const char *treename,
1293 const char *varexp,
1294 const char *cutcond,
1295 const char *hname)
1296{
1297 TString tfoldername, tobjectname;
1298 TGo4Slot::ProduceFolderAndName(treename, tfoldername, tobjectname);
1299
1300 TString hfoldername, hobjectname;
1301 TGo4Slot::ProduceFolderAndName(hname, hfoldername, hobjectname);
1302
1303 TString path;
1304 path.Form("Control/go4_sniffer/exe.json?method=RemoteTreeDraw&histoname=\"%s\"&treename=\"%s\"&varexpr=\"%s\"&cutexpr=\"%s\"",
1305 hobjectname.Data(), tobjectname.Data(), varexp, cutcond);
1306
1307 SubmitURL(path, 2);
1308}
1309
1310TGo4HttpAccess* TGo4HttpProxy::SubmitRequest(const char *itemname, Int_t kind, TGo4Slot *tgtslot, const char *extra_arg)
1311{
1312 if (!itemname || !tgtslot) return nullptr;
1313
1314 XMLNodePointer_t item = FindItem(itemname);
1315 if (!item) return nullptr;
1316
1317 if (kind == 4) {
1318 // when status for histogram is requested, redirect request to the sniffer
1319 const char *_objkind = fXML->GetAttr(item, "_kind");
1320 if (_objkind && ((strstr(_objkind, "ROOT.TH1") == _objkind) || (strstr(_objkind, "ROOT.TH2") == _objkind) ||
1321 (strstr(_objkind, "ROOT.TH3") == _objkind)))
1322 kind = 8;
1323 }
1324
1325 TGo4HttpAccess* access = new TGo4HttpAccess(this, item, kind, extra_arg);
1326 access->AssignObjectToSlot(tgtslot); // request event itself
1327
1328 return access;
1329}
1330
1331void TGo4HttpProxy::RequestEventStatus(const char *evname, Bool_t astree, TGo4Slot *tgtslot)
1332{
1333 if (!tgtslot) {
1334 // this is remote printing of event
1335
1336 TString url = evname;
1337 url.Append("/exe.bin?method=");
1338 url.Append(astree ? "ShowSampleTree" : "PrintEvent");
1339
1340 SubmitURL(url);
1341 return;
1342 }
1343
1344 SubmitRequest(evname, astree ? 5 : 1, tgtslot);
1345}
1346
1347void TGo4HttpProxy::RemotePrintEvent(const char *evname,
1348 Int_t evnumber,
1349 Int_t subid,
1350 Bool_t ishex,
1351 Bool_t islong)
1352{
1353 TString url;
1354 url.Form("Events/%s/exe.bin?method=SetPrintEvent&num=%d&sid=%d&longw=%d&hexw=%d&dataw=%d",
1355 evname, evnumber, subid, islong ? 1 : 0, ishex ? 1 : 0, ishex ? 0 : 1);
1356 SubmitURL(url);
1357}
1358
1359void TGo4HttpProxy::ChageObjectProtection(const char *fullpath, const char *flags)
1360{
1361 unsigned reset_bits = 0, set_bits = 0;
1362
1363 TString opt = flags;
1364 if(opt.Contains("+D")) reset_bits |= TGo4Status::kGo4CanDelete;
1365 if(opt.Contains("-D")) set_bits |= TGo4Status::kGo4CanDelete;
1366 if(opt.Contains("+C")) set_bits |= TGo4Status::kGo4NoReset;
1367 if(opt.Contains("-C")) reset_bits |= TGo4Status::kGo4NoReset;
1368
1369 TString url(fullpath);
1370 url.Append("/exe.bin?method=");
1371
1372 if (reset_bits != 0) SubmitURL(url + TString::Format("ResetBit&f=%u",reset_bits));
1373 if (set_bits != 0) SubmitURL(url + TString::Format("SetBit&f=%u&prototype=UInt_t",set_bits));
1374}
1375
1376void TGo4HttpProxy::PrintDynListEntry(const char *fullpath)
1377{
1378 SubmitURL(TString(fullpath)+"/exe.bin?method=Print");
1379}
1380
1381void TGo4HttpProxy::LoadConfigFile(const char *fname)
1382{
1383 SubmitURL(TString::Format("Control/Analysis/exe.bin?method=LoadStatus&fname=%s", fname));
1384}
1385
1386void TGo4HttpProxy::SaveConfigFile(const char *fname)
1387{
1388 SubmitURL(TString::Format("Control/Analysis/exe.bin?method=SaveStatus&fname=%s", fname));
1389}
1390
1391void TGo4HttpProxy::WriteAutoSave(const char *fname,
1392 Int_t complevel,
1393 Bool_t overwrite)
1394{
1395 SubmitURL(TString::Format("Control/Analysis/exe.bin?method=WriteAutoSave&fname=%s&overwrite=%s&complevel=%d", fname, overwrite ? "kTRUE" : "kFALSE", complevel));
1396}
1397
1398void TGo4HttpProxy::DisconnectAnalysis(Int_t waittime, Bool_t servershutdown)
1399{
1400 if (servershutdown && IsGo4Analysis() && IsAdministrator()) {
1401 SubmitCommand("Control/CmdExit");
1402 fShutdownCnt = waittime;
1403 } else {
1404 CheckShutdown(kTRUE);
1405 }
1406}
const char * GetHttpRootClassName(const char *kind)
void httpHReqError(QNetworkReply::NetworkError)
virtual ~QHttpProxy()
void updateRatemeter()
TGo4HttpProxy * fProxy
used only to receive hierarchy
void authenticationRequiredSlot(QNetworkReply *, QAuthenticator *)
QHttpProxy(TGo4HttpProxy *p)
friend class TGo4HttpProxy
void StartRequest(const char *url)
void httpFinished()
void updateHierarchy()
void regularRequestFinished()
QNetworkReply * fHReply
central manager of network requests
QNetworkAccessManager qnam
void DoObjectAssignement(TGo4ObjectManager *rcv, const char *path, TObject *obj, Bool_t owner)
Definition TGo4Proxy.cxx:63
@ kndRootCommand
Definition TGo4Proxy.h:43
@ kndEventElement
Definition TGo4Proxy.h:41
@ kndMoreFolder
Definition TGo4Proxy.h:42
Int_t AssignObjectToSlot(TGo4Slot *slot)
Made for convenience - extracts OM and slot path and calls AssignObjectTo method.
Definition TGo4Proxy.cxx:54
Status of the analysis instance.
QNetworkReply * fReply
TGo4HttpProxy * fProxy
TGo4ObjectManager * fReceiver
TGo4HttpAccess(TGo4HttpProxy *proxy, XMLNodePointer_t node, Int_t kind=1, const char *extra_arg=nullptr)
Int_t AssignObjectTo(TGo4ObjectManager *rcv, const char *path) override
Have to assign object to provided receiver.
TClass * GetObjectClass() const override
const char * GetObjectClassName() const override
void httpError(QNetworkReply::NetworkError)
XMLNodePointer_t fNode
const char * GetObjectName() const override
TGo4HttpLevelIter(TXMLEngine *xml, XMLNodePointer_t item)
const char * info() override
Bool_t isfolder() override
TGo4LevelIter * subiterator() override
XMLNodePointer_t fParent
Int_t sizeinfo() override
const char * GetClassName() override
const char * name() override
Bool_t next() override
virtual ~TGo4HttpLevelIter()
XMLNodePointer_t fChild
Int_t GetKind() override
Int_t getflag(const char *flagname) override
TGo4Slot * getslot() override
Here Go4/ROOT-specific functionality of HttpProxy.
TGo4LevelIter * MakeIter() override
Int_t fShutdownCnt
multiple request for rate, log and messages
virtual ~TGo4HttpProxy()
XMLDocPointer_t fxHierarchy
Bool_t DelayedRefreshNamesList(Int_t delay_sec) override
QHttpProxy fComm
pointer on dabc::Hierarchy class
friend class TGo4HttpAccess
void PrintDynListEntry(const char *fullpath) override
TXMLEngine * fXML
void RemoteTreeDraw(const char *treename, const char *varexp, const char *cutcond, const char *hname) override
Bool_t SubmitCommand(const char *name, Int_t waitres=-1, const char *arg1=nullptr, const char *arg2=nullptr, const char *arg3=nullptr) override
XMLNodePointer_t FindItem(const char *name, XMLNodePointer_t curr=nullptr) const
Bool_t CheckUserName(const char *expects, Bool_t dflt=kFALSE) const
void StartAnalysis() override
Bool_t IsAdministrator() const override
void RemotePrintEvent(const char *evname, Int_t evnumber, Int_t subid, Bool_t ishex, Bool_t islong) override
Bool_t UpdateAnalysisObject(const char *objectname, TObject *obj) override
void ReadData(TGo4Slot *slot, TDirectory *dir) override
Bool_t IsConnected() const override
Bool_t ServerHasRestrict() const
Bool_t RequestObjectStatus(const char *objectname, TGo4Slot *tgtslot) override
void SetAccount(const char *username, const char *passwd)
void SubmitAnalysisSettings() override
void Update(TGo4Slot *slot, Bool_t strong) override
Int_t NumCommandArgs(const char *name) override
void DisconnectAnalysis(Int_t waittime=30, Bool_t servershutdown=kFALSE) override
Close connection to analysis and destroys proxy with correspondent slot.
TGo4HttpAccess * SubmitRequest(const char *itemname, Int_t kind, TGo4Slot *tgtslot, const char *extra_arg=nullptr)
Int_t fStatusCnt
counter for ratemeter updates
TString fPassword
user name and password -
void ResetDebugOutputRequests() override
Bool_t UpdateHierarchy(Bool_t sync=kTRUE)
TString MakeUrlPath(XMLNodePointer_t item)
void ProcessRegularMultiRequest(Bool_t finished=kFALSE)
void StopAnalysis() override
Bool_t IsGo4Analysis() const override
void ClearAllAnalysisObjects() override
void GetHReply(QByteArray &res)
counter during shutdown
void ExecuteLine(const char *line) override
std::unique_ptr< TGo4Access > ProvideAccess(const char *name) override
void SaveConfigFile(const char *fname) override
void WriteAutoSave(const char *fname, Int_t complevel, Bool_t overwrite) override
void RequestAnalysisSettings() override
Bool_t SubmitURL(const char *path, Int_t waitres=-1)
Bool_t CanSubmitObjects() const override
Bool_t HasSublevels() const override
QNetworkReply * fRegularReq
true if connected
Bool_t IsViewer() const override
Bool_t PostObject(const char *prefix, TObject *obj, Int_t waitres=-1, Bool_t destroy_after=kTRUE)
const char * GetContainedObjectInfo() override
void ClearAnalysisObject(const char *fullpath) override
Bool_t CheckShutdown(Bool_t force=kFALSE)
Bool_t ServerHasMulti()
void WriteData(TGo4Slot *slot, TDirectory *dir, Bool_t onlyobjs) override
void RemoveObjectFromAnalysis(const char *fullpath) override
void Initialize(TGo4Slot *slot) override
Bool_t fbAnalysisRunning
counter for debug output updates
void RequestEventStatus(const char *evname, Bool_t astree, TGo4Slot *tgtslot) override
const char * GetUserName() const override
void LoadConfigFile(const char *fname) override
Bool_t RefreshNamesList() override
Int_t fDebugCnt
counter for status messages updates
TString FindCommand(const char *name) override
Bool_t NamesListReceived() const override
void ChageObjectProtection(const char *fullpath, const char *flags) override
void CloseAnalysisSettings() override
Bool_t Connect(const char *nodename)
Bool_t next(Bool_t goesinto=kTRUE)
Definition TGo4Iter.cxx:44
const char * getname()
Definition TGo4Iter.cxx:115
const char * getfullname()
Definition TGo4Iter.cxx:151
Int_t getflag(const char *flagname)
Definition TGo4Iter.cxx:133
static TClass * GetClass(const char *classname, Bool_t load=kFALSE)
Definition TGo4Proxy.cxx:73
Class containing event counter and ratemeter services.
const char * GetContainedObjectInfo() override
TGo4Slot * LoginfoSlot()
TString fNodeName
0 - not launched, 1 - external shell, 2 - in qt shell
virtual const char * GetServerName() const
TGo4Slot * fxParentSlot
TString fInfoStr
name of remote node
TGo4ServerProxy()
contained object info
TGo4Slot * DebugOutputSlot()
TGo4Slot * RatemeterSlot()
void Initialize(TGo4Slot *slot) override
TGo4Slot * SettingsSlot()
void SetAnalysisSettingsReady(Bool_t on=kTRUE)
void SetProxy(TGo4Proxy *cont)
Definition TGo4Slot.cxx:296
@ evObjAssigned
Definition TGo4Slot.h:47
static void ProduceFolderAndName(const char *fullname, TString &foldername, TString &objectname)
Definition TGo4Slot.cxx:646
Bool_t AssignObject(TObject *obj, Bool_t owner)
Definition TGo4Slot.cxx:344
TObject * GetAssignedObject()
Definition TGo4Slot.cxx:356
Int_t GetAssignCnt() const
Definition TGo4Slot.h:104