Nymph  v1.5.2
Flow-Based Data Processing Framework
KTApplication.cc
Go to the documentation of this file.
1 /*
2  * KTApplication.cc
3  *
4  * Created on: Aug 5, 2012
5  * Author: nsoblath
6  */
7 
8 #include "KTApplication.hh"
9 
10 #include "KTEventLoop.hh"
11 #include "KTLogger.hh"
12 
13 #include "param_codec.hh"
14 #include "param_json.hh"
15 
16 using std::set;
17 using std::string;
18 
19 #include <iostream>
20 
21 namespace Nymph
22 {
23  KTLOGGER(applog, "KTApplication");
24 
26  KTConfigurable("app"),
27  fCLHandler(KTCommandLineHandler::get_instance()),
28  fConfigurator( KTConfigurator::get_instance() ),
29  fConfigFilename()
30  {
31  }
32 
33  KTApplication::KTApplication(int argC, char** argV, bool requireArgs, const scarab::param_node& defaultConfig) :
34  KTConfigurable("app"),
35  fCLHandler(KTCommandLineHandler::get_instance()),
36  fConfigurator( KTConfigurator::get_instance() ),
38  {
39  // process command-line arguments
40  fCLHandler->ProcessCommandLine(argC, argV);
41 
42  // if requested, print help or version messages, and exit
43  if (fCLHandler->GetPrintHelpMessageFlag() || (requireArgs && fCLHandler->GetNArgs() == 1))
44  {
46  exit(0);
47  }
49  {
51  exit(0);
52  }
53 
54  // get configuration information from the CLHandler
56  string clJSON = fCLHandler->GetCommandLineJSON();
57  const scarab::param_node* clConfigOverride = fCLHandler->GetConfigOverride();
58 
59  // Default configuration
60  fConfigurator->Merge(defaultConfig);
61 
62  // JSON file configuration
63  if (! fConfigFilename.empty())
64  {
65  scarab::path configFilePath = scarab::expand_path( fConfigFilename );
66  scarab::param_translator translator;
67  scarab::param_ptr_t configFromFile = translator.read_file( configFilePath.native() );
68  if( configFromFile == NULL )
69  {
70  throw KTException() << "[KTApplication] error parsing config file";
71  }
72  if( ! configFromFile->is_node() )
73  {
74  throw KTException() << "[KTApplication] configuration file must consist of an object/node";
75  }
76  fConfigurator->Merge( configFromFile->as_node() );
77  }
78 
79  // Command-line JSON configuration
80  if (! clJSON.empty())
81  {
82  scarab::param_input_json inputJSON;
83  scarab::param_ptr_t configFromJSON = inputJSON.read_string( clJSON );
84  if( ! configFromJSON->is_node() )
85  {
86  throw KTException() << "[KTApplication] command line json must be an object";
87  }
88  fConfigurator->Merge( configFromJSON->as_node() );
89  }
90 
91  // Command-line overrides
92  if (clConfigOverride != NULL)
93  {
94  fConfigurator->Merge( *clConfigOverride );
95  }
96 
97  KTINFO( applog, "Final configuration:\n" << fConfigurator->Config() );
98 
101 
103  {
105  exit(0);
106  }
107 
109  }
110 
112  {
113  for (set< KTEventLoop* >::iterator loopIt = fEventLoops.begin(); loopIt != fEventLoops.end(); ++loopIt)
114  {
115  // does NOT delete event loops
116  (*loopIt)->Stop();
117  }
118  }
119 
120  void KTApplication::AddConfigOptionsToCLHandler(const scarab::param& param, const std::string& rootName)
121  {
122  if (param.is_null())
123  {
124  fCLHandler->AddOption("Config File Options", "Configuration flag: " + rootName, rootName, false);
125  }
126  else if (param.is_value())
127  {
128  fCLHandler->AddOption< string >("Config File Options", "Configuration value: " + rootName, rootName, false);
129  }
130  else if (param.is_array())
131  {
132  string nextRootName(rootName);
133  if (! rootName.empty() && rootName.back() != '.') nextRootName += ".";
134 
135  const scarab::param_array& paramArray = param.as_array();
136  unsigned arraySize = paramArray.size();
137  for (unsigned iParam = 0; iParam < arraySize; ++iParam)
138  {
139  AddConfigOptionsToCLHandler(paramArray[iParam], nextRootName + std::to_string(iParam));
140  }
141  }
142  else if (param.is_node())
143  {
144  string nextRootName(rootName);
145  if (! rootName.empty()) nextRootName += ".";
146 
147  const scarab::param_node& paramNode = param.as_node();
148  for (scarab::param_node::const_iterator nodeIt = paramNode.begin(); nodeIt != paramNode.end(); ++nodeIt)
149  {
150  AddConfigOptionsToCLHandler(*nodeIt, nextRootName + nodeIt.name());
151  }
152  }
153 
154  return;
155  }
156 
157  bool KTApplication::Configure(const scarab::param_node&)
158  {
159  return true;
160  }
161 
163  {
164  fEventLoops.insert(loop);
165  return;
166  }
167 
169  {
170  fEventLoops.erase(loop);
171  return;
172  }
173 
174 } /* namespace Nymph */
#define KTINFO(...)
Definition: KTLogger.hh:344
const scarab::param_node * GetConfigOverride() const
bool AddOption(const std::string &aTitle, const std::string &aHelpMsg, const std::string &aLongOpt, char aShortOpt, bool aWarnOnDuplicate=true)
Simple option adding function, with short option (flag only; no values allowed)
bool ProcessCommandLine(int argC, char **argV)
const std::string & GetConfigFilename() const
Return the file name provided by the user on the command line for the config file.
const std::string & GetCommandLineJSON() const
Return the string of json provided by the user on the command line.
Abstract base class for event loops.
Definition: KTEventLoop.hh:22
void RemoveEventLoop(KTEventLoop *loop)
Adds loop to the set of event loops overseen by KTApplication. Does NOT assume ownership of an event ...
Parses and stores command-line options.
void Merge(const scarab::param_node &aNode)
virtual bool Configure(const scarab::param_node &node)
Should perform parameter store and command-line configurations.
bool DelayedCommandLineProcessing()
Parses the remaining command line options (those that weren&#39;t parsed during the InitialCommandLinePro...
KTLOGGER(applog, "KTApplication")
std::string fConfigFilename
Contains KTApplication.
KTCommandLineHandler * fCLHandler
Removes loop from the set of event loops overseen by KTApplication. Does not stop the loop...
std::set< KTEventLoop *> fEventLoops
bool FinalizeNewOptionGroups()
Adds the groups of options to the set of usable options groups (note: this must be called to make the...
KTConfigurator * fConfigurator
Contains the logger class and macros, based on Kasper&#39;s KLogger class.
void AddConfigOptionsToCLHandler(const scarab::param &param, const std::string &rootName)
void AddEventLoop(KTEventLoop *loop)
scarab::param_node & Config()