42 #include <sys/types.h>
54 #include <ConstraintEvaluator.h>
56 #include <TheBESKeys.h>
57 #include <BESContextManager.h>
58 #include <BESDataDDSResponse.h>
59 #include <BESDapNames.h>
60 #include <BESDataNames.h>
65 #include <BESDapResponseBuilder.h>
68 #include <BESDapError.h>
69 #include <BESForbiddenError.h>
70 #include <BESInternalFatalError.h>
71 #include <DapFunctionUtils.h>
73 #include "FONcBaseType.h"
74 #include "FONcRequestHandler.h"
75 #include "FONcTransmitter.h"
76 #include "FONcTransform.h"
83 #define OUTPUT_FILE_BLOCK_SIZE 4096
105 struct wrap_temp_descriptor {
107 wrap_temp_descriptor(
int fd) : d_fd(fd) {}
108 ~wrap_temp_descriptor() { close(d_fd); }
118 struct wrap_temp_name {
120 wrap_temp_name(vector<char> &name) : d_name(name) {}
121 ~wrap_temp_name() { unlink(&d_name[0]); }
135 void updateHistoryAttribute(DDS *dds,
const string ce)
137 bool foundIt =
false;
138 string cf_history_entry = BESContextManager::TheManager()->
get_context(
"cf_history_entry", foundIt);
148 string request_url = dds->filename();
150 request_url = request_url.substr(request_url.find_last_of(
'/')+1);
152 request_url = request_url.substr(request_url.find_last_of(
'#')+1);
153 request_url +=
"?" + ce;
155 std::stringstream ss;
158 struct tm * timeinfo;
160 timeinfo = localtime(&raw_now);
164 strftime(time_str, 100,
"%Y-%m-%d %H:%M:%S", timeinfo);
166 ss << time_str <<
" " <<
"Hyrax" <<
" " << request_url;
167 cf_history_entry = ss.str();
171 "FONcTransmitter::updateHistoryAttribute() - Adding cf_history_entry context. '" << cf_history_entry <<
"'" << endl);
173 vector<string> hist_entry_vec;
174 hist_entry_vec.push_back(cf_history_entry);
176 "FONcTransmitter::updateHistoryAttribute() - hist_entry_vec.size(): " << hist_entry_vec.size() << endl);
180 AttrTable &globals = dds->get_attr_table();
185 unsigned int num_attrs = globals.get_size();
189 AttrTable::Attr_iter i = globals.attr_begin();
190 AttrTable::Attr_iter e = globals.attr_end();
191 for (; i != e && !done; i++) {
192 AttrType attrType = globals.get_attr_type(i);
193 string attr_name = globals.get_name(i);
197 AttrTable *source_file_globals = globals.get_attr_table(i);
198 AttrTable::Attr_iter history_attrItr = source_file_globals->simple_find(
"history");
199 if (history_attrItr != source_file_globals->attr_end()) {
202 "FONcTransmitter::updateHistoryAttribute() - Adding history entry to " << attr_name << endl);
203 source_file_globals->append_attr(
"history",
"string", &hist_entry_vec);
213 "FONcTransmitter::updateHistoryAttribute() - Adding history entry to top level AttrTable" << endl);
214 globals.append_attr(
"history",
"string", &hist_entry_vec);
237 BESDEBUG(
"fonc",
"FONcTransmitter::send_data() - BEGIN" << endl);
250 BESDEBUG(
"fonc",
"FONcTransmitter::send_data() - Reading data into DataDDS" << endl);
256 updateHistoryAttribute(loaded_dds, dhi.
data[POST_CONSTRAINT]);
262 string temp_file_name = FONcRequestHandler::temp_dir +
"/ncXXXXXX";
263 vector<char> temp_file(temp_file_name.length() + 1);
264 string::size_type len = temp_file_name.copy(&temp_file[0], temp_file_name.length());
265 temp_file[len] =
'\0';
268 mode_t original_mode = umask(077);
269 int fd = mkstemp(&temp_file[0]);
270 umask(original_mode);
275 wrap_temp_name w_temp_file(temp_file);
276 wrap_temp_descriptor w_fd(fd);
278 if (fd == -1)
throw BESInternalError(
"Failed to open the temporary file.", __FILE__, __LINE__);
281 bes::TempFile temp_file(FONcRequestHandler::temp_dir +
"/ncXXXXXX");
283 BESDEBUG(
"fonc",
"FONcTransmitter::send_data - Building response file " << temp_file.
get_name() << endl);
289 ostream &strm = dhi.get_output_stream();
290 if (!strm)
throw BESInternalError(
"Output stream is not set, can not return as", __FILE__, __LINE__);
292 BESDEBUG(
"fonc",
"FONcTransmitter::send_data - Transmitting temp file " << temp_file.
get_name() << endl);
294 FONcTransmitter::write_temp_file_to_stream(temp_file.
get_fd(), strm);
297 throw BESDapError(
"Failed to read data: " + e.get_error_message(),
false, e.get_error_code(), __FILE__, __LINE__);
302 catch (std::exception &e) {
303 throw BESInternalError(
"Failed to read data: STL Error: " +
string(e.what()), __FILE__, __LINE__);
306 throw BESInternalError(
"Failed to get read data: Unknown exception caught", __FILE__, __LINE__);
309 BESDEBUG(
"fonc",
"FONcTransmitter::send_data - done transmitting to netcdf" << endl);
321 void FONcTransmitter::write_temp_file_to_stream(
int fd, ostream &strm)
323 char block[OUTPUT_FILE_BLOCK_SIZE];
325 int nbytes = read(fd, block,
sizeof block);
327 strm.write(block, nbytes );
328 nbytes = read(fd, block,
sizeof block);