bes Updated for version 3.20.10
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 <libdap/DMR.h>
34#include <libdap/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
66using namespace std;
67using namespace libdap;
68using namespace bes;
69
70using namespace dmrpp;
71
72DmrppMetadataStore *DmrppMetadataStore::d_instance = 0;
73bool DmrppMetadataStore::d_enabled = true;
74
89
106 // FIXME This code will not work correctly in a multi-thread situation. See http::EffectiveUrlCache();
108DmrppMetadataStore::get_instance(const string &cache_dir, const string &prefix, unsigned long long size)
109{
110 if (d_enabled && d_instance == 0) {
111 d_instance = new DmrppMetadataStore(cache_dir, prefix, size); // never returns null_ptr
112 d_enabled = d_instance->cache_enabled();
113 if (!d_enabled) {
114 delete d_instance;
115 d_instance = 0;
116
117 BESDEBUG(DEBUG_KEY, "DmrppMetadataStore::"<<__func__ << "() - " << "Cache is DISABLED"<< endl);
118 }
119 else {
120 AT_EXIT(delete_instance);
121
122 BESDEBUG(DEBUG_KEY, "DmrppMetadataStore::"<<__func__ << "() - " << "Cache is ENABLED"<< endl);
123 }
124 }
125
126 BESDEBUG(DEBUG_KEY, "DmrppMetadataStore::get_instance(dir,prefix,size) - d_instance: " << d_instance << endl);
127
128 return d_instance;
129}
130
139{
140 if (d_enabled && d_instance == 0) {
141 d_instance = new DmrppMetadataStore();
142 d_enabled = d_instance->cache_enabled();
143 if (!d_enabled) {
144 delete d_instance;
145 d_instance = NULL;
146 BESDEBUG(DEBUG_KEY, "DmrppMetadataStore::"<<__func__ << "() - " << "Cache is DISABLED"<< endl);
147 }
148 else {
149 AT_EXIT(delete_instance);
150
151 BESDEBUG(DEBUG_KEY, "DmrppMetadataStore::"<<__func__ << "() - " << "Cache is ENABLED"<< endl);
152 }
153 }
154
155 BESDEBUG(DEBUG_KEY, "DmrppMetadataStore::get_instance() - d_instance: " << (void *) d_instance << endl);
156
157 return d_instance;
158}
160
161void DmrppMetadataStore::StreamDMRpp::operator()(ostream &os)
162{
163 // Even though StreamDMRpp is-a StreamDAP and the latter has a d_dds
164 // field, we cannot use it for this version of the output operator.
165 // jhrg 5/17/18
166 if (d_dmr && typeid(*d_dmr) == typeid(dmrpp::DMRpp)) {
167 // FIXME This is where we will add the href that points toward the data file in S3. jhrg 5/17/18
168 DMRpp *dmrpp = static_cast<dmrpp::DMRpp*>(d_dmr);
169 dmrpp->set_print_chunks(true);
170 XMLWriter xml;
171 dmrpp->print_dap4(xml);
172
173#if 0
174 string href = "";
175 static_cast<dmrpp::DMRpp*>(d_dmr)->print_dmrpp(xml, href);
176#endif
177
178 os << xml.get_doc();
179 }
180 else {
181 throw BESInternalFatalError("StreamDMRpp output operator call with non-DMRpp instance.", __FILE__, __LINE__);
182 }
183}
184
196bool
197DmrppMetadataStore::add_responses(DMR *dmr, const string &name)
198{
199 bool stored_dmr = GlobalMetadataStore::add_responses(dmr, name);
200
201 bool stored_dmrpp = false;
202 if (typeid(*dmr) == typeid(dmrpp::DMRpp)) {
203 d_ledger_entry = string("add DMR++ ").append(name);
204
205 StreamDMRpp write_the_dmrpp_response(dmr);
206 stored_dmrpp = store_dap_response(write_the_dmrpp_response, get_hash(name + "dmrpp_r"), name, "DMRpp");
207
208 write_ledger(); // write the index line
209 }
210 else {
211 stored_dmrpp = true; // if dmr is not a DMRpp, not writing the object is 'success.'
212 }
213
214 return(stored_dmr && stored_dmrpp);
215}
216
217bool
218DmrppMetadataStore::add_dmrpp_response(libdap::DMR *dmrpp, const std::string &name)
219{
220 bool stored_dmrpp = false;
221 if (typeid(*dmrpp) == typeid(dmrpp::DMRpp)) {
222 d_ledger_entry = string("add DMR++ ").append(name);
223
224 StreamDMRpp write_the_dmrpp_response(dmrpp);
225 stored_dmrpp = store_dap_response(write_the_dmrpp_response, get_hash(name + "dmrpp_r"), name, "DMRpp");
226
227 write_ledger(); // write the index line
228 }
229 else {
230 stored_dmrpp = true; // if dmr is not a DMRpp, not writing the object is 'success.'
231 }
232
233 return(stored_dmrpp);
234}
235
242DMR *
244{
245 // Get the DMR response, but then parse that so the resulting binary
246 // object is built with DMR++ types so that the chunk information can be
247 // stored in them.
248 stringstream oss;
249 write_dmr_response(name, oss); // throws BESInternalError if not found
250
251 DmrppTypeFactory dmrpp_btf;
252 unique_ptr<DMRpp> dmrpp(new DMRpp(&dmrpp_btf, "mds"));
253
254 DmrppParserSax2 parser;
255 parser.intern(oss.str(), dmrpp.get());
256
257 dmrpp->set_factory(0);
258
259 return dmrpp.release();
260}
261
274DMRpp *
276{
277 stringstream oss;
278 write_dmrpp_response(name, oss); // throws BESInternalError if not found
279
280 DmrppTypeFactory dmrpp_btf;
281 unique_ptr<DMRpp> dmrpp(new DMRpp(&dmrpp_btf, "mds"));
282
283 DmrppParserSax2 parser;
284 parser.intern(oss.str(), dmrpp.get());
285
286 dmrpp->set_factory(0);
287
288 return dmrpp.release();
289}
exception thrown if an internal error is found and is fatal to the BES
Store the DAP DMR++ metadata responses.
virtual bool add_responses(libdap::DMR *dmrpp, const std::string &name)
Add the DAP4 metadata responses using a DMR.
virtual libdap::DMR * get_dmr_object(const string &name)
Use the DMR response to build a DMR with Dmrpp Types.
static DmrppMetadataStore * get_instance()
virtual dmrpp::DMRpp * get_dmrpp_object(const std::string &name)
Build a DMR++ object from the cached Response.
virtual void write_dmr_response(const std::string &name, std::ostream &os)
Write the stored DMR response to a stream.
std::string get_hash(const std::string &name)
bool store_dap_response(StreamDAP &writer, const std::string &key, const std::string &name, const std::string &response_name)
virtual bool add_responses(libdap::DDS *dds, const std::string &name)
Add the DAP2 metadata responses using a DDS.
virtual void write_dmrpp_response(const std::string &name, std::ostream &os)
Write the stored DMR++ response to a stream.
Provide a way to print the DMR++ response.
Definition: DMRpp.h:44
void print_dap4(libdap::XMLWriter &xml, bool constrained=false)
override DMR::print_dap4() so the chunk info will print too.
Definition: DMRpp.cc:140
void intern(std::istream &f, libdap::DMR *dest_dmr)
Hack use a DMR to write a DMR++ response. WIP.