bes  Updated for version 3.19.1
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 
55  BESContainerStorage(n), _root_dir(""), _follow_sym_links(false)
56 {
57  string key = "BES.Data.RootDirectory";
58  bool found = false;
59  TheBESKeys::TheKeys()->get_value(key, _root_dir, found);
60  if (_root_dir == "") {
61  string s = key + " not defined in BES configuration file";
62  throw BESSyntaxUserError(s, __FILE__, __LINE__);
63  }
64 
65  found = false;
66  key = (string) "BES.FollowSymLinks";
67  string s_str;
68  TheBESKeys::TheKeys()->get_value(key, s_str, found);
69  s_str = BESUtil::lowercase(s_str);
70  if (found && (s_str == "yes" || s_str == "on" || s_str == "true")) {
71  _follow_sym_links = true;
72  }
73 }
74 
75 BESContainerStorageVolatile::~BESContainerStorageVolatile()
76 {
78 }
79 
91 {
92  BESContainer *ret_container = 0;
93 
94  BESContainerStorageVolatile::Container_citer i;
95  i = _container_list.find(sym_name);
96  if (i != _container_list.end()) {
97  BESContainer *c = (*i).second;
98  ret_container = c->ptr_duplicate();
99  }
100 
101  return ret_container;
102 }
103 
119 void BESContainerStorageVolatile::add_container(const string &sym_name, const string &real_name, const string &type)
120 {
121  BESDEBUG( "bes", "BESContainerStorageVolatile::add_container() - "
122  << "Adding container with name \"" << sym_name
123  << "\", real name \"" << real_name
124  << "\", type \"" << type << "\"" << endl );
125 
126  // The type must be specified so that we can find the request handler
127  // that knows how to handle the container.
128  if (type == "") {
129  string s = "Unable to add container, type of data must be specified";
130  throw BESInternalError(s, __FILE__, __LINE__);
131  }
132 
133  // if the container already exists then throw an error
134  BESContainerStorageVolatile::Container_citer i;
135  i = _container_list.find(sym_name);
136  if (i != _container_list.end()) {
137  string s = (string) "A container with the name " + sym_name + " already exists";
138  throw BESInternalError(s, __FILE__, __LINE__);
139  }
140 #if 1
141  // NB: I added the #if 1 ... endif to test _not_ making this check while
142  // working with the jgofs code. It was just a hack, but I needed to
143  // toggle it several times. jhrg 3/6/13
144 
145  // make sure that the path to the container exists. If follow_sym_links
146  // is false and there is a symbolic link in the path then an error will
147  // be thrown. If the path does not exist, an error will be thrown.
148  BESUtil::check_path(real_name, _root_dir, _follow_sym_links);
149 #endif
150  // add the root directory to the real_name passed
151  string new_r_name = BESUtil::assemblePath(_root_dir,real_name, false);
152  BESDEBUG("container","BESContainerStorageVolatile::add_container() - "
153  << " _root_dir: " << _root_dir
154  << " real_name: " << real_name
155  << " new_r_name: " << new_r_name
156  << endl);
157 
158  // Create the file container with the new information
159  BESContainer *c = new BESFileContainer(sym_name, new_r_name, type);
160 
161  // add it to the container list
162  _container_list[sym_name] = c;
163 }
164 
183 {
184  if (!c) {
185  string s = "Unable to add container, container passed is null";
186  throw BESInternalError(s, __FILE__, __LINE__);
187  }
188  if (c->get_container_type() == "") {
189  string s = "Unable to add container, type of data must be specified";
190  throw BESInternalError(s, __FILE__, __LINE__);
191  }
192  string sym_name = c->get_symbolic_name();
193  BESContainerStorageVolatile::Container_citer i;
194  i = _container_list.find(sym_name);
195  if (i != _container_list.end()) {
196  string s = (string) "A container with the name " + sym_name + " already exists";
197  throw BESInternalError(s, __FILE__, __LINE__);
198  }
199  _container_list[sym_name] = c;
200 }
201 
209 {
210  bool ret = false;
211  BESContainerStorageVolatile::Container_iter i;
212  i = _container_list.find(s_name);
213  if (i != _container_list.end()) {
214  BESContainer *c = (*i).second;
215  _container_list.erase(i);
216  if (c) {
217  delete c;
218  }
219  ret = true;
220  }
221  return ret;
222 }
223 
232 {
233  while (_container_list.size() != 0) {
234  Container_iter ci = _container_list.begin();
235  BESContainer *c = (*ci).second;
236  _container_list.erase(ci);
237  if (c) {
238  delete c;
239  }
240  }
241  return true;
242 }
243 
251 bool BESContainerStorageVolatile::isData(const string &inQuestion, list<string> &provides)
252 {
253  bool isit = false;
254  BESContainer *c = look_for(inQuestion);
255  if (c) {
256  isit = true;
257  string node_type = c->get_container_type();
258  BESServiceRegistry::TheRegistry()->services_handled(node_type, provides);
259  }
260  return isit;
261 }
262 
278 {
279  info.add_tag("name", get_name());
280  string::size_type root_len = _root_dir.length();
281  BESContainerStorageVolatile::Container_iter i = _container_list.begin();
282  BESContainerStorageVolatile::Container_iter e = _container_list.end();
283  for (; i != e; i++) {
284  BESContainer *c = (*i).second;
285  string sym = c->get_symbolic_name();
286  string real = c->get_real_name();
287  if (real.length() > root_len) {
288  if (real.compare(0, root_len, _root_dir) == 0) {
289  real = real.substr(root_len, real.length() - root_len);
290  }
291  }
292  string type = c->get_container_type();
293  show_container(sym, real, type, info);
294  }
295 }
296 
304 void BESContainerStorageVolatile::dump(ostream &strm) const
305 {
306  strm << BESIndent::LMarg << "BESContainerStorageVolatile::dump - (" << (void *) this << ")" << endl;
307  BESIndent::Indent();
308  strm << BESIndent::LMarg << "name: " << get_name() << endl;
309  if (_container_list.size()) {
310  strm << BESIndent::LMarg << "containers:" << endl;
311  BESIndent::Indent();
312  BESContainerStorageVolatile::Container_citer i = _container_list.begin();
313  BESContainerStorageVolatile::Container_citer ie = _container_list.end();
314  for (; i != ie; i++) {
315  BESContainer *c = (*i).second;
316  c->dump(strm);
317  }
318  BESIndent::UnIndent();
319  }
320  else {
321  strm << BESIndent::LMarg << "containers: none" << endl;
322  }
323  BESIndent::UnIndent();
324 }
325 
provides persistent storage for data storage information represented by a container.
virtual void show_container(const string &sym_name, const string &real_name, const string &type, BESInfo &info)
add information for a container to the informational response object
virtual BESContainer * look_for(const string &sym_name)
looks for the specified container using the symbolic name passed
exception thrown if inernal error encountered
static string lowercase(const string &s)
Definition: BESUtil.cc:189
virtual void dump(ostream &strm) const
dumps information about this object
Definition: BESContainer.cc:68
Holds real data, container type and constraint for symbolic name read from persistence.
void get_value(const string &s, string &val, bool &found)
Retrieve the value of a given key, if set.
Definition: TheBESKeys.cc:422
virtual void dump(ostream &strm) const
dumps information about this object
virtual void add_container(BESContainer *c)
add the passed container to the list of containers in volatile storage
error thrown if there is a user syntax error in the request or any other user error
static string assemblePath(const string &firstPart, const string &secondPart, bool addLeadingSlash=false)
Assemble path fragments making sure that they are separated by a single '/' character.
Definition: BESUtil.cc:757
virtual void show_containers(BESInfo &info)
show information for each container in this persistent store
informational response object
Definition: BESInfo.h:68
static TheBESKeys * TheKeys()
Definition: TheBESKeys.cc:62
virtual bool del_container(const string &s_name)
removes a container with the given symbolic name from the list and deletes it.
BESContainerStorageVolatile(const string &n)
create an instance of this persistent store with the given name.
string get_real_name() const
retrieve the real name for this container, such as a file name.
Definition: BESContainer.h:161
string get_container_type() const
retrieve the type of data this container holds, such as cedar or netcdf.
Definition: BESContainer.h:208
virtual bool del_containers()
removes all container
A container is something that holds data. I.E. a netcdf file or a database entry.
Definition: BESContainer.h:60
static void check_path(const string &path, const string &root, bool follow_sym_links)
Definition: BESUtil.cc:242
virtual const string & get_name() const
retrieve the name of this persistent store
virtual bool isData(const string &inQuestion, list< string > &provides)
determine if the given container is data and what servies are available for it
virtual BESContainer * ptr_duplicate()=0
pure abstract method to duplicate this instances of BESContainer
virtual void services_handled(const string &handler, list< string > &services)
returns the list of servies provided by the handler in question
string get_symbolic_name() const
retrieve the symbolic name for this container
Definition: BESContainer.h:197