bes  Updated for version 3.20.6
GatewayContainer.cc
1 // GatewayContainer.cc
2 
3 // -*- mode: c++; c-basic-offset:4 -*-
4 
5 // This file is part of gateway_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) 2002,2003 OPeNDAP, Inc.
9 // Author: Patrick West <pwest@ucar.edu>
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 // pcw Patrick West <pwest@ucar.edu>
29 
30 #include <BESSyntaxUserError.h>
31 #include <BESInternalError.h>
32 #include <BESDebug.h>
33 #include <BESUtil.h>
34 #include <TheBESKeys.h>
35 #include <WhiteList.h>
36 
37 #include "GatewayContainer.h"
38 #include "GatewayUtils.h"
39 #include "GatewayResponseNames.h"
40 #include "RemoteHttpResource.h"
41 
42 using namespace std;
43 using namespace gateway;
44 using namespace bes;
45 
56 GatewayContainer::GatewayContainer(const string &sym_name,
57  const string &real_name, const string &type) :
58  BESContainer(sym_name, real_name, type), d_remoteResource(0) {
59 
60  if (type.empty())
61  set_container_type("gateway");
62 
63  BESUtil::url url_parts;
64  BESUtil::url_explode(real_name, url_parts);
65  url_parts.uname = "";
66  url_parts.psswd = "";
67  string use_real_name = BESUtil::url_create(url_parts);
68 
69  if (!WhiteList::get_white_list()->is_white_listed(use_real_name)) {
70  string err = (string) "The specified URL " + real_name
71  + " does not match any of the accessible services in"
72  + " the white list.";
73  throw BESSyntaxUserError(err, __FILE__, __LINE__);
74  }
75 
76  // Because we know the name is really a URL, then we know the "relative_name" is meaningless
77  // So we set it to be the same as "name"
78  set_relative_name(real_name);
79 }
80 
84 GatewayContainer::GatewayContainer(const GatewayContainer &copy_from) :
85  BESContainer(copy_from), d_remoteResource(copy_from.d_remoteResource) {
86  // we can not make a copy of this container once the request has
87  // been made
88  if (d_remoteResource) {
89  string err = (string) "The Container has already been accessed, "
90  + "can not create a copy of this container.";
91  throw BESInternalError(err, __FILE__, __LINE__);
92  }
93 }
94 
95 void GatewayContainer::_duplicate(GatewayContainer &copy_to) {
96  if (copy_to.d_remoteResource) {
97  string err = (string) "The Container has already been accessed, "
98  + "can not duplicate this resource.";
99  throw BESInternalError(err, __FILE__, __LINE__);
100  }
101  copy_to.d_remoteResource = d_remoteResource;
102  BESContainer::_duplicate(copy_to);
103 }
104 
105 BESContainer *
107  GatewayContainer *container = new GatewayContainer;
108  _duplicate(*container);
109  return container;
110 }
111 
112 GatewayContainer::~GatewayContainer() {
113  if (d_remoteResource) {
114  release();
115  }
116 }
117 
124 
125  BESDEBUG( "gateway", "GatewayContainer::access() - BEGIN" << endl);
126 
127  // Since this the Gateway we know that the real_name is a URL.
128  string url = get_real_name();
129 
130  BESDEBUG( "gateway", "GatewayContainer::access() - Accessing " << url << endl);
131 
132  string type = get_container_type();
133  if (type == "gateway")
134  type = "";
135 
136  if(!d_remoteResource) {
137  BESDEBUG( "gateway", "GatewayContainer::access() - Building new RemoteResource." << endl );
138  d_remoteResource = new gateway::RemoteHttpResource(url);
139  d_remoteResource->retrieveResource();
140  }
141  BESDEBUG( "gateway", "GatewayContainer::access() - Located remote resource." << endl );
142 
143 
144  string cachedResource = d_remoteResource->getCacheFileName();
145  BESDEBUG( "gateway", "GatewayContainer::access() - Using local cache file: " << cachedResource << endl );
146 
147  type = d_remoteResource->getType();
148  set_container_type(type);
149  BESDEBUG( "gateway", "GatewayContainer::access() - Type: " << type << endl );
150 
151 
152  BESDEBUG( "gateway", "GatewayContainer::access() - Done accessing " << get_real_name() << " returning cached file " << cachedResource << endl);
153  BESDEBUG( "gateway", "GatewayContainer::access() - Done accessing " << *this << endl);
154  BESDEBUG( "gateway", "GatewayContainer::access() - END" << endl);
155 
156  return cachedResource; // this should return the file name from the GatewayCache
157 }
158 
159 
160 
168  if (d_remoteResource) {
169  BESDEBUG( "gateway", "GatewayContainer::release() - Releasing RemoteResource" << endl);
170  delete d_remoteResource;
171  d_remoteResource = 0;
172  }
173 
174  BESDEBUG( "gateway", "done releasing gateway response" << endl);
175  return true;
176 }
177 
185 void GatewayContainer::dump(ostream &strm) const {
186  strm << BESIndent::LMarg << "GatewayContainer::dump - (" << (void *) this
187  << ")" << endl;
188  BESIndent::Indent();
189  BESContainer::dump(strm);
190  if (d_remoteResource) {
191  strm << BESIndent::LMarg << "RemoteResource.getCacheFileName(): " << d_remoteResource->getCacheFileName()
192  << endl;
193  strm << BESIndent::LMarg << "response headers: ";
194  vector<string> *hdrs = d_remoteResource->getResponseHeaders();
195  if (hdrs) {
196  strm << endl;
197  BESIndent::Indent();
198  vector<string>::const_iterator i = hdrs->begin();
199  vector<string>::const_iterator e = hdrs->end();
200  for (; i != e; i++) {
201  string hdr_line = (*i);
202  strm << BESIndent::LMarg << hdr_line << endl;
203  }
204  BESIndent::UnIndent();
205  } else {
206  strm << "none" << endl;
207  }
208  } else {
209  strm << BESIndent::LMarg << "response not yet obtained" << endl;
210  }
211  BESIndent::UnIndent();
212 }
gateway::RemoteHttpResource::getResponseHeaders
std::vector< std::string > * getResponseHeaders()
Definition: gateway_module/RemoteHttpResource.h:129
gateway::RemoteHttpResource::getType
std::string getType()
Definition: gateway_module/RemoteHttpResource.h:109
gateway::GatewayContainer
Container representing a remote request.
Definition: GatewayContainer.h:51
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
gateway::GatewayContainer::dump
virtual void dump(std::ostream &strm) const
dumps information about this object
Definition: GatewayContainer.cc:185
gateway::GatewayContainer::release
virtual bool release()
release the resources
Definition: GatewayContainer.cc:167
gateway::GatewayContainer::ptr_duplicate
virtual BESContainer * ptr_duplicate()
pure abstract method to duplicate this instances of BESContainer
Definition: GatewayContainer.cc:106
BESUtil::url_explode
static void url_explode(const std::string &url_str, BESUtil::url &url_parts)
Given a url, break the url into its different parts.
Definition: BESUtil.cc:678
BESSyntaxUserError
error thrown if there is a user syntax error in the request or any other user error
Definition: BESSyntaxUserError.h:41
BESUtil::url
Definition: BESUtil.h:93
BESInternalError
exception thrown if internal error encountered
Definition: BESInternalError.h:43
gateway::RemoteHttpResource::retrieveResource
void retrieveResource()
Definition: gateway_module/RemoteHttpResource.cc:124
gateway::RemoteHttpResource
Definition: gateway_module/RemoteHttpResource.h:49
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
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
gateway::RemoteHttpResource::getCacheFileName
std::string getCacheFileName()
Definition: gateway_module/RemoteHttpResource.h:118
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
gateway::GatewayContainer::access
virtual std::string access()
access the remote target response by making the remote request
Definition: GatewayContainer.cc:123
BESContainer::dump
virtual void dump(std::ostream &strm) const
dumps information about this object
Definition: BESContainer.cc:73