bes  Updated for version 3.20.6
BESServiceRegistry.cc
1 // BESServiceRegistry.cc
2 
3 // This file is part of bes, A C++ back-end server implementation framework
4 // for the OPeNDAP Data Access Protocol.
5 
6 // Copyright (c) 2004-2009 University Corporation for Atmospheric Research
7 // Author: Patrick West <pwest@ucar.edu> and Jose Garcia <jgarcia@ucar.edu>
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 University Corporation for Atmospheric Research at
24 // 3080 Center Green Drive, Boulder, CO 80301
25 
26 // (c) COPYRIGHT University Corporation for Atmospheric Research 2004-2005
27 // Please read the full copyright statement in the file COPYRIGHT_UCAR.
28 //
29 // Authors:
30 // pwest Patrick West <pwest@ucar.edu>
31 // jgarcia Jose Garcia <jgarcia@ucar.edu>
32 
33 #include "BESServiceRegistry.h"
34 #include "BESInfo.h"
35 #include "BESInternalError.h"
36 
37 using std::endl;
38 using std::ostream;
39 using std::string;
40 using std::map;
41 using std::list;
42 
43 BESServiceRegistry *BESServiceRegistry::_instance = 0 ;
44 
45 BESServiceRegistry::BESServiceRegistry()
46 {
47 }
48 
49 BESServiceRegistry::~BESServiceRegistry()
50 {
51 }
52 
58 void
59 BESServiceRegistry::add_service( const string &name )
60 {
61  map<string,map<string,service_cmd> >::iterator i = _services.find( name ) ;
62  if( i == _services.end() )
63  {
64  map<string,service_cmd> cmds ;
65  _services[name] = cmds ;
66  }
67  else
68  {
69  string err = (string)"The service " + name
70  + " has already been registered" ;
71  throw BESInternalError( err, __FILE__, __LINE__ ) ;
72  }
73 }
74 
89 void
90 BESServiceRegistry::add_to_service( const string &service,
91  const string &cmd,
92  const string &cmd_descript,
93  const string &format )
94 {
95  map<string,map<string,service_cmd> >::iterator si ;
96  si = _services.find( service ) ;
97  if( si != _services.end() )
98  {
99  map<string,service_cmd>::const_iterator ci ;
100  ci = (*si).second.find( cmd ) ;
101  if( ci != (*si).second.end() )
102  {
103  string err = (string)"Attempting to add command "
104  + (*ci).first + " to the service "
105  + service + ", command alrady exists" ;
106  throw BESInternalError( err, __FILE__, __LINE__ ) ;
107  }
108  service_cmd sc ;
109  sc._description = cmd_descript ;
110  sc._formats[format] = format ;
111  (*si).second[cmd] = sc ;
112  }
113  else
114  {
115  string err = (string)"Attempting to add commands to the service "
116  + service + " that has not yet been registered" ;
117  throw BESInternalError( err, __FILE__, __LINE__ ) ;
118  }
119 }
120 
129 void
130 BESServiceRegistry::add_format( const string &service,
131  const string &cmd,
132  const string &format )
133 {
134  map<string,map<string,service_cmd> >::iterator si ;
135  si = _services.find( service ) ;
136  if( si != _services.end() )
137  {
138  map<string,service_cmd>::iterator ci = (*si).second.find( cmd ) ;
139  if( ci != (*si).second.end() )
140  {
141  map<string,string>::iterator fi ;
142  fi = (*ci).second._formats.find( format ) ;
143  if( fi == (*ci).second._formats.end() )
144  {
145  (*ci).second._formats[format] = format ;
146  }
147  else
148  {
149  string err = (string)"Attempting to add format "
150  + format + " to command " + cmd
151  + " for service " + service
152  + " where the format has already been registered" ;
153  throw BESInternalError( err, __FILE__, __LINE__ ) ;
154  }
155  }
156  else
157  {
158  string err = (string)"Attempting to add a format " + format
159  + " to command " + cmd + " for service " + service
160  + " where the command has not been registered" ;
161  throw BESInternalError( err, __FILE__, __LINE__ ) ;
162  }
163  }
164  else
165  {
166  string err = (string)"Attempting to add a format " + format
167  + " to command " + cmd + " for a service " + service
168  + " that has not been registered" ;
169  throw BESInternalError( err, __FILE__, __LINE__ ) ;
170  }
171 }
172 
181 void
182 BESServiceRegistry::remove_service( const string &service )
183 {
184  map<string,map<string,service_cmd> >::iterator i ;
185  i = _services.find( service ) ;
186  if( i != _services.end() )
187  {
188  // erase the service from the registry
189  _services.erase( i ) ;
190 
191  // remove the service from the _handles list as well, so that if
192  // asked, the handlers no longer handler the service because it no
193  // longer exists.
194  map<string,map<string,string> >::iterator hi = _handles.begin() ;
195  map<string,map<string,string> >::iterator he = _handles.end() ;
196  for( ; hi != he; hi++ )
197  {
198  map<string,string>::iterator hsi = (*hi).second.find( service ) ;
199  if( hsi != (*hi).second.end() )
200  {
201  (*hi).second.erase( hsi ) ;
202  }
203  }
204  }
205 }
206 
221 bool
223  const string &cmd,
224  const string &format )
225 {
226  bool isit = false ;
227  map<string,map<string,service_cmd> >::iterator si ;
228  si = _services.find( service ) ;
229  if( si != _services.end() )
230  {
231  if( !cmd.empty() )
232  {
233  map<string,service_cmd>::iterator ci = (*si).second.find( cmd ) ;
234  if( ci != (*si).second.end() )
235  {
236  if( !format.empty() )
237  {
238  map<string,string>::iterator fi ;
239  fi = (*ci).second._formats.find( format ) ;
240  if( fi != (*ci).second._formats.end() )
241  {
242  isit = true ;
243  }
244  }
245  else
246  {
247  isit = true ;
248  }
249  }
250  }
251  else
252  {
253  isit = true ;
254  }
255  }
256  return isit ;
257 }
258 
270 void
271 BESServiceRegistry::handles_service( const string &handler,
272  const string &service )
273 {
274  map<string,map<string,service_cmd> >::iterator si ;
275  si = _services.find( service ) ;
276  if( si == _services.end() )
277  {
278  string err = (string)"Registering a handler to handle service "
279  + service + " that has not yet been registered" ;
280  throw BESInternalError( err, __FILE__, __LINE__ ) ;
281  }
282 
283  map<string,map<string,string> >::iterator hi = _handles.find( handler ) ;
284  if( hi == _handles.end() )
285  {
286  map<string,string> services ;
287  services[service] = service ;
288  _handles[handler] = services ;
289  }
290  else
291  {
292  map<string,string>::iterator ci = (*hi).second.find( service ) ;
293  if( ci == (*hi).second.end() )
294  {
295  (*hi).second[service] = service ;
296  }
297  }
298 }
299 
308 bool
310  const string &service )
311 {
312  bool handled = false ;
313  map<string,map<string,string> >::iterator hi = _handles.find( handler ) ;
314  if( hi != _handles.end() )
315  {
316  map<string,string>::iterator si = (*hi).second.find( service ) ;
317  if( si != (*hi).second.end() )
318  {
319  handled = true ;
320  }
321  }
322  return handled ;
323 }
324 
333 void
335  list<string> &services )
336 {
337  map<string,map<string,string> >::iterator hi = _handles.find( handler ) ;
338  if( hi != _handles.end() )
339  {
340  map<string,string>::const_iterator si = (*hi).second.begin() ;
341  map<string,string>::const_iterator se = (*hi).second.end() ;
342  for( ; si != se; si++ )
343  {
344  services.push_back( (*si).second ) ;
345  }
346  }
347 }
348 
357 void
359 {
360  map<string,map<string,service_cmd> >::iterator si = _services.begin() ;
361  map<string,map<string,service_cmd> >::iterator se = _services.end() ;
362  for( ; si != se; si++ )
363  {
364  map<string,string> props ;
365  props["name"] = (*si).first ;
366  info.begin_tag( "serviceDescription", &props ) ;
367  map<string,service_cmd>::iterator ci = (*si).second.begin() ;
368  map<string,service_cmd>::iterator ce = (*si).second.end() ;
369  for( ; ci != ce; ci++ )
370  {
371  map<string,string> cprops ;
372  cprops["name"] = (*ci).first ;
373  info.begin_tag( "command", &cprops ) ;
374  info.add_tag( "description", (*ci).second._description ) ;
375  map<string,string>::iterator fi = (*ci).second._formats.begin() ;
376  map<string,string>::iterator fe = (*ci).second._formats.end() ;
377  for( ; fi != fe; fi++ )
378  {
379  map<string,string> fprops ;
380  fprops["name"] = (*fi).first ;
381  info.add_tag( "format", "", &fprops ) ;
382  }
383  info.end_tag( "command" ) ;
384  }
385  info.end_tag( "serviceDescription" ) ;
386  }
387 }
388 
396 void
397 BESServiceRegistry::dump( ostream &strm ) const
398 {
399  strm << BESIndent::LMarg << "BESServiceRegistry::dump - ("
400  << (void *)this << ")" << endl ;
401  BESIndent::Indent() ;
402  strm << BESIndent::LMarg << "registered services" << endl ;
403  BESIndent::Indent() ;
404  map<string,map<string,service_cmd> >::const_iterator si ;
405  si = _services.begin() ;
406  map<string,map<string,service_cmd> >::const_iterator se ;
407  se = _services.end() ;
408  for( ; si != se; si++ )
409  {
410  strm << BESIndent::LMarg << (*si).first << endl ;
411  BESIndent::Indent() ;
412  map<string,service_cmd>::const_iterator ci = (*si).second.begin() ;
413  map<string,service_cmd>::const_iterator ce = (*si).second.end() ;
414  for( ; ci != ce; ci++ )
415  {
416  strm << BESIndent::LMarg << (*ci).first << endl ;
417  BESIndent::Indent() ;
418  strm << BESIndent::LMarg << "description: "
419  << (*ci).second._description << endl ;
420  strm << BESIndent::LMarg << "formats:" << endl ;
421  BESIndent::Indent() ;
422  map<string,string>::const_iterator fi ;
423  fi = (*ci).second._formats.begin() ;
424  map<string,string>::const_iterator fe ;
425  fe = (*ci).second._formats.end() ;
426  for( ; fi != fe; fi++ )
427  {
428  strm << BESIndent::LMarg << (*fi).first << endl ;
429  }
430  BESIndent::UnIndent() ;
431  BESIndent::UnIndent() ;
432  }
433  BESIndent::UnIndent() ;
434  }
435  BESIndent::UnIndent() ;
436  strm << BESIndent::LMarg << "services provided by handler" << endl ;
437  BESIndent::Indent() ;
438  map<string,map<string,string> >::const_iterator hi = _handles.begin() ;
439  map<string,map<string,string> >::const_iterator he = _handles.end() ;
440  for( ; hi != he; hi++ )
441  {
442  strm << BESIndent::LMarg << (*hi).first ;
443  map<string,string>::const_iterator hsi = (*hi).second.begin() ;
444  map<string,string>::const_iterator hse = (*hi).second.end() ;
445  bool isfirst = true ;
446  for( ; hsi != hse; hsi++ )
447  {
448  if( !isfirst ) strm << ", " ;
449  else strm << ": " ;
450  strm << (*hsi).first ;
451  isfirst = false ;
452  }
453  strm << endl ;
454  }
455  BESIndent::UnIndent() ;
456  BESIndent::UnIndent() ;
457 }
458 
460 BESServiceRegistry::TheRegistry()
461 {
462  if( _instance == 0 )
463  {
464  _instance = new BESServiceRegistry ;
465  }
466  return _instance ;
467 }
468 
BESServiceRegistry::show_services
virtual void show_services(BESInfo &info)
fills in the response object for the <showService /> request
Definition: BESServiceRegistry.cc:358
BESServiceRegistry::services_handled
virtual void services_handled(const std::string &handler, std::list< std::string > &services)
returns the list of servies provided by the handler in question
Definition: BESServiceRegistry.cc:334
BESServiceRegistry::add_to_service
virtual void add_to_service(const std::string &service, const std::string &cmd, const std::string &cmd_descript, const std::string &format)
This function allows callers to add to a service that already exists.
Definition: BESServiceRegistry.cc:90
BESServiceRegistry
The service registry allows modules to register services with the BES that they provide.
Definition: BESServiceRegistry.h:56
BESServiceRegistry::remove_service
virtual void remove_service(const std::string &name)
remove a service from the BES
Definition: BESServiceRegistry.cc:182
BESServiceRegistry::handles_service
virtual void handles_service(const std::string &handler, const std::string &service)
The specified handler can handle the specified service.
Definition: BESServiceRegistry.cc:271
BESServiceRegistry::add_format
virtual void add_format(const std::string &service, const std::string &cmd, const std::string &format)
add a format response to a command of a service
Definition: BESServiceRegistry.cc:130
BESInfo
informational response object
Definition: BESInfo.h:63
BESInternalError
exception thrown if internal error encountered
Definition: BESInternalError.h:43
BESServiceRegistry::does_handle_service
virtual bool does_handle_service(const std::string &handler, const std::string &service)
Asks if the specified handler can handle the specified service.
Definition: BESServiceRegistry.cc:309
BESServiceRegistry::dump
virtual void dump(std::ostream &strm) const
dumps information about this object
Definition: BESServiceRegistry.cc:397
BESServiceRegistry::service_available
virtual bool service_available(const std::string &name, const std::string &cmd="", const std::string &format="")
Determines if a service and, optionally, a command and a return format, is available.
Definition: BESServiceRegistry.cc:222
BESServiceRegistry::add_service
virtual void add_service(const std::string &name)
Add a service to the BES.
Definition: BESServiceRegistry.cc:59