0.9.8.10
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Client.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 
22 #include <Common/Compat.h>
23 
24 #include "Client.h"
25 #include "Master/NamespaceFlag.h"
26 
27 #include <Hypertable/Lib/Config.h>
30 
31 #include <Hyperspace/DirEntry.h>
32 #include <Hypertable/Lib/Config.h>
33 
35 #include <AsyncComm/Comm.h>
37 
38 #include <Common/Init.h>
39 #include <Common/Error.h>
40 #include <Common/InetAddr.h>
41 #include <Common/Logger.h>
42 #include <Common/ScopeGuard.h>
43 #include <Common/System.h>
44 #include <Common/Timer.h>
45 
46 #include <boost/algorithm/string.hpp>
47 
48 #include <cassert>
49 #include <cstdlib>
50 
51 extern "C" {
52 #include <poll.h>
53 }
54 
55 using namespace std;
56 using namespace Hypertable;
57 using namespace Hyperspace;
58 using namespace Config;
59 
60 Client::Client(const string &install_dir, const string &config_file,
61  uint32_t default_timeout_ms)
62  : m_timeout_ms(default_timeout_ms), m_install_dir(install_dir) {
63  lock_guard<recursive_mutex> lock(rec_mutex);
64 
65  if (!properties)
66  init_with_policy<DefaultCommPolicy>(0, 0);
67 
68  m_props = make_shared<Properties>(config_file, file_desc());
69  initialize();
70 }
71 
72 Client::Client(const string &install_dir, uint32_t default_timeout_ms)
73  : m_timeout_ms(default_timeout_ms), m_install_dir(install_dir) {
74  lock_guard<recursive_mutex> lock(rec_mutex);
75 
76  if (!properties)
77  init_with_policy<DefaultCommPolicy>(0, 0);
78 
79  if (m_install_dir.empty())
81 
83  initialize();
84 }
85 
86 void Client::create_namespace(const string &name, Namespace *base, bool create_intermediate, bool if_not_exists) {
87 
88  string full_name;
89  string sub_name = name;
90  int flags=0;
91 
92  if (create_intermediate)
94  if (if_not_exists)
96 
97  if (base != NULL) {
98  full_name = base->get_name() + '/';
99  }
100  full_name += sub_name;
101 
102  Namespace::canonicalize(&full_name);
103  m_master_client->create_namespace(full_name, flags);
104 }
105 
106 NamespacePtr Client::open_namespace(const string &name, Namespace *base) {
107  string full_name;
108  string sub_name = name;
109 
110  Namespace::canonicalize(&sub_name);
111 
112  if (base != NULL) {
113  full_name = base->get_name() + '/';
114  }
115 
116  full_name += sub_name;
117 
118  return m_namespace_cache->get(full_name);
119 }
120 
121 bool Client::exists_namespace(const string &name, Namespace *base) {
122  string id;
123  bool is_namespace = false;
124  string full_name;
125  string sub_name = name;
126 
127  Namespace::canonicalize(&sub_name);
128 
129  if (base != NULL) {
130  full_name = base->get_name() + '/';
131  }
132 
133  full_name += sub_name;
134 
135  if (!m_namemap->name_to_id(full_name, id, &is_namespace) || !is_namespace)
136  return false;
137 
138  // TODO: issue 11
139 
140  string namespace_file = m_toplevel_dir + "/tables/" + id;
141 
142  try {
143  return m_hyperspace->exists(namespace_file);
144  }
145  catch(Exception &e) {
146  HT_THROW(e.code(), e.what());
147  }
148 }
149 
150 void Client::drop_namespace(const string &name, Namespace *base, bool if_exists) {
151  string full_name;
152  string sub_name = name;
153 
154  Namespace::canonicalize(&sub_name);
155 
156  if (sub_name == "tmp" || sub_name == "sys")
158  "Dropping system namespace /%s is not allowed", sub_name.c_str());
159 
160  if (base != NULL) {
161  full_name = base->get_name() + '/';
162  }
163 
164  full_name += sub_name;
165 
166  m_namespace_cache->remove(full_name);
167  int32_t flags = if_exists ? Lib::Master::NamespaceFlag::IF_EXISTS : 0;
168  m_master_client->drop_namespace(full_name, flags);
169 }
170 
172 {
173  return m_hyperspace;
174 }
175 
177  return m_master_client;
178 }
179 
181  return m_namemap;
182 }
183 
185  HT_WARN("close() is no longer supported");
186 }
187 
189  m_master_client->shutdown();
190 }
191 
192 
193 HqlInterpreter *Client::create_hql_interpreter(bool immutable_namespace) {
194  return new HqlInterpreter(this, this->m_conn_manager, immutable_namespace);
195 }
196 
197 // ------------- PRIVATE METHODS -----------------
199  uint32_t wait_time, remaining;
200  uint32_t interval=5000;
201 
202  m_toplevel_dir = m_props->get_str("Hypertable.Directory");
203  boost::trim_if(m_toplevel_dir, boost::is_any_of("/"));
205 
207  m_conn_manager = make_shared<ConnectionManager>(m_comm);
208 
209  if (m_timeout_ms == 0)
210  m_timeout_ms = m_props->get_i32("Hypertable.Request.Timeout");
211 
212  m_hyperspace_reconnect = m_props->get_bool("Hyperspace.Session.Reconnect");
213 
214  m_hyperspace = make_shared<Hyperspace::Session>(m_comm, m_props);
215 
216  Timer timer(m_timeout_ms, true);
217 
218  remaining = timer.remaining();
219  wait_time = (remaining < interval) ? remaining : interval;
220 
221  while (!m_hyperspace->wait_for_connection(wait_time)) {
222 
223  if (timer.expired())
225 
226  cout << "Waiting for connection to Hyperspace..." << endl;
227 
228  remaining = timer.remaining();
229  wait_time = (remaining < interval) ? remaining : interval;
230  }
231 
232  // Initialize cluster ID from Hyperspace, enabling ClusterId::get()
233  ClusterId cluster_id(m_hyperspace);
234 
235  m_namemap = make_shared<NameIdMapper>(m_hyperspace, m_toplevel_dir);
236 
237  m_app_queue =
238  make_shared<ApplicationQueue>(m_props->get_i32("Hypertable.Client.Workers"));
239 
241  make_shared<Lib::Master::Client>(m_conn_manager, m_hyperspace, m_toplevel_dir,
244 
245  if (!m_master_client->wait_for_connection(timer))
246  HT_THROW(Error::REQUEST_TIMEOUT, "Waiting for Master connection");
247 
249  make_shared<RangeLocator>(m_props, m_conn_manager,
251 
252  m_table_cache =
253  make_shared<TableCache>(m_props, m_range_locator, m_conn_manager,
255  m_timeout_ms);
256 
258  make_shared<NamespaceCache>(m_props, m_range_locator, m_conn_manager, m_hyperspace,
260  m_table_cache, m_timeout_ms, this);
261 }
static Comm * instance()
Creates/returns singleton instance of the Comm class.
Definition: Comm.h:72
Retrieves system information (hardware, installation directory, etc)
uint32_t m_timeout_ms
Definition: Client.h:148
RangeLocatorPtr m_range_locator
Definition: Client.h:147
NameIdMapperPtr get_nameid_mapper()
Definition: Client.cc:180
void drop_namespace(const std::string &name, Namespace *base=NULL, bool if_exists=false)
Removes a namespace.
Definition: Client.cc:150
NamespacePtr open_namespace(const std::string &name, Namespace *base=NULL)
Opens a Namespace.
Definition: Client.cc:106
NameIdMapperPtr m_namemap
Definition: Client.h:145
HqlInterpreter * create_hql_interpreter(bool immutable_namespace=true)
Definition: Client.cc:193
PropertiesPtr properties
This singleton map stores all options.
Definition: Config.cc:47
std::string String
A String is simply a typedef to std::string.
Definition: String.h:44
Lib::Master::ClientPtr m_master_client
Definition: Client.h:146
bool exists_namespace(const std::string &name, Namespace *base=NULL)
Checks if the namespace exists.
Definition: Client.cc:121
STL namespace.
static void canonicalize(String *original)
Get canonical format of name/id string.
Definition: Namespace.cc:84
ApplicationQueueInterfacePtr m_app_queue
Definition: Client.h:143
Client(const std::string &install_dir, const std::string &config_file, uint32_t default_timeout_ms=0)
Constructs the object using the specified config file.
Definition: Client.cc:60
Provides access to the cluster ID.
Definition: ClusterId.h:45
Hyperspace definitions
std::shared_ptr< Namespace > NamespacePtr
Shared smart pointer to Namespace.
Definition: Namespace.h:333
std::shared_ptr< Client > ClientPtr
Definition: Client.h:156
Hyperspace::SessionPtr m_hyperspace
Definition: Client.h:144
std::string m_install_dir
Definition: Client.h:149
Perform operation if namespace does not exist.
Definition: NamespaceFlag.h:49
std::shared_ptr< Session > SessionPtr
Definition: Session.h:734
TableCachePtr m_table_cache
Definition: Client.h:150
The API of HQL interpreter.
A timer class to keep timeout states across AsyncComm related calls.
Logging routines and macros.
void initialize()
Definition: Client.cc:198
Desc & file_desc(const char *usage)
Get the config file options description.
Definition: Config.cc:108
Compatibility Macros for C/C++.
Declarations for NamespaceFlag.
Initialization helper for applications.
PropertiesPtr m_props
Definition: Client.h:140
#define HT_THROW_(_code_)
Definition: Error.h:481
std::string m_toplevel_dir
Definition: Client.h:153
Hypertable definitions
Declarations for HqlCommandInterpreter.
Perform operation if namespace exists.
Definition: NamespaceFlag.h:47
Hyperspace::SessionPtr & get_hyperspace_session()
Definition: Client.cc:171
Declarations for Comm.
std::recursive_mutex rec_mutex
A global (recursive) configuration mutex.
Definition: Config.cc:46
#define HT_THROWF(_code_, _fmt_,...)
Definition: Error.h:490
void create_namespace(const std::string &name, Namespace *base=NULL, bool create_intermediate=false, bool if_not_exists=false)
Creates a namespace.
Definition: Client.cc:86
Internet address wrapper classes and utility functions.
Declarations for ReactorFactory.
A timer class to keep timeout states across AsyncComm related calls.
Definition: Timer.h:44
static String install_dir
The installation directory.
Definition: System.h:114
This is a generic exception class for Hypertable.
Definition: Error.h:314
std::shared_ptr< DispatchHandler > DispatchHandlerPtr
Smart pointer to DispatchHandler.
const std::string & get_name() const
Definition: Namespace.h:78
bool m_hyperspace_reconnect
Definition: Client.h:152
Declarations for ApplicationQueue.
#define HT_WARN(msg)
Definition: Logger.h:289
std::shared_ptr< ConnectionInitializer > ConnectionInitializerPtr
Smart pointer to ConnectionInitializer.
std::shared_ptr< NameIdMapper > NameIdMapperPtr
Smart pointer to NameIdMapper.
Definition: NameIdMapper.h:121
Error codes, Exception handling, error logging.
#define HT_THROW(_code_, _msg_)
Definition: Error.h:478
Declarations for ClusterId.
NamespaceCachePtr m_namespace_cache
Definition: Client.h:151
ConnectionManagerPtr m_conn_manager
Definition: Client.h:142
Lib::Master::ClientPtr get_master_client()
Definition: Client.cc:176
int code() const
Returns the error code.
Definition: Error.h:391
Executes user-defined functions when leaving the current scope.