bes Updated for version 3.20.13
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
104{
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->retrieveResource();
137 }
138
139 BESDEBUG(MODULE, prolog << "Located remote resource." << endl);
140
141 string cachedResource = d_remoteResource->getCacheFileName();
142 BESDEBUG(MODULE, prolog << "Using local cache file: " << cachedResource << endl);
143
144 string type = d_remoteResource->getType();
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.getCacheFileName(): " << d_remoteResource->getCacheFileName()
189 << endl;
190 strm << BESIndent::LMarg << "response headers: ";
191
192 vector<string> *hdrs = d_remoteResource->getResponseHeaders();
193 if (hdrs) {
194 strm << endl;
195 BESIndent::Indent();
196 vector<string>::const_iterator i = hdrs->begin();
197 vector<string>::const_iterator e = hdrs->end();
198 for (; i != e; i++) {
199 string hdr_line = (*i);
200 strm << BESIndent::LMarg << hdr_line << endl;
201 }
202 BESIndent::UnIndent();
203 }
204 else {
205 strm << "none" << endl;
206 }
207 }
208 else {
209 strm << BESIndent::LMarg << "response not yet obtained" << endl;
210 }
211
212 BESIndent::UnIndent();
213}
214
215} // namespace http_catalog
A container is something that holds data. E.G., a netcdf file or a database entry.
Definition: BESContainer.h:65
void set_container_type(const std::string &type)
set the type of data that this container represents, such as cedar or netcdf.
Definition: BESContainer.h:161
virtual void dump(std::ostream &strm) const
dumps information about this object
Definition: BESContainer.cc:73
void set_relative_name(const std::string &relative)
Set the relative name of the object in this container.
Definition: BESContainer.h:152
void _duplicate(BESContainer &copy_to)
duplicate this instance into the passed container
Definition: BESContainer.cc:54
std::string get_real_name() const
retrieve the real name for this container, such as a file name.
Definition: BESContainer.h:180
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:1065
std::string getCacheFileName()
std::vector< std::string > * getResponseHeaders()
std::string getType()
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
Definition: HttpdCatalog.h:50
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...