bes  Updated for version 3.20.6
DmrppRequestHandler.cc
1 // DmrppRequestHandler.cc
2 
3 // Copyright (c) 2016 OPeNDAP, Inc. Author: James Gallagher
4 // <jgallagher@opendap.org>, Patrick West <pwest@opendap.org>
5 // Nathan Potter <npotter@opendap.org>
6 //
7 // modify it under the terms of the GNU Lesser General Public License
8 // as published by the Free Software Foundation; either version 2.1 of
9 // the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful, but
12 // WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
15 //
16 // License along with this library; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 // 02110-1301 U\ SA
19 //
20 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI.
21 // 02874-0112.
22 
23 #include "config.h"
24 
25 #include <string>
26 #include <memory>
27 #include <sstream>
28 
29 #include <curl/curl.h>
30 #include <stdlib.h>
31 
32 #include <Ancillary.h>
33 #include <ObjMemCache.h>
34 #include <DMR.h>
35 #include <D4Group.h>
36 #include <DAS.h>
37 
38 #include <InternalErr.h>
39 #include <mime_util.h> // for name_path
40 
41 #include <BESResponseHandler.h>
42 #include <BESResponseNames.h>
43 #include <BESDapNames.h>
44 #include <BESDataNames.h>
45 #include <BESDASResponse.h>
46 #include <BESDDSResponse.h>
47 #include <BESDataDDSResponse.h>
48 #include <BESVersionInfo.h>
49 #include <BESTextInfo.h>
50 #include <BESContainer.h>
51 
52 #include <BESDMRResponse.h>
53 
54 #include <BESConstraintFuncs.h>
55 #include <BESServiceRegistry.h>
56 #include <BESUtil.h>
57 #include <TheBESKeys.h>
58 
59 #include <BESDapError.h>
60 #include <BESInternalFatalError.h>
61 #include <BESDebug.h>
62 #include <BESStopWatch.h>
63 
64 #include "DMRpp.h"
65 #include "DmrppTypeFactory.h"
66 #include "DmrppParserSax2.h"
67 #include "DmrppRequestHandler.h"
68 #include "CurlHandlePool.h"
69 #include "DmrppMetadataStore.h"
70 #include "CredentialsManager.h"
71 
72 using namespace bes;
73 using namespace libdap;
74 using namespace std;
75 
76 namespace dmrpp {
77 
78 const string module = "dmrpp";
79 
80 ObjMemCache *DmrppRequestHandler::das_cache = 0;
81 ObjMemCache *DmrppRequestHandler::dds_cache = 0;
82 ObjMemCache *DmrppRequestHandler::dmr_cache = 0;
83 
84 // This is used to maintain a pool of reusable curl handles that enable connection
85 // reuse. jhrg
86 CurlHandlePool *DmrppRequestHandler::curl_handle_pool = 0;
87 
88 bool DmrppRequestHandler::d_use_parallel_transfers = true;
89 unsigned int DmrppRequestHandler::d_max_parallel_transfers = 8;
90 
91 // Default minimum value is 2MB: 2 * (1024*1024)
92 unsigned int DmrppRequestHandler::d_min_size = 2097152;
93 
94 static void read_key_value(const std::string &key_name, bool &key_value)
95 {
96  bool key_found = false;
97  string value;
98  TheBESKeys::TheKeys()->get_value(key_name, value, key_found);
99  if (key_found) {
100  value = BESUtil::lowercase(value);
101  key_value = (value == "true" || value == "yes");
102  }
103 }
104 
105 static void read_key_value(const std::string &key_name, unsigned int &key_value)
106 {
107  bool key_found = false;
108  string value;
109  TheBESKeys::TheKeys()->get_value(key_name, value, key_found);
110  if (key_found) {
111  istringstream iss(value);
112  iss >> key_value;
113  }
114 }
115 
120 DmrppRequestHandler::DmrppRequestHandler(const string &name) :
121  BESRequestHandler(name)
122 {
123  add_method(DMR_RESPONSE, dap_build_dmr);
124  add_method(DAP4DATA_RESPONSE, dap_build_dap4data);
125  add_method(DAS_RESPONSE, dap_build_das);
126  add_method(DDS_RESPONSE, dap_build_dds);
127  add_method(DATA_RESPONSE, dap_build_dap2data);
128 
129  add_method(VERS_RESPONSE, dap_build_vers);
130  add_method(HELP_RESPONSE, dap_build_help);
131 
132  read_key_value("DMRPP.UseParallelTransfers", d_use_parallel_transfers);
133  read_key_value("DMRPP.MaxParallelTransfers", d_max_parallel_transfers);
134 
136 
137  if (!curl_handle_pool)
138  curl_handle_pool = new CurlHandlePool();
139 
140  curl_global_init(CURL_GLOBAL_DEFAULT);
141 }
142 
143 DmrppRequestHandler::~DmrppRequestHandler()
144 {
145  delete curl_handle_pool;
146  curl_global_cleanup();
147 }
148 
149 void DmrppRequestHandler::build_dmr_from_file(BESContainer *container, DMR* dmr)
150 {
151  string data_pathname = container->access();
152 
153  dmr->set_filename(data_pathname);
154  dmr->set_name(name_path(data_pathname));
155 
156  DmrppTypeFactory BaseFactory; // Use the factory for this handler's types
157  dmr->set_factory(&BaseFactory);
158 
159  DmrppParserSax2 parser;
160  ifstream in(data_pathname.c_str(), ios::in);
161 
162  parser.intern(in, dmr, BESDebug::IsSet(module));
163 
164  dmr->set_factory(0);
165 }
166 
180 {
181  BESDEBUG(module, "Entering dap_build_dmr..." << endl);
182 
183  BESResponseObject *response = dhi.response_handler->get_response_object();
184  BESDMRResponse *bdmr = dynamic_cast<BESDMRResponse *>(response);
185  if (!bdmr) throw BESInternalError("Cast error, expected a BESDDSResponse object.", __FILE__, __LINE__);
186 
187  try {
188  build_dmr_from_file(dhi.container, bdmr->get_dmr());
189 
190  bdmr->set_dap4_constraint(dhi);
191  bdmr->set_dap4_function(dhi);
192  }
193  catch (BESError &e) {
194  throw e;
195  }
196  catch (InternalErr & e) {
197  throw BESDapError(e.get_error_message(), true, e.get_error_code(), __FILE__, __LINE__);
198  }
199  catch (Error & e) {
200  throw BESDapError(e.get_error_message(), false, e.get_error_code(), __FILE__, __LINE__);
201  }
202  catch (...) {
203  throw BESInternalFatalError("Unknown exception caught building a DMR", __FILE__, __LINE__);
204  }
205 
206  BESDEBUG(module, "Leaving dap_build_dmr..." << endl);
207 
208  return true;
209 }
210 
211 bool DmrppRequestHandler::dap_build_dap4data(BESDataHandlerInterface &dhi)
212 {
213  BESDEBUG(module, "Entering dap_build_dap4data..." << endl);
214 
215  BESResponseObject *response = dhi.response_handler->get_response_object();
216  BESDMRResponse *bdmr = dynamic_cast<BESDMRResponse *>(response);
217  if (!bdmr) throw BESInternalError("Cast error, expected a BESDMRResponse object.", __FILE__, __LINE__);
218 
219  try {
220  // Check the Container to see if the handler should get the response from the MDS.
221  if (dhi.container->get_attributes().find(MDS_HAS_DMRPP) != string::npos) {
222  DmrppMetadataStore *mds = DmrppMetadataStore::get_instance();
223  if (!mds)
224  throw BESInternalError("MDS configuration error: The DMR++ module could not find the MDS", __FILE__, __LINE__);
225 
227  if (!dmrpp)
228  throw BESInternalError("DMR++ module error: Null DMR++ object read from the MDS", __FILE__, __LINE__);
229 
230  delete bdmr->get_dmr();
231  bdmr->set_dmr(dmrpp);
232  }
233  else {
234  build_dmr_from_file(dhi.container, bdmr->get_dmr());
235  }
236 
237  bdmr->set_dap4_constraint(dhi);
238  bdmr->set_dap4_function(dhi);
239  }
240  catch (BESError &e) {
241  throw e;
242  }
243  catch (InternalErr & e) {
244  throw BESDapError(e.get_error_message(), true, e.get_error_code(), __FILE__, __LINE__);
245  }
246  catch (Error & e) {
247  throw BESDapError(e.get_error_message(), false, e.get_error_code(), __FILE__, __LINE__);
248  }
249  catch (...) {
250  throw BESInternalFatalError("Unknown exception caught building DAP4 Data response", __FILE__, __LINE__);
251  }
252 
253  BESDEBUG(module, "Leaving dap_build_dap4data..." << endl);
254 
255  return false;
256 }
257 
262 {
263  BESStopWatch sw;
264  if (BESISDEBUG(TIMING_LOG)) sw.start("DmrppRequestHandler::dap_build_dap2data()", dhi.data[REQUEST_ID]);
265 
266  BESDEBUG(module, __func__ << "() - BEGIN" << endl);
267 
268  BESResponseObject *response = dhi.response_handler->get_response_object();
269  BESDataDDSResponse *bdds = dynamic_cast<BESDataDDSResponse *>(response);
270  if (!bdds) throw BESInternalError("Cast error, expected a BESDataDDSResponse object.", __FILE__, __LINE__);
271 
272  try {
273  string container_name_str = bdds->get_explicit_containers() ? dhi.container->get_symbolic_name() : "";
274 
275  DDS *dds = bdds->get_dds();
276  if (!container_name_str.empty()) dds->container_name(container_name_str);
277  string accessed = dhi.container->access();
278 
279  // Look in memory cache, if it's initialized
280  DDS *cached_dds_ptr = 0;
281  if (dds_cache && (cached_dds_ptr = static_cast<DDS*>(dds_cache->get(accessed)))) {
282  // copy the cached DAS into the BES response object
283  BESDEBUG(module, "DDS Cached hit for : " << accessed << endl);
284  *dds = *cached_dds_ptr;
285  bdds->set_constraint(dhi);
286  }
287  else {
288  // Not in the local binary cache, make one...
289  DMR *dmr = NULL;
290 
291  // Check the Container to see if the handler should get the response from the MDS.
292  if (dhi.container->get_attributes().find(MDS_HAS_DMRPP) != string::npos) {
293  DmrppMetadataStore *mds = DmrppMetadataStore::get_instance();
294  if (!mds)
295  throw BESInternalError("MDS configuration error: The DMR++ module could not find the MDS", __FILE__, __LINE__);
296 
297  dmr = mds->get_dmrpp_object(dhi.container->get_relative_name());
298  if (!dmr)
299  throw BESInternalError("DMR++ module error: Null DMR++ object read from the MDS", __FILE__, __LINE__);
300  }
301  else {
302  dmr = new DMR();
303  build_dmr_from_file(dhi.container, dmr);
304  }
305 
306  // delete the current one;
307  delete dds;
308  // assign the new one.
309  dds = dmr->getDDS();
310 
311  // Stuff it into the response.
312  bdds->set_dds(dds);
313  bdds->set_constraint(dhi);
314 
315  delete dmr;
316 
317  // Cache it, if the cache is active.
318  if (dds_cache) {
319  dds_cache->add(new DDS(*dds), accessed);
320  }
321  }
322 
323  bdds->clear_container();
324  }
325  catch (BESError &e) {
326  throw;
327  }
328  catch (InternalErr & e) {
329  BESDapError ex(e.get_error_message(), true, e.get_error_code(), __FILE__, __LINE__);
330  throw ex;
331  }
332  catch (Error & e) {
333  BESDapError ex(e.get_error_message(), false, e.get_error_code(), __FILE__, __LINE__);
334  throw ex;
335  }
336  catch (std::exception &e) {
337  string s = string("C++ Exception: ") + e.what();
338  BESInternalFatalError ex(s, __FILE__, __LINE__);
339  throw ex;
340  }
341  catch (...) {
342  string s = "unknown exception caught building DDS";
343  BESInternalFatalError ex(s, __FILE__, __LINE__);
344  throw ex;
345  }
346 
347  BESDEBUG(module, "DmrppRequestHandler::dap_build_dds() - END" << endl);
348  return true;
349 }
350 
355 {
356  BESStopWatch sw;
357  if (BESISDEBUG(TIMING_LOG)) sw.start("DmrppRequestHandler::dap_build_dds()", dhi.data[REQUEST_ID]);
358 
359  BESDEBUG(module, __func__ << "() - BEGIN" << endl);
360 
361  BESResponseObject *response = dhi.response_handler->get_response_object();
362  BESDDSResponse *bdds = dynamic_cast<BESDDSResponse *>(response);
363  if (!bdds) throw BESInternalError("Cast error, expected a BESDDSResponse object.", __FILE__, __LINE__);
364 
365  try {
366  string container_name_str = bdds->get_explicit_containers() ? dhi.container->get_symbolic_name() : "";
367 
368  DDS *dds = bdds->get_dds();
369  if (!container_name_str.empty()) dds->container_name(container_name_str);
370  string accessed = dhi.container->access();
371 
372  // Look in memory cache, if it's initialized
373  DDS *cached_dds_ptr = 0;
374  if (dds_cache && (cached_dds_ptr = static_cast<DDS*>(dds_cache->get(accessed)))) {
375  // copy the cached DAS into the BES response object
376  BESDEBUG(module, "DDS Cached hit for : " << accessed << endl);
377  *dds = *cached_dds_ptr;
378  }
379  else {
380  // Not in cache, make one...
381  DMR *dmr = new DMR(); // FIXME is this leaked? jhrg 6/1/18
382  build_dmr_from_file(dhi.container, dmr);
383 
384  // delete the current one;
385  delete dds;
386  dds = 0;
387 
388  // assign the new one.
389  dds = dmr->getDDS();
390 
391  // Stuff it into the response.
392  bdds->set_dds(dds);
393  bdds->set_constraint(dhi);
394 
395  // Cache it, if the cache is active.
396  if (dds_cache) {
397  dds_cache->add(new DDS(*dds), accessed);
398  }
399  }
400 
401  bdds->clear_container();
402  }
403  catch (BESError &e) {
404  throw;
405  }
406  catch (InternalErr & e) {
407  BESDapError ex(e.get_error_message(), true, e.get_error_code(), __FILE__, __LINE__);
408  throw ex;
409  }
410  catch (Error & e) {
411  BESDapError ex(e.get_error_message(), false, e.get_error_code(), __FILE__, __LINE__);
412  throw ex;
413  }
414  catch (std::exception &e) {
415  string s = string("C++ Exception: ") + e.what();
416  BESInternalFatalError ex(s, __FILE__, __LINE__);
417  throw ex;
418  }
419  catch (...) {
420  string s = "unknown exception caught building DDS";
421  BESInternalFatalError ex(s, __FILE__, __LINE__);
422  throw ex;
423  }
424 
425  BESDEBUG(module, "DmrppRequestHandler::dap_build_dds() - END" << endl);
426  return true;
427 }
428 
434 {
435  BESStopWatch sw;
436  if (BESISDEBUG(TIMING_LOG)) sw.start("DmrppRequestHandler::dap_build_das()", dhi.data[REQUEST_ID]);
437 
438  BESResponseObject *response = dhi.response_handler->get_response_object();
439  BESDASResponse *bdas = dynamic_cast<BESDASResponse *>(response);
440  if (!bdas) throw BESInternalError("Cast error, expected a BESDASResponse object.", __FILE__, __LINE__);
441 
442  try {
443  string container_name_str = bdas->get_explicit_containers() ? dhi.container->get_symbolic_name() : "";
444 
445  DAS *das = bdas->get_das();
446  if (!container_name_str.empty()) das->container_name(container_name_str);
447  string accessed = dhi.container->access();
448 
449  // Look in memory cache (if it's initialized)
450  DAS *cached_das_ptr = 0;
451  if (das_cache && (cached_das_ptr = static_cast<DAS*>(das_cache->get(accessed)))) {
452  // copy the cached DAS into the BES response object
453  *das = *cached_das_ptr;
454  }
455  else {
456  // Not in cache, better make one!
457  // 1) Build a DMR
458  DMR *dmr = new DMR();
459  build_dmr_from_file(dhi.container, dmr);
460 
461  // Get a DDS from the DMR
462  DDS *dds = dmr->getDDS();
463 
464  // Load the BESDASResponse DAS from the DDS
465  dds->get_das(das);
466 
467  delete dds;
468  delete dmr;
469 
470  Ancillary::read_ancillary_das(*das, accessed);
471  // Add to cache if cache is active
472  if (das_cache) {
473  das_cache->add(new DAS(*das), accessed);
474  }
475  }
476 
477  bdas->clear_container();
478  }
479  catch (BESError &e) {
480  throw;
481  }
482  catch (InternalErr & e) {
483  BESDapError ex(e.get_error_message(), true, e.get_error_code(), __FILE__, __LINE__);
484  throw ex;
485  }
486  catch (Error & e) {
487  BESDapError ex(e.get_error_message(), false, e.get_error_code(), __FILE__, __LINE__);
488  throw ex;
489  }
490  catch (std::exception &e) {
491  string s = string("C++ Exception: ") + e.what();
492  BESInternalFatalError ex(s, __FILE__, __LINE__);
493  throw ex;
494  }
495  catch (...) {
496  string s = "unknown exception caught building DAS";
497  BESInternalFatalError ex(s, __FILE__, __LINE__);
498  throw ex;
499  }
500 
501  BESDEBUG(module, __func__ << "() - END" << endl);
502  return true;
503 }
504 
505 
506 bool DmrppRequestHandler::dap_build_vers(BESDataHandlerInterface &dhi)
507 {
508  BESVersionInfo *info = dynamic_cast<BESVersionInfo *>(dhi.response_handler->get_response_object());
509  if (!info) throw BESInternalFatalError("Expected a BESVersionInfo instance.", __FILE__, __LINE__);
510 
511  info->add_module(MODULE_NAME, MODULE_VERSION);
512  return true;
513 }
514 
515 bool DmrppRequestHandler::dap_build_help(BESDataHandlerInterface &dhi)
516 {
517  BESInfo *info = dynamic_cast<BESInfo *>(dhi.response_handler->get_response_object());
518  if (!info) throw BESInternalFatalError("Expected a BESVersionInfo instance.", __FILE__, __LINE__);
519 
520  // This is an example. If you had a help file you could load it like
521  // this and if your handler handled the following responses.
522  map<string, string> attrs;
523  attrs["name"] = MODULE_NAME /* PACKAGE_NAME */;
524  attrs["version"] = MODULE_VERSION /* PACKAGE_VERSION */;
525  list<string> services;
526  BESServiceRegistry::TheRegistry()->services_handled(module, services);
527  if (services.size() > 0) {
528  string handles = BESUtil::implode(services, ',');
529  attrs["handles"] = handles;
530  }
531  info->begin_tag("module", &attrs);
532  info->end_tag("module");
533 
534  return true;
535 }
536 
537 void DmrppRequestHandler::dump(ostream &strm) const
538 {
539  strm << BESIndent::LMarg << "DmrppRequestHandler::dump - (" << (void *) this << ")" << endl;
540  BESIndent::Indent();
542  BESIndent::UnIndent();
543 }
544 
545 } // namespace dmrpp
BESRequestHandler
Represents a specific data type request handler.
Definition: BESRequestHandler.h:74
BESDataHandlerInterface::container
BESContainer * container
pointer to current container in this interface
Definition: BESDataHandlerInterface.h:75
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
BESDapResponse::set_dap4_constraint
virtual void set_dap4_constraint(BESDataHandlerInterface &dhi)
set the constraint depending on the context
Definition: BESDapResponse.cc:137
BESStopWatch::start
virtual bool start(std::string name)
Definition: BESStopWatch.cc:58
BESInternalFatalError
exception thrown if an internal error is found and is fatal to the BES
Definition: BESInternalFatalError.h:43
dmrpp::DmrppRequestHandler::dump
virtual void dump(std::ostream &strm) const
dumps information about this object
Definition: DmrppRequestHandler.cc:537
ObjMemCache
An in-memory cache for DapObj (DAS, DDS, ...) objects.
Definition: ObjMemCache.h:84
BESDapResponse::set_dap4_function
virtual void set_dap4_function(BESDataHandlerInterface &dhi)
set the constraint depending on the context
Definition: BESDapResponse.cc:154
BESDataDDSResponse::set_dds
void set_dds(libdap::DDS *ddsIn)
Definition: BESDataDDSResponse.h:73
dmrpp::DmrppRequestHandler::dap_build_dds
static bool dap_build_dds(BESDataHandlerInterface &dhi)
Definition: DmrppRequestHandler.cc:354
BESDDSResponse::set_dds
void set_dds(libdap::DDS *ddsIn)
Definition: BESDDSResponse.h:71
BESContainer::get_symbolic_name
std::string get_symbolic_name() const
retrieve the symbolic name for this container
Definition: BESContainer.h:221
BESDDSResponse::clear_container
virtual void clear_container()
clear the container in the DAP response object
Definition: BESDDSResponse.cc:73
BESDDSResponse::get_dds
libdap::DDS * get_dds()
Definition: BESDDSResponse.h:80
BESDASResponse
Represents an OPeNDAP DAS DAP2 data object within the BES.
Definition: BESDASResponse.h:44
BESInfo
informational response object
Definition: BESInfo.h:63
ObjMemCache::add
virtual void add(libdap::DapObj *obj, const std::string &key)
Add an object to the cache and associate it with a key.
Definition: ObjMemCache.cc:63
BESContainer::get_relative_name
std::string get_relative_name() const
Get the relative name of the object in this container.
Definition: BESContainer.h:186
BESRequestHandler::add_method
virtual bool add_method(const std::string &name, p_request_handler_method method)
add a handler method to the request handler that knows how to fill in a specific response object
Definition: BESRequestHandler.cc:58
libdap
Definition: BESDapFunctionResponseCache.h:35
TheBESKeys::TheKeys
static TheBESKeys * TheKeys()
Definition: TheBESKeys.cc:62
BESResponseHandler::get_response_object
virtual BESResponseObject * get_response_object()
return the current response object
Definition: BESResponseHandler.cc:82
BESVersionInfo
Definition: BESVersionInfo.h:47
dmrpp::DmrppRequestHandler::dap_build_dmr
static bool dap_build_dmr(BESDataHandlerInterface &dhi)
Definition: DmrppRequestHandler.cc:179
BESDebug::IsSet
static bool IsSet(const std::string &flagName)
see if the debug context flagName is set to true
Definition: BESDebug.h:157
BESContainer::access
virtual std::string access()=0
returns the true name of this container
BESDataHandlerInterface::data
std::map< std::string, std::string > data
the map of string data that will be required for the current request.
Definition: BESDataHandlerInterface.h:90
BESDapResponse::get_explicit_containers
bool get_explicit_containers() const
Should containers be explicitly represented in the DD* responses?
Definition: BESDapResponse.h:70
CredentialsManager::load_credentials
static void load_credentials()
Definition: CredentialsManager.cc:269
bes::DmrppMetadataStore
Store the DAP DMR++ metadata responses.
Definition: DmrppMetadataStore.h:83
BESDataDDSResponse::clear_container
virtual void clear_container()
clear the container in the DAP response object
Definition: BESDataDDSResponse.cc:59
BESContainer::get_attributes
std::string get_attributes() const
retrieve the attributes desired from this container
Definition: BESContainer.h:242
dmrpp::DmrppRequestHandler::dap_build_dap2data
static bool dap_build_dap2data(BESDataHandlerInterface &dhi)
Definition: DmrppRequestHandler.cc:261
BESInternalError
exception thrown if internal error encountered
Definition: BESInternalError.h:43
BESStopWatch
Definition: BESStopWatch.h:55
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
BESDDSResponse
Holds a DDS object within the BES.
Definition: BESDDSResponse.h:50
BESDASResponse::clear_container
virtual void clear_container()
clear the container in the DAP response object
Definition: BESDASResponse.cc:58
BESDapResponse::set_constraint
virtual void set_constraint(BESDataHandlerInterface &dhi)
set the constraint depending on the context
Definition: BESDapResponse.cc:115
BESDataDDSResponse
Represents an OPeNDAP DataDDS DAP2 data object within the BES.
Definition: BESDataDDSResponse.h:46
BESContainer
A container is something that holds data. E.G., a netcdf file or a database entry.
Definition: BESContainer.h:65
BESRequestHandler::dump
virtual void dump(std::ostream &strm) const
dumps information about this object
Definition: BESRequestHandler.cc:163
Error
BESUtil::lowercase
static std::string lowercase(const std::string &s)
Definition: BESUtil.cc:200
BESUtil::implode
static std::string implode(const std::list< std::string > &values, char delim)
Definition: BESUtil.cc:638
dmrpp::DMRpp
Provide a way to print the DMR++ response.
Definition: DMRpp.h:42
BESDapError
error object created from libdap error objects and can handle those errors
Definition: BESDapError.h:59
BESDataHandlerInterface
Structure storing information used by the BES to handle the request.
Definition: BESDataHandlerInterface.h:56
BESError
Abstract exception class for the BES with basic string message.
Definition: BESError.h:58
dmrpp::DmrppRequestHandler::dap_build_das
static bool dap_build_das(BESDataHandlerInterface &dhi)
Definition: DmrppRequestHandler.cc:433
bes::DmrppMetadataStore::get_dmrpp_object
virtual dmrpp::DMRpp * get_dmrpp_object(const std::string &name)
Build a DMR++ object from the cached Response.
Definition: DmrppMetadataStore.cc:274
dmrpp::CurlHandlePool
Definition: CurlHandlePool.h:114
BESResponseObject
Abstract base class representing a specific set of information in response to a request to the BES.
Definition: BESResponseObject.h:45
ObjMemCache::get
virtual libdap::DapObj * get(const std::string &key)
Get the cached pointer.
Definition: ObjMemCache.cc:105
BESDMRResponse
Represents an OPeNDAP DMR DAP4 data object within the BES.
Definition: BESDMRResponse.h:39