irods  4.2.8
About: iRODS (the integrated Rule Oriented Data System) is a distributed data-management system for creating data grids, digital libraries, persistent archives, and real-time data systems.
  Fossies Dox: irods-4.2.8.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

irods_plugin_base.hpp
Go to the documentation of this file.
1 #ifndef IRODS_PLUGIN_BASE_HPP
2 #define IRODS_PLUGIN_BASE_HPP
3 
4 #include <string>
5 
6 #include <boost/function.hpp>
7 
8 #include "irods_re_structs.hpp"
9 #include "rcConnect.h"
10 
11 #ifdef ENABLE_RE
13  #include "irods_re_plugin.hpp"
15  #include "irods_state_table.h"
16  #include "irods_at_scope_exit.hpp"
17 #endif
18 
19 #include "irods_error.hpp"
20 #include "irods_lookup_table.hpp"
21 #include "irods_plugin_context.hpp"
22 
23 static double PLUGIN_INTERFACE_VERSION = 2.0;
24 
26 
27 namespace irods
28 {
29  typedef std::function< irods::error( rcComm_t* ) > pdmo_type;
31 
33  return SUCCESS();
34  }
35 
37  return SUCCESS();
38  }
39 
48  {
49  private:
50 #ifdef ENABLE_RE
51  using rule_engine_context_manager_type = rule_engine_context_manager<unit, ruleExecInfo_t*, AUDIT_RULE>;
52 #endif
53 
54  public:
55  plugin_base(const std::string& _n, const std::string& _c)
56  : context_( _c )
57  , instance_name_( _n )
59  , operations_( )
62  {
63  } // ctor
64 
65  plugin_base(const plugin_base& _rhs)
66  : context_( _rhs.context_ )
69  , operations_( _rhs.operations_ )
72  {
73  } // cctor
74 
76  {
78  context_ = _rhs.context_;
80  operations_ = _rhs.operations_;
83  return *this;
84  } // operator=
85 
86  virtual ~plugin_base() {} // dtor
87 
90  return ERROR( NO_PDMO_DEFINED, "no defined operation" );
91  }
92 
96  _b = false;
97  return SUCCESS();
98  }
99 
102  error enumerate_operations( std::vector< std::string >& _ops ) {
103  for ( size_t i = 0; i < ops_for_delay_load_.size(); ++i ) {
104  _ops.push_back( ops_for_delay_load_[ i ].first );
105  }
106 
107  return SUCCESS();
108  }
109 
112  const std::string& context_string() const {
113  return context_;
114  }
115 
116  double interface_version() const {
117  return interface_version_;
118  }
119 
122  error add_operation(const std::string& _op, std::function<error(plugin_context&)> _f) {
123  // =-=-=-=-=-=-=-
124  // check params
125  if ( _op.empty() ) {
126  std::stringstream msg;
127  msg << "empty operation [" << _op << "]";
128  return ERROR( SYS_INVALID_INPUT_PARAM, msg.str() );
129  }
130  operations_[_op] = _f;
131  return SUCCESS();
132 
133  }
134 
137  template<typename... types_t>
139  const std::string& _op,
140  std::function<error(plugin_context&, types_t...)> _f ) {
141  // =-=-=-=-=-=-=-
142  // check params
143  if ( _op.empty() ) {
144  std::stringstream msg;
145  msg << "empty operation [" << _op << "]";
146  return ERROR( SYS_INVALID_INPUT_PARAM, msg.str() );
147  }
148  operations_[_op] = _f;
149  return SUCCESS();
150 
151  }
152 
153  template<typename... types_t>
155  rsComm_t* _comm,
156  const std::string& _operation_name,
158  types_t... _t)
159  {
160  using namespace std;
161 
162  try {
163  plugin_context ctx( _comm, properties_, _fco, "" );
164 
165  using adapted_func_type = std::function<error(plugin_context&, std::string*, types_t...)>;
166 
167  adapted_func_type adapted_fcn = [this, &_operation_name](plugin_context& _ctx, std::string* _out_param, types_t... _t) {
168  _ctx.rule_results( *_out_param );
169  typedef std::function<error(plugin_context&,types_t...)> fcn_t;
170  fcn_t& fcn = boost::any_cast< fcn_t& >( operations_[ _operation_name ] );
171  error ret = fcn( _ctx, _t... );
172  *_out_param = _ctx.rule_results();
173  return ret;
174  };
175 
176  std::string out_param;
177 #ifdef ENABLE_RE
178  error to_return_op_err = SUCCESS();
179  ruleExecInfo_t rei;
180  memset( &rei, 0, sizeof( rei ) );
181  if (_comm) {
182  rei.rsComm = _comm;
183  rei.uoic = &_comm->clientUser;
184  rei.uoip = &_comm->proxyUser;
185  }
186 
187  rule_engine_context_manager_type re_ctx_mgr(re_plugin_globals->global_re_mgr, &rei);
188 
189  // Always run the finally-PEP at scope exit.
190  at_scope_exit invoke_finally_pep{[&] {
191  error finally_err = invoke_policy_enforcement_point(re_ctx_mgr,
192  ctx,
193  &out_param,
194  _operation_name,
195  "finally",
196  forward<types_t>(_t)...);
197  if (!finally_err.ok()) {
198  irods::log(PASS(finally_err));
199  }
200  }};
201 
202  // invoke the pre-pep for this operation
203  error pre_err = invoke_policy_enforcement_point(
204  re_ctx_mgr,
205  ctx,
206  &out_param,
207  _operation_name,
208  "pre",
209  std::forward<types_t>(_t)...);
210 
211  if (pre_err.code() != RULE_ENGINE_SKIP_OPERATION) {
212  if(!pre_err.ok()) {
213  out_param = "error="+std::to_string(pre_err.code()) + ";message="+pre_err.result();
214 
215  // if the pre-pep fails, invoke the exception pep
216  error except_err = invoke_policy_enforcement_point(
217  re_ctx_mgr,
218  ctx,
219  &out_param,
220  _operation_name,
221  "except",
222  std::forward<types_t>(_t)...);
223 
224  if(!except_err.ok()) {
225  irods::log(PASS(except_err));
226  }
227 
228  return pre_err;
229  }
230 
231  to_return_op_err = adapted_fcn(ctx, &out_param, forward<types_t>(_t)...);
232 
233  if(!to_return_op_err.ok()) {
234  // if the operation fails, invoke the exception pep
235  out_param = "error="+std::to_string(to_return_op_err.code()) + ";message="+to_return_op_err.result();
236 
237  error except_err = invoke_policy_enforcement_point(
238  re_ctx_mgr,
239  ctx,
240  &out_param,
241  _operation_name,
242  "except",
243  forward<types_t>(_t)...);
244 
245  if(!except_err.ok()) {
246  irods::log(PASS(except_err));
247  }
248 
249  return to_return_op_err;
250  }
251 
252  // invoke the post-pep for this operation
253  error post_err = invoke_policy_enforcement_point(
254  re_ctx_mgr,
255  ctx,
256  &out_param,
257  _operation_name,
258  "post",
259  forward<types_t>(_t)...);
260 
261  if(!post_err.ok()) {
262  out_param = "error="+std::to_string(post_err.code()) + ";message="+post_err.result();
263 
264  // if the post-pep fails, invoke the exception pep
265  error except_err = invoke_policy_enforcement_point(
266  re_ctx_mgr,
267  ctx,
268  &out_param,
269  _operation_name,
270  "except",
271  forward<types_t>(_t)...);
272 
273  if(!except_err.ok()) {
274  irods::log(PASS(except_err));
275  }
276 
277  return post_err;
278  }
279 
280  return to_return_op_err;
281  } // skip operation
282 
283  return to_return_op_err;
284 #else // ENABLE_RE
285  return adapted_fcn( ctx, &out_param, forward<types_t>(_t)... );
286 #endif // ENABLE_RE
287  }
288  catch (const boost::bad_any_cast&) {
289  std::string msg( "failed for call - " );
290  msg += _operation_name;
291  return ERROR(INVALID_ANY_CAST, msg);
292  }
293  } // call
294 
296  template< typename T >
297  error get_property( const std::string& _key, T& _val ) {
298  error ret = properties_.get< T >( _key, _val );
299  return ASSERT_PASS( ret, "Failed to get property for auth plugin." );
300  } // get_property
301 
303  template< typename T >
304  error set_property( const std::string& _key, const T& _val ) {
305  error ret = properties_.set< T >( _key, _val );
306  return ASSERT_PASS( ret, "Failed to set property in the auth plugin." );
307  } // set_property
308 
310  start_operation_ = _op;
311  }
312 
314  stop_operation_ = _op;
315  }
316 
318  return start_operation_( properties_ );
319  }
320 
322  return stop_operation_( properties_ );
323  }
324 
325  protected:
326  std::string context_; // context string for this plugin
327  std::string instance_name_; // name of this instance of the plugin
328  double interface_version_; // version of the plugin interface supported
329 
333 
336  std::vector< std::pair< std::string, std::string > > ops_for_delay_load_;
337 
338  // =-=-=-=-=-=-=-
341 
344 
345  private:
346 #ifdef ENABLE_RE
347  template<typename... types_t>
348  error invoke_policy_enforcement_point(
349  rule_engine_context_manager_type _re_ctx_mgr,
350  plugin_context _ctx,
351  std::string* _out_param,
352  const std::string& _operation_name,
353  const std::string& _class,
354  types_t... _t)
355  {
356  bool ret = false;
357  error saved_op_err = SUCCESS();
358  error skip_op_err = SUCCESS();
359 
360  for ( auto& ns : NamespacesHelper::Instance()->getNamespaces() ) {
361  std::string rule_name = ns + "pep_" + _operation_name + "_" + _class;
362 
363  if (RuleExistsHelper::Instance()->checkOperation( rule_name ) ) {
364  if (_re_ctx_mgr.rule_exists(rule_name, ret).ok() && ret) {
365  error op_err = _re_ctx_mgr.exec_rule(rule_name, instance_name_, _ctx, _out_param, std::forward<types_t>(_t)...);
366 
367  if (!op_err.ok()) {
368  rodsLog(LOG_DEBUG, "%s-pep rule [%s] failed with error code [%d]", _class.c_str(), rule_name.c_str(), op_err.code());
369  saved_op_err = op_err;
370  }
371  else if (op_err.code() == RULE_ENGINE_SKIP_OPERATION) {
372  skip_op_err = op_err;
373 
374  if (_class != "pre") {
375  rodsLog(LOG_WARNING, "RULE_ENGINE_SKIP_OPERATION (%d) incorrectly returned from PEP [%s]! "
376  "RULE_ENGINE_SKIP_OPERATION should only be returned from pre-PEPs!",
377  RULE_ENGINE_SKIP_OPERATION, rule_name.c_str());
378  }
379  }
380  }
381  else {
382  rodsLog(LOG_DEBUG10, "Rule [%s] passes regex test, but does not exist", rule_name.c_str());
383  }
384  }
385  }
386 
387  if (!saved_op_err.ok()) {
388  return saved_op_err;
389  }
390 
391  if (skip_op_err.code() == RULE_ENGINE_SKIP_OPERATION) {
392  return skip_op_err;
393  }
394 
395  return saved_op_err;
396  } // invoke_policy_enforcement_point
397 #endif // ENABLE_RE
398  }; // class plugin_base
399 
400  // =-=-=-=-=-=-=-
401  // helpful typedef for sock comm interface & factory
402  typedef boost::shared_ptr<plugin_base> plugin_ptr;
403 } // namespace irods
404 
405 #endif // IRODS_PLUGIN_BASE_HPP
irods::plugin_base::get_property
error get_property(const std::string &_key, T &_val)
Definition: irods_plugin_base.hpp:297
rodsLog
void rodsLog(int level, const char *formatStr,...)
Definition: rodsLog.cpp:86
irods::plugin_ptr
boost::shared_ptr< plugin_base > plugin_ptr
Definition: irods_first_class_object.hpp:18
rcComm_t
Definition: rcConnect.h:95
irods::at_scope_exit
Definition: irods_at_scope_exit.hpp:10
rsComm_t
Definition: rcConnect.h:145
add_global_re_params_to_kvp_for_dynpep
irods::error add_global_re_params_to_kvp_for_dynpep(keyValPair_t &)
Definition: miscServerFunct.cpp:3100
irods::lookup_table< boost::any >
RuleExistsHelper::Instance
static RuleExistsHelper * Instance()
Definition: irods_re_ruleexistshelper.cpp:6
NO_PDMO_DEFINED
@ NO_PDMO_DEFINED
Definition: rodsErrorTable.h:755
RULE_ENGINE_SKIP_OPERATION
@ RULE_ENGINE_SKIP_OPERATION
Definition: irods_state_table.h:29
irods::rule_engine_context_manager
Definition: irods_re_plugin.hpp:522
irods::pdmo_type
std::function< irods::error(rcComm_t *) > pdmo_type
Definition: irods_plugin_base.hpp:29
PASS
#define PASS(prev_error_)
Definition: irods_error.hpp:118
LOG_WARNING
#define LOG_WARNING
Definition: rodsLog.h:38
irods::plugin_base::interface_version
double interface_version() const
Definition: irods_plugin_base.hpp:116
irods_plugin_context.hpp
rcConnect.h
NamespacesHelper::Instance
static NamespacesHelper * Instance()
Definition: irods_re_namespaceshelper.cpp:6
irods_re_ruleexistshelper.hpp
irods::plugin_base::stop_operation_
maintenance_operation_t stop_operation_
Definition: irods_plugin_base.hpp:343
irods::plugin_context
Definition: irods_plugin_context.hpp:18
irods::lookup_table::get
error get(const std::string &_key, ValueType &_val)
Definition: irods_lookup_table.hpp:71
irods::plugin_base::set_property
error set_property(const std::string &_key, const T &_val)
Definition: irods_plugin_base.hpp:304
SYS_INVALID_INPUT_PARAM
@ SYS_INVALID_INPUT_PARAM
Definition: rodsErrorTable.h:195
irods::plugin_base::plugin_base
plugin_base(const std::string &_n, const std::string &_c)
Definition: irods_plugin_base.hpp:55
irods_re_plugin.hpp
RuleExecInfo::rsComm
rsComm_t * rsComm
Definition: irods_re_structs.hpp:22
irods::plugin_base::add_operation
error add_operation(const std::string &_op, std::function< error(plugin_context &, types_t...)> _f)
Definition: irods_plugin_base.hpp:138
irods::maintenance_operation_t
std::function< irods::error(plugin_property_map &) > maintenance_operation_t
Definition: irods_plugin_base.hpp:30
irods::plugin_base::stop_operation
error stop_operation()
Definition: irods_plugin_base.hpp:321
SUCCESS
#define SUCCESS()
Definition: irods_error.hpp:121
irods::plugin_base::operator=
plugin_base & operator=(const plugin_base &_rhs)
Definition: irods_plugin_base.hpp:75
PLUGIN_INTERFACE_VERSION
static double PLUGIN_INTERFACE_VERSION
Definition: irods_plugin_base.hpp:23
irods::plugin_base::interface_version_
double interface_version_
Definition: irods_plugin_base.hpp:328
irods::error::code
long long code() const
Definition: irods_error.cpp:194
irods::first_class_object_ptr
boost::shared_ptr< first_class_object > first_class_object_ptr
Definition: irods_first_class_object.hpp:47
RuleExecInfo::uoip
userInfo_t * uoip
Definition: irods_re_structs.hpp:31
irods::plugin_base::start_operation_
maintenance_operation_t start_operation_
Definition: irods_plugin_base.hpp:342
LOG_DEBUG
#define LOG_DEBUG
Definition: rodsLog.h:23
irods::plugin_base::properties_
plugin_property_map properties_
Definition: irods_plugin_base.hpp:332
rsComm_t::proxyUser
userInfo_t proxyUser
Definition: rcConnect.h:152
irods
Definition: apiHandler.hpp:35
irods::plugin_base::call
error call(rsComm_t *_comm, const std::string &_operation_name, irods::first_class_object_ptr _fco, types_t... _t)
Definition: irods_plugin_base.hpp:154
irods::plugin_base::plugin_base
plugin_base(const plugin_base &_rhs)
Definition: irods_plugin_base.hpp:65
irods::plugin_base
Definition: irods_plugin_base.hpp:48
INVALID_ANY_CAST
@ INVALID_ANY_CAST
Definition: rodsErrorTable.h:771
ASSERT_PASS
#define ASSERT_PASS(prev_error_, format_,...)
Definition: irods_error.hpp:124
irods::log
void log(const error &)
Definition: irods_log.cpp:13
rsComm_t::clientUser
userInfo_t clientUser
Definition: rcConnect.h:153
irods::plugin_base::need_post_disconnect_maintenance_operation
virtual error need_post_disconnect_maintenance_operation(bool &_b)
Definition: irods_plugin_base.hpp:95
ERROR
#define ERROR(code_, message_)
Definition: irods_error.hpp:117
irods::plugin_base::~plugin_base
virtual ~plugin_base()
Definition: irods_plugin_base.hpp:86
irods::error
Definition: irods_error.hpp:23
irods::plugin_base::instance_name_
std::string instance_name_
Definition: irods_plugin_base.hpp:327
irods::default_plugin_start_operation
static error default_plugin_start_operation(plugin_property_map &)
Definition: irods_plugin_base.hpp:32
RuleExecInfo::uoic
userInfo_t * uoic
Definition: irods_re_structs.hpp:30
irods::plugin_base::set_start_operation
void set_start_operation(maintenance_operation_t _op)
Definition: irods_plugin_base.hpp:309
irods::plugin_base::enumerate_operations
error enumerate_operations(std::vector< std::string > &_ops)
Definition: irods_plugin_base.hpp:102
irods_re_namespaceshelper.hpp
irods::plugin_context::rule_results
virtual const std::string rule_results()
Definition: irods_plugin_context.hpp:105
irods::plugin_base::post_disconnect_maintenance_operation
virtual error post_disconnect_maintenance_operation(pdmo_type &)
Definition: irods_plugin_base.hpp:89
error
int error
Definition: filesystem.cpp:101
RuleExecInfo
Definition: irods_re_structs.hpp:18
irods_re_structs.hpp
irods::plugin_base::add_operation
error add_operation(const std::string &_op, std::function< error(plugin_context &)> _f)
Definition: irods_plugin_base.hpp:122
irods_at_scope_exit.hpp
irods::plugin_base::start_operation
error start_operation()
Definition: irods_plugin_base.hpp:317
irods::plugin_base::ops_for_delay_load_
std::vector< std::pair< std::string, std::string > > ops_for_delay_load_
Definition: irods_plugin_base.hpp:336
irods::plugin_base::context_string
const std::string & context_string() const
Definition: irods_plugin_base.hpp:112
LOG_DEBUG10
#define LOG_DEBUG10
Definition: rodsLog.h:19
irods::plugin_base::context_
std::string context_
Definition: irods_plugin_base.hpp:326
irods_error.hpp
irods::lookup_table::set
error set(const std::string &_key, const ValueType &_val)
Definition: irods_lookup_table.hpp:83
KeyValPair
Definition: objInfo.h:120
irods::error::ok
bool ok()
Definition: irods_error.cpp:258
irods::plugin_base::set_stop_operation
void set_stop_operation(maintenance_operation_t _op)
Definition: irods_plugin_base.hpp:313
irods::error::result
std::string result() const
Definition: irods_error.cpp:201
irods::re_plugin_globals
std::unique_ptr< struct irods::global_re_plugin_mgr > re_plugin_globals
Definition: irods_re_plugin.cpp:16
irods::default_plugin_stop_operation
static error default_plugin_stop_operation(plugin_property_map &)
Definition: irods_plugin_base.hpp:36
irods_lookup_table.hpp
irods::plugin_base::operations_
lookup_table< boost::any > operations_
Definition: irods_plugin_base.hpp:340
irods_state_table.h