bes Updated for version 3.21.1
The Backend Server (BES) is the lower two tiers of the Hyrax data server
BESDDSResponseHandler.cc
1// BESDDSResponseHandler.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 <memory>
36
37#include <libdap/DDS.h>
38
39#include "BESDDSResponseHandler.h"
40#include "BESDDSResponse.h"
41#include "BESRequestHandlerList.h"
42#include "BESDapNames.h"
43#include "BESDataNames.h"
44#include "BESTransmitter.h"
45
46#include "GlobalMetadataStore.h"
47#include "BESDebug.h"
48
49using namespace libdap;
50using namespace bes;
51
52BESDDSResponseHandler::BESDDSResponseHandler(const string &name) :
54{
55}
56
57BESDDSResponseHandler::~BESDDSResponseHandler()
58{
59}
60
69static bool
70function_in_ce(const string &ce)
71{
72 // 0x28 is '('
73 return ce.find("(") != string::npos || ce.find("%28") != string::npos; // hack
74}
75
96{
97 dhi.action_name = DDS_RESPONSE_STR;
98
100
102
103 dhi.first_container();
104 if (mds) lock = mds->is_dds_available(*(dhi.container));
105
106 if (mds && lock() && dhi.container->get_constraint().empty()) {
107 // Unconstrained DDS requests; send the stored response
108 mds->write_dds_response(dhi.container->get_relative_name(), dhi.get_output_stream());
109 // suppress transmitting a ResponseObject in transmit()
110 d_response_object = 0;
111 }
112 else {
113 DDS *dds = 0;
114
115 // Constrained DDS request (but not a CE with a function).
116 if (mds && lock() && !function_in_ce(dhi.container->get_constraint())) {
117 // If mds and lock(), the DDS is in the cache, get the _object_
118 dds = mds->get_dds_object(dhi.container->get_relative_name());
119 BESDDSResponse *bdds = new BESDDSResponse(dds);
120 bdds->set_constraint(dhi);
121 bdds->clear_container();
122 d_response_object = bdds;
123 }
124 else {
125 dds = new DDS(NULL, "virtual");
126
127 d_response_object = new BESDDSResponse(dds);
128
129 BESRequestHandlerList::TheList()->execute_each(dhi);
130
131 dhi.first_container(); // must reset container; execute_each() iterates over all of them
132
133#if ANNOTATION_SYSTEM
134 // Support for the experimental Dataset Annotation system. jhrg 12/19/18
135 if (!d_annotation_service_url.empty()) {
136 // resp_dds is a convenience object
137 BESDDSResponse *resp_dds = static_cast<BESDDSResponse*>(d_response_object);
138
139 // Add the Annotation Service URL attribute in the DODS_EXTRA container.
140 AttrTable *dods_extra = resp_dds->get_dds()->get_attr_table().find_container(DODS_EXTRA_ATTR_TABLE);
141 if (dods_extra)
142 dods_extra->append_attr(DODS_EXTRA_ANNOTATION_ATTR, "String", d_annotation_service_url);
143 else {
144 unique_ptr<AttrTable> new_dods_extra(new AttrTable);
145 new_dods_extra->append_attr(DODS_EXTRA_ANNOTATION_ATTR, "String", d_annotation_service_url);
146 resp_dds->get_dds()->get_attr_table().append_container(new_dods_extra.release(), DODS_EXTRA_ATTR_TABLE);
147 }
148 }
149#endif
150
151 // Cache the DDS if the MDS is not null but the DDS response was not in the cache
152 if (mds && !lock() && !function_in_ce(dhi.container->get_constraint())) {
153 // moved dhi.first_container(); // must reset container; execute_each() iterates over all of them
154 mds->add_responses(static_cast<BESDDSResponse*>(d_response_object)->get_dds(),
156 }
157 }
158 }
159}
160
174{
175 if (d_response_object) {
176 transmitter->send_response(DDS_SERVICE, d_response_object, dhi);
177 }
178}
179
187{
188 strm << BESIndent::LMarg << "BESDDSResponseHandler::dump - (" << (void *) this << ")" << endl;
189 BESIndent::Indent();
191 BESIndent::UnIndent();
192}
193
195BESDDSResponseHandler::DDSResponseBuilder(const string &name)
196{
197 return new BESDDSResponseHandler(name);
198}
199
std::string get_relative_name() const
Get the relative name of the object in this container.
std::string get_constraint() const
retrieve the constraint expression for this container
response handler that builds an OPeNDAP DDS response object
virtual void execute(BESDataHandlerInterface &dhi)
executes the command <get type="dds" definition=...>
virtual void dump(std::ostream &strm) const
dumps information about this object
virtual void transmit(BESTransmitter *transmitter, BESDataHandlerInterface &dhi)
transmit the response object built by the execute command using the specified transmitter object
Holds a DDS object within the BES.
virtual void clear_container()
clear the container in the DAP response object
libdap::DDS * get_dds()
virtual void set_constraint(BESDataHandlerInterface &dhi)
set the constraint depending on the context
Structure storing information used by the BES to handle the request.
void first_container()
set the container pointer to the first container in the containers list
BESContainer * container
pointer to current container in this interface
handler object that knows how to create a specific response object
void dump(std::ostream &strm) const override
dumps information about this object
Store the DAP metadata responses.
virtual libdap::DDS * get_dds_object(const std::string &name)
Build a DDS object from the cached Response.
virtual void write_dds_response(const std::string &name, std::ostream &os)
Write the stored DDS response to a stream.
static GlobalMetadataStore * get_instance()
virtual MDSReadLock is_dds_available(const std::string &name)
Is the DDS response for.
virtual bool add_responses(libdap::DDS *dds, const std::string &name)
Add the DAP2 metadata responses using a DDS.
STL class.
STL class.
Unlock and close the MDS item when the ReadLock goes out of scope.