bes  Updated for version 3.20.5
GlobalMetadataStore.h
1 // -*- mode: c++; c-basic-offset:4 -*-
2 
3 // This file is part of Hyrax, A C++ implementation of the OPeNDAP Data
4 // Access Protocol.
5 
6 // Copyright (c) 2018 OPeNDAP, Inc.
7 // Author: James Gallagher <jgallagher@opendap.org>
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 OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
24 
25 #ifndef _global_metadata_cache_h
26 #define _global_metadata_cache_h
27 
28 #include <string>
29 #include <functional>
30 
31 #include "BESFileLockingCache.h"
32 #include "BESInternalFatalError.h"
33 
37 #define XML_BASE_MISSING_MEANS_OMIT_ATTRIBUTE 1
38 
39 namespace libdap {
40 class DapObj;
41 class DDS;
42 class DMR;
43 }
44 
45 namespace bes {
46 
87 private:
88  bool d_use_local_time; // Base on BES.LogTimeLocal
89  std::string d_ledger_name; // Name of the ledger file
90  std::string d_xml_base; // The value of the context xml:basse
91 
92  static bool d_enabled;
93  static GlobalMetadataStore *d_instance;
94 
95  // Called by atexit()
96  static void delete_instance() {
97  delete d_instance;
98  d_instance = 0;
99  }
100 
101  friend class DmrppMetadataStore;
102  friend class DmrppMetadataStoreTest;
103  friend class GlobalMetadataStoreTest;
104 
105 protected:
106  std::string d_ledger_entry; // Built up as info is added, written on success
107  void write_ledger();
108 
109  std::string get_hash(const std::string &name);
110 
127  struct StreamDAP : public std::unary_function<libdap::DapObj*, void> {
128  libdap::DDS *d_dds;
129  libdap::DMR *d_dmr;
130 
131  StreamDAP() : d_dds(0), d_dmr(0) {
132  throw BESInternalFatalError("Unknown DAP object type.", __FILE__, __LINE__);
133  }
134  StreamDAP(libdap::DDS *dds) : d_dds(dds), d_dmr(0) { }
135  StreamDAP(libdap::DMR *dmr) : d_dds(0), d_dmr(dmr) { }
136 
137  virtual void operator()(std::ostream &os) = 0;
138  };
139 
141  struct StreamDDS : public StreamDAP {
142  StreamDDS(libdap::DDS *dds) : StreamDAP(dds) { }
143  StreamDDS(libdap::DMR *dmr) : StreamDAP(dmr) { }
144 
145  virtual void operator()(ostream &os);
146  };
147 
149  struct StreamDAS : public StreamDAP {
150  StreamDAS(libdap::DDS *dds) : StreamDAP(dds) { }
151  StreamDAS(libdap::DMR *dmr) : StreamDAP(dmr) { }
152 
153  virtual void operator()(ostream &os);
154  };
155 
157  struct StreamDMR : public StreamDAP {
158  StreamDMR(libdap::DDS *dds) : StreamDAP(dds) { }
159  StreamDMR(libdap::DMR *dmr) : StreamDAP(dmr) { }
160 
161  virtual void operator()(ostream &os);
162  };
163 
164  bool store_dap_response(StreamDAP &writer, const std::string &key, const string &name, const string &response_name);
165 
166  void write_response_helper(const std::string &name, std::ostream &os, const std::string &suffix,
167  const std::string &object_name);
168 
169  // This version adds xml:base to the DMR/DMR++
170  void write_response_helper(const std::string &name, std::ostream &os, const std::string &suffix,
171  const std::string &xml_base, const std::string &object_name);
172 
173  bool remove_response_helper(const std::string& name, const std::string &suffix, const std::string &object_name);
174 
175  static void transfer_bytes(int fd, ostream &os);
176  static void insert_xml_base(int fd, ostream &os, const string &xml_base);
177 
178 public:
188  struct MDSReadLock : public std::unary_function<std::string, bool> {
189  std::string name;
190  bool locked;
191  GlobalMetadataStore *mds;
192  MDSReadLock() : name(""), locked(false), mds(0) { }
193  MDSReadLock(const std::string n, bool l, GlobalMetadataStore *store): name(n), locked(l), mds(store) { }
194  ~MDSReadLock() {
195  if (locked) mds->unlock_and_close(name);
196  locked = false;
197  }
198 
199  virtual bool operator()() { return locked; }
200  };
201 
202  typedef struct MDSReadLock MDSReadLock;
203 
204 protected:
205  MDSReadLock get_read_lock_helper(const string &name, const string &suffix, const string &object_name);
206 
207  // Suppress the automatic generation of these ctors
209 
210  void initialize();
211 
212  // Only get_instance() should be used to instantiate this class
214  GlobalMetadataStore(const std::string &cache_dir, const std::string &prefix, unsigned long long size);
215 
216  // these are static because they are called by the static method get_instance()
217  static string get_cache_dir_from_config();
218  static string get_cache_prefix_from_config();
219  static unsigned long get_cache_size_from_config();
220 
221 public:
222  static GlobalMetadataStore *get_instance(const std::string &cache_dir, const std::string &prefix,
223  unsigned long long size);
225 
226  virtual ~GlobalMetadataStore()
227  {
228  }
229 
230  virtual bool add_responses(libdap::DDS *dds, const std::string &name);
231  virtual bool add_responses(libdap::DMR *dmr, const std::string &name);
232 
233  virtual MDSReadLock is_dmr_available(const std::string &name);
234  virtual MDSReadLock is_dds_available(const std::string &name);
235  virtual MDSReadLock is_das_available(const std::string &name);
236  virtual MDSReadLock is_dmrpp_available(const std::string &name);
237 
238  virtual void write_dds_response(const std::string &name, std::ostream &os);
239  virtual void write_das_response(const std::string &name, std::ostream &os);
240 
241  // Add a third parameter to enable changing the value of xmlbase in this response.
242  // jhrg 2.28.18
243  virtual void write_dmr_response(const std::string &name, std::ostream &os);
244  virtual void write_dmrpp_response(const std::string &name, std::ostream &os);
245 
246  virtual bool remove_responses(const std::string &name);
247 
248  virtual libdap::DDS *get_dds_object(const std::string &name);
249  virtual libdap::DMR *get_dmr_object(const std::string &name);
250 };
251 
252 } // namespace bes
253 
254 #endif // _global_metadata_cache_h
virtual void operator()(ostream &os)
Use an object (DDS or DMR) to write data to the MDS.
Unlock and close the MDS item when the ReadLock goes out of scope.
virtual libdap::DMR * get_dmr_object(const std::string &name)
Build a DMR object from the cached Response.
exception thrown if an internal error is found and is fatal to the BES
static GlobalMetadataStore * get_instance()
virtual void unlock_and_close(const std::string &target)
Instantiate with a DDS or DMR and use to write the DMR response.
void initialize()
Configure the ledger using LEDGER_KEY and LOCAL_TIME_KEY.
Store the DAP DMR++ metadata responses.
virtual void write_das_response(const std::string &name, std::ostream &os)
Write the stored DAS response to a stream.
virtual void write_dmrpp_response(const std::string &name, std::ostream &os)
Write the stored DMR++ response to a stream.
Implementation of a caching mechanism for compressed data.
virtual MDSReadLock is_das_available(const std::string &name)
Is the DAS response for.
virtual void write_dds_response(const std::string &name, std::ostream &os)
Write the stored DDS response to a stream.
virtual libdap::DDS * get_dds_object(const std::string &name)
Build a DDS object from the cached Response.
virtual bool add_responses(libdap::DDS *dds, const std::string &name)
Add the DAP2 metadata responses using a DDS.
virtual MDSReadLock is_dds_available(const std::string &name)
Is the DDS response for.
static void insert_xml_base(int fd, ostream &os, const string &xml_base)
like transfer_bytes(), but adds the xml:base attribute to the DMR/++
void write_response_helper(const std::string &name, std::ostream &os, const std::string &suffix, const std::string &object_name)
virtual bool remove_responses(const std::string &name)
Remove all cached responses and objects for a granule.
MDSReadLock get_read_lock_helper(const string &name, const string &suffix, const string &object_name)
Instantiate with a DDS or DMR and use to write the DDS response.
Instantiate with a DDS or DMR and use to write the DAS response.
bool store_dap_response(StreamDAP &writer, const std::string &key, const string &name, const string &response_name)
static void transfer_bytes(int fd, ostream &os)
std::string get_hash(const std::string &name)
virtual MDSReadLock is_dmr_available(const std::string &name)
Is the DMR response for.
virtual void write_dmr_response(const std::string &name, std::ostream &os)
Write the stored DMR response to a stream.
bool remove_response_helper(const std::string &name, const std::string &suffix, const std::string &object_name)
Store the DAP metadata responses.
virtual MDSReadLock is_dmrpp_available(const std::string &name)
Is the DMR++ response for.