bes  Updated for version 3.20.6
DmrppMetadataStore.cc
1 // -*- mode: c++; c-basic-offset:4 -*-
2 
3 // This file is part of HYrax, A C++ implementation of the OPeNDAP Data
4 // Access Protocol.
5 
6 // Copyright (c) 2018 OPeNDAP, Inc.
7 // Author: James Gallagher <jgallagher@opendap.org>
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 OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
24 
25 #include "config.h"
26 
27 #include <iostream>
28 #include <string>
29 #include <sstream>
30 #include <memory>
31 #include <typeinfo>
32 
33 #include <DMR.h>
34 #include <XMLWriter.h>
35 
36 #include "BESDebug.h"
37 
38 #include "BESInternalFatalError.h"
39 
40 #include "DmrppParserSax2.h"
41 #include "DmrppTypeFactory.h"
42 #include "DmrppMetadataStore.h"
43 
44 #include "DMRpp.h"
45 
46 #define DEBUG_KEY "dmrpp_store"
47 #define MAINTAIN_STORE_SIZE_EVEN_WHEN_UNLIMITED 0
48 
49 #ifdef HAVE_ATEXIT
50 #define AT_EXIT(x) atexit((x))
51 #else
52 #define AT_EXIT(x)
53 #endif
54 
64 #undef SYMETRIC_ADD_RESPONSES
65 
66 using namespace std;
67 using namespace libdap;
68 using namespace bes;
69 
70 using namespace dmrpp;
71 
72 DmrppMetadataStore *DmrppMetadataStore::d_instance = 0;
73 bool DmrppMetadataStore::d_enabled = true;
74 
88 
107 DmrppMetadataStore::get_instance(const string &cache_dir, const string &prefix, unsigned long long size)
108 {
109  if (d_enabled && d_instance == 0) {
110  d_instance = new DmrppMetadataStore(cache_dir, prefix, size); // never returns null_ptr
111  d_enabled = d_instance->cache_enabled();
112  if (!d_enabled) {
113  delete d_instance;
114  d_instance = 0;
115 
116  BESDEBUG(DEBUG_KEY, "DmrppMetadataStore::"<<__func__ << "() - " << "Cache is DISABLED"<< endl);
117  }
118  else {
119  AT_EXIT(delete_instance);
120 
121  BESDEBUG(DEBUG_KEY, "DmrppMetadataStore::"<<__func__ << "() - " << "Cache is ENABLED"<< endl);
122  }
123  }
124 
125  BESDEBUG(DEBUG_KEY, "DmrppMetadataStore::get_instance(dir,prefix,size) - d_instance: " << d_instance << endl);
126 
127  return d_instance;
128 }
129 
137 DmrppMetadataStore::get_instance()
138 {
139  if (d_enabled && d_instance == 0) {
140  d_instance = new DmrppMetadataStore();
141  d_enabled = d_instance->cache_enabled();
142  if (!d_enabled) {
143  delete d_instance;
144  d_instance = NULL;
145  BESDEBUG(DEBUG_KEY, "DmrppMetadataStore::"<<__func__ << "() - " << "Cache is DISABLED"<< endl);
146  }
147  else {
148  AT_EXIT(delete_instance);
149 
150  BESDEBUG(DEBUG_KEY, "DmrppMetadataStore::"<<__func__ << "() - " << "Cache is ENABLED"<< endl);
151  }
152  }
153 
154  BESDEBUG(DEBUG_KEY, "DmrppMetadataStore::get_instance() - d_instance: " << (void *) d_instance << endl);
155 
156  return d_instance;
157 }
159 
160 void DmrppMetadataStore::StreamDMRpp::operator()(ostream &os)
161 {
162  // Even though StreamDMRpp is-a StreamDAP and the latter has a d_dds
163  // field, we cannot use it for this version of the output operator.
164  // jhrg 5/17/18
165  if (d_dmr && typeid(*d_dmr) == typeid(dmrpp::DMRpp)) {
166  // FIXME This is where we will add the href that points toward the data file in S3. jhrg 5/17/18
167  DMRpp *dmrpp = static_cast<dmrpp::DMRpp*>(d_dmr);
168  dmrpp->set_print_chunks(true);
169  XMLWriter xml;
170  dmrpp->print_dap4(xml);
171 
172 #if 0
173  string href = "";
174  static_cast<dmrpp::DMRpp*>(d_dmr)->print_dmrpp(xml, href);
175 #endif
176 
177  os << xml.get_doc();
178  }
179  else {
180  throw BESInternalFatalError("StreamDMRpp output operator call with non-DMRpp instance.", __FILE__, __LINE__);
181  }
182 }
183 
195 bool
196 DmrppMetadataStore::add_responses(DMR *dmr, const string &name)
197 {
198  bool stored_dmr = GlobalMetadataStore::add_responses(dmr, name);
199 
200  bool stored_dmrpp = false;
201  if (typeid(*dmr) == typeid(dmrpp::DMRpp)) {
202  d_ledger_entry = string("add DMR++ ").append(name);
203 
204  StreamDMRpp write_the_dmrpp_response(dmr);
205  stored_dmrpp = store_dap_response(write_the_dmrpp_response, get_hash(name + "dmrpp_r"), name, "DMRpp");
206 
207  write_ledger(); // write the index line
208  }
209  else {
210  stored_dmrpp = true; // if dmr is not a DMRpp, not writing the object is 'success.'
211  }
212 
213  return(stored_dmr && stored_dmrpp);
214 }
215 
216 bool
217 DmrppMetadataStore::add_dmrpp_response(libdap::DMR *dmrpp, const std::string &name)
218 {
219  bool stored_dmrpp = false;
220  if (typeid(*dmrpp) == typeid(dmrpp::DMRpp)) {
221  d_ledger_entry = string("add DMR++ ").append(name);
222 
223  StreamDMRpp write_the_dmrpp_response(dmrpp);
224  stored_dmrpp = store_dap_response(write_the_dmrpp_response, get_hash(name + "dmrpp_r"), name, "DMRpp");
225 
226  write_ledger(); // write the index line
227  }
228  else {
229  stored_dmrpp = true; // if dmr is not a DMRpp, not writing the object is 'success.'
230  }
231 
232  return(stored_dmrpp);
233 }
234 
241 DMR *
242 DmrppMetadataStore::get_dmr_object(const string &name)
243 {
244  // Get the DMR response, but then parse that so the resulting binary
245  // object is built with DMR++ types so that the chunk information can be
246  // stored in them.
247  stringstream oss;
248  write_dmr_response(name, oss); // throws BESInternalError if not found
249 
250  DmrppTypeFactory dmrpp_btf;
251  unique_ptr<DMRpp> dmrpp(new DMRpp(&dmrpp_btf, "mds"));
252 
253  DmrppParserSax2 parser;
254  parser.intern(oss.str(), dmrpp.get());
255 
256  dmrpp->set_factory(0);
257 
258  return dmrpp.release();
259 }
260 
273 DMRpp *
274 DmrppMetadataStore::get_dmrpp_object(const string &name)
275 {
276  stringstream oss;
277  write_dmrpp_response(name, oss); // throws BESInternalError if not found
278 
279  DmrppTypeFactory dmrpp_btf;
280  unique_ptr<DMRpp> dmrpp(new DMRpp(&dmrpp_btf, "mds"));
281 
282  DmrppParserSax2 parser;
283  parser.intern(oss.str(), dmrpp.get());
284 
285  dmrpp->set_factory(0);
286 
287  return dmrpp.release();
288 }
dmrpp::DmrppParserSax2::intern
void intern(std::istream &f, libdap::DMR *dest_dmr, bool debug=false)
Definition: DmrppParserSax2.cc:1519
BESInternalFatalError
exception thrown if an internal error is found and is fatal to the BES
Definition: BESInternalFatalError.h:43
bes::DmrppMetadataStore::StreamDMRpp
Hack use a DMR to write a DMR++ response. WIP.
Definition: DmrppMetadataStore.h:98
dmrpp::DmrppTypeFactory
Definition: DmrppTypeFactory.h:39
dmrpp::DMRpp::print_dap4
virtual void print_dap4(libdap::XMLWriter &xml, bool constrained=false)
override DMR::print_dap4() so the chunk info will print too.
Definition: DMRpp.cc:134
libdap
Definition: BESDapFunctionResponseCache.h:35
dmrpp::DmrppParserSax2
Definition: DmrppParserSax2.h:62
bes::DmrppMetadataStore
Store the DAP DMR++ metadata responses.
Definition: DmrppMetadataStore.h:83
dmrpp::DMRpp
Provide a way to print the DMR++ response.
Definition: DMRpp.h:42