bes  Updated for version 3.20.5
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 namespace gateway;
56 
57 GatewayCache *GatewayCache::d_instance = 0;
58 bool GatewayCache::d_enabled = true;
59 
60 const string GatewayCache::DIR_KEY = "Gateway.Cache.dir";
61 const string GatewayCache::PREFIX_KEY = "Gateway.Cache.prefix";
62 const string GatewayCache::SIZE_KEY = "Gateway.Cache.size";
63 
64 unsigned long GatewayCache::getCacheSizeFromConfig()
65 {
66 
67  bool found;
68  string size;
69  unsigned long size_in_megabytes = 0;
70  TheBESKeys::TheKeys()->get_value(SIZE_KEY, size, found);
71  if (found) {
72  std::istringstream iss(size);
73  iss >> size_in_megabytes;
74  }
75  else {
76  string msg = "GatewayCache - The BES Key " + SIZE_KEY + " is not set.";
77  BESDEBUG("cache", msg << endl);
78  throw BESInternalError(msg, __FILE__, __LINE__);
79  }
80  return size_in_megabytes;
81 }
82 
83 string GatewayCache::getCacheDirFromConfig()
84 {
85  bool found;
86  string subdir = "";
87  TheBESKeys::TheKeys()->get_value(DIR_KEY, subdir, found);
88 
89  if (!found) {
90  string msg = "GatewayCache - The BES Key " + DIR_KEY + " is not set.";
91  BESDEBUG("cache", msg << endl);
92  throw BESInternalError(msg, __FILE__, __LINE__);
93  }
94 
95  return subdir;
96 }
97 
98 string GatewayCache::getCachePrefixFromConfig()
99 {
100  bool found;
101  string prefix = "";
102  TheBESKeys::TheKeys()->get_value(PREFIX_KEY, prefix, found);
103  if (found) {
104  prefix = BESUtil::lowercase(prefix);
105  }
106  else {
107  string msg = "GatewayCache - The BES Key " + PREFIX_KEY + " is not set.";
108  BESDEBUG("cache", msg << endl);
109  throw BESInternalError(msg, __FILE__, __LINE__);
110  }
111 
112  return prefix;
113 }
114 
115 GatewayCache::GatewayCache()
116 {
117  BESDEBUG("cache", "GatewayCache::GatewayCache() - BEGIN" << endl);
118 
119  string cacheDir = getCacheDirFromConfig();
120  string cachePrefix = getCachePrefixFromConfig();
121  unsigned long cacheSizeMbytes = getCacheSizeFromConfig();
122 
123  BESDEBUG("cache",
124  "GatewayCache() - Cache configuration params: " << cacheDir << ", " << cachePrefix << ", " << cacheSizeMbytes << endl);
125 
126  initialize(cacheDir, cachePrefix, cacheSizeMbytes);
127 
128  BESDEBUG("cache", "GatewayCache::GatewayCache() - END" << endl);
129 }
130 
131 GatewayCache::GatewayCache(const string &cache_dir, const string &prefix, unsigned long long size)
132 {
133  BESDEBUG("cache", "GatewayCache::GatewayCache() - BEGIN" << endl);
134 
135  initialize(cache_dir, prefix, size);
136 
137  BESDEBUG("cache", "GatewayCache::GatewayCache() - END" << endl);
138 }
139 
140 GatewayCache *
141 GatewayCache::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 GatewayCache(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("cache", "GatewayCache::"<<__func__ << "() - " << "Cache is DISABLED"<< endl);
151  }
152  else {
153  AT_EXIT(delete_instance);
154 
155  BESDEBUG("cache", "GatewayCache::"<<__func__ << "() - " << "Cache is ENABLED"<< endl);
156  }
157  }
158  }
159 
160  return d_instance;
161 }
162 
166 GatewayCache *
168 {
169  if (d_enabled && d_instance == 0) {
170  try {
171  d_instance = new GatewayCache();
172  d_enabled = d_instance->cache_enabled();
173  if (!d_enabled) {
174  delete d_instance;
175  d_instance = 0;
176  BESDEBUG("cache", "GatewayCache::"<<__func__ << "() - " << "Cache is DISABLED"<< endl);
177  }
178  else {
179  AT_EXIT(delete_instance);
180 
181  BESDEBUG("cache", "GatewayCache::" << __func__ << "() - " << "Cache is ENABLED"<< endl);
182  }
183  }
184  catch (BESInternalError &bie) {
185  BESDEBUG("cache",
186  "[ERROR] GatewayCache::get_instance(): Failed to obtain cache! msg: " << bie.get_message() << endl);
187  }
188  }
189 
190  return d_instance;
191 }
exception thrown if inernal error encountered
static string lowercase(const string &s)
Definition: BESUtil.cc:197
A cache for data files accessed using the Gateway.
Definition: GatewayCache.h:57
virtual std::string get_message()
get the error message for this exception
Definition: BESError.h:99
static bool dir_exists(const std::string &dir)
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
static TheBESKeys * TheKeys()
Definition: TheBESKeys.cc:61
void initialize(const std::string &cache_dir, const std::string &prefix, unsigned long long size)
Initialize an instance of FileLockingCache.
static GatewayCache * get_instance()