31#ifdef HAVE_UUID_UUID_H
33#elif defined(HAVE_UUID_H)
36#error "Could not find UUID library header"
57#define CLEAR_LOCAL_DATA
58#undef USE_LOCAL_TIMEOUT_SCHEME
60#include <libdap/DAS.h>
61#include <libdap/DDS.h>
62#include <libdap/Structure.h>
63#include <libdap/ConstraintEvaluator.h>
64#include <libdap/DDXParserSAX2.h>
65#include <libdap/Ancillary.h>
66#include <libdap/XDRStreamMarshaller.h>
67#include <libdap/XDRFileUnMarshaller.h>
69#include <libdap/DMR.h>
70#include <libdap/D4Group.h>
71#include <libdap/D4Attributes.h>
72#include <libdap/XMLWriter.h>
73#include <libdap/D4AsyncUtil.h>
74#include <libdap/D4StreamMarshaller.h>
75#include <libdap/chunked_ostream.h>
76#include <libdap/chunked_istream.h>
77#include <libdap/D4ConstraintEvaluator.h>
78#include <libdap/D4FunctionEvaluator.h>
79#include <libdap/D4BaseTypeFactory.h>
81#include <libdap/ServerFunctionsList.h>
83#include <libdap/mime_util.h>
84#include <libdap/escaping.h>
85#include <libdap/util.h>
88#if USE_LOCAL_TIMEOUT_SCHEME
90#include <libdap/SignalHandler.h>
91#include <libdap/EventHandler.h>
92#include <libdap/AlarmHandler.h>
96#include "TheBESKeys.h"
97#include "BESDapResponseBuilder.h"
98#include "BESContextManager.h"
99#include "BESDapFunctionResponseCache.h"
100#include "BESStoredDapResultCache.h"
103#include "BESResponseObject.h"
104#include "BESDDSResponse.h"
105#include "BESDataDDSResponse.h"
106#include "BESDMRResponse.h"
107#include "BESDataHandlerInterface.h"
108#include "BESInternalFatalError.h"
109#include "BESSyntaxUserError.h"
110#include "BESDataNames.h"
112#include "BESRequestHandler.h"
113#include "BESRequestHandlerList.h"
114#include "BESNotFoundError.h"
119#include "BESStopWatch.h"
120#include "DapFunctionUtils.h"
125const string CRLF =
"\r\n";
126const string BES_KEY_TIMEOUT_CANCEL =
"BES.CancelTimeoutOnSend";
129#define prolog std::string("BESDapResponseBuilder::").append(__func__).append("() - ")
138 string cancel_timeout_on_send =
"";
140 if (found && !cancel_timeout_on_send.empty()) {
142 downcase(cancel_timeout_on_send);
143 if (cancel_timeout_on_send ==
"yes" || cancel_timeout_on_send ==
"true")
148BESDapResponseBuilder::~BESDapResponseBuilder()
150#if USE_LOCAL_TIMEOUT_SCHEME
154 delete dynamic_cast<AlarmHandler*
>(SignalHandler::instance()->remove_handler(SIGALRM));
231std::string BESDapResponseBuilder::get_store_result()
const
236void BESDapResponseBuilder::set_store_result(std::string _sr)
239 BESDEBUG(MODULE, prolog <<
"store_result: " << _sr << endl);
242std::string BESDapResponseBuilder::get_async_accepted()
const
247void BESDapResponseBuilder::set_async_accepted(std::string _aa)
250 BESDEBUG(MODULE, prolog <<
"set_async_accepted() - async_accepted: " << _aa << endl);
278 d_dataset = www2id(ds,
"%",
"%20");
306#if USE_LOCAL_TIMEOUT_SCHEME
321#if USE_LOCAL_TIMEOUT_SCHEME
358#if USE_LOCAL_TIMEOUT_SCHEME
360 SignalHandler *sh = SignalHandler::instance();
361 EventHandler *old_eh = sh->register_handler(SIGALRM,
new AlarmHandler());
375#if USE_LOCAL_TIMEOUT_SCHEME
378 SignalHandler *sh = SignalHandler::instance();
379 EventHandler *old_eh = sh->register_handler(SIGALRM,
new AlarmHandler());
401static string::size_type find_closing_paren(
const string &ce, string::size_type pos)
408 pos = ce.find_first_of(
"()", pos + 1);
409 if (pos == string::npos){
411 msg <<
"Expected to find a matching closing parenthesis in: " << ce;
433 BESDEBUG(MODULE, prolog <<
"source expression: " << expr << endl);
441 string btp_function_ce =
"";
442 string::size_type pos = 0;
446 string::size_type first_paren = ce.find(
"(", pos);
447 string::size_type closing_paren = string::npos;
448 if (first_paren != string::npos) closing_paren = find_closing_paren(ce, first_paren);
450 while (first_paren != string::npos && closing_paren != string::npos) {
452 string name = ce.substr(pos, first_paren - pos);
456 if (eval.find_function(name, &f)) {
458 if (!btp_function_ce.empty()) btp_function_ce +=
",";
459 btp_function_ce += ce.substr(pos, closing_paren + 1 - pos);
460 ce.erase(pos, closing_paren + 1 - pos);
461 if (ce[pos] ==
',') ce.erase(pos, 1);
464 pos = closing_paren + 1;
466 if (pos < ce.length() && ce.at(pos) ==
',') ++pos;
469 first_paren = ce.find(
"(", pos);
470 closing_paren = ce.find(
")", pos);
476 BESDEBUG(MODULE, prolog <<
"Modified constraint: " <<
d_dap2ce << endl);
477 BESDEBUG(MODULE, prolog <<
"BTP Function part: " << btp_function_ce << endl);
478 BESDEBUG(MODULE, prolog <<
"END" << endl);
488throw_if_dap2_response_too_big(DDS *dds)
490 if (dds->too_big()) {
493 msg <<
"The Request for " << request_size / 1024 <<
" kilobytes is too large; ";
494 msg <<
"requests on this server are limited to "
495 + long_to_string(dds->get_response_limit() /1024) +
"KB.";
496 throw Error(msg.str());
499 msg <<
"The submitted DAP2 request will generate a " << dds->get_request_size_kb(
true);
500 msg <<
" kilobyte response, which is too large. ";
501 msg <<
"The maximum response size for this server is limited to " << dds->get_response_limit_kb();
502 msg <<
" kilobytes.";
508throw_if_dap4_response_too_big(DMR &dmr)
512 msg <<
"The submitted DAP4 request will generate a " << dmr.request_size_kb(
true);
513 msg <<
" kilobyte response, which is too large. ";
514 msg <<
"The maximum response size for this server is limited to " << dmr.response_limit_kb();
515 msg <<
" kilobytes.";
534void BESDapResponseBuilder::send_das(ostream &out, DAS &das,
bool with_mime_headers)
const
536 if (with_mime_headers) set_mime_text(out, dods_das, x_plain, last_modified_time(d_dataset),
"2.0");
560void BESDapResponseBuilder::send_das(ostream &out, DDS **dds, ConstraintEvaluator &eval,
bool constrained,
561 bool with_mime_headers)
563#if USE_LOCAL_TIMEOUT_SCHEME
569 if (with_mime_headers) set_mime_text(out, dods_das, x_plain, last_modified_time(d_dataset),
"2.0");
573 (*dds)->print_das(out);
585 ConstraintEvaluator func_eval;
589 if (responseCache && responseCache->can_be_cached(*dds, get_btp_func_ce())) {
593 func_eval.parse_constraint(get_btp_func_ce(), **dds);
594 fdds = func_eval.eval_function_clauses(**dds);
597 delete *dds; *dds = 0;
600 if (with_mime_headers)
601 set_mime_text(out, dods_das, x_plain, last_modified_time(d_dataset), (*dds)->get_dap_version());
605 (*dds)->print_das(out);
608 eval.parse_constraint(
d_dap2ce, **dds);
610 if (with_mime_headers)
611 set_mime_text(out, dods_das, x_plain, last_modified_time(d_dataset), (*dds)->get_dap_version());
615 (*dds)->print_das(out);
641 bool with_mime_headers)
644 if (with_mime_headers)
645 set_mime_text(out, dods_dds, x_plain, last_modified_time(d_dataset), (*dds)->get_dap_version());
654#if USE_LOCAL_TIMEOUT_SCHEME
667 ConstraintEvaluator func_eval;
672 if (responseCache && responseCache->can_be_cached(*dds, get_btp_func_ce())) {
676 func_eval.parse_constraint(get_btp_func_ce(), **dds);
677 fdds = func_eval.eval_function_clauses(**dds);
680 delete *dds; *dds = 0;
688 (*dds)->mark_all(
false);
700 promote_function_output_structures(*dds);
702 eval.parse_constraint(
d_dap2ce, **dds);
704 if (with_mime_headers)
705 set_mime_text(out, dods_dds, x_plain, last_modified_time(d_dataset), (*dds)->get_dap_version());
710 (*dds)->print_constrained(out);
713 eval.parse_constraint(
d_dap2ce, **dds);
715 if (with_mime_headers)
716 set_mime_text(out, dods_dds, x_plain, last_modified_time(d_dataset),(*dds)->get_dap_version());
720 (*dds)->print_constrained(out);
726#ifdef DAP2_STORED_RESULTS
741bool BESDapResponseBuilder::store_dap2_result(ostream &out, DDS &dds, ConstraintEvaluator &eval)
743 if (get_store_result().empty())
return false;
745 string serviceUrl = get_store_result();
756 string *stylesheet_ref = 0, ss_ref_value;
758 if (found && ss_ref_value.length() > 0) {
759 stylesheet_ref = &ss_ref_value;
763 if (resultCache == NULL) {
770 string msg =
"The Stored Result request cannot be serviced. ";
771 msg +=
"Unable to acquire StoredResultCache instance. ";
772 msg +=
"This is most likely because the StoredResultCache is not (correctly) configured.";
774 BESDEBUG(MODULE, prolog <<
"[WARNING] " << msg << endl);
776 d4au.writeD4AsyncResponseRejected(xmlWrtr, UNAVAILABLE, msg, stylesheet_ref);
777 out << xmlWrtr.get_doc();
780 BESDEBUG(MODULE,prolog <<
"Sent AsyncRequestRejected" << endl);
782 else if (get_async_accepted().length() != 0) {
787 BESDEBUG(MODULE, prolog <<
"serviceUrl="<< serviceUrl << endl);
790 string storedResultId =
"";
791 storedResultId = resultCache->store_dap2_result(dds,
get_ce(),
this, &eval);
793 BESDEBUG(MODULE, prolog <<
"storedResultId='"<< storedResultId <<
"'" << endl);
796 BESDEBUG(MODULE, prolog <<
"targetURL='"<< targetURL <<
"'" << endl);
799 d4au.writeD4AsyncAccepted(xmlWrtr, 0, 0, targetURL, stylesheet_ref);
800 out << xmlWrtr.get_doc();
803 BESDEBUG(MODULE, prolog <<
"Sent DAP4 AsyncAccepted response" << endl);
810 d4au.writeD4AsyncRequired(xmlWrtr, 0, 0, stylesheet_ref);
811 out << xmlWrtr.get_doc();
814 BESDEBUG(MODULE, prolog <<
"Sent DAP4 AsyncRequired response" << endl);
828 if (
BESDebug::IsSet(TIMING_LOG_KEY) || BESLog::TheLog()->is_verbose()) sw.
start(prolog +
"Timer",
"");
830 BESDEBUG(MODULE, prolog <<
"BEGIN" << endl);
832 (*dds)->print_constrained(out);
836 XDRStreamMarshaller m(out);
843 for (DDS::Vars_iter i = (*dds)->var_begin(); i != (*dds)->var_end(); i++) {
844 if ((*i)->send_p()) {
845 (*i)->serialize(eval, **dds, m, ce_eval);
846#ifdef CLEAR_LOCAL_DATA
847 (*i)->clear_local_data();
852 BESDEBUG(MODULE, prolog <<
"END" << endl);
855#ifdef DAP2_STORED_RESULTS
864void BESDapResponseBuilder::serialize_dap2_data_ddx(ostream &out, DDS **dds, ConstraintEvaluator &eval,
865 const string &boundary,
const string &start,
bool ce_eval)
867 BESDEBUG(MODULE, prolog <<
"BEGIN" << endl);
870 libdap::set_mime_ddx_boundary(out, boundary, start, dods_ddx, x_plain);
876 uuid_unparse(uu, &uuid[0]);
878 if (getdomainname(domain, 255) != 0 || strlen(domain) == 0) strncpy(domain,
"opendap.org", 255);
880 string cid = string(&uuid[0]) +
"@" + string(&domain[0]);
884 (*dds)->print_xml_writer(out,
true, cid);
887 set_mime_data_boundary(out, boundary, cid, dods_data_ddx , x_plain);
889 XDRStreamMarshaller m(out);
895 for (DDS::Vars_iter i = (*dds)->var_begin(); i != (*dds)->var_end(); i++) {
896 if ((*i)->send_p()) {
897 (*i)->serialize(eval, **dds, m, ce_eval);
898#ifdef CLEAR_LOCAL_DATA
899 (*i)->clear_local_data();
904 BESDEBUG(MODULE, prolog <<
"END" << endl);
926#if USE_LOCAL_TIMEOUT_SCHEME
947 BESDEBUG(MODULE, prolog <<
"BEGIN"<< endl);
958 set_async_accepted(dhi.
data[ASYNC]);
959 set_store_result(dhi.
data[STORE_RESULT]);
961 ConstraintEvaluator &eval = bdds->
get_ce();
972 ConstraintEvaluator func_eval;
974 if (responseCache && responseCache->can_be_cached(dds, get_btp_func_ce())) {
978 func_eval.parse_constraint(get_btp_func_ce(), *dds);
979 fdds = func_eval.eval_function_clauses(*dds);
986 dds->mark_all(
false);
988 promote_function_output_structures(dds);
991 eval.parse_constraint(
d_dap2ce, *dds);
992 BESDEBUG(MODULE, prolog <<
"END"<< endl);
1018 if (
BESDebug::IsSet(TIMING_LOG_KEY) || BESLog::TheLog()->is_verbose()) sw.
start(prolog +
"Timer",
"");
1020 BESDEBUG(MODULE, prolog <<
"BEGIN"<< endl);
1025 if (!bdds)
throw BESInternalFatalError(
"Expected a BESDataDDSResponse instance", __FILE__, __LINE__);
1027 DDS *dds = bdds->get_dds();
1031 set_async_accepted(dhi.
data[ASYNC]);
1032 set_store_result(dhi.
data[STORE_RESULT]);
1037 if(bdds->get_ia_flag() ==
false) {
1039 besRH->add_attributes(dhi);
1042 ConstraintEvaluator &eval = bdds->get_ce();
1050 if (!get_btp_func_ce().empty()) {
1051 BESDEBUG(MODULE,prolog <<
"Found function(s) in CE: " << get_btp_func_ce() << endl);
1055 ConstraintEvaluator func_eval;
1056 DDS *fdds =
nullptr;
1057 if (responseCache && responseCache->can_be_cached(dds, get_btp_func_ce())) {
1061 func_eval.parse_constraint(get_btp_func_ce(), *dds);
1062 fdds = func_eval.eval_function_clauses(*dds);
1074 dds->mark_all(
false);
1085 promote_function_output_structures(dds);
1089 eval.parse_constraint(
get_ce(), *dds);
1091 dds->tag_nested_sequences();
1093 throw_if_dap2_response_too_big(dds);
1097 for (DDS::Vars_iter i = dds->var_begin(), e = dds->var_end(); i != e; ++i) {
1098 if ((*i)->send_p()) {
1100 (*i)->intern_data(eval, *dds);
1102 catch(std::exception &e) {
1103 throw BESSyntaxUserError(
string(
"Caught a C++ standard exception while working on '") + (*i)->name() +
"' The error was: " + e.what(), __FILE__, __LINE__);
1108 BESDEBUG(MODULE, prolog <<
"END"<< endl);
1126void BESDapResponseBuilder::send_dap2_data(ostream &data_stream, DDS **dds, ConstraintEvaluator &eval,
1127 bool with_mime_headers)
1129 BESDEBUG(MODULE, prolog <<
"BEGIN"<< endl);
1131#if USE_LOCAL_TIMEOUT_SCHEME
1143 if (!get_btp_func_ce().empty()) {
1144 BESDEBUG(MODULE,prolog <<
"Found function(s) in CE: " << get_btp_func_ce() << endl);
1148 ConstraintEvaluator func_eval;
1150 if (response_cache && response_cache->can_be_cached(*dds, get_btp_func_ce())) {
1154 func_eval.parse_constraint(get_btp_func_ce(), **dds);
1155 fdds = func_eval.eval_function_clauses(**dds);
1158 delete *dds; *dds = 0;
1161 (*dds)->mark_all(
false);
1163 promote_function_output_structures(*dds);
1166 eval.parse_constraint(
get_ce(), **dds);
1168 (*dds)->tag_nested_sequences();
1170 throw_if_dap2_response_too_big(*dds);
1172 if (with_mime_headers)
1173 set_mime_binary(data_stream, dods_data, x_plain, last_modified_time(d_dataset), (*dds)->get_dap_version());
1175#if STORE_DAP2_RESULT_FEATURE
1177 if (!store_dap2_result(data_stream, **dds, eval)) {
1186 BESDEBUG(MODULE, prolog <<
"Simple constraint" << endl);
1188 eval.parse_constraint(
get_ce(), **dds);
1190 (*dds)->tag_nested_sequences();
1192 throw_if_dap2_response_too_big(*dds);
1194 if (with_mime_headers)
1195 set_mime_binary(data_stream, dods_data, x_plain, last_modified_time(d_dataset), (*dds)->get_dap_version());
1197#if STORE_DAP2_RESULT_FEATURE
1199 if (!store_dap2_result(data_stream, **dds, eval)) {
1207 data_stream << flush;
1209 BESDEBUG(MODULE, prolog <<
"END"<< endl);
1214 bool with_mime_headers)
1216 BESDEBUG(MODULE, prolog <<
"BEGIN"<< endl);
1218 ostream & data_stream = dhi.get_output_stream();
1219#if USE_LOCAL_TIMEOUT_SCHEME
1231 if (!get_btp_func_ce().empty()) {
1232 BESDEBUG(MODULE, prolog <<
"Found function(s) in CE: " << get_btp_func_ce() << endl);
1242 if(!bdds->get_ia_flag()) {
1244 besRH->add_attributes(dhi);
1249 ConstraintEvaluator func_eval;
1250 DDS *fdds =
nullptr;
1251 if (response_cache && response_cache->can_be_cached(*dds, get_btp_func_ce())) {
1255 func_eval.parse_constraint(get_btp_func_ce(), **dds);
1256 fdds = func_eval.eval_function_clauses(**dds);
1263 (*dds)->mark_all(
false);
1265 promote_function_output_structures(*dds);
1268 eval.parse_constraint(
get_ce(), **dds);
1270 (*dds)->tag_nested_sequences();
1272 throw_if_dap2_response_too_big(*dds);
1274 if (with_mime_headers)
1275 set_mime_binary(data_stream, dods_data, x_plain, last_modified_time(d_dataset), (*dds)->get_dap_version());
1277#if STORE_DAP2_RESULT_FEATURE
1279 if (!store_dap2_result(data_stream, **dds, eval)) {
1288 BESDEBUG(MODULE, prolog <<
"Simple constraint" << endl);
1290 eval.parse_constraint(
get_ce(), **dds);
1292 (*dds)->tag_nested_sequences();
1294 throw_if_dap2_response_too_big(*dds);
1296 if (with_mime_headers)
1297 set_mime_binary(data_stream, dods_data, x_plain, last_modified_time(d_dataset), (*dds)->get_dap_version());
1299#if STORE_DAP2_RESULT_FEATURE
1301 if (!store_dap2_result(data_stream, **dds, eval)) {
1309 data_stream << flush;
1311 BESDEBUG(MODULE, prolog <<
"END"<< endl);
1330 if (with_mime_headers)
1331 set_mime_text(out, dods_ddx, x_plain, last_modified_time(d_dataset), (*dds)->get_dap_version());
1333 (*dds)->print_xml_writer(out,
false ,
"");
1339#if USE_LOCAL_TIMEOUT_SCHEME
1354 ConstraintEvaluator func_eval;
1356 if (response_cache && response_cache->can_be_cached(*dds, get_btp_func_ce())) {
1360 func_eval.parse_constraint(get_btp_func_ce(), **dds);
1361 fdds = func_eval.eval_function_clauses(**dds);
1364 delete *dds; *dds = 0;
1367 (*dds)->mark_all(
false);
1369 promote_function_output_structures(*dds);
1371 eval.parse_constraint(
d_dap2ce, **dds);
1373 if (with_mime_headers)
1374 set_mime_text(out, dods_ddx, x_plain, last_modified_time(d_dataset), (*dds)->get_dap_version());
1378 (*dds)->print_xml_writer(out,
true,
"");
1381 eval.parse_constraint(
d_dap2ce, **dds);
1383 if (with_mime_headers)
1384 set_mime_text(out, dods_ddx, x_plain, last_modified_time(d_dataset), (*dds)->get_dap_version());
1390 (*dds)->print_xml_writer(out,
true,
"");
1396void BESDapResponseBuilder::send_dmr(ostream &out, DMR &dmr,
bool with_mime_headers)
1403 BESDEBUG(MODULE, prolog <<
"Parsing DAP4 constraint: '"<<
d_dap4ce <<
"'"<< endl);
1405 D4ConstraintEvaluator parser(&dmr);
1406 bool parse_ok = parser.parse(
d_dap4ce);
1409 msg <<
"Failed to parse the provided DAP4 server-side function expression: " <<
d_dap4function;
1417 dmr.root()->set_send_p(
true);
1420 if (with_mime_headers) set_mime_text(out, dap4_dmr, x_plain, last_modified_time(d_dataset), dmr.dap_version());
1424 BESDEBUG(MODULE, prolog <<
"dmr.request_xml_base(): '"<< dmr.request_xml_base() <<
"' (dmr: " << (
void *) &dmr <<
")" << endl);
1427 dmr.print_dap4(xml, !
d_dap4ce.empty() );
1428 out << xml.get_doc() << flush;
1431void BESDapResponseBuilder::send_dap4_data_using_ce(ostream &out, DMR &dmr,
bool with_mime_headers)
1434 BESDEBUG(MODULE ,
"BESDapResponseBuilder::send_dap4_data_using_ce() - expression constraint is not empty. " <<endl);
1435 D4ConstraintEvaluator parser(&dmr);
1436 bool parse_ok = parser.parse(
d_dap4ce);
1439 msg <<
"Failed to parse the provided DAP4 server-side function expression: " <<
d_dap4function;
1447 dmr.set_ce_empty(
true);
1448 dmr.root()->set_send_p(
true);
1451 throw_if_dap4_response_too_big(dmr);
1455 for (
auto i = dmr.root()->var_begin(), e = dmr.root()->var_end(); i != e; ++i) {
1456 BESDEBUG(MODULE , prolog << (*i)->name() << endl);
1457 if ((*i)->send_p()) {
1458 BESDEBUG(MODULE , prolog <<
"Obtain data- " << (*i)->name() << endl);
1459 D4Attributes *d4_attrs = (*i)->attributes();
1460 BESDEBUG(MODULE , prolog <<
"Number of attributes " << d4_attrs << endl);
1461 for (
auto ii = d4_attrs->attribute_begin(), ee = d4_attrs->attribute_end(); ii != ee; ++ii) {
1462 BESDEBUG(MODULE ,prolog <<
"Attribute name is " << (*ii)->name() << endl);
1484 if (
BESDebug::IsSet(TIMING_LOG_KEY) || BESLog::TheLog()->is_verbose()) sw.
start(prolog +
"Timer",
"");
1486 BESDEBUG(MODULE , prolog <<
"Expression constraint is not empty. " <<endl);
1487 D4ConstraintEvaluator parser(&dmr);
1488 bool parse_ok = parser.parse(
d_dap4ce);
1491 msg <<
"Failed to parse the provided DAP4 server-side function expression: " <<
d_dap4function;
1499 dmr.set_ce_empty(
true);
1500 dmr.root()->set_send_p(
true);
1502 throw_if_dap4_response_too_big(dmr);
1505void BESDapResponseBuilder::send_dap4_data(ostream &out, DMR &dmr,
bool with_mime_headers)
1511 D4BaseTypeFactory d4_factory;
1512 DMR function_result(&d4_factory,
"function_results");
1516 if (!ServerFunctionsList::TheList()) {
1518 msg <<
"The function expression could not be evaluated because ";
1519 msg <<
"there are no server-side functions defined on this server.";
1523 D4FunctionEvaluator parser(&dmr, ServerFunctionsList::TheList());
1527 msg <<
"Failed to parse the provided DAP4 server-side function expression: " <<
d_dap4function;
1530 parser.eval(&function_result);
1534 send_dap4_data_using_ce(out, function_result, with_mime_headers);
1537 send_dap4_data_using_ce(out, dmr, with_mime_headers);
1547 if (
BESDebug::IsSet(TIMING_LOG_KEY) || BESLog::TheLog()->is_verbose()) sw.
start(prolog +
"Timer",
"");
1549 BESDEBUG(MODULE, prolog <<
"BEGIN" << endl);
1551 if (with_mime_headers) set_mime_binary(out, dap4_data, x_plain, last_modified_time(d_dataset), dmr.dap_version());
1553 BESDEBUG(MODULE, prolog <<
"dmr.request_xml_base(): \"" << dmr.request_xml_base() <<
"\""<< endl);
1557 dmr.print_dap4(xml, !
d_dap4ce.empty());
1562 chunked_ostream cos(out, max((
unsigned int) CHUNK_SIZE, xml.get_doc_size() + 2));
1567 cos << xml.get_doc() << CRLF << flush;
1570 D4StreamMarshaller m(cos);
1571 dmr.root()->serialize(m, dmr, !
d_dap4ce.empty());
1572#ifdef CLEAR_LOCAL_DATA
1573 dmr.root()->clear_local_data();
1577 BESDEBUG(MODULE, prolog <<
"END" << endl);
1596 if (get_store_result().length() != 0) {
1597 string serviceUrl = get_store_result();
1604 string *stylesheet_ref = 0, ss_ref_value;
1606 if (found && ss_ref_value.length() > 0) {
1607 stylesheet_ref = &ss_ref_value;
1611 if (resultCache == NULL) {
1618 string msg =
"The Stored Result request cannot be serviced. ";
1619 msg +=
"Unable to acquire StoredResultCache instance. ";
1620 msg +=
"This is most likely because the StoredResultCache is not (correctly) configured.";
1622 BESDEBUG(MODULE, prolog <<
"[WARNING] " << msg << endl);
1623 d4au.writeD4AsyncResponseRejected(xmlWrtr, UNAVAILABLE, msg, stylesheet_ref);
1624 out << xmlWrtr.get_doc();
1626 BESDEBUG(MODULE, prolog <<
"Sent AsyncRequestRejected" << endl);
1631 if (get_async_accepted().length() != 0) {
1636 BESDEBUG(MODULE, prolog <<
"serviceUrl="<< serviceUrl << endl);
1638 string storedResultId =
"";
1641 BESDEBUG(MODULE,prolog <<
"storedResultId='"<< storedResultId <<
"'" << endl);
1644 BESDEBUG(MODULE, prolog <<
"targetURL='"<< targetURL <<
"'" << endl);
1646 d4au.writeD4AsyncAccepted(xmlWrtr, 0, 0, targetURL, stylesheet_ref);
1647 out << xmlWrtr.get_doc();
1649 BESDEBUG(MODULE, prolog <<
"Sent AsyncAccepted" << endl);
1657 d4au.writeD4AsyncRequired(xmlWrtr, 0, 0, stylesheet_ref);
1658 out << xmlWrtr.get_doc();
1660 BESDEBUG(MODULE, prolog <<
"Sent AsyncAccepted" << endl);
1691 if (
BESDebug::IsSet(TIMING_LOG_KEY) || BESLog::TheLog()->is_verbose()) sw.
start(prolog +
"Timer",
"");
1692 BESDEBUG(MODULE , prolog <<
"BEGIN" << endl);
1694 unique_ptr<DMR> dmr = setup_dap4_intern_data(obj, dhi);
1696 intern_dap4_data_grp(dmr->root());
1698 return dmr.release();
1709 unique_ptr<DMR> dmr(bdmr->get_dmr());
1712 bdmr->set_dmr(
nullptr);
1722 set_async_accepted(dhi.
data[ASYNC]);
1723 set_store_result(dhi.
data[STORE_RESULT]);
1726 D4BaseTypeFactory d4_factory;
1727 unique_ptr<DMR> function_result(
new DMR(&d4_factory,
"function_results"));
1731 if (!ServerFunctionsList::TheList()) {
1733 msg <<
"The function expression could not be evaluated because ";
1734 msg <<
"there are no server-side functions defined on this server.";
1738 D4FunctionEvaluator parser(dmr.get(), ServerFunctionsList::TheList());
1742 msg <<
"Failed to parse the provided DAP4 server-side function expression: " <<
d_dap4function;
1746 parser.eval(function_result.get());
1752 return function_result;
1755 BESDEBUG(MODULE , prolog <<
"Processing the constraint expression. " << endl);
1761void BESDapResponseBuilder::intern_dap4_data_grp(libdap::D4Group* grp) {
1762 for (D4Group::Vars_iter i = grp->var_begin(), e = grp->var_end(); i != e; ++i) {
1763 BESDEBUG(MODULE ,
"BESDapResponseBuilder::intern_dap4_data() - "<< (*i)->name() <<endl);
1764 if ((*i)->send_p()) {
1765 BESDEBUG(MODULE ,
"BESDapResponseBuilder::intern_dap4_data() Obtain data- "<< (*i)->name() <<endl);
1766 (*i)->intern_data();
1770 for (D4Group::groupsIter gi = grp->grp_begin(), ge = grp->grp_end(); gi != ge; ++gi) {
1771 BESDEBUG(MODULE ,
"BESDapResponseBuilder::intern_dap4_data() group- "<< (*gi)->name() <<endl);
1772 intern_dap4_data_grp(*gi);
std::string get_container_type() const
retrieve the type of data this container holds, such as cedar or netcdf.
Holds a DDS object within the BES.
libdap::ConstraintEvaluator & get_ce()
void set_dds(libdap::DDS *ddsIn)
Represents an OPeNDAP DMR DAP4 data object within the BES.
Cache the results from server functions.
virtual libdap::DDS * get_or_cache_dataset(libdap::DDS *dds, const std::string &constraint)
Return a DDS loaded with data that can be serialized back to a client.
virtual void set_dataset_name(const std::string _dataset)
Set the dataset pathname.
virtual std::string get_dataset_name() const
Get the dataset name.
virtual libdap::DMR * intern_dap4_data(BESResponseObject *obj, BESDataHandlerInterface &dhi)
void register_timeout() const
std::string d_dap4function
DAP4 Constraint expression.
virtual std::string get_dap4function() const
Get the DAP4 server side function expression.
virtual void split_ce(libdap::ConstraintEvaluator &eval, const std::string &expr="")
virtual std::string get_ce() const
Get the constraint expression.
int d_timeout
The BTP functions, extracted from the CE.
std::string d_dap2ce
Name of the dataset/database.
virtual void set_dap4ce(std::string _ce)
virtual void remove_timeout() const
Transmit data.
virtual libdap::DDS * process_dap2_dds(BESResponseObject *obj, BESDataHandlerInterface &dhi)
Process a DDS (i.e., apply a constraint) for a non-DAP transmitter.
virtual void serialize_dap4_data(std::ostream &out, libdap::DMR &dmr, bool with_mime_headers=true)
virtual libdap::DDS * intern_dap2_data(BESResponseObject *obj, BESDataHandlerInterface &dhi)
virtual void send_dds(std::ostream &out, libdap::DDS **dds, libdap::ConstraintEvaluator &eval, bool constrained=false, bool with_mime_headers=true)
Transmit a DDS.
virtual std::string get_dap4ce() const
Get the DAP4 constraint expression.
virtual void dap4_process_ce_for_intern_data(libdap::DMR &dmr)
Parse the DAP4 CE and throw if the request is too large.
virtual void establish_timeout(std::ostream &stream) const
bool d_cancel_timeout_on_send
Version string for the library's default protocol version.
std::string d_async_accepted
Should a timeout be cancelled once transmission starts?
void conditional_timeout_cancel()
virtual void send_ddx(std::ostream &out, libdap::DDS **dds, libdap::ConstraintEvaluator &eval, bool with_mime_headers=true)
virtual void serialize_dap2_data_dds(std::ostream &out, libdap::DDS **dds, libdap::ConstraintEvaluator &eval, bool ce_eval=true)
std::string d_store_result
virtual void set_dap4function(std::string _func)
virtual bool store_dap4_result(std::ostream &out, libdap::DMR &dmr)
void set_timeout(int timeout=0)
virtual void set_ce(std::string _ce)
std::string d_btp_func_ce
DAP4 Server Side Function expression.
std::string d_dap4ce
DAP2 Constraint expression.
Represents an OPeNDAP DataDDS DAP2 data object within the BES.
void set_dds(libdap::DDS *ddsIn)
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.
void first_container()
set the container pointer to the first container in the containers list
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
exception thrown if internal error encountered
exception thrown if an internal error is found and is fatal to the BES
virtual BESRequestHandler * find_handler(const std::string &handler_name)
find and return the specified request handler
Represents a specific data type request handler.
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 bool start(std::string name)
virtual string store_dap4_result(libdap::DMR &dmr, const string &constraint, BESDapResponseBuilder *rb)
static BESStoredDapResultCache * get_instance()
error thrown if there is a user syntax error in the request or any other user error
static std::string assemblePath(const std::string &firstPart, const std::string &secondPart, bool leadingSlash=false, bool trailingSlash=false)
Assemble path fragments making sure that they are separated by a single '/' character.
void get_value(const std::string &s, std::string &val, bool &found)
Retrieve the value of a given key, if set.
static TheBESKeys * TheKeys()