29 #include <curl/curl.h> 32 #include <Ancillary.h> 33 #include <ObjMemCache.h> 38 #include <InternalErr.h> 39 #include <mime_util.h> 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> 52 #include <BESDMRResponse.h> 54 #include <BESConstraintFuncs.h> 55 #include <BESServiceRegistry.h> 57 #include <TheBESKeys.h> 59 #include <BESDapError.h> 60 #include <BESInternalFatalError.h> 62 #include <BESStopWatch.h> 65 #include "DmrppTypeFactory.h" 66 #include "DmrppParserSax2.h" 67 #include "DmrppRequestHandler.h" 68 #include "CurlHandlePool.h" 69 #include "DmrppMetadataStore.h" 77 const string module =
"dmrpp";
85 CurlHandlePool *DmrppRequestHandler::curl_handle_pool = 0;
87 bool DmrppRequestHandler::d_use_parallel_transfers =
true;
88 int DmrppRequestHandler::d_max_parallel_transfers = 8;
90 static void read_key_value(
const std::string &key_name,
bool &key_value)
92 bool key_found =
false;
97 key_value = (value ==
"true" || value ==
"yes");
101 static void read_key_value(
const std::string &key_name,
int &key_value)
103 bool key_found =
false;
107 istringstream iss(value);
116 DmrppRequestHandler::DmrppRequestHandler(
const string &name) :
120 add_method(DAP4DATA_RESPONSE, dap_build_dap4data);
128 read_key_value(
"DMRPP.UseParallelTransfers", d_use_parallel_transfers);
129 read_key_value(
"DMRPP.MaxParallelTransfers", d_max_parallel_transfers);
131 if (!curl_handle_pool)
134 curl_global_init(CURL_GLOBAL_DEFAULT);
137 DmrppRequestHandler::~DmrppRequestHandler()
139 delete curl_handle_pool;
140 curl_global_cleanup();
143 void DmrppRequestHandler::build_dmr_from_file(
BESContainer *container, DMR* dmr)
145 string data_pathname = container->
access();
147 dmr->set_filename(data_pathname);
148 dmr->set_name(name_path(data_pathname));
150 DmrppTypeFactory BaseFactory;
151 dmr->set_factory(&BaseFactory);
153 DmrppParserSax2 parser;
154 ifstream in(data_pathname.c_str(), ios::in);
175 BESDEBUG(module,
"Entering dap_build_dmr..." << endl);
179 if (!bdmr)
throw BESInternalError(
"Cast error, expected a BESDDSResponse object.", __FILE__, __LINE__);
182 build_dmr_from_file(dhi.
container, bdmr->get_dmr());
190 catch (InternalErr & e) {
191 throw BESDapError(e.get_error_message(),
true, e.get_error_code(), __FILE__, __LINE__);
194 throw BESDapError(e.get_error_message(),
false, e.get_error_code(), __FILE__, __LINE__);
200 BESDEBUG(module,
"Leaving dap_build_dmr..." << endl);
207 BESDEBUG(module,
"Entering dap_build_dap4data..." << endl);
211 if (!bdmr)
throw BESInternalError(
"Cast error, expected a BESDMRResponse object.", __FILE__, __LINE__);
218 throw BESInternalError(
"MDS configuration error: The DMR++ module could not find the MDS", __FILE__, __LINE__);
222 throw BESInternalError(
"DMR++ module error: Null DMR++ object read from the MDS", __FILE__, __LINE__);
224 delete bdmr->get_dmr();
225 bdmr->set_dmr(dmrpp);
228 build_dmr_from_file(dhi.
container, bdmr->get_dmr());
237 catch (InternalErr & e) {
238 throw BESDapError(e.get_error_message(),
true, e.get_error_code(), __FILE__, __LINE__);
241 throw BESDapError(e.get_error_message(),
false, e.get_error_code(), __FILE__, __LINE__);
244 throw BESInternalFatalError(
"Unknown exception caught building DAP4 Data response", __FILE__, __LINE__);
247 BESDEBUG(module,
"Leaving dap_build_dap4data..." << endl);
258 if (BESISDEBUG(TIMING_LOG)) sw.
start(
"DmrppRequestHandler::dap_build_dap2data()", dhi.
data[REQUEST_ID]);
260 BESDEBUG(module, __func__ <<
"() - BEGIN" << endl);
264 if (!bdds)
throw BESInternalError(
"Cast error, expected a BESDataDDSResponse object.", __FILE__, __LINE__);
269 DDS *dds = bdds->get_dds();
270 if (!container_name_str.empty()) dds->container_name(container_name_str);
274 DDS *cached_dds_ptr = 0;
275 if (dds_cache && (cached_dds_ptr = static_cast<DDS*>(dds_cache->
get(accessed)))) {
277 BESDEBUG(module,
"DDS Cached hit for : " << accessed << endl);
278 *dds = *cached_dds_ptr;
289 throw BESInternalError(
"MDS configuration error: The DMR++ module could not find the MDS", __FILE__, __LINE__);
293 throw BESInternalError(
"DMR++ module error: Null DMR++ object read from the MDS", __FILE__, __LINE__);
313 dds_cache->
add(
new DDS(*dds), accessed);
322 catch (InternalErr & e) {
323 BESDapError ex(e.get_error_message(),
true, e.get_error_code(), __FILE__, __LINE__);
327 BESDapError ex(e.get_error_message(),
false, e.get_error_code(), __FILE__, __LINE__);
330 catch (std::exception &e) {
331 string s = string(
"C++ Exception: ") + e.what();
336 string s =
"unknown exception caught building DDS";
341 BESDEBUG(module,
"DmrppRequestHandler::dap_build_dds() - END" << endl);
351 if (BESISDEBUG(TIMING_LOG)) sw.
start(
"DmrppRequestHandler::dap_build_dds()", dhi.
data[REQUEST_ID]);
353 BESDEBUG(module, __func__ <<
"() - BEGIN" << endl);
357 if (!bdds)
throw BESInternalError(
"Cast error, expected a BESDDSResponse object.", __FILE__, __LINE__);
363 if (!container_name_str.empty()) dds->container_name(container_name_str);
367 DDS *cached_dds_ptr = 0;
368 if (dds_cache && (cached_dds_ptr = static_cast<DDS*>(dds_cache->
get(accessed)))) {
370 BESDEBUG(module,
"DDS Cached hit for : " << accessed << endl);
371 *dds = *cached_dds_ptr;
375 DMR *dmr =
new DMR();
391 dds_cache->
add(
new DDS(*dds), accessed);
400 catch (InternalErr & e) {
401 BESDapError ex(e.get_error_message(),
true, e.get_error_code(), __FILE__, __LINE__);
405 BESDapError ex(e.get_error_message(),
false, e.get_error_code(), __FILE__, __LINE__);
408 catch (std::exception &e) {
409 string s = string(
"C++ Exception: ") + e.what();
414 string s =
"unknown exception caught building DDS";
419 BESDEBUG(module,
"DmrppRequestHandler::dap_build_dds() - END" << endl);
430 if (BESISDEBUG(TIMING_LOG)) sw.
start(
"DmrppRequestHandler::dap_build_das()", dhi.
data[REQUEST_ID]);
434 if (!bdas)
throw BESInternalError(
"Cast error, expected a BESDASResponse object.", __FILE__, __LINE__);
439 DAS *das = bdas->get_das();
440 if (!container_name_str.empty()) das->container_name(container_name_str);
444 DAS *cached_das_ptr = 0;
445 if (das_cache && (cached_das_ptr = static_cast<DAS*>(das_cache->
get(accessed)))) {
447 *das = *cached_das_ptr;
452 DMR *dmr =
new DMR();
456 DDS *dds = dmr->getDDS();
464 Ancillary::read_ancillary_das(*das, accessed);
467 das_cache->
add(
new DAS(*das), accessed);
476 catch (InternalErr & e) {
477 BESDapError ex(e.get_error_message(),
true, e.get_error_code(), __FILE__, __LINE__);
481 BESDapError ex(e.get_error_message(),
false, e.get_error_code(), __FILE__, __LINE__);
484 catch (std::exception &e) {
485 string s = string(
"C++ Exception: ") + e.what();
490 string s =
"unknown exception caught building DAS";
495 BESDEBUG(module, __func__ <<
"() - END" << endl);
505 info->add_module(MODULE_NAME, MODULE_VERSION);
516 map<string, string> attrs;
517 attrs[
"name"] = MODULE_NAME ;
518 attrs[
"version"] = MODULE_VERSION ;
519 list<string> services;
521 if (services.size() > 0) {
523 attrs[
"handles"] = handles;
525 info->begin_tag(
"module", &attrs);
526 info->end_tag(
"module");
533 strm << BESIndent::LMarg <<
"DmrppRequestHandler::dump - (" << (
void *)
this <<
")" << endl;
536 BESIndent::UnIndent();
void set_dds(libdap::DDS *ddsIn)
static bool dap_build_dap2data(BESDataHandlerInterface &dhi)
exception thrown if an internal error is found and is fatal to the BES
exception thrown if inernal error encountered
std::string get_relative_name() const
Get the relative name of the object in this container.
Provide a way to print the DMR++ response.
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
void set_dds(libdap::DDS *ddsIn)
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 bool start(string name)
virtual bool add_method(const 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
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)
static bool dap_build_das(BESDataHandlerInterface &dhi)
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
virtual void dump(std::ostream &strm) const
dumps information about this object
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.
static bool dap_build_dds(BESDataHandlerInterface &dhi)
virtual void dump(ostream &strm) const
dumps information about this object
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.
A container is something that holds data. E.G., a netcdf file or a database entry.
An in-memory cache for DapObj (DAS, DDS, ...) objects.
string get_attributes() const
retrieve the attributes desired from this container
Abstract base class representing a specific set of information in response to a request to the BES.
static bool IsSet(const std::string &flagName)
see if the debug context flagName is set to true
BESContainer * container
pointer to current container in this interface
static bool dap_build_dmr(BESDataHandlerInterface &dhi)
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