bes  Updated for version 3.17.4
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 
51  BESContainerStorage(n), _root_dir(""), _follow_sym_links(false)
52 {
53  string key = "BES.Data.RootDirectory";
54  bool found = false;
55  TheBESKeys::TheKeys()->get_value(key, _root_dir, found);
56  if (_root_dir == "") {
57  string s = key + " not defined in BES configuration file";
58  throw BESSyntaxUserError(s, __FILE__, __LINE__);
59  }
60 
61  found = false;
62  key = (string) "BES.FollowSymLinks";
63  string s_str;
64  TheBESKeys::TheKeys()->get_value(key, s_str, found);
65  s_str = BESUtil::lowercase(s_str);
66  if (found && (s_str == "yes" || s_str == "on" || s_str == "true")) {
67  _follow_sym_links = true;
68  }
69 }
70 
71 BESContainerStorageVolatile::~BESContainerStorageVolatile()
72 {
74 }
75 
87 {
88  BESContainer *ret_container = 0;
89 
90  BESContainerStorageVolatile::Container_citer i;
91  i = _container_list.find(sym_name);
92  if (i != _container_list.end()) {
93  BESContainer *c = (*i).second;
94  ret_container = c->ptr_duplicate();
95  }
96 
97  return ret_container;
98 }
99 
115 void BESContainerStorageVolatile::add_container(const string &sym_name, const string &real_name, const string &type)
116 {
117  BESDEBUG( "bes", "BESContainerStorageVolatile::add_container() - "
118  << "Adding container with name \"" << sym_name
119  << "\", real name \"" << real_name
120  << "\", type \"" << type << "\"" << endl );
121 
122  // The type must be specified so that we can find the request handler
123  // that knows how to handle the container.
124  if (type == "") {
125  string s = "Unable to add container, type of data must be specified";
126  throw BESInternalError(s, __FILE__, __LINE__);
127  }
128 
129  // if the container already exists then throw an error
130  BESContainerStorageVolatile::Container_citer i;
131  i = _container_list.find(sym_name);
132  if (i != _container_list.end()) {
133  string s = (string) "A container with the name " + sym_name + " already exists";
134  throw BESInternalError(s, __FILE__, __LINE__);
135  }
136 #if 1
137  // NB: I added the #if 1 ... endif to test _not_ making this check while
138  // working with the jgofs code. It was just a hack, but I needed to
139  // toggle it several times. jhrg 3/6/13
140 
141  // make sure that the path to the container exists. If follow_sym_links
142  // is false and there is a symbolic link in the path then an error will
143  // be thrown. If the path does not exist, an error will be thrown.
144  BESUtil::check_path(real_name, _root_dir, _follow_sym_links);
145 #endif
146  // add the root directory to the real_name passed
147  string new_r_name = BESUtil::assemblePath(_root_dir,real_name, false);
148  BESDEBUG("container","BESContainerStorageVolatile::add_container() - "
149  << " _root_dir: " << _root_dir
150  << " real_name: " << real_name
151  << " new_r_name: " << new_r_name
152  << endl);
153 
154  // Create the file container with the new information
155  BESContainer *c = new BESFileContainer(sym_name, new_r_name, type);
156 
157  // add it to the container list
158  _container_list[sym_name] = c;
159 }
160 
179 {
180  if (!c) {
181  string s = "Unable to add container, container passed is null";
182  throw BESInternalError(s, __FILE__, __LINE__);
183  }
184  if (c->get_container_type() == "") {
185  string s = "Unable to add container, type of data must be specified";
186  throw BESInternalError(s, __FILE__, __LINE__);
187  }
188  string sym_name = c->get_symbolic_name();
189  BESContainerStorageVolatile::Container_citer i;
190  i = _container_list.find(sym_name);
191  if (i != _container_list.end()) {
192  string s = (string) "A container with the name " + sym_name + " already exists";
193  throw BESInternalError(s, __FILE__, __LINE__);
194  }
195  _container_list[sym_name] = c;
196 }
197 
205 {
206  bool ret = false;
207  BESContainerStorageVolatile::Container_iter i;
208  i = _container_list.find(s_name);
209  if (i != _container_list.end()) {
210  BESContainer *c = (*i).second;
211  _container_list.erase(i);
212  if (c) {
213  delete c;
214  }
215  ret = true;
216  }
217  return ret;
218 }
219 
228 {
229  while (_container_list.size() != 0) {
230  Container_iter ci = _container_list.begin();
231  BESContainer *c = (*ci).second;
232  _container_list.erase(ci);
233  if (c) {
234  delete c;
235  }
236  }
237  return true;
238 }
239 
247 bool BESContainerStorageVolatile::isData(const string &inQuestion, list<string> &provides)
248 {
249  bool isit = false;
250  BESContainer *c = look_for(inQuestion);
251  if (c) {
252  isit = true;
253  string node_type = c->get_container_type();
254  BESServiceRegistry::TheRegistry()->services_handled(node_type, provides);
255  }
256  return isit;
257 }
258 
274 {
275  info.add_tag("name", get_name());
276  string::size_type root_len = _root_dir.length();
277  BESContainerStorageVolatile::Container_iter i = _container_list.begin();
278  BESContainerStorageVolatile::Container_iter e = _container_list.end();
279  for (; i != e; i++) {
280  BESContainer *c = (*i).second;
281  string sym = c->get_symbolic_name();
282  string real = c->get_real_name();
283  if (real.length() > root_len) {
284  if (real.compare(0, root_len, _root_dir) == 0) {
285  real = real.substr(root_len, real.length() - root_len);
286  }
287  }
288  string type = c->get_container_type();
289  show_container(sym, real, type, info);
290  }
291 }
292 
300 void BESContainerStorageVolatile::dump(ostream &strm) const
301 {
302  strm << BESIndent::LMarg << "BESContainerStorageVolatile::dump - (" << (void *) this << ")" << endl;
303  BESIndent::Indent();
304  strm << BESIndent::LMarg << "name: " << get_name() << endl;
305  if (_container_list.size()) {
306  strm << BESIndent::LMarg << "containers:" << endl;
307  BESIndent::Indent();
308  BESContainerStorageVolatile::Container_citer i = _container_list.begin();
309  BESContainerStorageVolatile::Container_citer ie = _container_list.end();
310  for (; i != ie; i++) {
311  BESContainer *c = (*i).second;
312  c->dump(strm);
313  }
314  BESIndent::UnIndent();
315  }
316  else {
317  strm << BESIndent::LMarg << "containers: none" << endl;
318  }
319  BESIndent::UnIndent();
320 }
321 
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:186
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.
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 &#39;/&#39; character.
Definition: BESUtil.cc:754
virtual void show_containers(BESInfo &info)
show information for each container in this persistent store
informational response object
Definition: BESInfo.h:68
virtual bool del_container(const string &s_name)
removes a container with the given symbolic name from the list and deletes it.
void get_value(const string &s, string &val, bool &found)
Retrieve the value of a given key, if set.
Definition: BESKeys.cc:483
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:239
static BESKeys * TheKeys()
Definition: TheBESKeys.cc:43
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