bes  Updated for version 3.20.6
BESContainerStorageVolatile.cc
1 // BESContainerStorageVolatile.cc
2 
3 // This file is part of bes, A C++ back-end server implementation framework
4 // for the OPeNDAP Data Access Protocol.
5 
6 // Copyright (c) 2004-2009 University Corporation for Atmospheric Research
7 // Author: Patrick West <pwest@ucar.edu> and Jose Garcia <jgarcia@ucar.edu>
8 //
9 // This library is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU Lesser General Public
11 // License as published by the Free Software Foundation; either
12 // version 2.1 of the License, or (at your option) any later version.
13 //
14 // This library is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 // Lesser General Public License for more details.
18 //
19 // You should have received a copy of the GNU Lesser General Public
20 // License along with this library; if not, write to the Free Software
21 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 //
23 // You can contact University Corporation for Atmospheric Research at
24 // 3080 Center Green Drive, Boulder, CO 80301
25 
26 // (c) COPYRIGHT University Corporation for Atmospheric Research 2004-2005
27 // Please read the full copyright statement in the file COPYRIGHT_UCAR.
28 //
29 // Authors:
30 // pwest Patrick West <pwest@ucar.edu>
31 // jgarcia Jose Garcia <jgarcia@ucar.edu>
32 
33 #include "BESContainerStorageVolatile.h"
34 #include "BESFileContainer.h"
35 #include "BESInternalError.h"
36 #include "BESSyntaxUserError.h"
37 #include "BESInfo.h"
38 #include "TheBESKeys.h"
39 #include "BESUtil.h"
40 #include "BESServiceRegistry.h"
41 #include "BESDebug.h"
42 
43 using std::endl;
44 using std::string;
45 using std::list;
46 using std::ostream;
47 
63  BESContainerStorage(n), _root_dir(""), _follow_sym_links(false)
64 {
65  string key = "BES.Data.RootDirectory";
66  bool found = false;
67  TheBESKeys::TheKeys()->get_value(key, _root_dir, found);
68  if (_root_dir == "") {
69  string s = key + " not defined in BES configuration file";
70  throw BESSyntaxUserError(s, __FILE__, __LINE__);
71  }
72 
73  found = false;
74  key = (string) "BES.FollowSymLinks";
75  string s_str;
76  TheBESKeys::TheKeys()->get_value(key, s_str, found);
77  s_str = BESUtil::lowercase(s_str);
78  if (found && (s_str == "yes" || s_str == "on" || s_str == "true")) {
79  _follow_sym_links = true;
80  }
81 }
82 
83 BESContainerStorageVolatile::~BESContainerStorageVolatile()
84 {
86 }
87 
99 {
100  BESContainer *ret_container = 0;
101 
102  BESContainerStorageVolatile::Container_citer i;
103  i = _container_list.find(sym_name);
104  if (i != _container_list.end()) {
105  BESContainer *c = (*i).second;
106  ret_container = c->ptr_duplicate();
107  }
108 
109  return ret_container;
110 }
111 
128 void BESContainerStorageVolatile::add_container(const string &sym_name, const string &real_name, const string &type)
129 {
130  // The type must be specified so that we can find the request handler
131  // that knows how to handle the container.
132  // Changed sym_name to real_name to make the message clearer. jhrg 11/14/19
133  if (type.empty())
134  throw BESInternalError(string("Unable to add container '").append(real_name).append("', type of data must be specified"), __FILE__, __LINE__);
135 
136  // if the container already exists then throw an error
137  BESContainerStorageVolatile::Container_citer i = _container_list.find(sym_name);
138  if (i != _container_list.end()) {
139  throw BESInternalError(string("A container with the name '").append(sym_name).append("' already exists"), __FILE__, __LINE__);
140  }
141 
142  // make sure that the path to the container exists. If follow_sym_links
143  // is false and there is a symbolic link in the path then an error will
144  // be thrown. If the path does not exist, an error will be thrown.
145  BESUtil::check_path(real_name, _root_dir, _follow_sym_links);
146 
147  // add the root directory to the real_name passed
148  string fully_qualified_real_name = BESUtil::assemblePath(_root_dir, real_name, false);
149 
150  BESDEBUG("container","BESContainerStorageVolatile::add_container() - "
151  << " _root_dir: " << _root_dir
152  << " real_name: " << real_name
153  << " symbolic name: " << sym_name
154  << " fully_qualified_real_name: " << fully_qualified_real_name
155  << " type: " << type
156  << endl);
157 
158  // Create the file container with the new information
159  BESContainer *c = new BESFileContainer(sym_name, fully_qualified_real_name, type);
160  c->set_relative_name(real_name);
161 
162  // add it to the container list
163  _container_list[sym_name] = c;
164 }
165 
184 {
185  if (!c) {
186  throw BESInternalError("Unable to add container, container passed is null", __FILE__, __LINE__);
187  }
188  if (c->get_container_type().empty()) {
189  throw BESInternalError("Unable to add container, type of data must be specified", __FILE__, __LINE__);
190  }
191 
192  string sym_name = c->get_symbolic_name();
193 
194  BESContainerStorageVolatile::Container_citer i = _container_list.find(sym_name);
195  if (i != _container_list.end()) {
196  throw BESInternalError(string("A container with the name '").append(sym_name).append("' already exists"), __FILE__, __LINE__);
197  }
198 
199  _container_list[sym_name] = c;
200 }
201 
209 {
210  bool ret = false;
211  BESContainerStorageVolatile::Container_iter i = _container_list.find(s_name);
212  if (i != _container_list.end()) {
213  BESContainer *c = (*i).second;
214  _container_list.erase(i);
215  if (c) {
216  delete c;
217  }
218  ret = true;
219  }
220  return ret;
221 }
222 
231 {
232  while (_container_list.size() != 0) {
233  Container_iter ci = _container_list.begin();
234  BESContainer *c = (*ci).second;
235  _container_list.erase(ci);
236  if (c) {
237  delete c;
238  }
239  }
240  return true;
241 }
242 
250 bool BESContainerStorageVolatile::isData(const string &inQuestion, list<string> &provides)
251 {
252  bool isit = false;
253  BESContainer *c = look_for(inQuestion);
254  if (c) {
255  isit = true;
256  string node_type = c->get_container_type();
257  BESServiceRegistry::TheRegistry()->services_handled(node_type, provides);
258  }
259  return isit;
260 }
261 
277 {
278  info.add_tag("name", get_name());
279  string::size_type root_len = _root_dir.length();
280  BESContainerStorageVolatile::Container_iter i = _container_list.begin();
281  BESContainerStorageVolatile::Container_iter e = _container_list.end();
282  for (; i != e; i++) {
283  BESContainer *c = (*i).second;
284  string sym = c->get_symbolic_name();
285  string real = c->get_real_name();
286  if (real.length() > root_len) {
287  if (real.compare(0, root_len, _root_dir) == 0) {
288  real = real.substr(root_len, real.length() - root_len);
289  }
290  }
291  string type = c->get_container_type();
292  show_container(sym, real, type, info);
293  }
294 }
295 
303 void BESContainerStorageVolatile::dump(ostream &strm) const
304 {
305  strm << BESIndent::LMarg << "BESContainerStorageVolatile::dump - (" << (void *) this << ")" << endl;
306  BESIndent::Indent();
307  strm << BESIndent::LMarg << "name: " << get_name() << endl;
308  if (_container_list.size()) {
309  strm << BESIndent::LMarg << "containers:" << endl;
310  BESIndent::Indent();
311  BESContainerStorageVolatile::Container_citer i = _container_list.begin();
312  BESContainerStorageVolatile::Container_citer ie = _container_list.end();
313  for (; i != ie; i++) {
314  BESContainer *c = (*i).second;
315  c->dump(strm);
316  }
317  BESIndent::UnIndent();
318  }
319  else {
320  strm << BESIndent::LMarg << "containers: none" << endl;
321  }
322  BESIndent::UnIndent();
323 }
324 
BESServiceRegistry::services_handled
virtual void services_handled(const std::string &handler, std::list< std::string > &services)
returns the list of servies provided by the handler in question
Definition: BESServiceRegistry.cc:334
BESContainerStorageVolatile::isData
virtual bool isData(const std::string &inQuestion, std::list< std::string > &provides)
determine if the given container is data and what servies are available for it
Definition: BESContainerStorageVolatile.cc:250
BESContainerStorage
provides persistent storage for data storage information represented by a container.
Definition: BESContainerStorage.h:67
BESContainerStorageVolatile::dump
virtual void dump(std::ostream &strm) const
dumps information about this object
Definition: BESContainerStorageVolatile.cc:303
BESFileContainer
Holds real data, container type and constraint for symbolic name read from persistence.
Definition: BESFileContainer.h:56
BESContainer::ptr_duplicate
virtual BESContainer * ptr_duplicate()=0
pure abstract method to duplicate this instances of BESContainer
BESContainerStorageVolatile::add_container
virtual void add_container(BESContainer *c)
add the passed container to the list of containers in volatile storage
Definition: BESContainerStorageVolatile.cc:183
BESContainer::get_container_type
std::string get_container_type() const
retrieve the type of data this container holds, such as cedar or netcdf.
Definition: BESContainer.h:232
BESContainer::get_symbolic_name
std::string get_symbolic_name() const
retrieve the symbolic name for this container
Definition: BESContainer.h:221
BESUtil::check_path
static void check_path(const std::string &path, const std::string &root, bool follow_sym_links)
Check if the specified path is valid.
Definition: BESUtil.cc:254
BESInfo
informational response object
Definition: BESInfo.h:63
BESContainerStorageVolatile::look_for
virtual BESContainer * look_for(const std::string &sym_name)
looks for the specified container using the symbolic name passed
Definition: BESContainerStorageVolatile.cc:98
BESContainerStorageVolatile::del_containers
virtual bool del_containers()
removes all container
Definition: BESContainerStorageVolatile.cc:230
BESUtil::assemblePath
static std::string assemblePath(const std::string &firstPart, const std::string &secondPart, bool leadingSlash=false, bool trailingSlash=false)
Assemble path fragments making sure that they are separated by a single '/' character.
Definition: BESUtil.cc:821
BESContainerStorage::get_name
virtual const std::string & get_name() const
retrieve the name of this persistent store
Definition: BESContainerStorage.h:91
TheBESKeys::TheKeys
static TheBESKeys * TheKeys()
Definition: TheBESKeys.cc:62
BESSyntaxUserError
error thrown if there is a user syntax error in the request or any other user error
Definition: BESSyntaxUserError.h:41
BESInternalError
exception thrown if internal error encountered
Definition: BESInternalError.h:43
BESContainerStorage::show_container
virtual void show_container(const std::string &sym_name, const std::string &real_name, const std::string &type, BESInfo &info)
add information for a container to the informational response object
Definition: BESContainerStorage.cc:48
TheBESKeys::get_value
void get_value(const std::string &s, std::string &val, bool &found)
Retrieve the value of a given key, if set.
Definition: TheBESKeys.cc:272
BESContainerStorageVolatile::BESContainerStorageVolatile
BESContainerStorageVolatile(const std::string &n)
create an instance of this persistent store with the given name.
Definition: BESContainerStorageVolatile.cc:62
BESContainerStorageVolatile::show_containers
virtual void show_containers(BESInfo &info)
show information for each container in this persistent store
Definition: BESContainerStorageVolatile.cc:276
BESContainer
A container is something that holds data. E.G., a netcdf file or a database entry.
Definition: BESContainer.h:65
BESContainerStorageVolatile::del_container
virtual bool del_container(const std::string &s_name)
removes a container with the given symbolic name from the list and deletes it.
Definition: BESContainerStorageVolatile.cc:208
BESContainer::get_real_name
std::string get_real_name() const
retrieve the real name for this container, such as a file name.
Definition: BESContainer.h:180
BESUtil::lowercase
static std::string lowercase(const std::string &s)
Definition: BESUtil.cc:200
BESContainer::set_relative_name
void set_relative_name(const std::string &relative)
Set the relative name of the object in this container.
Definition: BESContainer.h:152
BESContainer::dump
virtual void dump(std::ostream &strm) const
dumps information about this object
Definition: BESContainer.cc:73