bes  Updated for version 3.20.6
CmrContainer.cc
1 // CmrContainer.cc
2 
3 // -*- mode: c++; c-basic-offset:4 -*-
4 
5 // This file is part of cnr_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) 2018 OPeNDAP, Inc.
9 // Author: Nathan Potter <ndp@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 
27 // Authors:
28 // ndp Nathan Potter <ndp@opendap.org>
29 
30 #include <BESSyntaxUserError.h>
31 #include <BESInternalError.h>
32 #include <BESNotFoundError.h>
33 #include <BESDebug.h>
34 #include <BESUtil.h>
35 #include <TheBESKeys.h>
36 #include <WhiteList.h>
37 
38 #include "CmrContainer.h"
39 #include "CmrUtils.h"
40 #include "CmrNames.h"
41 #include "RemoteHttpResource.h"
42 
43 using namespace std;
44 using namespace bes;
45 
46 #define prolog std::string("CmrContainer::").append(__func__).append("() - ")
47 
48 namespace cmr {
49 
60 CmrContainer::CmrContainer(const string &sym_name,
61  const string &real_name, const string &type) :
62  BESContainer(sym_name, real_name, type), d_remoteResource(0) {
63 
64  BESDEBUG( MODULE, prolog << "BEGIN sym_name: " << sym_name
65  << " real_name: " << real_name << " type: " << type << endl);
66 
67 
68  string path = BESUtil::normalize_path(real_name,true, false);
69  vector<string> path_elements = BESUtil::split(path);
70  BESDEBUG(MODULE, prolog << "path: '" << path << "' path_elements.size(): " << path_elements.size() << endl);
71 
72 
73  set_relative_name(path);
74 
75  if(type==""){
76  // @TODO FIX Dynamically determine the type from the Granule information (type-match to name, mime-type, etc)
77  this->set_container_type("nc");
78  }
79 
80 
81 
82  /*
83 
84  if (type.empty())
85  set_container_type("cmr");
86 
87  BESUtil::url url_parts;
88  BESUtil::url_explode(real_name, url_parts);
89  url_parts.uname = "";
90  url_parts.psswd = "";
91  string use_real_name = BESUtil::url_create(url_parts);
92 
93  if (!WhiteList::get_white_list()->is_white_listed(use_real_name)) {
94  string err = (string) "The specified URL " + real_name
95  + " does not match any of the accessible services in"
96  + " the white list.";
97  throw BESSyntaxUserError(err, __FILE__, __LINE__);
98  }
99 
100  // Because we know the name is really a URL, then we know the "relative_name" is meaningless
101  // So we set it to be the same as "name"
102  set_relative_name(real_name);
103  */
104 
105  BESDEBUG( MODULE, prolog << "END" << endl);
106 
107 }
108 
112 CmrContainer::CmrContainer(const CmrContainer &copy_from) :
113  BESContainer(copy_from), d_remoteResource(copy_from.d_remoteResource) {
114  // we can not make a copy of this container once the request has
115  // been made
116  if (d_remoteResource) {
117  string err = (string) "The Container has already been accessed, "
118  + "can not create a copy of this container.";
119  throw BESInternalError(err, __FILE__, __LINE__);
120  }
121 }
122 
123 void CmrContainer::_duplicate(CmrContainer &copy_to) {
124  if (copy_to.d_remoteResource) {
125  string err = (string) "The Container has already been accessed, "
126  + "can not duplicate this resource.";
127  throw BESInternalError(err, __FILE__, __LINE__);
128  }
129  copy_to.d_remoteResource = d_remoteResource;
130  BESContainer::_duplicate(copy_to);
131 }
132 
133 BESContainer *
135  CmrContainer *container = new CmrContainer;
136  _duplicate(*container);
137  return container;
138 }
139 
140 CmrContainer::~CmrContainer() {
141  if (d_remoteResource) {
142  release();
143  }
144 }
145 
152 
153  BESDEBUG( MODULE, prolog << "BEGIN" << endl);
154 
155  // Since this the CMR thang we know that the real_name is a path of facets and such.
156  string path = get_real_name();
157  BESDEBUG( MODULE, prolog << "path: " << path << endl);
158 
159  Granule *granule = CmrUtils::getTemporalFacetGranule(path);
160  if(!granule){
161  throw BESNotFoundError("Failed locate a granule associated with the path "+path,__FILE__,__LINE__);
162  }
163  string url = granule->getDataAccessUrl();
164  delete granule;
165  granule = 0;
166 
167  string type = get_container_type();
168  if (type == MODULE)
169  type = "";
170 
171  if(!d_remoteResource) {
172  BESDEBUG( MODULE, prolog << "Building new RemoteResource." << endl );
173  d_remoteResource = new cmr::RemoteHttpResource(url);
174  d_remoteResource->retrieveResource();
175  }
176  BESDEBUG( MODULE, prolog << "Located remote resource." << endl );
177 
178 
179  string cachedResource = d_remoteResource->getCacheFileName();
180  BESDEBUG( MODULE, prolog << "Using local cache file: " << cachedResource << endl );
181 
182  type = d_remoteResource->getType();
183  set_container_type(type);
184  BESDEBUG( MODULE, prolog << "Type: " << type << endl );
185 
186 
187  BESDEBUG( MODULE, prolog << "Done accessing " << get_real_name() << " returning cached file " << cachedResource << endl);
188  BESDEBUG( MODULE, prolog << "Done accessing " << *this << endl);
189  BESDEBUG( MODULE, prolog << "END" << endl);
190 
191  return cachedResource; // this should return the file name from the CmrCache
192 }
193 
194 
195 
203  BESDEBUG( MODULE, prolog << "BEGIN" << endl);
204  if (d_remoteResource) {
205  BESDEBUG( MODULE, prolog << "Releasing RemoteResource" << endl);
206  delete d_remoteResource;
207  d_remoteResource = 0;
208  }
209  BESDEBUG( MODULE, prolog << "END" << endl);
210  return true;
211 }
212 
220 void CmrContainer::dump(ostream &strm) const {
221  strm << BESIndent::LMarg << prolog << "(" << (void *) this
222  << ")" << endl;
223  BESIndent::Indent();
224  BESContainer::dump(strm);
225  if (d_remoteResource) {
226  strm << BESIndent::LMarg << "RemoteResource.getCacheFileName(): " << d_remoteResource->getCacheFileName()
227  << endl;
228  strm << BESIndent::LMarg << "response headers: ";
229 
230  vector<string> *hdrs = d_remoteResource->getResponseHeaders();
231  if (hdrs) {
232  strm << endl;
233  BESIndent::Indent();
234  vector<string>::const_iterator i = hdrs->begin();
235  vector<string>::const_iterator e = hdrs->end();
236  for (; i != e; i++) {
237  string hdr_line = (*i);
238  strm << BESIndent::LMarg << hdr_line << endl;
239  }
240  BESIndent::UnIndent();
241  } else {
242  strm << "none" << endl;
243  }
244  } else {
245  strm << BESIndent::LMarg << "response not yet obtained" << endl;
246  }
247  BESIndent::UnIndent();
248 }
249 
250 } // namespace cmr
cmr::RemoteHttpResource::getType
std::string getType()
Definition: cmr_module/RemoteHttpResource.h:112
cmr::RemoteHttpResource
Definition: cmr_module/RemoteHttpResource.h:49
cmr::CmrContainer::dump
virtual void dump(std::ostream &strm) const
dumps information about this object
Definition: CmrContainer.cc:220
cmr::CmrContainer::access
virtual std::string access()
access the remote target response by making the remote request
Definition: CmrContainer.cc:151
cmr::CmrContainer
Container representing a remote request.
Definition: CmrContainer.h:51
cmr::RemoteHttpResource::getResponseHeaders
std::vector< std::string > * getResponseHeaders()
Definition: cmr_module/RemoteHttpResource.h:135
BESNotFoundError
error thrown if the resource requested cannot be found
Definition: BESNotFoundError.h:40
cmr::RemoteHttpResource::getCacheFileName
std::string getCacheFileName()
Definition: cmr_module/RemoteHttpResource.h:121
BESUtil::normalize_path
static std::string normalize_path(const std::string &path, bool leading_separator, bool trailing_separator, const std::string separator="/")
Removes duplicate separators and provides leading and trailing separators as directed.
Definition: BESUtil.cc:1011
BESContainer::get_container_type
std::string get_container_type() const
retrieve the type of data this container holds, such as cedar or netcdf.
Definition: BESContainer.h:232
cmr::CmrContainer::ptr_duplicate
virtual BESContainer * ptr_duplicate()
pure abstract method to duplicate this instances of BESContainer
Definition: CmrContainer.cc:134
cmr::Granule
Definition: Granule.h:43
BESInternalError
exception thrown if internal error encountered
Definition: BESInternalError.h:43
BESContainer
A container is something that holds data. E.G., a netcdf file or a database entry.
Definition: BESContainer.h:65
BESContainer::get_real_name
std::string get_real_name() const
retrieve the real name for this container, such as a file name.
Definition: BESContainer.h:180
BESUtil::split
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:1125
cmr::CmrContainer::release
virtual bool release()
release the resources
Definition: CmrContainer.cc:202
BESContainer::set_container_type
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
cmr::RemoteHttpResource::retrieveResource
void retrieveResource()
Definition: cmr_module/RemoteHttpResource.cc:130
BESContainer::set_relative_name
void set_relative_name(const std::string &relative)
Set the relative name of the object in this container.
Definition: BESContainer.h:152
BESContainer::_duplicate
void _duplicate(BESContainer &copy_to)
duplicate this instance into the passed container
Definition: BESContainer.cc:54
BESContainer::dump
virtual void dump(std::ostream &strm) const
dumps information about this object
Definition: BESContainer.cc:73