27 #include "config_nc.h" 35 #include <mime_util.h> 36 #include <D4BaseTypeFactory.h> 38 #include <BESResponseHandler.h> 39 #include <BESResponseNames.h> 40 #include <BESDapNames.h> 41 #include <BESDASResponse.h> 42 #include <BESDDSResponse.h> 43 #include <BESDataDDSResponse.h> 44 #include <BESVersionInfo.h> 46 #include <BESDapError.h> 47 #include <BESInternalFatalError.h> 48 #include <BESDataNames.h> 49 #include <TheBESKeys.h> 50 #include <BESServiceRegistry.h> 53 #include <BESStopWatch.h> 54 #include <BESContextManager.h> 55 #include <BESDMRResponse.h> 57 #include <ObjMemCache.h> 59 #include <InternalErr.h> 60 #include <Ancillary.h> 62 #include "NCRequestHandler.h" 68 bool NCRequestHandler::_show_shared_dims =
true;
69 bool NCRequestHandler::_show_shared_dims_set =
false;
71 bool NCRequestHandler::_ignore_unknown_types =
false;
72 bool NCRequestHandler::_ignore_unknown_types_set =
false;
74 bool NCRequestHandler::_promote_byte_to_short =
false;
75 bool NCRequestHandler::_promote_byte_to_short_set =
false;
77 unsigned int NCRequestHandler::_cache_entries = 100;
78 float NCRequestHandler::_cache_purge_level = 0.2;
84 extern void nc_read_dataset_attributes(DAS & das,
const string & filename);
85 extern void nc_read_dataset_variables(DDS & dds,
const string & filename);
93 static bool version_ge(
const string &version,
float value)
97 istringstream iss(version);
112 static bool get_bool_key(
const string &key,
bool def_val)
116 const string dosettrue =
"true";
117 const string dosetyes =
"yes";
122 return (dosettrue == doset || dosetyes == doset);
127 static unsigned int get_uint_key(
const string &key,
unsigned int def_val)
134 return atoi(doset.c_str());
141 static float get_float_key(
const string &key,
float def_val)
148 return atof(doset.c_str());
155 NCRequestHandler::NCRequestHandler(
const string &name) :
158 BESDEBUG(NC_NAME,
"In NCRequestHandler::NCRequestHandler" << endl);
160 add_method(DAS_RESPONSE, NCRequestHandler::nc_build_das);
161 add_method(DDS_RESPONSE, NCRequestHandler::nc_build_dds);
162 add_method(DATA_RESPONSE, NCRequestHandler::nc_build_data);
164 add_method(DMR_RESPONSE, NCRequestHandler::nc_build_dmr);
165 add_method(DAP4DATA_RESPONSE, NCRequestHandler::nc_build_dmr);
167 add_method(HELP_RESPONSE, NCRequestHandler::nc_build_help);
168 add_method(VERS_RESPONSE, NCRequestHandler::nc_build_version);
173 if (NCRequestHandler::_show_shared_dims_set ==
false) {
174 bool key_found =
false;
179 NCRequestHandler::_show_shared_dims_set =
true;
182 if (doset ==
"true" || doset ==
"yes") {
183 NCRequestHandler::_show_shared_dims =
true;
186 NCRequestHandler::_show_shared_dims =
false;
190 if (NCRequestHandler::_ignore_unknown_types_set ==
false) {
191 bool key_found =
false;
196 if (doset ==
"true" || doset ==
"yes")
197 NCRequestHandler::_ignore_unknown_types =
true;
199 NCRequestHandler::_ignore_unknown_types =
false;
201 NCRequestHandler::_ignore_unknown_types_set =
true;
205 if (NCRequestHandler::_promote_byte_to_short_set ==
false) {
206 bool key_found =
false;
211 if (doset ==
"true" || doset ==
"yes")
212 NCRequestHandler::_promote_byte_to_short =
true;
214 NCRequestHandler::_promote_byte_to_short =
false;
216 NCRequestHandler::_promote_byte_to_short_set =
true;
220 NCRequestHandler::_cache_entries = get_uint_key(
"NC.CacheEntries", 0);
221 NCRequestHandler::_cache_purge_level = get_float_key(
"NC.CachePurgeLevel", 0.2);
223 if (get_cache_entries()) {
224 das_cache =
new ObjMemCache(get_cache_entries(), get_cache_purge_level());
225 dds_cache =
new ObjMemCache(get_cache_entries(), get_cache_purge_level());
226 dmr_cache =
new ObjMemCache(get_cache_entries(), get_cache_purge_level());
229 BESDEBUG(NC_NAME,
"Exiting NCRequestHandler::NCRequestHandler" << endl);
232 NCRequestHandler::~NCRequestHandler()
242 if (BESISDEBUG( TIMING_LOG ))
243 sw.
start(
"NCRequestHandler::nc_build_das", dhi.
data[REQUEST_ID]);
245 BESDEBUG(NC_NAME,
"In NCRequestHandler::nc_build_das" << endl);
255 DAS *das = bdas->get_das();
256 if (!container_name.empty()) das->container_name(container_name);
260 DAS *cached_das_ptr = 0;
261 if (das_cache && (cached_das_ptr = static_cast<DAS*>(das_cache->
get(accessed)))) {
263 BESDEBUG(NC_NAME,
"DAS Cached hit for : " << accessed << endl);
264 *das = *cached_das_ptr;
267 nc_read_dataset_attributes(*das, accessed);
268 Ancillary::read_ancillary_das(*das, accessed);
271 BESDEBUG(NC_NAME,
"DAS added to the cache for : " << accessed << endl);
272 das_cache->
add(
new DAS(*das), accessed);
281 catch (InternalErr & e) {
282 BESDapError ex(e.get_error_message(),
true, e.get_error_code(), __FILE__, __LINE__);
286 BESDapError ex(e.get_error_message(),
false, e.get_error_code(), __FILE__, __LINE__);
289 catch (std::exception &e) {
290 string s = string(
"C++ Exception: ") + e.what();
295 string s =
"unknown exception caught building DAS";
300 BESDEBUG(NC_NAME,
"Exiting NCRequestHandler::nc_build_das" << endl);
310 void NCRequestHandler::get_dds_with_attributes(
const string& dataset_name,
const string& container_name, DDS* dds)
313 DDS* cached_dds_ptr = 0;
314 if (dds_cache && (cached_dds_ptr = static_cast<DDS*>(dds_cache->
get(dataset_name)))) {
317 BESDEBUG(NC_NAME,
"DDS Cached hit for : " << dataset_name << endl);
318 *dds = *cached_dds_ptr;
321 if (!container_name.empty()) dds->container_name(container_name);
322 dds->filename(dataset_name);
324 nc_read_dataset_variables(*dds, dataset_name);
327 if (das_cache && (das = static_cast<DAS*>(das_cache->
get(dataset_name)))) {
328 BESDEBUG(NC_NAME,
"DAS Cached hit for : " << dataset_name << endl);
329 dds->transfer_attributes(das);
335 if (!container_name.empty()) das->container_name(container_name);
337 nc_read_dataset_attributes(*das, dataset_name);
338 Ancillary::read_ancillary_das(*das, dataset_name);
340 dds->transfer_attributes(das);
345 BESDEBUG(NC_NAME,
"DAS added to the cache for : " << dataset_name << endl);
346 das_cache->
add(das, dataset_name);
355 BESDEBUG(NC_NAME,
"DDS added to the cache for : " << dataset_name << endl);
356 dds_cache->
add(
new DDS(*dds), dataset_name);
365 if (BESISDEBUG( TIMING_LOG ))
366 sw.
start(
"NCRequestHandler::nc_build_dds", dhi.
data[REQUEST_ID]);
377 if (NCRequestHandler::_show_shared_dims_set ==
false) {
378 bool context_found =
false;
379 string context_value = BESContextManager::TheManager()->
get_context(
"xdap_accept", context_found);
381 BESDEBUG(NC_NAME,
"xdap_accept: " << context_value << endl);
382 if (version_ge(context_value, 3.2))
383 NCRequestHandler::_show_shared_dims =
false;
385 NCRequestHandler::_show_shared_dims =
true;
401 catch (InternalErr & e) {
402 BESDapError ex(e.get_error_message(),
true, e.get_error_code(), __FILE__, __LINE__);
406 BESDapError ex(e.get_error_message(),
false, e.get_error_code(), __FILE__, __LINE__);
409 catch (std::exception &e) {
410 string s = string(
"C++ Exception: ") + e.what();
415 string s =
"unknown exception caught building DDS";
426 if (BESISDEBUG( TIMING_LOG ))
427 sw.
start(
"NCRequestHandler::nc_build_data", dhi.
data[REQUEST_ID]);
435 if (NCRequestHandler::_show_shared_dims_set ==
false) {
436 bool context_found =
false;
437 string context_value = BESContextManager::TheManager()->
get_context(
"xdap_accept", context_found);
439 BESDEBUG(NC_NAME,
"xdap_accept: " << context_value << endl);
440 if (version_ge(context_value, 3.2))
441 NCRequestHandler::_show_shared_dims =
false;
443 NCRequestHandler::_show_shared_dims =
true;
448 DDS *dds = bdds->get_dds();
459 catch (InternalErr & e) {
460 BESDapError ex(e.get_error_message(),
true, e.get_error_code(), __FILE__, __LINE__);
464 BESDapError ex(e.get_error_message(),
false, e.get_error_code(), __FILE__, __LINE__);
467 catch (std::exception &e) {
468 string s = string(
"C++ Exception: ") + e.what();
473 string s =
"unknown exception caught building DAS";
484 if (BESISDEBUG( TIMING_LOG ))
485 sw.
start(
"NCRequestHandler::nc_build_dmr", dhi.
data[REQUEST_ID]);
500 DMR *dmr = bdmr.get_dmr();
503 DMR* cached_dmr_ptr = 0;
504 if (dmr_cache && (cached_dmr_ptr = static_cast<DMR*>(dmr_cache->
get(dataset_name)))) {
506 BESDEBUG(NC_NAME,
"DMR Cached hit for : " << dataset_name << endl);
507 *dmr = *cached_dmr_ptr;
512 BaseTypeFactory factory;
513 DDS dds(&factory, name_path(dataset_name),
"3.2");
516 get_dds_with_attributes(dataset_name,
"", &dds);
518 dmr->set_factory(
new D4BaseTypeFactory);
519 dmr->build_using_dds(dds);
523 dmr->set_factory(
new D4BaseTypeFactory);
526 if (dds_cache && (dds_ptr = static_cast<DDS*>(dds_cache->
get(dataset_name)))) {
528 BESDEBUG(NC_NAME,
"DDS Cached hit (while building DMR) for : " << dataset_name << endl);
530 dmr->build_using_dds(*dds_ptr);
535 BaseTypeFactory factory;
536 DDS dds(&factory, name_path(dataset_name),
"3.2");
538 dds.filename(dataset_name);
539 nc_read_dataset_variables(dds, dataset_name);
543 nc_read_dataset_attributes(das, dataset_name);
544 Ancillary::read_ancillary_das(das, dataset_name);
546 dds.transfer_attributes(&das);
547 dmr->build_using_dds(dds);
553 BESDEBUG(NC_NAME,
"DMR added to the cache for : " << dataset_name << endl);
554 dmr_cache->
add(
new DMR(*dmr), dataset_name);
566 catch (InternalErr &e) {
567 throw BESDapError(e.get_error_message(),
true, e.get_error_code(), __FILE__, __LINE__);
570 throw BESDapError(e.get_error_message(),
false, e.get_error_code(), __FILE__, __LINE__);
573 throw BESDapError(
"Caught unknown error build NC DMR response",
true, unknown_error, __FILE__, __LINE__);
582 if (BESISDEBUG( TIMING_LOG ))
583 sw.
start(
"NCRequestHandler::nc_build_help", dhi.
data[REQUEST_ID]);
586 BESInfo *info = dynamic_cast<BESInfo *> (response);
590 map < string, string > attrs;
591 attrs[
"name"] = MODULE_NAME ;
592 attrs[
"version"] = MODULE_VERSION ;
594 attrs[
"name"] = PACKAGE_NAME;
595 attrs[
"version"] = PACKAGE_VERSION;
597 list < string > services;
599 if (services.size() > 0) {
601 attrs[
"handles"] = handles;
603 info->begin_tag(
"module", &attrs);
604 info->end_tag(
"module");
612 if (BESISDEBUG( TIMING_LOG ))
613 sw.
start(
"NCRequestHandler::nc_build_version", dhi.
data[REQUEST_ID]);
621 info->add_module(PACKAGE_NAME, PACKAGE_VERSION);
623 info->add_module(MODULE_NAME, MODULE_VERSION);
exception thrown if an internal error is found and is fatal to the BES
exception thrown if inernal error encountered
static string lowercase(const string &s)
Holds a DDS object within the BES.
virtual void clear_container()
clear the container in the DAP response object
virtual libdap::DapObj * get(const std::string &key)
Get the cached pointer.
virtual void set_dap4_constraint(BESDataHandlerInterface &dhi)
set the constraint depending on the context
void get_value(const std::string &s, std::string &val, bool &found)
Retrieve the value of a given key, if set.
virtual string get_context(const string &name, bool &found)
retrieve the value of the specified context from the BES
virtual bool start(string name)
virtual string access()=0
returns the true name of this container
virtual void clear_container()
clear the container in the DAP response object
virtual void set_dap4_function(BESDataHandlerInterface &dhi)
set the constraint depending on the context
informational response object
static string implode(const list< string > &values, char delim)
virtual BESResponseObject * get_response_object()
return the current response object
Abstract exception class for the BES with basic string message.
static TheBESKeys * TheKeys()
virtual void add(libdap::DapObj *obj, const std::string &key)
Add an object to the cache and associate it with a key.
virtual void set_constraint(BESDataHandlerInterface &dhi)
set the constraint depending on the context
Represents an OPeNDAP DMR DAP4 data object within the BES.
error object created from libdap error objects and can handle those errors
Represents an OPeNDAP DataDDS DAP2 data object within the BES.
virtual void clear_container()
clear the container in the DAP response object
Represents a specific data type request handler.
Structure storing information used by the BES to handle the request.
map< string, string > data
the map of string data that will be required for the current request.
bool get_explicit_containers() const
Should containers be explicitly represented in the DD* responses?
Represents an OPeNDAP DAS DAP2 data object within the BES.
An in-memory cache for DapObj (DAS, DDS, ...) objects.
Abstract base class representing a specific set of information in response to a request to the BES.
BESContainer * container
pointer to current container in this interface
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