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"
70 #include "CredentialsManager.h"
78 const string module =
"dmrpp";
86 CurlHandlePool *DmrppRequestHandler::curl_handle_pool = 0;
88 bool DmrppRequestHandler::d_use_parallel_transfers =
true;
89 unsigned int DmrppRequestHandler::d_max_parallel_transfers = 8;
92 unsigned int DmrppRequestHandler::d_min_size = 2097152;
94 static void read_key_value(
const std::string &key_name,
bool &key_value)
96 bool key_found =
false;
101 key_value = (value ==
"true" || value ==
"yes");
105 static void read_key_value(
const std::string &key_name,
unsigned int &key_value)
107 bool key_found =
false;
111 istringstream iss(value);
120 DmrppRequestHandler::DmrppRequestHandler(
const string &name) :
124 add_method(DAP4DATA_RESPONSE, dap_build_dap4data);
132 read_key_value(
"DMRPP.UseParallelTransfers", d_use_parallel_transfers);
133 read_key_value(
"DMRPP.MaxParallelTransfers", d_max_parallel_transfers);
137 if (!curl_handle_pool)
140 curl_global_init(CURL_GLOBAL_DEFAULT);
143 DmrppRequestHandler::~DmrppRequestHandler()
145 delete curl_handle_pool;
146 curl_global_cleanup();
149 void DmrppRequestHandler::build_dmr_from_file(
BESContainer *container, DMR* dmr)
151 string data_pathname = container->
access();
153 dmr->set_filename(data_pathname);
154 dmr->set_name(name_path(data_pathname));
156 DmrppTypeFactory BaseFactory;
157 dmr->set_factory(&BaseFactory);
159 DmrppParserSax2 parser;
160 ifstream in(data_pathname.c_str(), ios::in);
181 BESDEBUG(module,
"Entering dap_build_dmr..." << endl);
185 if (!bdmr)
throw BESInternalError(
"Cast error, expected a BESDDSResponse object.", __FILE__, __LINE__);
188 build_dmr_from_file(dhi.
container, bdmr->get_dmr());
196 catch (InternalErr & e) {
197 throw BESDapError(e.get_error_message(),
true, e.get_error_code(), __FILE__, __LINE__);
200 throw BESDapError(e.get_error_message(),
false, e.get_error_code(), __FILE__, __LINE__);
206 BESDEBUG(module,
"Leaving dap_build_dmr..." << endl);
213 BESDEBUG(module,
"Entering dap_build_dap4data..." << endl);
217 if (!bdmr)
throw BESInternalError(
"Cast error, expected a BESDMRResponse object.", __FILE__, __LINE__);
224 throw BESInternalError(
"MDS configuration error: The DMR++ module could not find the MDS", __FILE__, __LINE__);
228 throw BESInternalError(
"DMR++ module error: Null DMR++ object read from the MDS", __FILE__, __LINE__);
230 delete bdmr->get_dmr();
231 bdmr->set_dmr(dmrpp);
234 build_dmr_from_file(dhi.
container, bdmr->get_dmr());
243 catch (InternalErr & e) {
244 throw BESDapError(e.get_error_message(),
true, e.get_error_code(), __FILE__, __LINE__);
247 throw BESDapError(e.get_error_message(),
false, e.get_error_code(), __FILE__, __LINE__);
250 throw BESInternalFatalError(
"Unknown exception caught building DAP4 Data response", __FILE__, __LINE__);
253 BESDEBUG(module,
"Leaving dap_build_dap4data..." << endl);
264 if (BESISDEBUG(TIMING_LOG)) sw.
start(
"DmrppRequestHandler::dap_build_dap2data()", dhi.
data[REQUEST_ID]);
266 BESDEBUG(module, __func__ <<
"() - BEGIN" << endl);
270 if (!bdds)
throw BESInternalError(
"Cast error, expected a BESDataDDSResponse object.", __FILE__, __LINE__);
275 DDS *dds = bdds->get_dds();
276 if (!container_name_str.empty()) dds->container_name(container_name_str);
280 DDS *cached_dds_ptr = 0;
281 if (dds_cache && (cached_dds_ptr =
static_cast<DDS*
>(dds_cache->
get(accessed)))) {
283 BESDEBUG(module,
"DDS Cached hit for : " << accessed << endl);
284 *dds = *cached_dds_ptr;
295 throw BESInternalError(
"MDS configuration error: The DMR++ module could not find the MDS", __FILE__, __LINE__);
299 throw BESInternalError(
"DMR++ module error: Null DMR++ object read from the MDS", __FILE__, __LINE__);
319 dds_cache->
add(
new DDS(*dds), accessed);
328 catch (InternalErr & e) {
329 BESDapError ex(e.get_error_message(),
true, e.get_error_code(), __FILE__, __LINE__);
333 BESDapError ex(e.get_error_message(),
false, e.get_error_code(), __FILE__, __LINE__);
336 catch (std::exception &e) {
337 string s = string(
"C++ Exception: ") + e.what();
342 string s =
"unknown exception caught building DDS";
347 BESDEBUG(module,
"DmrppRequestHandler::dap_build_dds() - END" << endl);
357 if (BESISDEBUG(TIMING_LOG)) sw.
start(
"DmrppRequestHandler::dap_build_dds()", dhi.
data[REQUEST_ID]);
359 BESDEBUG(module, __func__ <<
"() - BEGIN" << endl);
363 if (!bdds)
throw BESInternalError(
"Cast error, expected a BESDDSResponse object.", __FILE__, __LINE__);
369 if (!container_name_str.empty()) dds->container_name(container_name_str);
373 DDS *cached_dds_ptr = 0;
374 if (dds_cache && (cached_dds_ptr =
static_cast<DDS*
>(dds_cache->
get(accessed)))) {
376 BESDEBUG(module,
"DDS Cached hit for : " << accessed << endl);
377 *dds = *cached_dds_ptr;
381 DMR *dmr =
new DMR();
397 dds_cache->
add(
new DDS(*dds), accessed);
406 catch (InternalErr & e) {
407 BESDapError ex(e.get_error_message(),
true, e.get_error_code(), __FILE__, __LINE__);
411 BESDapError ex(e.get_error_message(),
false, e.get_error_code(), __FILE__, __LINE__);
414 catch (std::exception &e) {
415 string s = string(
"C++ Exception: ") + e.what();
420 string s =
"unknown exception caught building DDS";
425 BESDEBUG(module,
"DmrppRequestHandler::dap_build_dds() - END" << endl);
436 if (BESISDEBUG(TIMING_LOG)) sw.
start(
"DmrppRequestHandler::dap_build_das()", dhi.
data[REQUEST_ID]);
440 if (!bdas)
throw BESInternalError(
"Cast error, expected a BESDASResponse object.", __FILE__, __LINE__);
445 DAS *das = bdas->get_das();
446 if (!container_name_str.empty()) das->container_name(container_name_str);
450 DAS *cached_das_ptr = 0;
451 if (das_cache && (cached_das_ptr =
static_cast<DAS*
>(das_cache->
get(accessed)))) {
453 *das = *cached_das_ptr;
458 DMR *dmr =
new DMR();
462 DDS *dds = dmr->getDDS();
470 Ancillary::read_ancillary_das(*das, accessed);
473 das_cache->
add(
new DAS(*das), accessed);
482 catch (InternalErr & e) {
483 BESDapError ex(e.get_error_message(),
true, e.get_error_code(), __FILE__, __LINE__);
487 BESDapError ex(e.get_error_message(),
false, e.get_error_code(), __FILE__, __LINE__);
490 catch (std::exception &e) {
491 string s = string(
"C++ Exception: ") + e.what();
496 string s =
"unknown exception caught building DAS";
501 BESDEBUG(module, __func__ <<
"() - END" << endl);
511 info->add_module(MODULE_NAME, MODULE_VERSION);
522 map<string, string> attrs;
523 attrs[
"name"] = MODULE_NAME ;
524 attrs[
"version"] = MODULE_VERSION ;
525 list<string> services;
527 if (services.size() > 0) {
529 attrs[
"handles"] = handles;
531 info->begin_tag(
"module", &attrs);
532 info->end_tag(
"module");
539 strm << BESIndent::LMarg <<
"DmrppRequestHandler::dump - (" << (
void *)
this <<
")" << endl;
542 BESIndent::UnIndent();
A container is something that holds data. E.G., a netcdf file or a database entry.
std::string get_attributes() const
retrieve the attributes desired from this container
std::string get_symbolic_name() const
retrieve the symbolic name for this container
std::string get_relative_name() const
Get the relative name of the object in this container.
virtual std::string access()=0
returns the true name of this container
Represents an OPeNDAP DAS DAP2 data object within the BES.
virtual void clear_container()
clear the container in the DAP response object
Holds a DDS object within the BES.
void set_dds(libdap::DDS *ddsIn)
virtual void clear_container()
clear the container in the DAP response object
Represents an OPeNDAP DMR DAP4 data object within the BES.
error object created from libdap error objects and can handle those errors
virtual void set_dap4_function(BESDataHandlerInterface &dhi)
set the constraint depending on the context
virtual void set_dap4_constraint(BESDataHandlerInterface &dhi)
set the constraint depending on the context
virtual void set_constraint(BESDataHandlerInterface &dhi)
set the constraint depending on the context
bool get_explicit_containers() const
Should containers be explicitly represented in the DD* responses?
Represents an OPeNDAP DataDDS DAP2 data object within the BES.
void set_dds(libdap::DDS *ddsIn)
virtual void clear_container()
clear the container in the DAP response object
Structure storing information used by the BES to handle the request.
std::map< std::string, std::string > data
the map of string data that will be required for the current request.
BESContainer * container
pointer to current container in this interface
static bool IsSet(const std::string &flagName)
see if the debug context flagName is set to true
Abstract exception class for the BES with basic string message.
informational response object
exception thrown if internal error encountered
exception thrown if an internal error is found and is fatal to the BES
Represents a specific data type request handler.
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
virtual void dump(std::ostream &strm) const
dumps information about this object
virtual BESResponseObject * get_response_object()
return the current response object
Abstract base class representing a specific set of information in response to a request to the BES.
virtual void services_handled(const std::string &handler, std::list< std::string > &services)
returns the list of servies provided by the handler in question
virtual bool start(std::string name)
static std::string lowercase(const std::string &s)
static std::string implode(const std::list< std::string > &values, char delim)
static void load_credentials()
An in-memory cache for DapObj (DAS, DDS, ...) objects.
virtual void add(libdap::DapObj *obj, const std::string &key)
Add an object to the cache and associate it with a key.
virtual libdap::DapObj * get(const std::string &key)
Get the cached pointer.
void get_value(const std::string &s, std::string &val, bool &found)
Retrieve the value of a given key, if set.
static TheBESKeys * TheKeys()
Provide a way to print the DMR++ response.
static bool dap_build_dds(BESDataHandlerInterface &dhi)
static bool dap_build_dap2data(BESDataHandlerInterface &dhi)
static bool dap_build_dmr(BESDataHandlerInterface &dhi)
static bool dap_build_das(BESDataHandlerInterface &dhi)
virtual void dump(std::ostream &strm) const
dumps information about this object