OPeNDAP Hyrax Back End Server (BES)  Updated for version 3.8.3
BESContainerStorageVolatile.cc
Go to the documentation of this file.
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 
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 
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 
72 {
74 }
75 
87 {
88  BESContainer *ret_container = 0;
89 
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
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.
145 #endif
146  // add the root directory to the real_name passed
147  string new_r_name = _root_dir + "/" + real_name;
148 
149  // Create the file container with the new information
150  BESContainer *c = new BESFileContainer(sym_name, new_r_name, type);
151 
152  // add it to the container list
153  _container_list[sym_name] = c;
154 }
155 
174 {
175  if (!c) {
176  string s = "Unable to add container, container passed is null";
177  throw BESInternalError(s, __FILE__, __LINE__);
178  }
179  if (c->get_container_type() == "") {
180  string s = "Unable to add container, type of data must be specified";
181  throw BESInternalError(s, __FILE__, __LINE__);
182  }
183  string sym_name = c->get_symbolic_name();
185  i = _container_list.find(sym_name);
186  if (i != _container_list.end()) {
187  string s = (string) "A container with the name " + sym_name + " already exists";
188  throw BESInternalError(s, __FILE__, __LINE__);
189  }
190  _container_list[sym_name] = c;
191 }
192 
200 {
201  bool ret = false;
203  i = _container_list.find(s_name);
204  if (i != _container_list.end()) {
205  BESContainer *c = (*i).second;
206  _container_list.erase(i);
207  if (c) {
208  delete c;
209  }
210  ret = true;
211  }
212  return ret;
213 }
214 
223 {
224  while (_container_list.size() != 0) {
225  Container_iter ci = _container_list.begin();
226  BESContainer *c = (*ci).second;
227  _container_list.erase(ci);
228  if (c) {
229  delete c;
230  }
231  }
232  return true;
233 }
234 
242 bool BESContainerStorageVolatile::isData(const string &inQuestion, list<string> &provides)
243 {
244  bool isit = false;
245  BESContainer *c = look_for(inQuestion);
246  if (c) {
247  isit = true;
248  string node_type = c->get_container_type();
249  BESServiceRegistry::TheRegistry()->services_handled(node_type, provides);
250  }
251  return isit;
252 }
253 
269 {
270  info.add_tag("name", get_name());
271  string::size_type root_len = _root_dir.length();
272  BESContainerStorageVolatile::Container_iter i = _container_list.begin();
273  BESContainerStorageVolatile::Container_iter e = _container_list.end();
274  for (; i != e; i++) {
275  BESContainer *c = (*i).second;
276  string sym = c->get_symbolic_name();
277  string real = c->get_real_name();
278  if (real.length() > root_len) {
279  if (real.compare(0, root_len, _root_dir) == 0) {
280  real = real.substr(root_len, real.length() - root_len);
281  }
282  }
283  string type = c->get_container_type();
284  show_container(sym, real, type, info);
285  }
286 }
287 
295 void BESContainerStorageVolatile::dump(ostream &strm) const
296 {
297  strm << BESIndent::LMarg << "BESContainerStorageVolatile::dump - (" << (void *) this << ")" << endl;
299  strm << BESIndent::LMarg << "name: " << get_name() << endl;
300  if (_container_list.size()) {
301  strm << BESIndent::LMarg << "containers:" << endl;
303  BESContainerStorageVolatile::Container_citer i = _container_list.begin();
304  BESContainerStorageVolatile::Container_citer ie = _container_list.end();
305  for (; i != ie; i++) {
306  BESContainer *c = (*i).second;
307  c->dump(strm);
308  }
310  }
311  else {
312  strm << BESIndent::LMarg << "containers: none" << endl;
313  }
315 }
316 
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
string get_symbolic_name() const
retrieve the symbolic name for this container
Definition: BESContainer.h:159
static string lowercase(const string &s)
Convert a string to all lower case.
Definition: BESUtil.cc:179
virtual void add_tag(const string &tag_name, const string &tag_data, map< string, string > *attrs=0)=0
Holds real data, container type and constraint for symbolic name read from persistence.
map< string, BESContainer * >::iterator Container_iter
string get_container_type() const
retrieve the type of data this container holds, such as cedar or netcdf.
Definition: BESContainer.h:170
static void Indent()
Definition: BESIndent.cc:38
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 ...
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.
static BESServiceRegistry * TheRegistry()
static ostream & LMarg(ostream &strm)
Definition: BESIndent.cc:73
string get_real_name() const
retrieve the real name for this container, such as a file name.
Definition: BESContainer.h:141
void get_value(const string &s, string &val, bool &found)
Retrieve the value of a given key, if set.
Definition: BESKeys.cc:453
BESContainerStorageVolatile(const string &n)
create an instance of this persistent store with the given name.
virtual void dump(ostream &strm) const
dumps information about this object
Definition: BESContainer.cc:65
#define BESDEBUG(x, y)
macro used to send debug information to the debug stream
Definition: BESDebug.h:64
virtual bool del_containers()
removes all container
A container is something that holds data.
Definition: BESContainer.h:60
map< string, BESContainer * >::const_iterator Container_citer
virtual void dump(ostream &strm) const
dumps information about this object
static void UnIndent()
Definition: BESIndent.cc:44
static void check_path(const string &path, const string &root, bool follow_sym_links)
Check if the specified path is valid.
Definition: BESUtil.cc:229
static BESKeys * TheKeys()
Definition: TheBESKeys.cc:48
virtual bool isData(const string &inQuestion, list< string > &provides)
determine if the given container is data and what servies are available for it
virtual const string & get_name() const
retrieve the name of this persistent store
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