bes Updated for version 3.21.1
The Backend Server (BES) is the lower two tiers of the Hyrax data server
HttpdCatalogContainer.cc
1// -*- mode: c++; c-basic-offset:4 -*-
2//
3// This file is part of cnr_module, A C++ module that can be loaded in to
4// the OPeNDAP Back-End Server (BES) and is able to handle remote requests.
5//
6// Copyright (c) 2018 OPeNDAP, Inc.
7// Author: Nathan Potter <ndp@opendap.org>
8//
9// This library is free software; you can redistribute it and/or
10// modify it under the terms of the GNU Lesser General Public
11// License as published by the Free Software Foundation; either
12// version 2.1 of the License, or (at your option) any later version.
13//
14// This library is distributed in the hope that it will be useful,
15// but WITHOUT ANY WARRANTY; without even the implied warranty of
16// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17// Lesser General Public License for more details.
18//
19// You should have received a copy of the GNU Lesser General Public
20// License along with this library; if not, write to the Free Software
21// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22//
23// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
24
25#include <memory>
26
27#include <BESSyntaxUserError.h>
28#include <BESInternalError.h>
29#include <BESDebug.h>
30#include <AllowedHosts.h>
31#include "RemoteResource.h"
32
33#include "HttpdCatalogContainer.h"
34#include "HttpdCatalog.h"
35
36using namespace std;
37using namespace bes;
38
39#define prolog std::string("HttpdCatalogContainer::").append(__func__).append("() - ")
40
41namespace httpd_catalog {
42
53HttpdCatalogContainer::HttpdCatalogContainer(const string &sym_name, const string &real_name, const string &type) :
54 BESContainer(sym_name, real_name, type), d_remoteResource(0)
55{
56
57 BESDEBUG(MODULE, prolog << "BEGIN sym_name: " << sym_name << " real_name: " << real_name << " type: " << type << endl);
58
59 string path = real_name;
60 if (path.empty() || path[0] != '/') {
61 path = "/" + path;
62 }
63
64#if 0
65 // unused
66 vector<string> path_elements = BESUtil::split(path);
67 BESDEBUG(MODULE, prolog << "path: '" << path << "' path_elements.size(): " << path_elements.size() << endl);
68#endif
69
70
72
73 // The container type is set in the access() method when the remote resource is accessed using the
74 // MIME type information using mappings between handlers (e.g., 'h5') and MIME types like application/x-hdf5.
75 // However, bes/dispatchBESContainerStorageVolatile::add_container(BESContainer *) expects the field
76 // to be not empty, so I'll add a place holder value. jhrg 1/25/19
77 if (type == "")
78 this->set_container_type("place_holder");
79
80 BESDEBUG(MODULE, prolog << "END" << endl);
81}
82
83HttpdCatalogContainer::HttpdCatalogContainer(const HttpdCatalogContainer &copy_from) :
84 BESContainer(copy_from), d_remoteResource(0)
85{
86 // we can not make a copy of this container once the request has
87 // been made
88 if (copy_from.d_remoteResource) {
89 throw BESInternalError("The Container has already been accessed, cannot create a copy of this container.", __FILE__, __LINE__);
90 }
91}
92
93void HttpdCatalogContainer::_duplicate(HttpdCatalogContainer &copy_to)
94{
95 if (copy_to.d_remoteResource) {
96 throw BESInternalError("The Container has already been accessed, cannot duplicate this resource.", __FILE__, __LINE__);
97 }
98 copy_to.d_remoteResource = d_remoteResource;
100}
101
102BESContainer *
104{
105 HttpdCatalogContainer *container = new HttpdCatalogContainer;
106 _duplicate(*container);
107 return container;
108}
109
110HttpdCatalogContainer::~HttpdCatalogContainer()
111{
112 if (d_remoteResource) {
113 release();
114 }
115}
116
123{
124 BESDEBUG(MODULE, prolog << "BEGIN" << endl);
125
126 string path = get_real_name();
127 BESDEBUG(MODULE, prolog << "path: " << path << endl);
128
129 HttpdCatalog hc;
130 string access_url = hc.path_to_access_url(path);
131
132 if (!d_remoteResource) {
133 BESDEBUG(MODULE, prolog << "Building new RemoteResource." << endl);
134 std::shared_ptr<http::url> access_url_ptr(new http::url(access_url));
135 d_remoteResource = new http::RemoteResource(access_url_ptr);
136 d_remoteResource->retrieve_resource();
137 }
138
139 BESDEBUG(MODULE, prolog << "Located remote resource." << endl);
140
141 string cachedResource = d_remoteResource->get_filename();
142 BESDEBUG(MODULE, prolog << "Using local cache file: " << cachedResource << endl);
143
144 string type = d_remoteResource->get_type();
145 set_container_type(type);
146
147 BESDEBUG(MODULE, prolog << "Type: " << type << endl);
148
149 BESDEBUG(MODULE, prolog << "Done accessing " << get_real_name() << " returning cached file " << cachedResource << endl);
150 BESDEBUG(MODULE, prolog << "Done accessing " << *this << endl);
151 BESDEBUG(MODULE, prolog << "END" << endl);
152
153 return cachedResource; // this should return the file name from the CmrCache
154}
155
163{
164 BESDEBUG(MODULE, prolog << "BEGIN" << endl);
165 if (d_remoteResource) {
166 BESDEBUG(MODULE, prolog << "Releasing RemoteResource" << endl);
167 delete d_remoteResource;
168 d_remoteResource = 0;
169 }
170 BESDEBUG(MODULE, prolog << "END" << endl);
171 return true;
172}
173
181void HttpdCatalogContainer::dump(ostream &strm) const
182{
183 strm << BESIndent::LMarg << prolog<<"(" << (void *) this
184 << ")" << endl;
185 BESIndent::Indent();
186 BESContainer::dump(strm);
187 if (d_remoteResource) {
188 strm << BESIndent::LMarg << "RemoteResource.get_filename(): " << d_remoteResource->get_filename()
189 << endl;
190 }
191 else {
192 strm << BESIndent::LMarg << "response not yet obtained" << endl;
193 }
194
195 BESIndent::UnIndent();
196}
197
198} // namespace http_catalog
A container is something that holds data. E.G., a netcdf file or a database entry.
void set_container_type(const std::string &type)
set the type of data that this container represents, such as cedar or netcdf.
void dump(std::ostream &strm) const override
dumps information about this object
void set_relative_name(const std::string &relative)
Set the relative name of the object in this container.
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
static std::vector< std::string > split(const std::string &s, char delim='/', bool skip_empty=true)
Splits the string s into the return vector of tokens using the delimiter delim and skipping empty val...
Definition BESUtil.cc:1068
Parse a URL into the protocol, host, path and query parts.
Definition url_impl.h:44
Container representing a remote request.
virtual bool release()
release the resources
virtual std::string access()
access the remote target response by making the remote request
virtual void dump(std::ostream &strm) const
dumps information about this object
virtual BESContainer * ptr_duplicate()
pure abstract method to duplicate this instances of BESContainer
builds catalogs from a directory structure exposed by Apache httpd
virtual std::string path_to_access_url(const std::string &path) const
Takes a path which begins with the name of an HttpdCatalog collection and returns the associated acce...