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)  

libdeferred.cpp
Go to the documentation of this file.
1 // =-=-=-=-=-=-=-
2 // irods includes
3 #include "msParam.h"
4 #include "generalAdmin.h"
5 #include "miscServerFunct.hpp"
6 
7 // =-=-=-=-=-=-=-
9 #include "irods_file_object.hpp"
15 #include "irods_stacktrace.hpp"
17 #include "irods_random.hpp"
18 
19 // =-=-=-=-=-=-=-
20 // stl includes
21 #include <iostream>
22 #include <sstream>
23 #include <vector>
24 #include <string>
25 
26 // =-=-=-=-=-=-=-
27 // boost includes
28 #include <boost/lexical_cast.hpp>
29 #include <boost/function.hpp>
30 #include <boost/any.hpp>
31 
34 const std::string DEFER_POLICY_KEY( "defer_policy" );
35 
38 const std::string DEFER_POLICY_LOCALHOST( "localhost_defer_policy" );
39 
42 template< typename DEST_TYPE >
44  irods::plugin_context& _ctx ) {
45  irods::error result = SUCCESS();
46 
47  // =-=-=-=-=-=-=-
48  // ask the context if it is valid
49  irods::error ret = _ctx.valid< DEST_TYPE >();
50  result = ASSERT_PASS( ret, "Resource context invalid." );
51 
52  return result;
53 
54 } // deferred_check_params
55 
60  const std::string& _name,
61  const std::string& _hier,
63  irods::resource_ptr& _resc ) {
64  irods::error result = SUCCESS();
65 
66  irods::resource_child_map* cmap_ref;
67  _props.get< irods::resource_child_map* >(
69  cmap_ref );
70 
71  // =-=-=-=-=-=-=-
72  // create a parser and parse the string
74  irods::error err = parse.set_string( _hier );
75  if ( ( result = ASSERT_PASS( err, "Failed in set_string" ) ).ok() ) {
76 
77  // =-=-=-=-=-=-=-
78  // get the next resource in the series
79  std::string next;
80  err = parse.next( _name, next );
81 
82  if ( ( result = ASSERT_PASS( err, "Failed in next." ) ).ok() ) {
83 
84  // =-=-=-=-=-=-=-
85  // get the next resource from the child map
86  if ( ( result = ASSERT_ERROR( cmap_ref->has_entry( next ), CHILD_NOT_FOUND, "Child map missing entry: \"%s\"",
87  next.c_str() ) ).ok() ) {
88  // =-=-=-=-=-=-=-
89  // assign resource
90  _resc = (*cmap_ref)[ next ].second;
91  }
92  }
93  }
94 
95  return result;
96 
97 } // get_next_child_in_hier
98 
99 // =-=-=-=-=-=-=-
102 template< typename DEST_TYPE >
104  irods::plugin_context& _ctx,
105  irods::resource_ptr& _resc ) {
106  irods::error result = SUCCESS();
107 
108  // =-=-=-=-=-=-=-
109  // check incoming parameters
110  irods::error err = deferred_check_params< DEST_TYPE >( _ctx );
111  if ( ( result = ASSERT_PASS( err, "Bad resource context." ) ).ok() ) {
112 
113  // =-=-=-=-=-=-=-
114  // get the object's name
115  std::string name;
116  err = _ctx.prop_map().get< std::string >( irods::RESOURCE_NAME, name );
117  if ( ( result = ASSERT_PASS( err, "Failed to get property." ) ).ok() ) {
118 
119  // =-=-=-=-=-=-=-
120  // get the object's hier string
121  boost::shared_ptr< DEST_TYPE > dst_obj = boost::dynamic_pointer_cast< DEST_TYPE >( _ctx.fco() );
122  std::string hier = dst_obj->resc_hier( );
123 
124  // =-=-=-=-=-=-=-
125  // get the next child pointer given our name and the hier string
126  err = get_next_child_in_hier( name, hier, _ctx.prop_map(), _resc );
127  result = ASSERT_PASS( err, "Get next child failed." );
128  }
129  }
130 
131  return result;
132 
133 } // deferred_get_resc_for_call
134 
135 // =-=-=-=-=-=-=-
140  return SUCCESS();
141 
142 } // deferred_start_operation
143 
149  std::string& _next_child ) {
150  irods::error result = SUCCESS();
151 
152  // =-=-=-=-=-=-=-
153  // if the child map is empty then just return
154  if ( _cmap.size() > 0 ) {
155 
156  // =-=-=-=-=-=-=-
157  // get the size of the map and deferredly pick an index into it
158  size_t target_index = irods::getRandom<unsigned int>() % _cmap.size();
159 
160  // =-=-=-=-=-=-=-
161  // child map is keyed by resource name so we need to count out the index
162  // and then snag the child name from the key of the hash map
163  size_t counter = 0;
164  std::string next_child;
166  for ( ; itr != _cmap.end(); ++itr ) {
167  if ( counter == target_index ) {
168  next_child = itr->first;
169  break;
170 
171  }
172  else {
173  ++counter;
174 
175  }
176 
177  } // for itr
178 
179  // =-=-=-=-=-=-=-
180  // assign the next_child to the out variable
181  _next_child = next_child;
182  }
183 
184  return result;
185 
186 } // deferred_get_next_child_resource
187 
191  irods::plugin_context& _ctx ) {
192  irods::error result = SUCCESS();
193 
194  // =-=-=-=-=-=-=-
195  // get the child resc to call
196  irods::resource_ptr resc;
197  irods::error err = deferred_get_resc_for_call< irods::file_object >( _ctx, resc );
198  if ( ( result = ASSERT_PASS( err, "Invalid resource context." ) ).ok() ) {
199 
200  // =-=-=-=-=-=-=-
201  // call create on the child
202  err = resc->call( _ctx.comm(), irods::RESOURCE_OP_CREATE, _ctx.fco() );
203  result = ASSERT_PASS( err, "Failed calling create on child resource." );
204  }
205 
206  return result;
207 } // deferred_file_create
208 
209 // =-=-=-=-=-=-=-
210 // interface for POSIX Open
212  irods::plugin_context& _ctx ) {
213  irods::error result = SUCCESS();
214 
215  // =-=-=-=-=-=-=-
216  // get the child resc to call
217  irods::resource_ptr resc;
218  irods::error err = deferred_get_resc_for_call< irods::file_object >( _ctx, resc );
219  if ( ( result = ASSERT_PASS( err, "Failed in file open." ) ).ok() ) {
220 
221  // =-=-=-=-=-=-=-
222  // call open operation on the child
223  err = resc->call( _ctx.comm(), irods::RESOURCE_OP_OPEN, _ctx.fco() );
224  result = ASSERT_PASS( err, "Failed calling open on the child." );
225  }
226 
227  return result;
228 } // deferred_file_open
229 
233  irods::plugin_context& _ctx,
234  void* _buf,
235  int _len ) {
236  irods::error result = SUCCESS();
237 
238  // =-=-=-=-=-=-=-
239  // get the child resc to call
240  irods::resource_ptr resc;
241  irods::error err = deferred_get_resc_for_call< irods::file_object >( _ctx, resc );
242  if ( ( result = ASSERT_PASS( err, "Failed finding resource." ) ).ok() ) {
243 
244  // =-=-=-=-=-=-=-
245  // call read on the child
246  err = resc->call< void*, int >( _ctx.comm(), irods::RESOURCE_OP_READ, _ctx.fco(), _buf, _len );
247  result = ASSERT_PASS( err, "Failed calling operation on child resource." );
248  }
249 
250  return result;
251 
252 } // deferred_file_read
253 
257  irods::plugin_context& _ctx,
258  void* _buf,
259  int _len ) {
260  irods::error result = SUCCESS();
261 
262  // =-=-=-=-=-=-=-
263  // get the child resc to call
264  irods::resource_ptr resc;
265  irods::error err = deferred_get_resc_for_call< irods::file_object >( _ctx, resc );
266  if ( ( result = ASSERT_PASS( err, "Failed choosing child resource." ) ).ok() ) {
267 
268  // =-=-=-=-=-=-=-
269  // call write on the child
270  err = resc->call< void*, int >( _ctx.comm(), irods::RESOURCE_OP_WRITE, _ctx.fco(), _buf, _len );
271  result = ASSERT_PASS( err, "Failed calling operation on child resource." );
272  }
273 
274  return result;
275 } // deferred_file_write
276 
280  irods::plugin_context& _ctx ) {
281  irods::error result = SUCCESS();
282 
283  // =-=-=-=-=-=-=-
284  // get the child resc to call
285  irods::resource_ptr resc;
286  irods::error err = deferred_get_resc_for_call< irods::file_object >( _ctx, resc );
287  if ( ( result = ASSERT_PASS( err, "Failed to select deferred resource." ) ).ok() ) {
288 
289  // =-=-=-=-=-=-=-
290  // call close on the child
291  err = resc->call( _ctx.comm(), irods::RESOURCE_OP_CLOSE, _ctx.fco() );
292  result = ASSERT_PASS( err, "Failed calling operation in child." );
293  }
294 
295  return result;
296 } // deferred_file_close
297 
301  irods::plugin_context& _ctx ) {
302  irods::error result = SUCCESS();
303 
304  // =-=-=-=-=-=-=-
305  // get the child resc to call
306  irods::resource_ptr resc;
307  irods::error err = deferred_get_resc_for_call< irods::data_object >( _ctx, resc );
308  if ( ( result = ASSERT_PASS( err, "Failed to select deferred resource." ) ).ok() ) {
309 
310  // =-=-=-=-=-=-=-
311  // call unlink on the child
312  err = resc->call( _ctx.comm(), irods::RESOURCE_OP_UNLINK, _ctx.fco() );
313  result = ASSERT_PASS( err, "Failed during call to child operation." );
314  }
315 
316  return result;
317 } // deferred_file_unlink
318 
322  irods::plugin_context& _ctx,
323  struct stat* _statbuf ) {
324  irods::error result = SUCCESS();
325 
326  // =-=-=-=-=-=-=-
327  // get the child resc to call
328  irods::resource_ptr resc;
329  irods::error err = deferred_get_resc_for_call< irods::data_object >( _ctx, resc );
330  if ( ( result = ASSERT_PASS( err, "Failed selecting deferred child resource." ) ).ok() ) {
331 
332  // =-=-=-=-=-=-=-
333  // call stat on the child
334  err = resc->call< struct stat* >( _ctx.comm(), irods::RESOURCE_OP_STAT, _ctx.fco(), _statbuf );
335  result = ASSERT_PASS( err, "Failed in call to child operation." );
336  }
337 
338  return result;
339 } // deferred_file_stat
340 
344  irods::plugin_context& _ctx,
345  long long _offset,
346  int _whence ) {
347  irods::error result = SUCCESS();
348 
349  // =-=-=-=-=-=-=-
350  // get the child resc to call
351  irods::resource_ptr resc;
352  irods::error err = deferred_get_resc_for_call< irods::file_object >( _ctx, resc );
353  if ( ( result = ASSERT_PASS( err, "Failed to select deferred child." ) ).ok() ) {
354 
355  // =-=-=-=-=-=-=-
356  // call lseek on the child
357  err = resc->call< long long, int >( _ctx.comm(), irods::RESOURCE_OP_LSEEK, _ctx.fco(), _offset, _whence );
358  result = ASSERT_PASS( err, "Failed calling child operation." );
359  }
360 
361  return result;
362 } // deferred_file_lseek
363 
367  irods::plugin_context& _ctx ) {
368  irods::error result = SUCCESS();
369 
370  // =-=-=-=-=-=-=-
371  // get the child resc to call
372  irods::resource_ptr resc;
373  irods::error err = deferred_get_resc_for_call< irods::collection_object >( _ctx, resc );
374  if ( ( result = ASSERT_PASS( err, "Failed to select deferred child resource." ) ).ok() ) {
375 
376  // =-=-=-=-=-=-=-
377  // call mkdir on the child
378  err = resc->call( _ctx.comm(), irods::RESOURCE_OP_MKDIR, _ctx.fco() );
379  result = ASSERT_PASS( err, "Failed calling child operation." );
380  }
381 
382  return result;
383 } // deferred_file_mkdir
384 
388  irods::plugin_context& _ctx ) {
389  irods::error result = SUCCESS();
390 
391  // =-=-=-=-=-=-=-
392  // get the child resc to call
393  irods::resource_ptr resc;
394  irods::error err = deferred_get_resc_for_call< irods::collection_object >( _ctx, resc );
395  if ( ( result = ASSERT_PASS( err, "Failed to select deferred resource." ) ).ok() ) {
396 
397  // =-=-=-=-=-=-=-
398  // call rmdir on the child
399  err = resc->call( _ctx.comm(), irods::RESOURCE_OP_RMDIR, _ctx.fco() );
400  result = ASSERT_PASS( err, "Failed calling child operation." );
401  }
402 
403  return result;
404 } // deferred_file_rmdir
405 
409  irods::plugin_context& _ctx ) {
410  irods::error result = SUCCESS();
411 
412  // =-=-=-=-=-=-=-
413  // get the child resc to call
414  irods::resource_ptr resc;
415  irods::error err = deferred_get_resc_for_call< irods::collection_object >( _ctx, resc );
416  if ( ( result = ASSERT_PASS( err, "Failed to select deferred resource." ) ).ok() ) {
417 
418  // =-=-=-=-=-=-=-
419  // call opendir on the child
420  err = resc->call( _ctx.comm(), irods::RESOURCE_OP_OPENDIR, _ctx.fco() );
421  result = ASSERT_PASS( err, "Failed calling child operation." );
422  }
423 
424  return result;
425 } // deferred_file_opendir
426 
427 // =-=-=-=-=-=-=-
430  irods::plugin_context& _ctx ) {
431  irods::error result = SUCCESS();
432 
433  // =-=-=-=-=-=-=-
434  // get the child resc to call
435  irods::resource_ptr resc;
436  irods::error err = deferred_get_resc_for_call< irods::collection_object >( _ctx, resc );
437  if ( ( result = ASSERT_PASS( err, "Failed to select deferred resource." ) ).ok() ) {
438 
439  // =-=-=-=-=-=-=-
440  // call closedir on the child
441  err = resc->call( _ctx.comm(), irods::RESOURCE_OP_CLOSEDIR, _ctx.fco() );
442  result = ASSERT_PASS( err, "Failed calling child operation." );
443  }
444 
445  return result;
446 } // deferred_file_closedir
447 
451  irods::plugin_context& _ctx,
452  struct rodsDirent** _dirent_ptr ) {
453  irods::error result = SUCCESS();
454 
455  // =-=-=-=-=-=-=-
456  // get the child resc to call
457  irods::resource_ptr resc;
458  irods::error err = deferred_get_resc_for_call< irods::collection_object >( _ctx, resc );
459  if ( ( result = ASSERT_PASS( err, "Failed to select deferred resource." ) ).ok() ) {
460 
461  // =-=-=-=-=-=-=-
462  // call readdir on the child
463  err = resc->call< struct rodsDirent** >( _ctx.comm(), irods::RESOURCE_OP_READDIR, _ctx.fco(), _dirent_ptr );
464  result = ASSERT_PASS( err, "Failed calling child operation." );
465  }
466 
467  return result;
468 } // deferred_file_readdir
469 
473  irods::plugin_context& _ctx,
474  const char* _new_file_name ) {
475  irods::error result = SUCCESS();
476 
477  // =-=-=-=-=-=-=-
478  // get the child resc to call
479  irods::resource_ptr resc;
480  irods::error err = deferred_get_resc_for_call< irods::file_object >( _ctx, resc );
481  if ( ( result = ASSERT_PASS( err, "Failed to select deferred resource." ) ).ok() ) {
482 
483  // =-=-=-=-=-=-=-
484  // call rename on the child
485  err = resc->call< const char* >( _ctx.comm(), irods::RESOURCE_OP_RENAME, _ctx.fco(), _new_file_name );
486  result = ASSERT_PASS( err, "Failed calling child operation." );
487  }
488 
489  return result;
490 } // deferred_file_rename
491 
495  irods::plugin_context& _ctx ) {
496  irods::error result = SUCCESS();
497 
498  // =-=-=-=-=-=-=-
499  // get the child resc to call
500  irods::resource_ptr resc;
501  irods::error err = deferred_get_resc_for_call< irods::file_object >( _ctx, resc );
502  if ( ( result = ASSERT_PASS( err, "Failed selecting deferred resource." ) ).ok() ) {
503 
504  // =-=-=-=-=-=-=-
505  // call freespace on the child
506  err = resc->call( _ctx.comm(), irods::RESOURCE_OP_TRUNCATE, _ctx.fco() );
507  result = ASSERT_PASS( err, "Failed calling child operation." );
508  }
509 
510  return result;
511 } // deferred_file_getfs_truncate
512 
516  irods::plugin_context& _ctx ) {
517  irods::error result = SUCCESS();
518 
519  // =-=-=-=-=-=-=-
520  // get the child resc to call
521  irods::resource_ptr resc;
522  irods::error err = deferred_get_resc_for_call< irods::file_object >( _ctx, resc );
523  if ( ( result = ASSERT_PASS( err, "Failed selecting deferred resource." ) ).ok() ) {
524 
525  // =-=-=-=-=-=-=-
526  // call freespace on the child
527  err = resc->call( _ctx.comm(), irods::RESOURCE_OP_FREESPACE, _ctx.fco() );
528  result = ASSERT_PASS( err, "Failed calling child operation." );
529  }
530 
531  return result;
532 } // deferred_file_getfs_freespace
533 
538  irods::plugin_context& _ctx,
539  const char* _cache_file_name ) {
540  irods::error result = SUCCESS();
541 
542  // =-=-=-=-=-=-=-
543  // get the child resc to call
544  irods::resource_ptr resc;
545  irods::error err = deferred_get_resc_for_call< irods::file_object >( _ctx, resc );
546  if ( ( result = ASSERT_PASS( err, "Failed to select deferred resource." ) ).ok() ) {
547  // =-=-=-=-=-=-=-
548  // call stage on the child
549  err = resc->call< const char* >( _ctx.comm(), irods::RESOURCE_OP_STAGETOCACHE, _ctx.fco(), _cache_file_name );
550  result = ASSERT_PASS( err, "Failed calling child operation." );
551  }
552 
553  return result;
554 } // deferred_file_stage_to_cache
555 
561  irods::plugin_context& _ctx,
562  const char* _cache_file_name ) {
563  irods::error result = SUCCESS();
564 
565  // =-=-=-=-=-=-=-
566  // get the child resc to call
567  irods::resource_ptr resc;
568  irods::error err = deferred_get_resc_for_call< irods::file_object >( _ctx, resc );
569  if ( ( result = ASSERT_PASS( err, "Failed selecting deferred resource." ) ).ok() ) {
570 
571  // =-=-=-=-=-=-=-
572  // call synctoarch on the child
573  err = resc->call< const char* >( _ctx.comm(), irods::RESOURCE_OP_SYNCTOARCH, _ctx.fco(), _cache_file_name );
574  result = ASSERT_PASS( err, "Failed calling child operation." );
575  }
576 
577  return result;
578 } // deferred_file_sync_to_arch
579 
583  irods::plugin_context& _ctx ) {
584  irods::error result = SUCCESS();
585 
586  // =-=-=-=-=-=-=-
587  // get the child resc to call
588  irods::resource_ptr resc;
589  irods::error err = deferred_get_resc_for_call< irods::file_object >( _ctx, resc );
590  if ( ( result = ASSERT_PASS( err, "Failed selecting deferred resource." ) ).ok() ) {
591 
592  // =-=-=-=-=-=-=-
593  // call rename on the child
594  err = resc->call( _ctx.comm(), irods::RESOURCE_OP_REGISTERED, _ctx.fco() );
595  result = ASSERT_PASS( err, "Failed calling child operation." );
596  }
597 
598  return result;
599 } // deferred_file_registered
600 
604  irods::plugin_context& _ctx ) {
605  irods::error result = SUCCESS();
606 
607  // =-=-=-=-=-=-=-
608  // get the child resc to call
609  irods::resource_ptr resc;
610  irods::error err = deferred_get_resc_for_call< irods::file_object >( _ctx, resc );
611  if ( ( result = ASSERT_PASS( err, "Failed selecting deferred resource." ) ).ok() ) {
612 
613  // =-=-=-=-=-=-=-
614  // call rename on the child
615  err = resc->call( _ctx.comm(), irods::RESOURCE_OP_UNREGISTERED, _ctx.fco() );
616  result = ASSERT_PASS( err, "Failed calling child operation." );
617  }
618 
619  return result;
620 } // deferred_file_unregistered
621 
625  irods::plugin_context& _ctx ) {
626  irods::error result = SUCCESS();
627 
628  // =-=-=-=-=-=-=-
629  // get the child resc to call
630  irods::resource_ptr resc;
631  irods::error err = deferred_get_resc_for_call< irods::file_object >( _ctx, resc );
632  if ( ( result = ASSERT_PASS( err, "Failed selecting deferred resource." ) ).ok() ) {
633 
634  // =-=-=-=-=-=-=-
635  // call rename on the child
636  err = resc->call( _ctx.comm(), irods::RESOURCE_OP_MODIFIED, _ctx.fco() );
637  result = ASSERT_PASS( err, "Failed calling child operation." );
638  }
639 
640  return result;
641 } // deferred_file_modified
642 
646  irods::plugin_context& _ctx,
647  const std::string* _opr ) {
648  irods::error result = SUCCESS();
649 
650  // =-=-=-=-=-=-=-
651  // get the child resc to call
652  irods::resource_ptr resc;
653  irods::error err = deferred_get_resc_for_call< irods::file_object >( _ctx, resc );
654  if ( ( result = ASSERT_PASS( err, "Failed selecting deferred resource." ) ).ok() ) {
655 
656  // =-=-=-=-=-=-=-
657  // call rename on the child
658  err = resc->call( _ctx.comm(), irods::RESOURCE_OP_NOTIFY, _ctx.fco(), _opr );
659  result = ASSERT_PASS( err, "Failed calling child operation." );
660  }
661 
662  return result;
663 } // deferred_file_notify
664 
668  irods::plugin_context& _ctx,
669  const std::string* _opr,
670  const std::string* _curr_host,
671  irods::hierarchy_parser* _out_parser,
672  float* _out_vote ) {
673  // =-=-=-=-=-=-=-
674  // ensure we start with a vote of 0 should something go wrong
675  (*_out_vote) = 0.0;
676 
677 
678  // =-=-=-=-=-=-=-
679  // data struct to hold parser and vote from the search
680  std::map< float, irods::hierarchy_parser > result_map;
681  irods::resource_child_map* cmap_ref;
684  cmap_ref );
685 
686  // =-=-=-=-=-=-=-
687  // if we have no children return early
688  if( cmap_ref->empty() ) {
689  std::string name;
690  irods::error ret = _ctx.prop_map().get< std::string >(
692  if( ret.ok() ) {
693  rodsLog(
694  LOG_NOTICE,
695  "deferred resource [%s] has zero children",
696  name.c_str() );
697  }
698  else {
699  irods::log(PASS(ret));
700  }
701  return SUCCESS();
702  }
703 
704  // =-=-=-=-=-=-=-
705  // iterate over all the children and pick the highest vote
706  irods::resource_child_map::iterator itr = cmap_ref->begin();
707  for ( ; itr != cmap_ref->end(); ++itr ) {
708  // =-=-=-=-=-=-=-
709  // cache resc ptr for ease of use
710  irods::resource_ptr resc = itr->second.second;
711 
712  // =-=-=-=-=-=-=-
713  // temp results from open redirect call - init parser with incoming
714  // hier parser
715  float vote = 0.0;
716  irods::hierarchy_parser parser = ( *_out_parser );
717 
718  // =-=-=-=-=-=-=-
719  // forward the redirect call to the child for assertion of the whole operation,
720  // there may be more than a leaf beneath us
721  irods::error err = resc->call <
722  const std::string*,
723  const std::string*,
725  float* > (
726  _ctx.comm(),
728  _ctx.fco(),
729  _opr,
730  _curr_host,
731  &parser,
732  &vote );
733  std::string hier;
734  parser.str( hier );
735  rodsLog( LOG_DEBUG10, "deferred node - hier : [%s], vote %f", hier.c_str(), vote );
736  if ( !err.ok() ) {
737  // on a fail, force a zero vote and not error
738  // out in order to preserve reliability within
739  // the hierarchy, other resources may be able
740  // to service the operation.
741  vote = 0.0;
742  }
743  else {
744  result_map[ vote ] = parser;
745  }
746 
747  } // for
748 
749  // =-=-=-=-=-=-=-
750  // now that we have collected all of the results the map
751  // will have put the largest one at the end of the map
752  // so grab that one and return the result if it is non zero
753  if( !result_map.empty() ) {
754  float high_vote = result_map.rbegin()->first;
755  if ( high_vote > 0.0 ) {
756  ( *_out_parser ) = result_map.rbegin()->second;
757  ( *_out_vote ) = high_vote;
758  }
759  }
760 
761  return SUCCESS();
762 
763 } // deferred_redirect_for_operation
764 
765 
770  irods::plugin_context& _ctx,
771  const std::string* _opr,
772  const std::string* _curr_host,
773  irods::hierarchy_parser* _out_parser,
774  float* _out_vote ) {
775 
776  // =-=-=-=-=-=-=-
777  // check incoming parameters
778  irods::error ret = deferred_check_params< irods::file_object >( _ctx );
779  if ( !ret.ok() ) {
780  return PASSMSG( "Invalid resource context.", ret );
781  }
782 
783  if ( NULL == _opr || NULL == _curr_host || NULL == _out_parser || NULL == _out_vote ) {
784  return ERROR( SYS_INVALID_INPUT_PARAM, "Invalid parameters." );
785  }
786 
787  // =-=-=-=-=-=-=-
788  // get the name of this resource
789  std::string name;
790  ret = _ctx.prop_map().get< std::string >( irods::RESOURCE_NAME, name );
791  if ( !ret.ok() ) {
792  return PASSMSG( std::string( "Failed to get property: \"" + irods::RESOURCE_NAME + "\"." ), ret );
793  }
794 
795  // =-=-=-=-=-=-=-
796  // add ourselves into the hierarchy before calling child resources
797  _out_parser->add_child( name );
798 
799  // =-=-=-=-=-=-=-
800  // test the operation to determine which choices to make
801  if ( irods::OPEN_OPERATION == ( *_opr ) ||
802  irods::WRITE_OPERATION == ( *_opr ) ||
803  irods::UNLINK_OPERATION == ( *_opr ) ||
804  irods::CREATE_OPERATION == ( *_opr ) ) {
805  ret = deferred_redirect_for_operation( _ctx, _opr, _curr_host, _out_parser, _out_vote );
806  if ( !ret.ok() ) {
807  ret = PASSMSG( std::string( "failed in resolve hierarchy for [" + ( *_opr ) + "]" ), ret );
808  }
809  }
810  else {
811  // =-=-=-=-=-=-=-
812  // must have been passed a bad operation
813  ret = ERROR( INVALID_OPERATION, std::string( "Operation not supported: \"" + ( *_opr ) + "\"." ) );
814  }
815 
816  return ret;
817 } // deferred_file_resolve_hierarchy
818 
819 // =-=-=-=-=-=-=-
820 // deferred_file_rebalance - code which would rebalance the subtree
822  irods::plugin_context& _ctx ) {
823  // =-=-=-=-=-=-=-
824  // forward request for rebalance to children
825  irods::resource_child_map* cmap_ref;
828  cmap_ref );
829 
830  irods::error result = SUCCESS();
831  irods::resource_child_map::iterator itr = cmap_ref->begin();
832  for ( ; itr != cmap_ref->end(); ++itr ) {
833  irods::error ret = itr->second.second->call( _ctx.comm(), irods::RESOURCE_OP_REBALANCE, _ctx.fco() );
834  if ( !( result = ASSERT_PASS( ret, "Failed calling child operation." ) ).ok() ) {
835  irods::log( PASS( result ) );
836  }
837  }
838 
839  if ( !result.ok() ) {
840  return PASS( result );
841  }
842 
843  return SUCCESS();
844 
845 } // deferred_file_rebalance
846 
847 // =-=-=-=-=-=-=-
848 // 3. create derived class to handle unix file system resources
849 // necessary to do custom parsing of the context string to place
850 // any useful values into the property map for reference in later
851 // operations. semicolon is the preferred delimiter
853  public:
855  const std::string& _inst_name,
856  const std::string& _context ) :
857  irods::resource( _inst_name, _context ) {
858  // =-=-=-=-=-=-=-
859  // extract the defer policy from the context string
860  irods::kvp_map_t kvp;
862  _context,
863  kvp );
864  if(!ret.ok()) {
865  rodsLog(
866  LOG_ERROR,
867  "libdeferred: invalid context [%s]",
868  _context.c_str() );
869  return;
870  }
871 
872  if ( kvp.end() != kvp.find( DEFER_POLICY_KEY ) ) {
873  properties_.set< std::string >(
875  kvp[ DEFER_POLICY_KEY ] );
876  }
877  else {
878  properties_.set< std::string >(
881  rodsLog(
882  LOG_DEBUG,
883  "deferred_resource :: using localhost policy, none specificed" );
884  }
885 
886  }
887 
888  // =-=-=-=-=-=-
889  // override from plugin_base
891  _flg = false;
892  return ERROR( -1, "nop" );
893  }
894 
895  // =-=-=-=-=-=-
896  // override from plugin_base
898  return ERROR( -1, "nop" );
899  }
900 
901 }; // class
902 
903 // =-=-=-=-=-=-=-
904 // 4. create the plugin factory function which will return a dynamically
905 // instantiated object of the previously defined derived resource. use
906 // the add_operation member to associate a 'call name' to the interfaces
907 // defined above. for resource plugins these call names are standardized
908 // as used by the irods facing interface defined in
909 // server/drivers/src/fileDriver.c
910 extern "C"
911 irods::resource* plugin_factory( const std::string& _inst_name,
912  const std::string& _context ) {
913  // =-=-=-=-=-=-=-
914  // 4a. create unixfilesystem_resource
915  deferred_resource* resc = new deferred_resource( _inst_name, _context );
916 
917  // =-=-=-=-=-=-=-
918  // 4b. map function names to operations. this map will be used to load
919  // the symbols from the shared object in the delay_load stage of
920  // plugin loading.
921  using namespace irods;
922  using namespace std;
923  resc->add_operation(
925  function<error(plugin_context&)>(
927 
928  resc->add_operation(
930  function<error(plugin_context&)>(
931  deferred_file_open ) );
932 
933  resc->add_operation<void*,int>(
935  std::function<
936  error(irods::plugin_context&,void*,int)>(
937  deferred_file_read ) );
938 
939  resc->add_operation<void*,int>(
941  function<error(plugin_context&,void*,int)>(
943 
944  resc->add_operation(
946  function<error(plugin_context&)>(
948 
949  resc->add_operation(
951  function<error(plugin_context&)>(
953 
954  resc->add_operation<struct stat*>(
956  function<error(plugin_context&, struct stat*)>(
957  deferred_file_stat ) );
958 
959  resc->add_operation(
961  function<error(plugin_context&)>(
963 
964  resc->add_operation(
966  function<error(plugin_context&)>(
968 
969  resc->add_operation<struct rodsDirent**>(
971  function<error(plugin_context&,struct rodsDirent**)>(
973 
974  resc->add_operation<const char*>(
976  function<error(plugin_context&, const char*)>(
978 
979  resc->add_operation(
981  function<error(plugin_context&)>(
983 
984  resc->add_operation<long long, int>(
986  function<error(plugin_context&, long long, int)>(
988 
989  resc->add_operation(
991  function<error(plugin_context&)>(
993 
994  resc->add_operation(
996  function<error(plugin_context&)>(
998 
999  resc->add_operation<const char*>(
1001  function<error(plugin_context&, const char*)>(
1003 
1004  resc->add_operation<const char*>(
1006  function<error(plugin_context&, const char*)>(
1008 
1009  resc->add_operation(
1011  function<error(plugin_context&)>(
1013 
1014  resc->add_operation(
1016  function<error(plugin_context&)>(
1018 
1019  resc->add_operation(
1021  function<error(plugin_context&)>(
1023 
1024  resc->add_operation<const std::string*>(
1026  function<error(plugin_context&, const std::string*)>(
1028 
1029  resc->add_operation(
1031  function<error(plugin_context&)>(
1033 
1034  resc->add_operation<const std::string*, const std::string*, irods::hierarchy_parser*, float*>(
1036  function<error(plugin_context&,const std::string*, const std::string*, irods::hierarchy_parser*, float*)>(
1038 
1039  resc->add_operation(
1041  function<error(plugin_context&)>(
1043 
1044  // =-=-=-=-=-=-=-
1045  // set some properties necessary for backporting to iRODS legacy code
1046  resc->set_property< int >( irods::RESOURCE_CHECK_PATH_PERM, 2 );//DO_CHK_PATH_PERM );
1047  resc->set_property< int >( irods::RESOURCE_CREATE_PATH, 1 );//CREATE_PATH );
1048 
1049  // =-=-=-=-=-=-=-
1050  // 4c. return the pointer through the generic interface of an
1051  // irods::resource pointer
1052  return dynamic_cast<irods::resource*>( resc );
1053 
1054 } // plugin_factory
rodsLog
void rodsLog(int level, const char *formatStr,...)
Definition: rodsLog.cpp:86
deferred_file_stage_to_cache
irods::error deferred_file_stage_to_cache(irods::plugin_context &_ctx, const char *_cache_file_name)
Definition: libdeferred.cpp:537
NULL
#define NULL
Definition: rodsDef.h:70
irods_physical_object.hpp
deferred_file_opendir
irods::error deferred_file_opendir(irods::plugin_context &_ctx)
Definition: libdeferred.cpp:408
deferred_get_next_child_resource
irods::error deferred_get_next_child_resource(irods::resource_child_map &_cmap, std::string &_next_child)
Definition: libdeferred.cpp:147
deferred_file_read
irods::error deferred_file_read(irods::plugin_context &_ctx, void *_buf, int _len)
Definition: libdeferred.cpp:232
irods::lookup_table< boost::any >
irods::RESOURCE_NAME
const std::string RESOURCE_NAME("resource_property_name")
irods::RESOURCE_OP_STAT
const std::string RESOURCE_OP_STAT("resource_stat")
deferred_file_rmdir
irods::error deferred_file_rmdir(irods::plugin_context &_ctx)
Definition: libdeferred.cpp:387
deferred_file_getfs_freespace
irods::error deferred_file_getfs_freespace(irods::plugin_context &_ctx)
Definition: libdeferred.cpp:515
msParam.h
irods::plugin_context::valid
virtual error valid()
Definition: irods_plugin_context.hpp:77
irods.six.next
next
Definition: six.py:518
irods::resource
Definition: irods_resource_plugin.hpp:25
irods::RESOURCE_CHECK_PATH_PERM
const std::string RESOURCE_CHECK_PATH_PERM("resource_property_check_path_perm")
deferred_file_open
irods::error deferred_file_open(irods::plugin_context &_ctx)
Definition: libdeferred.cpp:211
irods::RESOURCE_OP_MODIFIED
const std::string RESOURCE_OP_MODIFIED("resource_modified")
irods_file_object.hpp
irods::RESOURCE_OP_CLOSEDIR
const std::string RESOURCE_OP_CLOSEDIR("resource_closedir")
irods_stacktrace.hpp
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
irods_collection_object.hpp
irods::resource_ptr
boost::shared_ptr< resource > resource_ptr
Definition: irods_resource_types.hpp:11
deferred_file_modified
irods::error deferred_file_modified(irods::plugin_context &_ctx)
Definition: libdeferred.cpp:624
irods::RESOURCE_OP_RESOLVE_RESC_HIER
const std::string RESOURCE_OP_RESOLVE_RESC_HIER("resource_resolve_hierarchy")
deferred_file_stat
irods::error deferred_file_stat(irods::plugin_context &_ctx, struct stat *_statbuf)
Definition: libdeferred.cpp:321
generalAdmin.h
irods::RESOURCE_OP_READDIR
const std::string RESOURCE_OP_READDIR("resource_readdir")
deferred_file_notify
irods::error deferred_file_notify(irods::plugin_context &_ctx, const std::string *_opr)
Definition: libdeferred.cpp:645
irods::hierarchy_parser
Definition: irods_hierarchy_parser.hpp:14
deferred_redirect_for_operation
irods::error deferred_redirect_for_operation(irods::plugin_context &_ctx, const std::string *_opr, const std::string *_curr_host, irods::hierarchy_parser *_out_parser, float *_out_vote)
Definition: libdeferred.cpp:667
irods::lookup_table::begin
iterator begin()
Definition: irods_lookup_table.hpp:53
irods::RESOURCE_OP_READ
const std::string RESOURCE_OP_READ("resource_read")
irods::RESOURCE_OP_FREESPACE
const std::string RESOURCE_OP_FREESPACE("resource_freespace")
irods::lookup_table< std::pair< std::string, resource_ptr > >::iterator
irods_hash_map::iterator iterator
Definition: irods_lookup_table.hpp:31
irods::RESOURCE_OP_LSEEK
const std::string RESOURCE_OP_LSEEK("resource_lseek")
PASSMSG
#define PASSMSG(message_, prev_error_)
Definition: irods_error.hpp:119
deploy_schemas_locally.parser
parser
Definition: deploy_schemas_locally.py:59
deferred_file_close
irods::error deferred_file_close(irods::plugin_context &_ctx)
Definition: libdeferred.cpp:279
irods::plugin_context
Definition: irods_plugin_context.hpp:18
LOG_ERROR
#define LOG_ERROR
Definition: rodsLog.h:43
generate_iadmin_commands_for_41_to_42_upgrade.name
name
Definition: generate_iadmin_commands_for_41_to_42_upgrade.py:23
irods::lookup_table::get
error get(const std::string &_key, ValueType &_val)
Definition: irods_lookup_table.hpp:71
irods_resource_redirect.hpp
irods::resource::resource
resource(const std::string &_inst, const std::string &_ctx)
Definition: irods_resource_plugin.hpp:29
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
deferred_file_closedir
irods::error deferred_file_closedir(irods::plugin_context &_ctx)
Definition: libdeferred.cpp:429
ASSERT_ERROR
#define ASSERT_ERROR(expr_, code_, format_,...)
Definition: irods_error.hpp:123
irods::lookup_table::size
int size() const
Definition: irods_lookup_table.hpp:38
irods_resource_plugin.hpp
deferred_file_truncate
irods::error deferred_file_truncate(irods::plugin_context &_ctx)
Definition: libdeferred.cpp:494
SUCCESS
#define SUCCESS()
Definition: irods_error.hpp:121
INVALID_OPERATION
@ INVALID_OPERATION
Definition: rodsErrorTable.h:760
irods::plugin_context::comm
virtual rsComm_t * comm()
Definition: irods_plugin_context.hpp:95
irods::RESOURCE_OP_TRUNCATE
const std::string RESOURCE_OP_TRUNCATE("resource_truncate")
irods_string_tokenize.hpp
irods::RESOURCE_OP_RENAME
const std::string RESOURCE_OP_RENAME("resource_rename")
irods::OPEN_OPERATION
const std::string OPEN_OPERATION("OPEN")
get_next_child_in_hier
irods::error get_next_child_in_hier(const std::string &_name, const std::string &_hier, irods::plugin_property_map &_props, irods::resource_ptr &_resc)
Definition: libdeferred.cpp:59
deferred_start_operation
irods::error deferred_start_operation(irods::plugin_property_map &, irods::resource_child_map &)
Definition: libdeferred.cpp:137
irods.pypyodbc.long
long
Definition: pypyodbc.py:43
irods::plugin_context::prop_map
virtual irods::plugin_property_map & prop_map()
Definition: irods_plugin_context.hpp:99
irods::lookup_table::empty
bool empty() const
Definition: irods_lookup_table.hpp:50
LOG_DEBUG
#define LOG_DEBUG
Definition: rodsLog.h:23
irods::plugin_base::properties_
plugin_property_map properties_
Definition: irods_plugin_base.hpp:332
irods::hierarchy_parser::add_child
error add_child(const std::string &_resc)
Definition: irods_hierarchy_parser.cpp:88
deferred_file_rename
irods::error deferred_file_rename(irods::plugin_context &_ctx, const char *_new_file_name)
Definition: libdeferred.cpp:472
irods::RESOURCE_OP_CREATE
const std::string RESOURCE_OP_CREATE("resource_create")
irods
Definition: apiHandler.hpp:35
irods::RESOURCE_OP_NOTIFY
const std::string RESOURCE_OP_NOTIFY("resource_notify")
deferred_file_resolve_hierarchy
irods::error deferred_file_resolve_hierarchy(irods::plugin_context &_ctx, const std::string *_opr, const std::string *_curr_host, irods::hierarchy_parser *_out_parser, float *_out_vote)
Definition: libdeferred.cpp:769
DEFER_POLICY_LOCALHOST
const std::string DEFER_POLICY_LOCALHOST("localhost_defer_policy")
irods::RESOURCE_CREATE_PATH
const std::string RESOURCE_CREATE_PATH("resource_property_create_path")
irods::RESOURCE_OP_WRITE
const std::string RESOURCE_OP_WRITE("resource_write")
deferred_resource::post_disconnect_maintenance_operation
irods::error post_disconnect_maintenance_operation(irods::pdmo_type &)
Definition: libdeferred.cpp:897
deferred_check_params
irods::error deferred_check_params(irods::plugin_context &_ctx)
Definition: libdeferred.cpp:43
ASSERT_PASS
#define ASSERT_PASS(prev_error_, format_,...)
Definition: irods_error.hpp:124
deferred_file_write
irods::error deferred_file_write(irods::plugin_context &_ctx, void *_buf, int _len)
Definition: libdeferred.cpp:256
irods::lookup_table::has_entry
bool has_entry(KeyType _k) const
Definition: irods_lookup_table.hpp:41
irods::RESOURCE_OP_CLOSE
const std::string RESOURCE_OP_CLOSE("resource_close")
deferred_file_unregistered
irods::error deferred_file_unregistered(irods::plugin_context &_ctx)
Definition: libdeferred.cpp:603
irods::log
void log(const error &)
Definition: irods_log.cpp:13
irods::RESC_CHILD_MAP_PROP
const std::string RESC_CHILD_MAP_PROP("resource_child_map_property")
deferred_file_lseek
irods::error deferred_file_lseek(irods::plugin_context &_ctx, long long _offset, int _whence)
Definition: libdeferred.cpp:343
rodsDirent
Definition: rodsType.h:70
irods::RESOURCE_OP_UNLINK
const std::string RESOURCE_OP_UNLINK("resource_unlink")
LOG_NOTICE
#define LOG_NOTICE
Definition: rodsLog.h:33
irods::RESOURCE_OP_RMDIR
const std::string RESOURCE_OP_RMDIR("resource_rmdir")
irods::lookup_table::end
iterator end()
Definition: irods_lookup_table.hpp:56
ERROR
#define ERROR(code_, message_)
Definition: irods_error.hpp:117
irods::RESOURCE_OP_UNREGISTERED
const std::string RESOURCE_OP_UNREGISTERED("resource_unregistered")
irods::error
Definition: irods_error.hpp:23
miscServerFunct.hpp
irods::RESOURCE_OP_REGISTERED
const std::string RESOURCE_OP_REGISTERED("resource_registered")
deferred_file_mkdir
irods::error deferred_file_mkdir(irods::plugin_context &_ctx)
Definition: libdeferred.cpp:366
deferred_resource
Definition: libdeferred.cpp:852
irods_hierarchy_parser.hpp
irods::parse_kvp_string
error parse_kvp_string(const std::string &_str, kvp_map_t &_kvp, const std::string &_association=KVP_DEF_ASSOCIATION, const std::string &_delimeter=KVP_DEF_DELIMITER)
Definition: irods_kvp_string_parser.cpp:69
irods::RESOURCE_OP_MKDIR
const std::string RESOURCE_OP_MKDIR("resource_mkdir")
deferred_get_resc_for_call
irods::error deferred_get_resc_for_call(irods::plugin_context &_ctx, irods::resource_ptr &_resc)
Definition: libdeferred.cpp:103
irods::RESOURCE_OP_OPENDIR
const std::string RESOURCE_OP_OPENDIR("resource_opendir")
irods::RESOURCE_OP_STAGETOCACHE
const std::string RESOURCE_OP_STAGETOCACHE("resource_stagetocache")
deferred_file_unlink
irods::error deferred_file_unlink(irods::plugin_context &_ctx)
Definition: libdeferred.cpp:300
error
int error
Definition: filesystem.cpp:101
irods::WRITE_OPERATION
const std::string WRITE_OPERATION("WRITE")
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::plugin_context::fco
virtual first_class_object_ptr fco()
Definition: irods_plugin_context.hpp:102
irods::RESOURCE_OP_SYNCTOARCH
const std::string RESOURCE_OP_SYNCTOARCH("resource_synctoarch")
irods_kvp_string_parser.hpp
deferred_file_registered
irods::error deferred_file_registered(irods::plugin_context &_ctx)
Definition: libdeferred.cpp:582
CHILD_NOT_FOUND
@ CHILD_NOT_FOUND
Definition: rodsErrorTable.h:753
deferred_file_create
irods::error deferred_file_create(irods::plugin_context &_ctx)
Definition: libdeferred.cpp:190
LOG_DEBUG10
#define LOG_DEBUG10
Definition: rodsLog.h:19
deferred_resource::need_post_disconnect_maintenance_operation
irods::error need_post_disconnect_maintenance_operation(bool &_flg)
Definition: libdeferred.cpp:890
irods_random.hpp
DEFER_POLICY_KEY
const std::string DEFER_POLICY_KEY("defer_policy")
irods::RESOURCE_OP_REBALANCE
const std::string RESOURCE_OP_REBALANCE("resource_rebalance")
plugin_factory
irods::resource * plugin_factory(const std::string &_inst_name, const std::string &_context)
Definition: libdeferred.cpp:911
irods::lookup_table::set
error set(const std::string &_key, const ValueType &_val)
Definition: irods_lookup_table.hpp:83
deferred_file_readdir
irods::error deferred_file_readdir(irods::plugin_context &_ctx, struct rodsDirent **_dirent_ptr)
Definition: libdeferred.cpp:450
deferred_file_rebalance
irods::error deferred_file_rebalance(irods::plugin_context &_ctx)
Definition: libdeferred.cpp:821
irods::kvp_map_t
std::map< std::string, std::string > kvp_map_t
Definition: irods_kvp_string_parser.hpp:30
irods::error::ok
bool ok()
Definition: irods_error.cpp:258
irods::RESOURCE_OP_OPEN
const std::string RESOURCE_OP_OPEN("resource_open")
irods::CREATE_OPERATION
const std::string CREATE_OPERATION("CREATE")
deferred_resource::deferred_resource
deferred_resource(const std::string &_inst_name, const std::string &_context)
Definition: libdeferred.cpp:854
irods::UNLINK_OPERATION
const std::string UNLINK_OPERATION("UNLINK")
deferred_file_sync_to_arch
irods::error deferred_file_sync_to_arch(irods::plugin_context &_ctx, const char *_cache_file_name)
Definition: libdeferred.cpp:560