ANNA Suite  2020b
Multipurpose development suite for Telco applications
ByRangeDelivery.hpp
Go to the documentation of this file.
1 // ANNA - Anna is Not Nothingness Anymore //
2 // //
3 // (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo //
4 // //
5 // See project site at http://redmine.teslayout.com/projects/anna-suite //
6 // See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
7 
8 
9 #ifndef anna_comm_ByRangeDelivery_hpp
10 #define anna_comm_ByRangeDelivery_hpp
11 
12 #include <anna/core/functions.hpp>
14 
15 #include <anna/xml/Node.hpp>
16 #include <anna/xml/Attribute.hpp>
17 
19 
20 namespace anna {
21 
22 namespace comm {
23 class Resource;
24 }
25 
26 namespace comm {
27 
42 template < typename TKey, typename TDelivery = RoundRobinDelivery, typename TSerializer = anna::functions > class ByRangeDelivery : public comm::Service {
43 protected:
44  struct Range {
45  const TKey bottom;
46  const TKey top;
47  TDelivery* delivery;
48 
49  Range(const std::string& baseName, const TKey& _bottom, const TKey& _top) :
50  bottom(_bottom), top(_top) {
51  std::string name(baseName);
52  name += '[';
53  name += TSerializer::asString(_bottom);
54  name += ',';
55  name += TSerializer::asString(_top);
56  name += ']';
57  delivery = new TDelivery(name.c_str(), false);
58  }
59 
60  std::string asString() const {
61  std::string result("comm::ByRangeDelivery { Bottom: ");
62  result += TSerializer::asString(bottom);
63  result += " | Top: ";
64  result += TSerializer::asString(top);
65  result += " | ";
66  result += delivery->asString();
67  return result += " }";
68  }
69 
70  xml::Node* asXML(xml::Node* parent) const {
71  xml::Node* result = parent->createChild("comm.Range");
72  result->createAttribute("Bottom", TSerializer::asString(bottom));
73  result->createAttribute("Top", TSerializer::asString(top));
74  delivery->asXML(result);
75  return result;
76  }
77  };
78 
79 public:
80  typedef std::vector<Range*> range_container;
81  typedef typename range_container::iterator range_iterator;
82  typedef typename range_container::const_iterator const_range_iterator;
83 
90  ByRangeDelivery(const char* name, const bool isCritical) :
91  comm::Service(name, isCritical),
92  a_currentRange(NULL)
93  {;}
94 
98  virtual ~ByRangeDelivery() {
99  for(range_iterator ii = range_begin(), maxii = range_end(); ii != maxii; ii ++)
100  delete range(ii)->delivery;
101 
102  a_ranges.clear();
103  }
104 
114  range_iterator createRange(const TKey& bottom, const TKey& top)
115  noexcept(false) {
116  Range* result;
117 
118  if(bottom > top) {
119  std::string msg(asString());
120  msg += " | Bottom: ";
121  msg += TSerializer::asString(bottom);
122  msg += " | Invalid range (bottom > top)";
124  }
125 
126  if((result = find(bottom)) != NULL) {
127  std::string msg(asString());
128  msg += " | Bottom: ";
129  msg += TSerializer::asString(bottom);
130  msg += " | Overlapped with ";
131  msg += result->asString();
133  }
134 
135  if((result = find(top)) != NULL) {
136  std::string msg(asString());
137  msg += " | top: ";
138  msg += TSerializer::asString(top);
139  msg += " | Overlapped with ";
140  msg += result->asString();
142  }
143 
144  a_ranges.push_back(result = new Range(getName(), bottom, top));
145  return range_begin() + a_ranges.size() - 1;
146  }
147 
153  void attach(range_iterator& ii, Server* server) noexcept(false) {
154  range(ii)->delivery->attach(server);
155  comm::Service::attach(server);
156  }
157 
163  void prepare(const TKey& key) noexcept(false) {
164  Range* w = find(key);
165 
166  if(w == NULL && Logger::isActive(Logger::Warning)) {
167  std::string msg(asString());
168  msg += " | TKey: ";
169  msg += TSerializer::asString(key);
170  msg += " | No range associated";
172  } else
173  a_currentRange = w;
174 
175  if(a_currentRange == NULL) {
176  std::string msg(asString());
177  msg += " | TKey: ";
178  msg += TSerializer::asString(key);
179  msg += " | No delivery service associated has been found";
181  }
182  }
183 
184  std::string asString() const
185  {
186  std::string result = className();
187  result += " { ";
188  result += comm::Delivery::asString();
189  result += " | Ranges: ";
190 
191  for(const_range_iterator ii = range_begin(), maxii = range_end(); ii != maxii; ii ++) {
192  result += "\n\t";
193  result += range(ii)->asString();
194  }
195 
196  return result += "}";
197  }
198 
199  xml::Node* asXML(xml::Node* parent) const
200  {
201  xml::Node* result = parent->createChild("anna.comm.ByRangeDelivery");
202  xml::Node* node = comm::Service::asXML(result);
203 
204  for(const_range_iterator ii = range_begin(), maxii = range_end(); ii != maxii; ii ++)
205  range(ii)->asXML(node);
206 
207  return result;
208  }
209 
216  static const char* className() { return "anna::comm::ByRangeDelivery"; }
217 
218 protected:
219  range_iterator range_begin() { return a_ranges.begin(); }
220  range_iterator range_end() { return a_ranges.end(); }
221 
222  const_range_iterator range_begin() const { return a_ranges.begin(); }
223  const_range_iterator range_end() const { return a_ranges.end(); }
224 
225  static Range* range(range_iterator& ii) { return *ii; }
226  static const Range* range(const_range_iterator& ii) { return *ii; }
227 
228  virtual void do_initialize()
229  noexcept(false) {
230  for(range_iterator ii = range_begin(), maxii = range_end(); ii != maxii; ii ++)
231  range(ii)->delivery->initialize();
232  }
233 
234 private:
235  range_container a_ranges;
236  Range* a_currentRange;
237 
238  Range* find(const TKey& key) {
239  Range* result(NULL);
240  Range* w;
241 
242  for(range_iterator ii = range_begin(), maxii = range_end(); ii != maxii; ii ++) {
243  w = range(ii);
244 
245  if(w->bottom <= key && key <= w->top) {
246  result = w;
247  break;
248  }
249  }
250 
251  return result;
252  }
253 
254  comm::Resource* do_apply()
255  noexcept(false) {
256  if(a_currentRange == NULL) {
257  std::string msg(asString());
258  msg += " | Wrong call to anna::comm::ByRangeDelivery::prepare";
260  }
261 
262  return a_currentRange->delivery->apply();
263  }
264 
265  // Considera que el servicio esta NO-disponible cuando TODOS los servicios fallan
266  bool do_fault(const comm::Resource* resource)
267  {
268  int n, nfault;
269  n = nfault = 0;
270 
271  for(range_iterator ii = range_begin(), maxii = range_end(); ii != maxii; ii ++) {
272  n ++;
273 
274  if(range(ii)->delivery->fault(resource) == true)
275  nfault ++;
276  }
277 
278  return (n == nfault);
279  }
280 
281  // Considera que el servicio esta recuperado cuando alguno de los servicios esta disponible
282  bool do_recover(const comm::Resource* resource)
283  {
284  bool result(false);
285 
286  for(range_iterator ii = range_begin(), maxii = range_end(); ii != maxii; ii ++) {
287  if(range(ii)->delivery->recover(resource) == true)
288  result = true;
289  }
290 
291  return result;
292  }
293 };
294 
295 }
296 }
297 
298 #endif
299 
range_iterator createRange(const TKey &bottom, const TKey &top) noexcept(false)
Definition: ByRangeDelivery.hpp:114
TDelivery * delivery
Definition: ByRangeDelivery.hpp:47
xml::Attribute * createAttribute(const char *name, const char *value, const Namespace *_namespace=NULL)
virtual std::string asString() const
Node * createChild(const char *name)
static const char * className()
Definition: ByRangeDelivery.hpp:216
std::string asString() const
Definition: ByRangeDelivery.hpp:184
const TKey top
Definition: ByRangeDelivery.hpp:46
Definition: Server.hpp:53
static const Range * range(const_range_iterator &ii)
Definition: ByRangeDelivery.hpp:226
Definition: Node.hpp:56
void prepare(const TKey &key) noexcept(false)
Definition: ByRangeDelivery.hpp:163
xml::Node * asXML(xml::Node *parent) const
Definition: ByRangeDelivery.hpp:199
virtual void do_initialize() noexcept(false)
Definition: ByRangeDelivery.hpp:228
Range(const std::string &baseName, const TKey &_bottom, const TKey &_top)
Definition: ByRangeDelivery.hpp:49
std::vector< Range * > range_container
Definition: ByRangeDelivery.hpp:80
static void warning(const std::string &text, const char *fromFile, const int fromLine)
Definition: Logger.hpp:338
static Range * range(range_iterator &ii)
Definition: ByRangeDelivery.hpp:225
range_iterator range_end()
Definition: ByRangeDelivery.hpp:220
range_container::const_iterator const_range_iterator
Definition: ByRangeDelivery.hpp:82
xml::Node * asXML(xml::Node *parent) const
const_range_iterator range_end() const
Definition: ByRangeDelivery.hpp:223
ByRangeDelivery(const char *name, const bool isCritical)
Definition: ByRangeDelivery.hpp:90
void attach(Server *server) noexcept(false)
Definition: Logger.hpp:41
virtual ~ByRangeDelivery()
Definition: ByRangeDelivery.hpp:98
xml::Node * asXML(xml::Node *parent) const
Definition: ByRangeDelivery.hpp:70
range_iterator range_begin()
Definition: ByRangeDelivery.hpp:219
std::string asString() const
Definition: ByRangeDelivery.hpp:60
Definition: Resource.hpp:25
Definition: app.hpp:12
const_range_iterator range_begin() const
Definition: ByRangeDelivery.hpp:222
Definition: ByRangeDelivery.hpp:42
#define ANNA_FILE_LOCATION
Definition: defines.hpp:23
range_container::iterator range_iterator
Definition: ByRangeDelivery.hpp:81
const TKey bottom
Definition: ByRangeDelivery.hpp:45
void attach(range_iterator &ii, Server *server) noexcept(false)
Definition: ByRangeDelivery.hpp:153
Definition: ByRangeDelivery.hpp:44
Definition: RuntimeException.hpp:23
static bool isActive(const Level level)
Definition: Logger.hpp:169
Definition: Service.hpp:28