0.9.8.10
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
ToJson.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2007-2015 Hypertable, Inc.
3  *
4  * This file is part of Hypertable.
5  *
6  * Hypertable is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; version 3 of the
9  * License, or any later version.
10  *
11  * Hypertable is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19  * 02110-1301, USA.
20  */
21 
26 
27 #include <Common/Compat.h>
28 
29 #include "ToJson.h"
30 #include "Tokenizer.h"
31 
32 #include <Common/FileUtils.h>
34 #include <Common/Logger.h>
35 #include <Common/String.h>
36 #include <Common/System.h>
37 #include <Common/Version.h>
38 
39 #include <boost/algorithm/string.hpp>
40 #include <boost/tokenizer.hpp>
41 
42 #include <cctype>
43 #include <cerrno>
44 #include <cstdlib>
45 #include <ctime>
46 #include <fstream>
47 #include <iostream>
48 #include <map>
49 #include <set>
50 #include <stack>
51 #include <string>
52 #include <vector>
53 
54 extern "C" {
55 #include <netdb.h>
56 #include <pwd.h>
57 #include <strings.h>
58 #include <sys/stat.h>
59 #include <sys/types.h>
60 #include <unistd.h>
61 }
62 
63 #if defined(__APPLE__)
64 extern char **environ;
65 #endif
66 
67 using namespace Hypertable;
68 using namespace Hypertable::ClusterDefinitionFile;
69 using namespace std;
70 
71 namespace {
72 
73  class Node {
74  public:
75  Node(const string &n) : name(n) {}
76  string name;
77  set<string> roles;
78  };
79 
80  class Definition {
81  public:
82  void add_role(const string &text) {
83  const char *base = text.c_str();
84  const char *ptr;
85  for (ptr=base; *ptr && !isspace(*ptr); ptr++)
86  ;
87  string token(base, ptr-base);
88  boost::trim(token);
89  if (strcasecmp(token.c_str(), "role:"))
90  HT_THROWF(Error::SYNTAX_ERROR, "Mal-formed role definition: %s", text.c_str());
91  while (*ptr && isspace(*ptr))
92  ptr++;
93  base = ptr;
94  while (*ptr && !isspace(*ptr))
95  ptr++;
96  string name(base, ptr-base);
97  boost::trim(name);
98  if (name.empty())
99  HT_THROWF(Error::SYNTAX_ERROR, "Mal-formed role definition: %s", text.c_str());
100  string input(ptr);
101  string value;
102 
103  boost::char_separator<char> sep(" \t\n\r");
104  boost::tokenizer< boost::char_separator<char> > tokens(input, sep);
105  for (auto &t : tokens)
106  value += t + " ";
107  boost::trim(value);
108 
109  m_roles[name] = value;
110 
111  if (!m_uber_hostspec.empty())
112  m_uber_hostspec += " + ";
113  m_uber_hostspec += "(" + value + ")";
114  }
115 
116  string to_json() {
117  map<string, Node *> node_map;
118 
119  // Populate m_nodes and node_map
120  vector<string> nodes = HostSpecification(m_uber_hostspec);
121  m_nodes.reserve(nodes.size());
122  for (auto & node : nodes) {
123  m_nodes.push_back(make_unique<Node>(node));
124  node_map[node] = m_nodes.back().get();
125  }
126 
127  bool first {};
128  string str = "{\n";
129 
130  // roles
131  {
132  first = true;
133  str += " \"roles\": {\n";
134  for (auto entry : m_roles) {
135  if (!first)
136  str += ",\n";
137  else
138  first = false;
139  str += " \"" + entry.first + "\": \"" + entry.second + "\"";
140  vector<string> nodes = HostSpecification(entry.second);
141  for (auto & node : nodes)
142  node_map[node]->roles.insert(entry.first);
143  }
144  str += "\n },\n";
145  }
146 
147  // nodes
148  first = true;
149  str += " \"nodes\": [\n";
150  for (auto & node : m_nodes) {
151  if (!first)
152  str += ",\n";
153  else
154  first = false;
155  struct hostent *hent = gethostbyname(node->name.c_str());
156  str.append(" { \"hostname\": \"");
157  str.append((const char *)(hent->h_name));
158  str.append("\", \"roles\": [");
159  bool first2 {true};
160  for (auto & role : node->roles) {
161  if (first2)
162  first2 = false;
163  else
164  str += ", ";
165  str += "\"" + role + "\"";
166  }
167  str += "] }";
168  }
169  str += "\n ]\n";
170 
171  str += "}";
172  return str;
173  }
174 
175  private:
176  string m_uber_hostspec;
177  map<string, string> m_roles;
178  vector<unique_ptr<Node>> m_nodes;
179  };
180 
181 }
182 
183 
184 ToJson::ToJson(const string &fname) : m_definition_file(fname) {
185 
186  // Create map of environment variables
187  map<string, string> environ_map;
188  for (size_t i=0; environ[i]; i++) {
189  const char *ptr = strchr(environ[i], '=');
190  HT_ASSERT(ptr);
191  environ_map[string(environ[i], ptr-environ[i])] = string(ptr+1);
192  }
193 
194  stack<TokenizerPtr> definitions;
195 
196  definitions.push( make_shared<Tokenizer>(m_definition_file) );
197 
198  Token token;
199  Definition def;
200 
201  while (!definitions.empty()) {
202  while (definitions.top()->next(token)) {
203  if (token.type == Token::ROLE)
204  def.add_role(token.text);
205  }
206  definitions.pop();
207  }
208 
209  m_str = def.to_json();
210 }
211 
Retrieves system information (hardware, installation directory, etc)
Declarations for HostSpecification.
Converts host specification pattern to list of host names.
Po::typed_value< String > * str(String *v=0)
Definition: Properties.h:166
STL namespace.
Declarations for ToJson.
Cluster definition file token.
Definition: Token.h:43
#define HT_ASSERT(_e_)
Definition: Logger.h:396
File system utility functions.
Logging routines and macros.
Compatibility Macros for C/C++.
string m_definition_file
Cluster definition file.
Definition: ToJson.h:67
Hypertable definitions
#define HT_THROWF(_code_, _fmt_,...)
Definition: Error.h:490
string m_str
Output JSON string.
Definition: ToJson.h:70
A String class based on std::string.
ToJson(const string &fname)
Constructor.
Definition: ToJson.cc:184
Declarations for Tokenizer.
Cluster definition file translation definitions.
Definition: Compiler.h:35