bes  Updated for version 3.20.6
GatewayCache.cc
1 // -*- mode: c++; c-basic-offset:4 -*-
2 
3 // This file is part of gateway_module, A C++ module that can be loaded in to
4 // the OPeNDAP Back-End Server (BES) and is able to handle remote requests.
5 
6 // Copyright (c) 2015 OPeNDAP, Inc.
7 // Author: Nathan Potter <ndp@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 /*
26  * GatewayCache.cc
27  *
28  * Created on: Oct 2, 2015
29  * Author: ndp
30  */
31 
32 #include "config.h"
33 
34 #include <sys/stat.h>
35 
36 #include <string>
37 #include <fstream>
38 #include <sstream>
39 
40 #include <cstdlib>
41 
42 #include "BESInternalError.h"
43 #include "BESDebug.h"
44 #include "BESUtil.h"
45 #include "TheBESKeys.h"
46 
47 #include "GatewayCache.h"
48 
49 #ifdef HAVE_ATEXIT
50 #define AT_EXIT(x) atexit((x))
51 #else
52 #define AT_EXIT(x)
53 #endif
54 
55 using std::endl;
56 using std::string;
57 using namespace gateway;
58 
59 GatewayCache *GatewayCache::d_instance = 0;
60 bool GatewayCache::d_enabled = true;
61 
62 const string GatewayCache::DIR_KEY = "Gateway.Cache.dir";
63 const string GatewayCache::PREFIX_KEY = "Gateway.Cache.prefix";
64 const string GatewayCache::SIZE_KEY = "Gateway.Cache.size";
65 
66 unsigned long GatewayCache::getCacheSizeFromConfig()
67 {
68 
69  bool found;
70  string size;
71  unsigned long size_in_megabytes = 0;
72  TheBESKeys::TheKeys()->get_value(SIZE_KEY, size, found);
73  if (found) {
74  std::istringstream iss(size);
75  iss >> size_in_megabytes;
76  }
77  else {
78  string msg = "GatewayCache - The BES Key " + SIZE_KEY + " is not set.";
79  BESDEBUG("cache", msg << endl);
80  throw BESInternalError(msg, __FILE__, __LINE__);
81  }
82  return size_in_megabytes;
83 }
84 
85 string GatewayCache::getCacheDirFromConfig()
86 {
87  bool found;
88  string subdir = "";
89  TheBESKeys::TheKeys()->get_value(DIR_KEY, subdir, found);
90 
91  if (!found) {
92  string msg = "GatewayCache - The BES Key " + DIR_KEY + " is not set.";
93  BESDEBUG("cache", msg << endl);
94  throw BESInternalError(msg, __FILE__, __LINE__);
95  }
96 
97  return subdir;
98 }
99 
100 string GatewayCache::getCachePrefixFromConfig()
101 {
102  bool found;
103  string prefix = "";
104  TheBESKeys::TheKeys()->get_value(PREFIX_KEY, prefix, found);
105  if (found) {
106  prefix = BESUtil::lowercase(prefix);
107  }
108  else {
109  string msg = "GatewayCache - The BES Key " + PREFIX_KEY + " is not set.";
110  BESDEBUG("cache", msg << endl);
111  throw BESInternalError(msg, __FILE__, __LINE__);
112  }
113 
114  return prefix;
115 }
116 
117 GatewayCache::GatewayCache()
118 {
119  BESDEBUG("cache", "GatewayCache::GatewayCache() - BEGIN" << endl);
120 
121  string cacheDir = getCacheDirFromConfig();
122  string cachePrefix = getCachePrefixFromConfig();
123  unsigned long cacheSizeMbytes = getCacheSizeFromConfig();
124 
125  BESDEBUG("cache",
126  "GatewayCache() - Cache configuration params: " << cacheDir << ", " << cachePrefix << ", " << cacheSizeMbytes << endl);
127 
128  initialize(cacheDir, cachePrefix, cacheSizeMbytes);
129 
130  BESDEBUG("cache", "GatewayCache::GatewayCache() - END" << endl);
131 }
132 
133 GatewayCache::GatewayCache(const string &cache_dir, const string &prefix, unsigned long long size)
134 {
135  BESDEBUG("cache", "GatewayCache::GatewayCache() - BEGIN" << endl);
136 
137  initialize(cache_dir, prefix, size);
138 
139  BESDEBUG("cache", "GatewayCache::GatewayCache() - END" << endl);
140 }
141 
142 GatewayCache *
143 GatewayCache::get_instance(const string &cache_dir, const string &cache_file_prefix, unsigned long long max_cache_size)
144 {
145  if (d_enabled && d_instance == 0) {
146  if (dir_exists(cache_dir)) {
147  d_instance = new GatewayCache(cache_dir, cache_file_prefix, max_cache_size);
148  d_enabled = d_instance->cache_enabled();
149  if (!d_enabled) {
150  delete d_instance;
151  d_instance = 0;
152  BESDEBUG("cache", "GatewayCache::"<<__func__ << "() - " << "Cache is DISABLED"<< endl);
153  }
154  else {
155  AT_EXIT(delete_instance);
156 
157  BESDEBUG("cache", "GatewayCache::"<<__func__ << "() - " << "Cache is ENABLED"<< endl);
158  }
159  }
160  }
161 
162  return d_instance;
163 }
164 
168 GatewayCache *
170 {
171  if (d_enabled && d_instance == 0) {
172  try {
173  d_instance = new GatewayCache();
174  d_enabled = d_instance->cache_enabled();
175  if (!d_enabled) {
176  delete d_instance;
177  d_instance = 0;
178  BESDEBUG("cache", "GatewayCache::"<<__func__ << "() - " << "Cache is DISABLED"<< endl);
179  }
180  else {
181  AT_EXIT(delete_instance);
182 
183  BESDEBUG("cache", "GatewayCache::" << __func__ << "() - " << "Cache is ENABLED"<< endl);
184  }
185  }
186  catch (BESInternalError &bie) {
187  BESDEBUG("cache",
188  "[ERROR] GatewayCache::get_instance(): Failed to obtain cache! msg: " << bie.get_message() << endl);
189  }
190  }
191 
192  return d_instance;
193 }
gateway::GatewayCache::get_instance
static GatewayCache * get_instance()
Definition: GatewayCache.cc:169
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
BESFileLockingCache::dir_exists
static bool dir_exists(const std::string &dir)
Definition: BESFileLockingCache.cc:1136
gateway::GatewayCache
A cache for data files accessed using the Gateway.
Definition: GatewayCache.h:57
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