bes Updated for version 3.21.1
The Backend Server (BES) is the lower two tiers of the Hyrax data server
NgapBuildDmrppContainer.cc
1// NgapBuildDmrppContainer.cc
2
3// -*- mode: c++; c-basic-offset:4 -*-
4
5// This file is part of builddmrpp_module, A C++ module that can be loaded in to
6// the OPeNDAP Back-End Server (BES) and is able to handle remote requests.
7
8// Copyright (c) 2023 OPeNDAP, Inc.
9// Authors: Daniel Holloway <dholloway@opendap.org>
10//
11// This library is free software; you can redistribute it and/or
12// modify it under the terms of the GNU Lesser General Public
13// License as published by the Free Software Foundation; either
14// version 2.1 of the License, or (at your option) any later version.
15//
16// This library is distributed in the hope that it will be useful,
17// but WITHOUT ANY WARRANTY; without even the implied warranty of
18// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19// Lesser General Public License for more details.
20//
21// You should have received a copy of the GNU Lesser General Public
22// License along with this library; if not, write to the Free Software
23// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24//
25// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
26// Authors:
27// dan Daniel Holloway <dholloway@opendap.org>
28// ndp Nathan Potter <ndp@opendap.org>
29
30#include "config.h"
31
32#include <map>
33#include <memory>
34#include <string>
35
36#include "BESStopWatch.h"
37#include "BESLog.h"
38#include "BESSyntaxUserError.h"
39#include "BESInternalError.h"
40#include "BESDebug.h"
41#include "BESContextManager.h"
42#include "CurlUtils.h"
43#include "RemoteResource.h"
44
45#include "NgapApi.h"
46#include "NgapNames.h"
47#include "NgapBuildDmrppContainer.h"
48
49#define prolog std::string("NgapBuildDmrppContainer::").append(__func__).append("() - ")
50
51using namespace std;
52using namespace ngap;
53
54namespace builddmrpp {
55
66NgapBuildDmrppContainer::NgapBuildDmrppContainer(const string &sym_name, const string &real_name, const string &type) :
67 BESContainer(sym_name, real_name, type) {
68 initialize();
69}
70
71void NgapBuildDmrppContainer::initialize()
72{
73 BESDEBUG(MODULE, prolog << "BEGIN (obj_addr: "<< (void *) this << ")" << endl);
74 BESDEBUG(MODULE, prolog << "sym_name: "<< get_symbolic_name() << endl);
75 BESDEBUG(MODULE, prolog << "real_name: "<< get_real_name() << endl);
76 BESDEBUG(MODULE, prolog << "type: "<< get_container_type() << endl);
77
78#if 0
79 // Removed jhrg 10/20/23
80 // I removed this becase the uid was used by convert_ngap_resty_...() only as part of
81 // the key for cached data. The cache has been moved out of that code and into the
82 // NgapContainer class.
83
84 bool found;
85 string uid = BESContextManager::TheManager()->get_context(EDL_UID_KEY, found);
86 BESDEBUG(MODULE, prolog << "EDL_UID_KEY(" << EDL_UID_KEY << "): " << uid << endl);
87#endif
88
90
91 set_real_name(data_access_url);
92
93 BESDEBUG(MODULE, prolog << "END (obj_addr: "<< (void *) this << ")" << endl);
94}
95
96NgapBuildDmrppContainer::NgapBuildDmrppContainer(const NgapBuildDmrppContainer &copy_from) :
97 BESContainer(copy_from), d_data_rresource(copy_from.d_data_rresource), d_real_name(copy_from.d_real_name) {
98
99 BESDEBUG(MODULE, prolog << "BEGIN object address: "<< (void *) this << " Copying from: " << (void *) &copy_from << endl);
100 // We can not make a copy of this container once the request has been made.
101 if (d_data_rresource) {
102 throw BESInternalError("The Container has already been accessed, cannot create a copy of this container.",
103 __FILE__, __LINE__);
104 }
105 BESDEBUG(MODULE, prolog << "object address: "<< (void *) this << endl);
106}
107
112void NgapBuildDmrppContainer::_duplicate(NgapBuildDmrppContainer &copy_to) {
113 BESDEBUG(MODULE, prolog << "BEGIN object address: "<< (void *) this << " Copying to: " << (void *) &copy_to << endl);
114
115 if (copy_to.d_data_rresource) {
116 throw BESInternalError("The Container has already been accessed, cannot duplicate this resource.",
117 __FILE__, __LINE__);
118 }
119
121
122 copy_to.d_real_name = d_real_name;
123 copy_to.d_data_rresource = d_data_rresource;
124}
125
128 auto container = make_unique<NgapBuildDmrppContainer>();
129 _duplicate(*container.get());
130 BESDEBUG(MODULE, prolog << "object address: "<< (void *) this << " to: " << container.get() << endl);
131 return container.release();
132}
133
140 BESDEBUG(MODULE, prolog << "BEGIN (obj_addr: "<< (void *) this << ")" << endl);
141
142 // Since this the ngap we know that the real_name is a URL.
143 string data_access_url_str = get_real_name();
144
145 BESDEBUG(MODULE, prolog << " data_access_url: " << data_access_url_str << endl);
146
147 string href="href=\"";
148 string trusted_url_hack= R"(" dmrpp:trust="true")";
149
150 string data_access_url_key = href + DATA_ACCESS_URL_KEY + "\"";
151 BESDEBUG(MODULE, prolog << " data_access_url_key: " << data_access_url_key << endl);
152
153 string data_access_url_with_trusted_attr_str = href + data_access_url_str + trusted_url_hack;
154 BESDEBUG(MODULE, prolog << " data_access_url_with_trusted_attr_str: " << data_access_url_with_trusted_attr_str << endl);
155
156 if (!d_data_rresource) {
157 BESDEBUG(MODULE, prolog << "Building new RemoteResource (dmr++)." << endl);
158 map<string, string> content_filters;
159
160 auto data_url(std::make_shared<http::url>(data_access_url_str, true));
161 {
162 d_data_rresource = std::make_shared<http::RemoteResource>(data_url);
163 BES_STOPWATCH_START(MODULE, prolog + "DMR++ retrieval: " + data_url->str());
164 d_data_rresource->retrieve_resource();
165 }
166 BESDEBUG(MODULE, prolog << "Retrieved remote resource: " << data_url->str() << endl);
167 }
168
169 string tmp_filename = d_data_rresource->get_filename();
170
171 BESDEBUG(MODULE, prolog << "Using local cache file: " << tmp_filename << endl);
172 BESDEBUG(MODULE, prolog << "Done retrieving: " << data_access_url_str << " returning cached file " << tmp_filename << endl);
173 BESDEBUG(MODULE, prolog << "END (obj_addr: "<< (void *) this << ")" << endl);
174
175 return tmp_filename; // this should return the dmr++ file name from the NgapCache
176}
177
185void NgapBuildDmrppContainer::dump(ostream &strm) const {
186 strm << BESIndent::LMarg << "NgapBuildDmrppContainer::dump - (" << (void *) this << ")" << endl;
187 BESIndent::Indent();
188 BESContainer::dump(strm);
189 if (d_data_rresource) {
190 strm << BESIndent::LMarg << "RemoteResource.getCacheFileName(): " << d_data_rresource->get_filename()
191 << endl;
192 } else {
193 strm << BESIndent::LMarg << "response not yet obtained" << endl;
194 }
195 BESIndent::UnIndent();
196}
197
198} // namespace builddmrpp
A container is something that holds data. E.G., a netcdf file or a database entry.
std::string get_symbolic_name() const
retrieve the symbolic name for this container
void dump(std::ostream &strm) const override
dumps information about this object
void set_real_name(const std::string &real_name)
set the real name for this container, such as a file name if reading a data file.
std::string get_container_type() const
retrieve the type of data this container holds, such as cedar or netcdf.
void _duplicate(BESContainer &copy_to)
duplicate this instance into the passed container
std::string get_real_name() const
retrieve the real name for this container, such as a file name.
exception thrown if internal error encountered
void _duplicate(NgapBuildDmrppContainer &copy_to)
Duplicate the contents of this instance into 'copy_to.'.
std::string access() override
access the remote target response by making the remote request
BESContainer * ptr_duplicate() override
pure abstract method to duplicate this instances of BESContainer
void dump(std::ostream &strm) const override
dumps information about this object
static std::string convert_ngap_resty_path_to_data_access_url(const std::string &restified_path)
Converts an NGAP restified granule path into a CMR metadata query for the granule.
Definition NgapApi.cc:414