bes  Updated for version 3.20.5
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 namespace httpd_catalog {
53 
54 RemoteHttpResourceCache *RemoteHttpResourceCache::d_instance = 0;
55 bool RemoteHttpResourceCache::d_enabled = true;
56 
57 const string RemoteHttpResourceCache::DIR_KEY = "HttpResourceCache.dir";
58 const string RemoteHttpResourceCache::PREFIX_KEY = "HttpResourceCache.prefix";
59 const string RemoteHttpResourceCache::SIZE_KEY = "HttpResourceCache.size";
60 
61 unsigned long RemoteHttpResourceCache::getCacheSizeFromConfig()
62 {
63  bool found;
64  string size;
65  unsigned long size_in_megabytes = 0;
66  TheBESKeys::TheKeys()->get_value(SIZE_KEY, size, found);
67 
68  if (found) {
69  std::istringstream iss(size);
70  iss >> size_in_megabytes;
71  }
72  else {
73  string msg = "HttpdCatalogCache - The BES Key " + SIZE_KEY + " is not set.";
74  BESDEBUG(MODULE, msg << endl);
75  throw BESInternalError(msg, __FILE__, __LINE__);
76  }
77 
78  return size_in_megabytes;
79 }
80 
81 string RemoteHttpResourceCache::getCacheDirFromConfig()
82 {
83  bool found;
84  string subdir = "";
85  TheBESKeys::TheKeys()->get_value(DIR_KEY, subdir, found);
86 
87  if (!found) {
88  string msg = "HttpdCatalogCache - The BES Key " + DIR_KEY + " is not set.";
89  BESDEBUG(MODULE, msg << endl);
90  throw BESInternalError(msg, __FILE__, __LINE__);
91  }
92 
93  return subdir;
94 }
95 
96 string RemoteHttpResourceCache::getCachePrefixFromConfig()
97 {
98  bool found;
99  string prefix = "";
100  TheBESKeys::TheKeys()->get_value(PREFIX_KEY, prefix, found);
101 
102  if (found) {
103  prefix = BESUtil::lowercase(prefix);
104  }
105  else {
106  string msg = "HttpdCatalogCache - The BES Key " + PREFIX_KEY + " is not set.";
107  BESDEBUG(MODULE, msg << endl);
108  throw BESInternalError(msg, __FILE__, __LINE__);
109  }
110 
111  return prefix;
112 }
113 
114 RemoteHttpResourceCache::RemoteHttpResourceCache()
115 {
116  BESDEBUG(MODULE, "HttpdCatalogCache::HttpdCatalogCache() - BEGIN" << endl);
117 
118  string cacheDir = getCacheDirFromConfig();
119  string cachePrefix = getCachePrefixFromConfig();
120  unsigned long cacheSizeMbytes = getCacheSizeFromConfig();
121 
122  BESDEBUG(MODULE, "HttpdCatalogCache() - Cache configuration params: " << cacheDir << ", " << cachePrefix << ", " << cacheSizeMbytes << endl);
123 
124  initialize(cacheDir, cachePrefix, cacheSizeMbytes);
125 
126  BESDEBUG(MODULE, "HttpdCatalogCache::HttpdCatalogCache() - END" << endl);
127 }
128 
129 RemoteHttpResourceCache::RemoteHttpResourceCache(const string &cache_dir, const string &prefix, unsigned long long size)
130 {
131  BESDEBUG(MODULE, "HttpdCatalogCache::HttpdCatalogCache() - BEGIN" << endl);
132 
133  initialize(cache_dir, prefix, size);
134 
135  BESDEBUG(MODULE, "HttpdCatalogCache::HttpdCatalogCache() - END" << endl);
136 }
137 
138 RemoteHttpResourceCache *
139 RemoteHttpResourceCache::get_instance(const string &cache_dir, const string &cache_file_prefix, unsigned long long max_cache_size)
140 {
141  if (d_enabled && d_instance == 0) {
142  if (dir_exists(cache_dir)) {
143  d_instance = new RemoteHttpResourceCache(cache_dir, cache_file_prefix, max_cache_size);
144  d_enabled = d_instance->cache_enabled();
145  if (!d_enabled) {
146  delete d_instance;
147  d_instance = 0;
148  BESDEBUG(MODULE, "HttpdCatalogCache::"<<__func__ << "() - " << "Cache is DISABLED"<< endl);
149  }
150  else {
151  AT_EXIT(delete_instance);
152 
153  BESDEBUG(MODULE, "HttpdCatalogCache::"<<__func__ << "() - " << "Cache is ENABLED"<< endl);
154  }
155  }
156  }
157 
158  return d_instance;
159 }
160 
164 RemoteHttpResourceCache *
166 {
167  if (d_enabled && d_instance == 0) {
168  try {
169  d_instance = new RemoteHttpResourceCache();
170  d_enabled = d_instance->cache_enabled();
171  if (!d_enabled) {
172  delete d_instance;
173  d_instance = 0;
174  BESDEBUG(MODULE, "HttpdCatalogCache::"<<__func__ << "() - " << "Cache is DISABLED"<< endl);
175  }
176  else {
177  AT_EXIT(delete_instance);
178 
179  BESDEBUG(MODULE, "HttpdCatalogCache::" << __func__ << "() - " << "Cache is ENABLED"<< endl);
180  }
181  }
182  catch (BESInternalError &bie) {
183  BESDEBUG(MODULE, "[ERROR] HttpdCatalogCache::get_instance(): Failed to obtain cache! msg: " << bie.get_message() << endl);
184  }
185  }
186 
187  return d_instance;
188 }
189 
196 inline string RemoteHttpResourceCache::get_hash(const string &name)
197 {
198  if (name.empty()) throw BESInternalError("Empty name passed to the Metadata Store.", __FILE__, __LINE__);
199  return picosha2::hash256_hex_string(name[0] == '/' ? name : "/" + name);
200 }
201 
202 string RemoteHttpResourceCache::get_cache_file_name(const string &src, bool /*mangle*/)
203 {
205 }
206 
207 
208 } // namespqce httpd_catalog
httpd_catalog::RemoteHttpResourceCache::get_instance
static RemoteHttpResourceCache * get_instance()
Definition: RemoteHttpResourceCache.cc:165
BESFileLockingCache::cache_enabled
bool cache_enabled() const
Definition: BESFileLockingCache.h:194
httpd_catalog::RemoteHttpResourceCache::get_hash
string get_hash(const string &name)
Definition: RemoteHttpResourceCache.cc:196
BESError::get_message
virtual std::string get_message()
get the error message for this exception
Definition: BESError.h:99
BESUtil::assemblePath
static string assemblePath(const string &firstPart, const string &secondPart, bool leadingSlash=false, bool trailingSlash=false)
Assemble path fragments making sure that they are separated by a single '/' character.
Definition: BESUtil.cc:818
BESFileLockingCache::dir_exists
static bool dir_exists(const std::string &dir)
Definition: BESFileLockingCache.cc:1123
BESFileLockingCache::get_cache_file_prefix
const std::string get_cache_file_prefix()
Definition: BESFileLockingCache.h:178
httpd_catalog::RemoteHttpResourceCache
A cache for content accessed via HTTP.
Definition: RemoteHttpResourceCache.h:50
TheBESKeys::TheKeys
static TheBESKeys * TheKeys()
Definition: TheBESKeys.cc:61
BESUtil::lowercase
static string lowercase(const string &s)
Definition: BESUtil.cc:197
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 inernal 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:420
httpd_catalog::RemoteHttpResourceCache::get_cache_file_name
virtual string get_cache_file_name(const string &src, bool mangle=true)
Definition: RemoteHttpResourceCache.cc:202
BESFileLockingCache::get_cache_directory
const std::string get_cache_directory()
Definition: BESFileLockingCache.h:184