bes  Updated for version 3.20.6
RemoteHttpResourceCache.cc
1 
2 // -*- mode: c++; c-basic-offset:4 -*-
3 
4 // This file is part of cmr_module, A C++ MODULE that can be loaded in to
5 // the OPeNDAP Back-End Server (BES) and is able to handle remote requests.
6 
7 // Copyright (c) 2018 OPeNDAP, Inc.
8 // Author: Nathan Potter <ndp@opendap.org>
9 //
10 // This library is free software; you can redistribute it and/or
11 // modify it under the terms of the GNU Lesser General Public
12 // License as published by the Free Software Foundation; either
13 // version 2.1 of the License, or (at your option) any later version.
14 //
15 // This library is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 // Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public
21 // License along with this library; if not, write to the Free Software
22 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 //
24 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
25 
26 #include <config.h>
27 
28 #include <sys/stat.h>
29 
30 #include <string>
31 #include <fstream>
32 #include <sstream>
33 
34 #include <cstdlib>
35 
36 #include "PicoSHA2/picosha2.h"
37 
38 #include <BESInternalError.h>
39 #include <BESDebug.h>
40 #include <BESUtil.h>
41 #include <TheBESKeys.h>
42 
43 #include "RemoteHttpResourceCache.h"
44 #include "HttpdCatalogNames.h"
45 
46 #ifdef HAVE_ATEXIT
47 #define AT_EXIT(x) atexit((x))
48 #else
49 #define AT_EXIT(x)
50 #endif
51 
52 using std::endl;
53 using std::string;
54 namespace httpd_catalog {
55 
56 RemoteHttpResourceCache *RemoteHttpResourceCache::d_instance = 0;
57 bool RemoteHttpResourceCache::d_enabled = true;
58 
59 const string RemoteHttpResourceCache::DIR_KEY = "HttpResourceCache.dir";
60 const string RemoteHttpResourceCache::PREFIX_KEY = "HttpResourceCache.prefix";
61 const string RemoteHttpResourceCache::SIZE_KEY = "HttpResourceCache.size";
62 
63 unsigned long RemoteHttpResourceCache::getCacheSizeFromConfig()
64 {
65  bool found;
66  string size;
67  unsigned long size_in_megabytes = 0;
68  TheBESKeys::TheKeys()->get_value(SIZE_KEY, size, found);
69 
70  if (found) {
71  std::istringstream iss(size);
72  iss >> size_in_megabytes;
73  }
74  else {
75  string msg = "HttpdCatalogCache - The BES Key " + SIZE_KEY + " is not set.";
76  BESDEBUG(MODULE, msg << endl);
77  throw BESInternalError(msg, __FILE__, __LINE__);
78  }
79 
80  return size_in_megabytes;
81 }
82 
83 string RemoteHttpResourceCache::getCacheDirFromConfig()
84 {
85  bool found;
86  string subdir = "";
87  TheBESKeys::TheKeys()->get_value(DIR_KEY, subdir, found);
88 
89  if (!found) {
90  string msg = "HttpdCatalogCache - The BES Key " + DIR_KEY + " is not set.";
91  BESDEBUG(MODULE, msg << endl);
92  throw BESInternalError(msg, __FILE__, __LINE__);
93  }
94 
95  return subdir;
96 }
97 
98 string RemoteHttpResourceCache::getCachePrefixFromConfig()
99 {
100  bool found;
101  string prefix = "";
102  TheBESKeys::TheKeys()->get_value(PREFIX_KEY, prefix, found);
103 
104  if (found) {
105  prefix = BESUtil::lowercase(prefix);
106  }
107  else {
108  string msg = "HttpdCatalogCache - The BES Key " + PREFIX_KEY + " is not set.";
109  BESDEBUG(MODULE, msg << endl);
110  throw BESInternalError(msg, __FILE__, __LINE__);
111  }
112 
113  return prefix;
114 }
115 
116 RemoteHttpResourceCache::RemoteHttpResourceCache()
117 {
118  BESDEBUG(MODULE, "HttpdCatalogCache::HttpdCatalogCache() - BEGIN" << endl);
119 
120  string cacheDir = getCacheDirFromConfig();
121  string cachePrefix = getCachePrefixFromConfig();
122  unsigned long cacheSizeMbytes = getCacheSizeFromConfig();
123 
124  BESDEBUG(MODULE, "HttpdCatalogCache() - Cache configuration params: " << cacheDir << ", " << cachePrefix << ", " << cacheSizeMbytes << endl);
125 
126  initialize(cacheDir, cachePrefix, cacheSizeMbytes);
127 
128  BESDEBUG(MODULE, "HttpdCatalogCache::HttpdCatalogCache() - END" << endl);
129 }
130 
131 RemoteHttpResourceCache::RemoteHttpResourceCache(const string &cache_dir, const string &prefix, unsigned long long size)
132 {
133  BESDEBUG(MODULE, "HttpdCatalogCache::HttpdCatalogCache() - BEGIN" << endl);
134 
135  initialize(cache_dir, prefix, size);
136 
137  BESDEBUG(MODULE, "HttpdCatalogCache::HttpdCatalogCache() - END" << endl);
138 }
139 
140 RemoteHttpResourceCache *
141 RemoteHttpResourceCache::get_instance(const string &cache_dir, const string &cache_file_prefix, unsigned long long max_cache_size)
142 {
143  if (d_enabled && d_instance == 0) {
144  if (dir_exists(cache_dir)) {
145  d_instance = new RemoteHttpResourceCache(cache_dir, cache_file_prefix, max_cache_size);
146  d_enabled = d_instance->cache_enabled();
147  if (!d_enabled) {
148  delete d_instance;
149  d_instance = 0;
150  BESDEBUG(MODULE, "HttpdCatalogCache::"<<__func__ << "() - " << "Cache is DISABLED"<< endl);
151  }
152  else {
153  AT_EXIT(delete_instance);
154 
155  BESDEBUG(MODULE, "HttpdCatalogCache::"<<__func__ << "() - " << "Cache is ENABLED"<< endl);
156  }
157  }
158  }
159 
160  return d_instance;
161 }
162 
166 RemoteHttpResourceCache *
168 {
169  if (d_enabled && d_instance == 0) {
170  try {
171  d_instance = new RemoteHttpResourceCache();
172  d_enabled = d_instance->cache_enabled();
173  if (!d_enabled) {
174  delete d_instance;
175  d_instance = 0;
176  BESDEBUG(MODULE, "HttpdCatalogCache::"<<__func__ << "() - " << "Cache is DISABLED"<< endl);
177  }
178  else {
179  AT_EXIT(delete_instance);
180 
181  BESDEBUG(MODULE, "HttpdCatalogCache::" << __func__ << "() - " << "Cache is ENABLED"<< endl);
182  }
183  }
184  catch (BESInternalError &bie) {
185  BESDEBUG(MODULE, "[ERROR] HttpdCatalogCache::get_instance(): Failed to obtain cache! msg: " << bie.get_message() << endl);
186  }
187  }
188 
189  return d_instance;
190 }
191 
198 inline string RemoteHttpResourceCache::get_hash(const string &name)
199 {
200  if (name.empty()) throw BESInternalError("Empty name passed to the Metadata Store.", __FILE__, __LINE__);
201  return picosha2::hash256_hex_string(name[0] == '/' ? name : "/" + name);
202 }
203 
204 string RemoteHttpResourceCache::get_cache_file_name(const string &src, bool /*mangle*/)
205 {
207 }
208 
209 
210 } // namespqce httpd_catalog
httpd_catalog::RemoteHttpResourceCache::get_instance
static RemoteHttpResourceCache * get_instance()
Definition: RemoteHttpResourceCache.cc:167
BESFileLockingCache::cache_enabled
bool cache_enabled() const
Definition: BESFileLockingCache.h:198
BESError::get_message
virtual std::string get_message()
get the error message for this exception
Definition: BESError.h:99
httpd_catalog::RemoteHttpResourceCache::get_hash
std::string get_hash(const std::string &name)
Definition: RemoteHttpResourceCache.cc:198
BESFileLockingCache::dir_exists
static bool dir_exists(const std::string &dir)
Definition: BESFileLockingCache.cc:1136
BESFileLockingCache::get_cache_file_prefix
const std::string get_cache_file_prefix()
Definition: BESFileLockingCache.h:182
BESUtil::assemblePath
static std::string assemblePath(const std::string &firstPart, const std::string &secondPart, bool leadingSlash=false, bool trailingSlash=false)
Assemble path fragments making sure that they are separated by a single '/' character.
Definition: BESUtil.cc:821
httpd_catalog::RemoteHttpResourceCache
A cache for content accessed via HTTP.
Definition: RemoteHttpResourceCache.h:50
TheBESKeys::TheKeys
static TheBESKeys * TheKeys()
Definition: TheBESKeys.cc:62
BESFileLockingCache::initialize
void initialize(const std::string &cache_dir, const std::string &prefix, unsigned long long size)
Initialize an instance of FileLockingCache.
Definition: BESFileLockingCache.cc:116
BESInternalError
exception thrown if internal error encountered
Definition: BESInternalError.h:43
TheBESKeys::get_value
void get_value(const std::string &s, std::string &val, bool &found)
Retrieve the value of a given key, if set.
Definition: TheBESKeys.cc:272
BESUtil::lowercase
static std::string lowercase(const std::string &s)
Definition: BESUtil.cc:200
httpd_catalog::RemoteHttpResourceCache::get_cache_file_name
virtual std::string get_cache_file_name(const std::string &src, bool mangle=true)
Definition: RemoteHttpResourceCache.cc:204
BESFileLockingCache::get_cache_directory
const std::string get_cache_directory()
Definition: BESFileLockingCache.h:188