35#include <libdap/DataDDS.h>
37#include <BESConstraintFuncs.h>
38#include <BESContainerStorage.h>
39#include <BESContainerStorageList.h>
40#include <BESDapNames.h>
41#include <BESDapResponse.h>
42#include <BESDataDDSResponse.h>
43#include <BESDataHandlerInterface.h>
44#include <BESDDSResponse.h>
45#include <BESStopWatch.h>
46#include <BESInternalError.h>
47#include <BESResponseHandler.h>
48#include <BESResponseNames.h>
49#include <BESRequestHandlerList.h>
50#include <BESServiceRegistry.h>
51#include <BESTextInfo.h>
53#include <BESVersionInfo.h>
66#define prolog std::string("DDSLoader::").append(__func__).append("() - ")
71long DDSLoader::_gensymID = 0L;
76 _dhi(dhi), _hijacked(false), _filename(
""), _store(0), _containerSymbol(
""), _origAction(
""), _origActionName(
77 ""), _origContainer(0), _origResponse(0)
83 _dhi(proto._dhi), _hijacked(false), _filename(
""), _store(0), _containerSymbol(
""), _origAction(
84 ""), _origActionName(
""), _origContainer(0), _origResponse(0)
91 BESDEBUG(
"ncml",
"DDSLoader::operator=: " << endl);
128 if (&_dhi != &rhs._dhi) _dhi.make_copy(rhs._dhi);
140unique_ptr<BESDapResponse> DDSLoader::load(
const string& location, ResponseType type)
145 loadInto(location, type, response.get());
152 VALID_PTR(pResponse);
153 VALID_PTR(_dhi.response_handler);
159 _filename = location;
175 container = addNewContainerToStorage();
179 removeContainerFromStorage();
200 _dhi.container = container;
201 _dhi.response_handler->set_response_object(pResponse);
210 THROW_NCML_INTERNAL_ERROR(
"DDSLoader::load expected BESDDSResponse or BESDataDDSResponse but got neither!");
216 BESDEBUG(
"ncml",
"Before BESRequestHandlerList::TheList()->execute_current" << endl);
217 BESDEBUG(
"ncml",
"Handler name: " << BESRequestHandlerList::TheList()->get_handler_names() << endl);
219 BESRequestHandlerList::TheList()->execute_current(_dhi);
224 if(type == eRT_RequestDataDDS) {
231 if(bdds->get_ia_flag() ==
false) {
232 BESDEBUG(
"ncml",
"Underneath handler "<< _dhi.container->get_container_type() <<
" call add_attributes() " << endl);
233 BESRequestHandler *besRH = BESRequestHandlerList::TheList()->find_handler(_dhi.container->get_container_type());
234 besRH->add_attributes(_dhi);
238 BESDEBUG(
"ncml",
"After BESRequestHandlerList::TheList()->execute_current.\n");
257bool is_url(
const std::string &location) {
258 std::string
http(
"http://");
259 std::string https(
"https://");
262 std::string tip = location.substr(0,
http.size());
263 std::transform(tip.begin(), tip.end(), tip.begin(), ::tolower);
264 bool result =
http == tip;
267 tip = location.substr(0,https.size());
268 std::transform(tip.begin(), tip.end(), tip.begin(), ::tolower);
270 result = result ||
http == tip;
276DDSLoader::addNewContainerToStorage()
280 VALID_PTR(store_list);
284 if(is_url(_filename)){
285 BESDEBUG(
"ncml", __func__ <<
"() - GATEWAY CONTAINER!" << endl);
286 store = store_list->find_persistence(
"gateway");
289 store = store_list->find_persistence(
"catalog");
292 throw BESInternalError(
"couldn't find the catalog storage", __FILE__, __LINE__);
296 string newSymbol = getNextContainerName() +
"__" + _filename;
307 _containerSymbol = newSymbol;
310 BESContainer *container = store->
look_for(_containerSymbol);
312 throw BESInternalError(
"couldn't find the container we just added:" + newSymbol, __FILE__, __LINE__);
318void DDSLoader::removeContainerFromStorage()
326 _store->del_container(_containerSymbol);
328 catch (BESError& besErr) {
329 ERROR_LOG(
"WARNING: tried to remove symbol " + _containerSymbol
330 +
" from singleton but unexpectedly it was not there.\n");
332 _containerSymbol =
"";
337void DDSLoader::snapshotDHI()
339 VALID_PTR(_dhi.response_handler);
341 BESDEBUG(
"ncml",
"DDSLoader::snapshotDHI() - Taking snapshot of DataHAndlerInterface for (action: " << _dhi.action <<
" action_name: " << _dhi.action_name <<
")" << endl );
342 BESDEBUG(
"ncml_verbose",
"original dhi = " << _dhi << endl );
345 _origContainer = _dhi.container;
347 _origAction = _dhi.action;
348 _origActionName = _dhi.action_name;
350 _origResponse = _dhi.response_handler->get_response_object();
352 BESDEBUG(
"ncml",
"DDSLoader::snapshotDHI() - Replaced with DataHAndlerInterface for (action: " << _dhi.action <<
" action_name: " << _dhi.action_name <<
")" << endl );
357void DDSLoader::restoreDHI()
359 VALID_PTR(_dhi.response_handler);
377 if (_dhi.container) _dhi.container->release();
379 delete _dhi.container;
382 _dhi.container = _origContainer;
383 _dhi.action = _origAction;
384 _dhi.action_name = _origActionName;
386 _dhi.response_handler->set_response_object(_origResponse);
388 BESDEBUG(
"ncml",
"DDSLoader::restoreDHI() - Restored of DataHAndlerInterface for (action: " << _dhi.action <<
" action_name: " << _dhi.action_name <<
")" << endl );
390 BESDEBUG(
"ncml_verbose",
"restored dhi = " << _dhi << endl );
394 _origActionName =
"";
405void DDSLoader::ensureClean()
414 removeContainerFromStorage();
418std::string DDSLoader::getNextContainerName()
420 static const string _sPrefix =
"__DDSLoader_Container_ID_";
422 std::ostringstream oss;
423 oss << _sPrefix << (_gensymID);
429 if (type == eRT_RequestDDX) {
431 return unique_ptr<BESDapResponse>(
new BESDDSResponse(
new DDS(
nullptr ,
"virtual")));
433 else if (type == eRT_RequestDataDDS) {
435 return unique_ptr<BESDapResponse>(
new BESDataDDSResponse(
new DDS(
nullptr ,
"virtual")));
438 THROW_NCML_INTERNAL_ERROR(
"DDSLoader::makeResponseForType() got unknown type!");
444 if (type == eRT_RequestDDX) {
447 else if (type == eRT_RequestDataDDS) {
448 return DATA_RESPONSE;
451 THROW_NCML_INTERNAL_ERROR(
"DDSLoader::getActionForType(): unknown type!");
456 if (type == eRT_RequestDDX) {
457 return DDX_RESPONSE_STR;
459 else if (type == eRT_RequestDataDDS) {
460 return DATA_RESPONSE_STR;
463 THROW_NCML_INTERNAL_ERROR(
"DDSLoader::getActionNameForType(): unknown type!");
468 if (type == eRT_RequestDDX) {
471 else if (type == eRT_RequestDataDDS) {
Provides a mechanism for accessing container information from different container stores registered w...
provides persistent storage for data storage information represented by a container.
virtual void add_container(const std::string &sym_name, const std::string &real_name, const std::string &type)=0
adds a container with the provided information
virtual BESContainer * look_for(const std::string &sym_name)=0
looks for a container in this persistent store
A container is something that holds data. E.G., a netcdf file or a database entry.
Holds a DDS object within the BES.
Represents an OPeNDAP DAP response object within the BES.
std::string get_request_xml_base() const
Return the xml:base URL for this request.
Represents an OPeNDAP DataDDS DAP2 data object within the BES.
Structure storing information used by the BES to handle the request.
Base exception class for the BES with basic string message.
exception thrown if internal error encountered
Represents a specific data type request handler.
Abstract base class representing a specific set of information in response to a request to the BES.
static std::unique_ptr< BESDapResponse > makeResponseForType(ResponseType type)
void loadInto(const std::string &location, ResponseType type, BESDapResponse *pResponse)
Load a DDX or DataDDS response into the given pResponse object, which must be non-null.
DDSLoader(BESDataHandlerInterface &dhi)
Create a loader that will hijack dhi on a load call, then restore it's state.
static bool checkResponseIsValidType(ResponseType type, BESDapResponse *pResponse)
void cleanup()
restore dhi to clean state
static std::string getActionForType(ResponseType type)
static std::string getActionNameForType(ResponseType type)
virtual ~DDSLoader()
Dtor restores the state of dhi Restores the state of the dhi to what it was when object if it is stil...
static libdap::DDS * getDDSFromEitherResponse(BESDapResponse *response)
Helper class for temporarily hijacking an existing dhi to load a DDX response for one particular file...
utility class for the HTTP catalog module