DABC (Data Acquisition Backbone Core)  2.9.9
TDabcEngine.cxx
Go to the documentation of this file.
1 // $Id: TDabcEngine.cxx 3887 2018-05-16 15:01:49Z linev $
2 
3 /************************************************************
4  * The Data Acquisition Backbone Core (DABC) *
5  ************************************************************
6  * Copyright (C) 2009 - *
7  * GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
8  * Planckstr. 1, 64291 Darmstadt, Germany *
9  * Contact: http://dabc.gsi.de *
10  ************************************************************
11  * This software can be used under the GPL license *
12  * agreements as stated in LICENSE.txt file *
13  * which is part of the distribution. *
14  ************************************************************/
15 
16 #include "root/TDabcEngine.h"
17 
18 #include "dabc/Command.h"
19 #include "dabc/api.h"
20 #include "dabc/Url.h"
21 #include "dabc/Manager.h"
22 
23 #include "root/Monitor.h"
24 
25 #include "THttpServer.h"
26 
27 TDabcEngine::TDabcEngine() : THttpEngine("dabc","Bridge between DABC and ROOT")
28 {
29  // constructor
30 }
31 
33 {
34  // destructor
35 }
36 
37 Bool_t TDabcEngine::Create(const char* args)
38 {
39  // create different kinds of DABC access to the ROOT server. Possible
40  //
41  // 1. DABC server
42  // In this case args should be ":portnumber"
43  // Optionally, one can allow clients to connect. Example
44  // serv->CreateEngine("dabc:1237?allowclients");
45  //
46  // 2. DABC slave
47  // One could attach ROOT process to other DABC server. In this case one should
48  // specify host and port number of the master DABC process like:
49  // serv->CreateEngine("dabc:masterhost:1237");
50  //
51  // 3. DABC http server
52  // To start DABC version of http server, one should specify:
53  // serv->CreateEngine("dabc:http:8090");
54  //
55  // 4. DABC fastcgi server
56  // To start DABC version of fastcgi server, one should specify:
57  // serv->CreateEngine("dabc:fastcgi:8090");
58  // Optionally, one can enable debug mode for the fastcgi server "dabc:fastcgi:8090?debug"
59  //
60  // For all kinds of servers on can optionally specify name of top folder
61  // For instance, when starting http server:
62  // serv->CreateEngine("dabc:http:8090?top=myapp");
63 
64 
65  if (args!=0) Info("Create", "args = %s", args);
66 
67  dabc::Url url;
68 
69  if (strncmp(args,"http:",5) == 0) {
70  url.SetUrl(std::string("http://localhost:") + (args+5), false);
71  } else
72  if (strncmp(args,"fastcgi:",8) == 0) {
73  url.SetUrl(std::string("fastcgi://localhost:") + (args+8), false);
74  } else
75  if (strncmp(args,"master:",7) == 0) {
76  url.SetUrl(std::string("dabc://") + (args+7), false);
77  } else
78  if (strchr(args,':')!=0) {
79  url.SetUrl(std::string("dabc://") + args, false);
80  } else {
81  url.SetUrl(std::string("server://localhost:") + args, false);
82  }
83 
84  if (!url.IsValid()) {
85  EOUT("Wrong arguments %s", args);
86  return kFALSE;
87  }
88 
89  std::string topfolder = url.GetOptionStr("top", "ROOT");
90 
91  if (dabc::mgr.null()) {
93  dabc::CreateManager("dabc", -1);
94  }
95 
96  // creating web server
97  if (url.GetProtocol() == "http") {
98  if (dabc::mgr.FindItem("/http").null()) {
99  dabc::CmdCreateObject cmd1("http::Civetweb","/http");
100  cmd1.SetInt("port", url.GetPort());
101  cmd1.SetStr("urlopt", url.GetOptions());
102  if (!dabc::mgr.Execute(cmd1)) return kFALSE;
103 
104  dabc::WorkerRef w1 = cmd1.GetRef("Object");
105  w1.MakeThreadForWorker("MainThread");
106  }
107  } else
108  // creating fastcgi server
109  if (url.GetProtocol() == "fastcgi") {
110  if (dabc::mgr.FindItem("/fastcgi").null()) {
111  dabc::CmdCreateObject cmd1("http::FastCgi","/fastcgi");
112  cmd1.SetInt("port", url.GetPort());
113  cmd1.SetBool("debug", url.HasOption("debug"));
114  cmd1.SetStr("urlopt", url.GetOptions());
115  if (!dabc::mgr.Execute(cmd1)) return kFALSE;
116 
117  dabc::WorkerRef w1 = cmd1.GetRef("Object");
118  w1.MakeThreadForWorker("MainThread");
119  }
120  return kTRUE;
121  } else
122  // connect to master
123  if (url.GetProtocol() == "dabc") {
124 
125  std::string master_url = url.GetHostNameWithPort();
126 
127  // we selecting ROOT sniffer as the only objects, seen from the server
128  if (!dabc::mgr.CreateControl(false)) {
129  DOUT0("Cannot create control instance");
130  return false;
131  }
132 
133  DOUT1("Create slave command channel for master %s ", master_url.c_str());
134 
135  dabc::Command cmd("ConfigureMaster");
136  cmd.SetStr("Master", master_url);
137  cmd.SetStr("NameSufix", topfolder);
138  if (dabc::mgr.GetCommandChannel().Execute(cmd) != dabc::cmd_true) {
139  DOUT0("FAIL to activate connection to master %s", master_url.c_str());
140  return kFALSE;
141  }
142  } else {
143  if (!dabc::mgr.CreateControl(true, url.GetPort(), url.HasOption("allowclients"))) return kFALSE;
144  }
145 
147 
148  if (dabc::mgr.FindItem("/ROOT").null()) {
149 
150  std::string player_class = url.GetOptionStr("player", "root::Monitor");
151 
152  dabc::CmdCreateObject cmd2(player_class,"/ROOT");
153  cmd2.SetBool("enabled", true);
154  cmd2.SetStr("prefix", topfolder);
155 
156  if (!dabc::mgr.Execute(cmd2)) return kFALSE;
157  dabc::WorkerRef player = cmd2.GetRef("Object");
158 
159  if (player.null()) return kFALSE;
160 
161  player.MakeThreadForWorker("MainThread");
162  DOUT1("Create root player %p thrdname %s", player(), player.thread().GetName());
163  }
164 
165  return kTRUE;
166 }
167 
168 
170 {
171  // method called from ROOT context and used to perform actions in root context
172 
173  if (!GetServer() || !GetServer()->GetSniffer()) return;
174 
175  root::MonitorRef player = dabc::mgr.FindItem("/ROOT");
176 
177  player.ProcessActionsInRootContext(GetServer(), GetServer()->GetSniffer());
178 }
virtual Bool_t Create(const char *args)
Definition: TDabcEngine.cxx:37
virtual ~TDabcEngine()
Definition: TDabcEngine.cxx:32
virtual void Process()
Represents command with its arguments.
Definition: Command.h:99
bool SetStr(const std::string &name, const char *value)
Definition: Command.h:134
bool SetBool(const std::string &name, bool v)
Definition: Command.h:141
bool SetInt(const std::string &name, int v)
Definition: Command.h:138
Reference GetRef(const std::string &name)
Returns reference from the command, can be called only once.
Definition: Command.cxx:175
Reference FindItem(const std::string &name)
Definition: Manager.cxx:2054
bool CreatePublisher()
Create publisher, which manage all published hierarchies.
Definition: Manager.cxx:2315
const char * GetName() const
Return name of referenced object, if object not assigned, returns "---".
Definition: Reference.cxx:167
bool null() const
Returns true if reference contains nullptr.
Definition: Reference.h:151
Uniform Resource Locator interpreter.
Definition: Url.h:33
std::string GetOptionStr(const std::string &optname, const std::string &dflt="") const
Definition: Url.cxx:281
bool SetUrl(const std::string &url, bool showerr=true)
Definition: Url.cxx:46
bool HasOption(const std::string &optname) const
Definition: Url.h:70
std::string GetProtocol() const
Definition: Url.h:57
std::string GetHostNameWithPort(int dfltport=0) const
Definition: Url.cxx:139
std::string GetOptions() const
Definition: Url.h:63
int GetPort() const
Definition: Url.h:59
bool IsValid() const
Definition: Url.h:55
Reference on dabc::Worker
Definition: Worker.h:466
ThreadRef thread()
Definition: Worker.h:492
bool MakeThreadForWorker(const std::string &thrdname="")
Definition: Worker.h:498
void ProcessActionsInRootContext(THttpServer *serv, TRootSniffer *sniff)
Definition: Monitor.h:95
#define DOUT0(args ...)
Definition: logging.h:156
#define EOUT(args ...)
Definition: logging.h:150
#define DOUT1(args ...)
Definition: logging.h:162
bool CreateManager(const std::string &name, int cmd_port=-1)
Function should be used to create manager instance.
Definition: api.cxx:26
void SetDebugLevel(int level=0)
Definition: logging.cxx:468
ManagerRef mgr
Definition: Manager.cxx:42
@ cmd_true
Definition: Command.h:38