bes Updated for version 3.21.1
The Backend Server (BES) is the lower two tiers of the Hyrax data server
BESXMLGetCommand.cc
1// BESXMLGetCommand.cc
2
3// This file is part of bes, A C++ back-end server implementation framework
4// for the OPeNDAP Data Access Protocol.
5
6// Copyright (c) 2004-2009 University Corporation for Atmospheric Research
7// Author: Patrick West <pwest@ucar.edu> and Jose Garcia <jgarcia@ucar.edu>
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 University Corporation for Atmospheric Research at
24// 3080 Center Green Drive, Boulder, CO 80301
25
26// (c) COPYRIGHT University Corporation for Atmospheric Research 2004-2005
27// Please read the full copyright statement in the file COPYRIGHT_UCAR.
28//
29// Authors:
30// pwest Patrick West <pwest@ucar.edu>
31// jgarcia Jose Garcia <jgarcia@ucar.edu>
32
33#include "config.h"
34
35#include <sstream>
36
37#include "BESXMLGetCommand.h"
38#include "BESDefinitionStorageList.h"
39#include "BESDefinitionStorage.h"
40#include "BESDefine.h"
41#include "BESDataNames.h"
42#include "BESResponseNames.h"
43#include "BESDapNames.h"
44
45#include "BESXMLUtils.h"
46#include "BESUtil.h"
47#include "BESSyntaxUserError.h"
48#include "BESLog.h"
49#include "BESDebug.h"
50
51using namespace std;
52
53BESXMLGetCommand::BESXMLGetCommand(const BESDataHandlerInterface &base_dhi) :
54 BESXMLCommand(base_dhi), _sub_cmd(0)
55{
56}
57
71{
72 string name;
73 string value;
74 map<string, string> props;
75 BESXMLUtils::GetNodeInfo(node, name, value, props);
76
77 if (name != GET_RESPONSE) {
78 string err = "The specified command " + name + " is not a get command";
79 throw BESSyntaxUserError(err, __FILE__, __LINE__);
80 }
81
82 // grab the type first and check to see if there is a registered command
83 // to handle get.<type> requests
84 string type = props["type"];
85 if (type.empty()) {
86 string err = name + " command: Must specify data product type";
87 throw BESSyntaxUserError(err, __FILE__, __LINE__);
88 }
89
90 // TODO I don't think this is ever used. jhrg 3/13/18
91 string new_cmd = (string) GET_RESPONSE + "." + type;
92 p_xmlcmd_builder bldr = BESXMLCommand::find_command(new_cmd);
93 if (bldr) {
94 // the base dhi was copied to this instance's _dhi variable.
95 _sub_cmd = bldr(d_xmlcmd_dhi);
96 if (!_sub_cmd) {
97 string err = (string) "Failed to build command object for " + new_cmd;
98 throw BESInternalError(err, __FILE__, __LINE__);
99 }
100
101 // parse the request given the current node
102 _sub_cmd->parse_request(node);
103
104 // return from this sub command
105 return;
106 }
107
108 parse_basic_get(type, props);
109 d_cmd_log_info += ";";
110
111 // Now that we've set the action, get the response handler for the action
113}
114
127void BESXMLGetCommand::parse_basic_get(const string &type, map<string, string> &props)
128{
129 d_cmd_log_info = "get "; // Remove any old value of this string
130 d_cmd_log_info.append(type);
131
132 _definition = props["definition"];
133 if (_definition.empty())
134 throw BESSyntaxUserError("get command: Must specify definition", __FILE__, __LINE__);
135
136 d_cmd_log_info.append(" for ").append(_definition);
137
138 _space = props["space"];
139
140 if (!_space.empty()) d_cmd_log_info.append(" in ").append(_space);
141
142 // An empty 'return as' value means 'return a DAP response'. The DAP Module handles
143 // both versions of the protocol. If the value is not empty, then it's the name of
144 // the file format like netCDF4. jhrg 1/6/25
145 if (props["returnAs"].empty()) {
146 d_xmlcmd_dhi.data[RETURN_CMD] = DAP_FORMAT;
147 }
148 else {
149 d_xmlcmd_dhi.data[RETURN_CMD] = props["returnAs"];
150 }
151
152 if (!props["returnAs"].empty()) {
153 d_cmd_log_info.append(" return as ").append(props["returnAs"]);
154 }
155
156 d_xmlcmd_dhi.data[STORE_RESULT] = props[STORE_RESULT];
157 d_xmlcmd_dhi.data[ASYNC] = props[ASYNC];
158
159 d_xmlcmd_dhi.action = "get.";
160 d_xmlcmd_dhi.action.append(BESUtil::lowercase(type));
161
162 BESDEBUG("besxml", "Converted xml element name to command " << d_xmlcmd_dhi.action << endl);
163}
164
173{
174 if (_sub_cmd) return _sub_cmd->get_xmlcmd_dhi();
175
176 return d_xmlcmd_dhi;
177}
178
187{
188 // if there is a sub command then execute the prep request on it
189 // TODO I don't think this is ever used. jhrg 3/13/18
190 if (_sub_cmd) {
191 _sub_cmd->prep_request();
192 return;
193 }
194
195 BESDefine *d = 0;
196
197 if (!_space.empty()) {
198 BESDefinitionStorage *ds = BESDefinitionStorageList::TheList()->find_persistence(_space);
199 if (ds) {
200 d = ds->look_for(_definition);
201 }
202 }
203 else {
204 d = BESDefinitionStorageList::TheList()->look_for(_definition);
205 }
206
207 if (!d) {
208 string s = (string) "Unable to find definition " + _definition;
209 throw BESSyntaxUserError(s, __FILE__, __LINE__);
210 }
211
212 BESDefine::containers_citer i = d->first_container();
213 BESDefine::containers_citer ie = d->end_container();
214 while (i != ie) {
215 d_xmlcmd_dhi.containers.push_back(*i);
216 i++;
217 }
218
219 // TODO Not ever used. jhrg 3/13/18
220 d_xmlcmd_dhi.data[AGG_CMD] = d->get_agg_cmd();
221 d_xmlcmd_dhi.data[AGG_HANDLER] = d->get_agg_handler();
222}
223
230void BESXMLGetCommand::dump(ostream &strm) const
231{
232 strm << BESIndent::LMarg << "BESXMLGetCommand::dump - (" << (void *) this << ")" << endl;
233 BESIndent::Indent();
235 BESIndent::UnIndent();
236}
237
239BESXMLGetCommand::CommandBuilder(const BESDataHandlerInterface &base_dhi)
240{
241 return new BESXMLGetCommand(base_dhi);
242}
243
Structure storing information used by the BES to handle the request.
provides persistent storage for a specific view of different containers including contraints and aggr...
virtual BESDefine * look_for(const std::string &def_name)=0
looks for a definition in this persistent store with the given name
exception thrown if internal error encountered
error thrown if there is a user syntax error in the request or any other user error
static std::string lowercase(const std::string &s)
Definition BESUtil.cc:257
Base class for the BES's commands.
virtual void dump(std::ostream &strm) const
dumps information about this object
virtual void set_response()
The request has been parsed, use the command action name to set the response handler.
std::string d_cmd_log_info
Used only for the log.
static p_xmlcmd_builder find_command(const std::string &cmd_str)
Find the BESXMLCommand creation function with the given name.
virtual void parse_request(xmlNode *node)
parse a get command.
virtual void prep_request()
Prepare any information needed to execute the request of this get command.
virtual void parse_basic_get(const std::string &type, std::map< std::string, std::string > &props)
Extract information from the 'props' map.
virtual void dump(std::ostream &strm) const
dumps information about this object
virtual BESDataHandlerInterface & get_xmlcmd_dhi()
returns the BESDataHandlerInterface of either a sub command, if one exists, or this command's
static void GetNodeInfo(xmlNode *node, std::string &name, std::string &value, std::map< std::string, std::string > &props)
get the name, value if any, and any properties for the specified node