41 #include <sys/types.h>
50 #include <ConstraintEvaluator.h>
65 #define FONC_TEMP_DIR "/tmp"
67 #define RETURNAS_NETCDF "netcdf"
68 #define RETURNAS_NETCDF4 "netcdf-4"
70 string FONcTransmitter::temp_dir;
87 static void read_key_value(
const std::string &key_name,
bool &key_value,
bool &is_key_set)
89 if (is_key_set ==
false) {
90 bool key_found =
false;
98 key_value = (doset ==
"true" || doset ==
"yes");
120 if (FONcTransmitter::temp_dir.empty()) {
123 string key =
"FONc.Tempdir";
125 if (!found || FONcTransmitter::temp_dir.empty()) {
128 string::size_type len = FONcTransmitter::temp_dir.length();
129 if (FONcTransmitter::temp_dir[len - 1] ==
'/') {
130 FONcTransmitter::temp_dir = FONcTransmitter::temp_dir.substr(0, len - 1);
156 DataDDS *dds = bdds->
get_dds();
158 throw BESInternalError(
"No DataDDS has been created for transmit", __FILE__, __LINE__);
160 BESDEBUG(
"fonc",
"FONcTransmitter::send_data - parsing the constraint" << endl);
162 ConstraintEvaluator &eval = bdds->
get_ce();
168 throw BESInternalError(
"Output stream is not set, can not return as", __FILE__, __LINE__);
173 eval.parse_constraint(ce, *dds);
176 throw BESInternalError(
"Failed to parse the constraint expression: " + e.get_error_message(), __FILE__, __LINE__);
179 throw BESInternalError(
"Failed to parse the constraint expression: Unknown exception caught", __FILE__, __LINE__);
189 BESDEBUG(
"fonc",
"FONcTransmitter::send_data - reading data into DataDDS" << endl);
196 if (eval.function_clauses()) {
197 BESDEBUG(
"fonc",
"processing a functional constraint clause(s)." << endl);
198 DataDDS *tmp_dds = eval.eval_function_clauses(*dds);
215 for (DDS::Vars_iter i = dds->var_begin(); i != dds->var_end(); i++) {
216 if ((*i)->send_p()) {
217 (*i)->intern_data(eval, *dds);
223 throw BESInternalError(
"Failed to read data: " + e.get_error_message(), __FILE__, __LINE__);
226 throw BESInternalError(
"Failed to read data: Unknown exception caught", __FILE__, __LINE__);
229 string temp_file_name = FONcTransmitter::temp_dir +
'/' +
"ncXXXXXX";
230 vector<char> temp_full(temp_file_name.length() + 1);
231 string::size_type len = temp_file_name.copy(&temp_full[0], temp_file_name.length());
232 temp_full[len] =
'\0';
235 mode_t original_mode = umask(077);
236 int fd = mkstemp(&temp_full[0]);
237 umask(original_mode);
240 throw BESInternalError(
"Failed to open the temporary file: " + temp_file_name, __FILE__, __LINE__);
243 BESDEBUG(
"fonc",
"FONcTransmitter::send_data - transforming into temporary file " << &temp_full[0] << endl);
249 BESDEBUG(
"fonc",
"FONcTransmitter::send_data - transmitting temp file " << &temp_full[0] << endl);
250 FONcTransmitter::return_temp_stream(&temp_full[0], strm, ncVersion);
254 (void) unlink(&temp_full[0]);
261 (void) unlink(&temp_full[0]);
265 throw BESInternalError(
"File out netcdf, was not able to transform to netcdf, unknown error", __FILE__, __LINE__);
269 (void) unlink(&temp_full[0]);
273 BESDEBUG(
"fonc",
"FONcTransmitter::send_data - done transmitting to netcdf" << endl);
285 void FONcTransmitter::return_temp_stream(
const string &filename,
287 const string &ncVersion)
291 os.open(filename.c_str(), ios::binary | ios::in);
293 string err =
"Can not connect to file " + filename;
300 os.read(block,
sizeof block);
301 nbytes = os.gcount();
304 string context =
"transmit_protocol";
306 if (protocol ==
"HTTP") {
307 strm <<
"HTTP/1.0 200 OK\n";
308 strm <<
"Content-type: application/octet-stream\n";
309 strm <<
"Content-Description: " <<
"BES dataset" <<
"\n";
311 strm <<
"Content-Disposition: filename=" << filename <<
".nc4;\n\n";
314 strm <<
"Content-Disposition: filename=" << filename <<
".nc;\n\n";
318 strm.write(block, nbytes);
325 string err = (string)
"0XAAE234F: failed to stream. Internal server "
326 +
"error, got zero count on stream buffer." + filename;
331 os.read(block,
sizeof block);
332 nbytes = os.gcount();
333 strm.write(block, nbytes);
void set_dds(DataDDS *ddsIn)
Set the response object's DDS.
exception thrown if inernal error encountered
static string lowercase(const string &s)
Convert a string to all lower case.
ostream & get_output_stream()
FONcTransmitter()
Construct the FONcTransmitter, adding it with name netcdf to be able to transmit a data response...
virtual bool add_method(string method_name, p_transmitter trans_method)
static void send_data(BESResponseObject *obj, BESDataHandlerInterface &dhi)
The static method registered to transmit OPeNDAP data objects as a netcdf file.
virtual string get_context(const string &name, bool &found)
retrieve the value of the specified context from the BES
static class NCMLUtil overview
Abstract exception class for the BES with basic string message.
Represents an OPeNDAP DataDDS DAP2 data object within the BES.
static BESContextManager * TheManager()
void get_value(const string &s, string &val, bool &found)
Retrieve the value of a given key, if set.
ConstraintEvaluator & get_ce()
Structure storing information used by the BES to handle the request.
map< string, string > data
the map of string data that will be required for the current request.
#define BESDEBUG(x, y)
macro used to send debug information to the debug stream
static BESKeys * TheKeys()
Abstract base class representing a specific set of information in response to a request to the BES...