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"
63 #include "GlobalMetadataStore.h"
69 bool NCRequestHandler::_show_shared_dims =
true;
70 bool NCRequestHandler::_show_shared_dims_set =
false;
72 bool NCRequestHandler::_ignore_unknown_types =
false;
73 bool NCRequestHandler::_ignore_unknown_types_set =
false;
75 bool NCRequestHandler::_promote_byte_to_short =
false;
76 bool NCRequestHandler::_promote_byte_to_short_set =
false;
77 bool NCRequestHandler::_use_mds =
false;
79 unsigned int NCRequestHandler::_cache_entries = 100;
80 float NCRequestHandler::_cache_purge_level = 0.2;
87 extern void nc_read_dataset_attributes(DAS & das,
const string & filename);
88 extern void nc_read_dataset_variables(DDS & dds,
const string & filename);
96 static bool version_ge(
const string &version,
float value)
100 istringstream iss(version);
115 static bool get_bool_key(
const string &key,
bool def_val)
119 const string dosettrue =
"true";
120 const string dosetyes =
"yes";
125 return (dosettrue == doset || dosetyes == doset);
130 static unsigned int get_uint_key(
const string &key,
unsigned int def_val)
137 return atoi(doset.c_str());
144 static float get_float_key(
const string &key,
float def_val)
151 return atof(doset.c_str());
158 NCRequestHandler::NCRequestHandler(
const string &name) :
161 BESDEBUG(NC_NAME,
"In NCRequestHandler::NCRequestHandler" << endl);
163 add_method(DAS_RESPONSE, NCRequestHandler::nc_build_das);
164 add_method(DDS_RESPONSE, NCRequestHandler::nc_build_dds);
165 add_method(DATA_RESPONSE, NCRequestHandler::nc_build_data);
167 add_method(DMR_RESPONSE, NCRequestHandler::nc_build_dmr);
168 add_method(DAP4DATA_RESPONSE, NCRequestHandler::nc_build_dmr);
170 add_method(HELP_RESPONSE, NCRequestHandler::nc_build_help);
171 add_method(VERS_RESPONSE, NCRequestHandler::nc_build_version);
175 if (NCRequestHandler::_show_shared_dims_set ==
false) {
176 bool key_found =
false;
181 NCRequestHandler::_show_shared_dims_set =
true;
184 if (doset ==
"true" || doset ==
"yes") {
185 NCRequestHandler::_show_shared_dims =
true;
188 NCRequestHandler::_show_shared_dims =
false;
192 if (NCRequestHandler::_ignore_unknown_types_set ==
false) {
193 bool key_found =
false;
198 if (doset ==
"true" || doset ==
"yes")
199 NCRequestHandler::_ignore_unknown_types =
true;
201 NCRequestHandler::_ignore_unknown_types =
false;
203 NCRequestHandler::_ignore_unknown_types_set =
true;
207 if (NCRequestHandler::_promote_byte_to_short_set ==
false) {
208 bool key_found =
false;
213 if (doset ==
"true" || doset ==
"yes")
214 NCRequestHandler::_promote_byte_to_short =
true;
216 NCRequestHandler::_promote_byte_to_short =
false;
218 NCRequestHandler::_promote_byte_to_short_set =
true;
222 NCRequestHandler::_use_mds = get_bool_key(
"NC.UseMDS",
false);
223 NCRequestHandler::_cache_entries = get_uint_key(
"NC.CacheEntries", 0);
224 NCRequestHandler::_cache_purge_level = get_float_key(
"NC.CachePurgeLevel", 0.2);
226 if (get_cache_entries()) {
227 das_cache =
new ObjMemCache(get_cache_entries(), get_cache_purge_level());
228 dds_cache =
new ObjMemCache(get_cache_entries(), get_cache_purge_level());
229 datadds_cache =
new ObjMemCache(get_cache_entries(), get_cache_purge_level());
230 dmr_cache =
new ObjMemCache(get_cache_entries(), get_cache_purge_level());
233 BESDEBUG(NC_NAME,
"Exiting NCRequestHandler::NCRequestHandler" << endl);
236 NCRequestHandler::~NCRequestHandler()
240 delete datadds_cache;
247 if (BESISDEBUG( TIMING_LOG ))
248 sw.
start(
"NCRequestHandler::nc_build_das", dhi.
data[REQUEST_ID]);
250 BESDEBUG(NC_NAME,
"In NCRequestHandler::nc_build_das" << endl);
260 DAS *das = bdas->get_das();
261 if (!container_name.empty()) das->container_name(container_name);
265 DAS *cached_das_ptr = 0;
266 if (das_cache && (cached_das_ptr =
static_cast<DAS*
>(das_cache->
get(accessed)))) {
268 BESDEBUG(NC_NAME,
"DAS Cached hit for : " << accessed << endl);
269 *das = *cached_das_ptr;
272 nc_read_dataset_attributes(*das, accessed);
273 Ancillary::read_ancillary_das(*das, accessed);
276 BESDEBUG(NC_NAME,
"DAS added to the cache for : " << accessed << endl);
277 das_cache->
add(
new DAS(*das), accessed);
286 catch (InternalErr & e) {
287 BESDapError ex(e.get_error_message(),
true, e.get_error_code(), __FILE__, __LINE__);
291 BESDapError ex(e.get_error_message(),
false, e.get_error_code(), __FILE__, __LINE__);
294 catch (std::exception &e) {
295 string s = string(
"C++ Exception: ") + e.what();
300 string s =
"unknown exception caught building DAS";
305 BESDEBUG(NC_NAME,
"Exiting NCRequestHandler::nc_build_das" << endl);
315 void NCRequestHandler::get_dds_with_attributes(
const string& dataset_name,
const string& container_name, DDS* dds)
318 DDS* cached_dds_ptr = 0;
319 if (dds_cache && (cached_dds_ptr =
static_cast<DDS*
>(dds_cache->
get(dataset_name)))) {
322 BESDEBUG(NC_NAME,
"DDS Cached hit for : " << dataset_name << endl);
323 *dds = *cached_dds_ptr;
326 if (!container_name.empty()) dds->container_name(container_name);
327 dds->filename(dataset_name);
329 nc_read_dataset_variables(*dds, dataset_name);
332 if (das_cache && (das =
static_cast<DAS*
>(das_cache->
get(dataset_name)))) {
333 BESDEBUG(NC_NAME,
"DAS Cached hit for : " << dataset_name << endl);
334 dds->transfer_attributes(das);
340 if (!container_name.empty()) das->container_name(container_name);
342 nc_read_dataset_attributes(*das, dataset_name);
343 Ancillary::read_ancillary_das(*das, dataset_name);
345 dds->transfer_attributes(das);
350 BESDEBUG(NC_NAME,
"DAS added to the cache for : " << dataset_name << endl);
351 das_cache->
add(das, dataset_name);
360 BESDEBUG(NC_NAME,
"DDS added to the cache for : " << dataset_name << endl);
361 dds_cache->
add(
new DDS(*dds), dataset_name);
366 void NCRequestHandler::get_dds_without_attributes(
const string& dataset_name,
const string& container_name, DDS* dds)
369 DDS* cached_datadds_ptr = 0;
370 if (datadds_cache && (cached_datadds_ptr =
static_cast<DDS*
>(datadds_cache->
get(dataset_name)))) {
372 BESDEBUG(NC_NAME,
"DataDDS Cached hit for : " << dataset_name << endl);
373 *dds = *cached_datadds_ptr;
376 if (!container_name.empty()) dds->container_name(container_name);
377 dds->filename(dataset_name);
379 nc_read_dataset_variables(*dds, dataset_name);
383 BESDEBUG(NC_NAME,
"DataDDS added to the cache for : " << dataset_name << endl);
384 datadds_cache->
add(
new DDS(*dds), dataset_name);
394 if (BESISDEBUG( TIMING_LOG ))
395 sw.
start(
"NCRequestHandler::nc_build_dds", dhi.
data[REQUEST_ID]);
406 if (NCRequestHandler::_show_shared_dims_set ==
false) {
407 bool context_found =
false;
408 string context_value = BESContextManager::TheManager()->
get_context(
"xdap_accept", context_found);
410 BESDEBUG(NC_NAME,
"xdap_accept: " << context_value << endl);
411 if (version_ge(context_value, 3.2))
412 NCRequestHandler::_show_shared_dims =
false;
414 NCRequestHandler::_show_shared_dims =
true;
430 catch (InternalErr & e) {
431 BESDapError ex(e.get_error_message(),
true, e.get_error_code(), __FILE__, __LINE__);
435 BESDapError ex(e.get_error_message(),
false, e.get_error_code(), __FILE__, __LINE__);
438 catch (std::exception &e) {
439 string s = string(
"C++ Exception: ") + e.what();
444 string s =
"unknown exception caught building DDS";
455 if (BESISDEBUG( TIMING_LOG ))
456 sw.
start(
"NCRequestHandler::nc_build_data", dhi.
data[REQUEST_ID]);
464 if (NCRequestHandler::_show_shared_dims_set ==
false) {
465 bool context_found =
false;
466 string context_value = BESContextManager::TheManager()->
get_context(
"xdap_accept", context_found);
468 BESDEBUG(NC_NAME,
"xdap_accept: " << context_value << endl);
469 if (version_ge(context_value, 3.2))
470 NCRequestHandler::_show_shared_dims =
false;
472 NCRequestHandler::_show_shared_dims =
true;
477 DDS *dds = bdds->get_dds();
480 get_dds_without_attributes(dhi.
container->
access(), container_name, dds);
483 BESDEBUG(NC_NAME,
"Data ACCESS build_data(): set the including attribute flag to false: "<<dhi.
container->
access() << endl);
484 bdds->set_ia_flag(
false);
490 catch (InternalErr & e) {
491 BESDapError ex(e.get_error_message(),
true, e.get_error_code(), __FILE__, __LINE__);
495 BESDapError ex(e.get_error_message(),
false, e.get_error_code(), __FILE__, __LINE__);
498 catch (std::exception &e) {
499 string s = string(
"C++ Exception: ") + e.what();
504 string s =
"unknown exception caught building DAS";
515 if (BESISDEBUG( TIMING_LOG ))
516 sw.
start(
"NCRequestHandler::nc_build_dmr", dhi.
data[REQUEST_ID]);
531 DMR *dmr = bdmr.get_dmr();
534 DMR* cached_dmr_ptr = 0;
535 if (dmr_cache && (cached_dmr_ptr =
static_cast<DMR*
>(dmr_cache->
get(dataset_name)))) {
537 BESDEBUG(NC_NAME,
"DMR Cached hit for : " << dataset_name << endl);
538 *dmr = *cached_dmr_ptr;
543 BaseTypeFactory factory;
544 DDS dds(&factory, name_path(dataset_name),
"3.2");
547 get_dds_with_attributes(dataset_name,
"", &dds);
549 dmr->set_factory(
new D4BaseTypeFactory);
550 dmr->build_using_dds(dds);
554 dmr->set_factory(
new D4BaseTypeFactory);
557 if (dds_cache && (dds_ptr =
static_cast<DDS*
>(dds_cache->
get(dataset_name)))) {
559 BESDEBUG(NC_NAME,
"DDS Cached hit (while building DMR) for : " << dataset_name << endl);
561 dmr->build_using_dds(*dds_ptr);
566 BaseTypeFactory factory;
567 DDS dds(&factory, name_path(dataset_name),
"3.2");
569 dds.filename(dataset_name);
570 nc_read_dataset_variables(dds, dataset_name);
574 nc_read_dataset_attributes(das, dataset_name);
575 Ancillary::read_ancillary_das(das, dataset_name);
577 dds.transfer_attributes(&das);
578 dmr->build_using_dds(dds);
584 BESDEBUG(NC_NAME,
"DMR added to the cache for : " << dataset_name << endl);
585 dmr_cache->
add(
new DMR(*dmr), dataset_name);
597 catch (InternalErr &e) {
598 throw BESDapError(e.get_error_message(),
true, e.get_error_code(), __FILE__, __LINE__);
601 throw BESDapError(e.get_error_message(),
false, e.get_error_code(), __FILE__, __LINE__);
604 throw BESDapError(
"Caught unknown error build NC DMR response",
true, unknown_error, __FILE__, __LINE__);
613 if (BESISDEBUG( TIMING_LOG ))
614 sw.
start(
"NCRequestHandler::nc_build_help", dhi.
data[REQUEST_ID]);
621 map < string, string > attrs;
622 attrs[
"name"] = MODULE_NAME ;
623 attrs[
"version"] = MODULE_VERSION ;
625 attrs[
"name"] = PACKAGE_NAME;
626 attrs[
"version"] = PACKAGE_VERSION;
628 list < string > services;
630 if (services.size() > 0) {
632 attrs[
"handles"] = handles;
634 info->begin_tag(
"module", &attrs);
635 info->end_tag(
"module");
643 if (BESISDEBUG( TIMING_LOG ))
644 sw.
start(
"NCRequestHandler::nc_build_version", dhi.
data[REQUEST_ID]);
652 info->add_module(PACKAGE_NAME, PACKAGE_VERSION);
654 info->add_module(MODULE_NAME, MODULE_VERSION);
665 DDS *dds = bdds->get_dds();
669 if (das_cache && (das =
static_cast<DAS*
>(das_cache->
get(dataset_name)))) {
670 BESDEBUG(NC_NAME,
"DAS Cached hit for : " << dataset_name << endl);
671 dds->transfer_attributes(das);
677 if (!container_name.empty()) das->container_name(container_name);
680 if(
true == get_use_mds()) {
683 bool valid_mds =
true;
688 if(
true ==valid_mds) {
693 BESDEBUG(
"nc",
"Using MDS to generate DAS in the data response for file " << dataset_name << endl);
694 mds->parse_das_from_mds(das,rel_file_path);
697 nc_read_dataset_attributes(*das, dataset_name);
699 mds_das_lock.clearLock();
702 nc_read_dataset_attributes(*das, dataset_name);
706 nc_read_dataset_attributes(*das, dataset_name);
708 Ancillary::read_ancillary_das(*das, dataset_name);
710 dds->transfer_attributes(das);
715 BESDEBUG(NC_NAME,
"DAS added to the cache for : " << dataset_name << endl);
716 das_cache->
add(das, dataset_name);
722 BESDEBUG(NC_NAME,
"Data ACCESS in add_attributes(): set the including attribute flag to true: "<<dataset_name << endl);
723 bdds->set_ia_flag(
true);