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)  

librandom.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"
16 #include "irods_random.hpp"
17 
18 // =-=-=-=-=-=-=-
19 // stl includes
20 #include <iostream>
21 #include <sstream>
22 #include <vector>
23 #include <string>
24 
25 // =-=-=-=-=-=-=-
26 // boost includes
27 #include <boost/lexical_cast.hpp>
28 #include <boost/function.hpp>
29 #include <boost/any.hpp>
30 
31 
34 template< typename DEST_TYPE >
36  irods::plugin_context& _ctx ) {
37  irods::error result = SUCCESS();
38 
39  // =-=-=-=-=-=-=-
40  // ask the context if it is valid
41  irods::error ret = _ctx.valid< DEST_TYPE >();
42  result = ASSERT_PASS( ret, "Resource context invalid." );
43 
44  return result;
45 
46 } // random_check_params
47 
52  const std::string& _name,
53  const std::string& _hier,
55  irods::resource_ptr& _resc ) {
56  irods::error result = SUCCESS();
57 
58  irods::resource_child_map* cmap_ref;
59  _props.get< irods::resource_child_map* >(
61  cmap_ref );
62 
63  // =-=-=-=-=-=-=-
64  // create a parser and parse the string
66  irods::error err = parse.set_string( _hier );
67  if ( ( result = ASSERT_PASS( err, "Failed in set_string" ) ).ok() ) {
68 
69  // =-=-=-=-=-=-=-
70  // get the next resource in the series
71  std::string next;
72  err = parse.next( _name, next );
73  if ( ( result = ASSERT_PASS( err, "Failed in next." ) ).ok() ) {
74 
75  // =-=-=-=-=-=-=-
76  // get the next resource from the child map
77  if ( ( result = ASSERT_ERROR( cmap_ref->has_entry( next ), CHILD_NOT_FOUND, "Child map missing entry: hier [%s] name [%s] next [%s]",
78  _hier.c_str(), _name.c_str(), next.c_str() ) ).ok() ) {
79  // =-=-=-=-=-=-=-
80  // assign resource
81  _resc = (*cmap_ref)[ next ].second;
82  }
83  }
84  }
85 
86  return result;
87 
88 } // get_next_child_in_hier
89 
94  const std::string& _name,
95  irods::file_object_ptr& _file_obj,
97  irods::resource_ptr& _resc ) {
98  // =-=-=-=-=-=-=-
99  // set up iteration over physical objects
100  std::vector< irods::physical_object > objs = _file_obj->replicas();
101  std::vector< irods::physical_object >::iterator itr = objs.begin();
102 
103  // =-=-=-=-=-=-=-
104  // check to see if the replica is in this resource, if one is requested
105  for ( ; itr != objs.end(); ++itr ) {
106  // =-=-=-=-=-=-=-
107  // run the hier string through the parser
109  parser.set_string( itr->resc_hier() );
110 
111  // =-=-=-=-=-=-=-
112  // find this resource in the hier
113  if ( !parser.resc_in_hier( _name ) ) {
114  continue;
115  }
116 
117  // =-=-=-=-=-=-=-
118  // if we have a hit, get the resc ptr to the next resc
119  return get_next_child_in_hier(
120  _name,
121  itr->resc_hier(),
122  _props,
123  _resc );
124 
125  } // for itr
126 
127  std::string msg( "no replica found in resc [" );
128  msg += _name + "]";
129  return ERROR(
131  msg );
132 
133 } // get_next_child_for_open_or_write
134 
135 // =-=-=-=-=-=-=-
138 template< typename DEST_TYPE >
140  irods::plugin_context& _ctx,
141  irods::resource_ptr& _resc ) {
142  irods::error result = SUCCESS();
143 
144  // =-=-=-=-=-=-=-
145  // check incoming parameters
146  irods::error err = random_check_params< DEST_TYPE >( _ctx );
147  if ( ( result = ASSERT_PASS( err, "Bad resource context." ) ).ok() ) {
148 
149  // =-=-=-=-=-=-=-
150  // get the object's name
151  std::string name;
152  err = _ctx.prop_map().get< std::string >( irods::RESOURCE_NAME, name );
153  if ( ( result = ASSERT_PASS( err, "Failed to get property." ) ).ok() ) {
154 
155  // =-=-=-=-=-=-=-
156  // get the object's hier string
157  boost::shared_ptr< DEST_TYPE > dst_obj = boost::dynamic_pointer_cast< DEST_TYPE >( _ctx.fco() );
158  std::string hier = dst_obj->resc_hier( );
159 
160  // =-=-=-=-=-=-=-
161  // get the next child pointer given our name and the hier string
162  err = get_next_child_in_hier( name, hier, _ctx.prop_map(), _resc );
163  result = ASSERT_PASS( err, "Get next child failed." );
164  }
165  }
166 
167  return result;
168 
169 } // random_get_resc_for_call
170 
176  std::string& _next_child ) {
177  irods::error result = SUCCESS();
178 
179  // =-=-=-=-=-=-=-
180  // if the child map is empty then just return
181  if ( _cmap.size() > 0 ) {
182 
183  // =-=-=-=-=-=-=-
184  // get the size of the map and randomly pick an index into it
185  size_t target_index = irods::getRandom<unsigned int>() % _cmap.size();
186 
187  // =-=-=-=-=-=-=-
188  // child map is keyed by resource name so we need to count out the index
189  // and then snag the child name from the key of the hash map
190  size_t counter = 0;
191  std::string next_child;
193  for ( ; itr != _cmap.end(); ++itr ) {
194  if ( counter == target_index ) {
195  next_child = itr->first;
196  break;
197 
198  }
199  else {
200  ++counter;
201 
202  }
203 
204  } // for itr
205 
206  // =-=-=-=-=-=-=-
207  // assign the next_child to the out variable
208  _next_child = next_child;
209  }
210 
211  return result;
212 
213 } // random_get_next_child_resource
214 
218  irods::plugin_context& _ctx ) {
219  irods::error result = SUCCESS();
220 
221  // =-=-=-=-=-=-=-
222  // get the child resc to call
223  irods::resource_ptr resc;
224  irods::error err = random_get_resc_for_call< irods::file_object >( _ctx, resc );
225  if ( ( result = ASSERT_PASS( err, "Invalid resource context." ) ).ok() ) {
226 
227  // =-=-=-=-=-=-=-
228  // call create on the child
229  err = resc->call( _ctx.comm(), irods::RESOURCE_OP_CREATE, _ctx.fco() );
230  result = ASSERT_PASS( err, "Failed calling create on child resource." );
231  }
232 
233  return result;
234 } // random_file_create
235 
236 // =-=-=-=-=-=-=-
237 // interface for POSIX Open
239  irods::plugin_context& _ctx ) {
240  irods::error result = SUCCESS();
241 
242  // =-=-=-=-=-=-=-
243  // get the child resc to call
244  irods::resource_ptr resc;
245  irods::error err = random_get_resc_for_call< irods::file_object >( _ctx, resc );
246  if ( ( result = ASSERT_PASS( err, "Failed in file open." ) ).ok() ) {
247 
248  // =-=-=-=-=-=-=-
249  // call open operation on the child
250  err = resc->call( _ctx.comm(), irods::RESOURCE_OP_OPEN, _ctx.fco() );
251  result = ASSERT_PASS( err, "Failed calling open on the child." );
252  }
253 
254  return result;
255 } // random_file_open
256 
260  irods::plugin_context& _ctx,
261  void* _buf,
262  int _len ) {
263  irods::error result = SUCCESS();
264 
265  // =-=-=-=-=-=-=-
266  // get the child resc to call
267  irods::resource_ptr resc;
268  irods::error err = random_get_resc_for_call< irods::file_object >( _ctx, resc );
269  if ( ( result = ASSERT_PASS( err, "Failed finding resource." ) ).ok() ) {
270 
271  // =-=-=-=-=-=-=-
272  // call read on the child
273  err = resc->call< void*, int >( _ctx.comm(), irods::RESOURCE_OP_READ, _ctx.fco(), _buf, _len );
274  result = ASSERT_PASS( err, "Failed calling operation on child resource." );
275  }
276 
277  return result;
278 
279 } // random_file_read
280 
284  irods::plugin_context& _ctx,
285  void* _buf,
286  int _len ) {
287  irods::error result = SUCCESS();
288 
289  // =-=-=-=-=-=-=-
290  // get the child resc to call
291  irods::resource_ptr resc;
292  irods::error err = random_get_resc_for_call< irods::file_object >( _ctx, resc );
293  if ( ( result = ASSERT_PASS( err, "Failed choosing child resource." ) ).ok() ) {
294 
295  // =-=-=-=-=-=-=-
296  // call write on the child
297  err = resc->call< void*, int >( _ctx.comm(), irods::RESOURCE_OP_WRITE, _ctx.fco(), _buf, _len );
298  result = ASSERT_PASS( err, "Failed calling operation on child resource." );
299  }
300 
301  return result;
302 } // random_file_write
303 
307  irods::plugin_context& _ctx ) {
308  irods::error result = SUCCESS();
309 
310  // =-=-=-=-=-=-=-
311  // get the child resc to call
312  irods::resource_ptr resc;
313  irods::error err = random_get_resc_for_call< irods::file_object >( _ctx, resc );
314  if ( ( result = ASSERT_PASS( err, "Failed to select random resource." ) ).ok() ) {
315 
316  // =-=-=-=-=-=-=-
317  // call close on the child
318  err = resc->call( _ctx.comm(), irods::RESOURCE_OP_CLOSE, _ctx.fco() );
319  result = ASSERT_PASS( err, "Failed calling operation in child." );
320  }
321 
322  return result;
323 } // random_file_close
324 
328  irods::plugin_context& _ctx ) {
329  irods::error result = SUCCESS();
330 
331  // =-=-=-=-=-=-=-
332  // get the child resc to call
333  irods::resource_ptr resc;
334  irods::error err = random_get_resc_for_call< irods::data_object >( _ctx, resc );
335  if ( ( result = ASSERT_PASS( err, "Failed to select random resource." ) ).ok() ) {
336 
337  // =-=-=-=-=-=-=-
338  // call unlink on the child
339  err = resc->call( _ctx.comm(), irods::RESOURCE_OP_UNLINK, _ctx.fco() );
340  result = ASSERT_PASS( err, "Failed during call to child operation." );
341  }
342 
343  return result;
344 } // random_file_unlink
345 
349  irods::plugin_context& _ctx,
350  struct stat* _statbuf ) {
351  irods::error result = SUCCESS();
352 
353  // =-=-=-=-=-=-=-
354  // get the child resc to call
355  irods::resource_ptr resc;
356  irods::error err = random_get_resc_for_call< irods::data_object >( _ctx, resc );
357  if ( ( result = ASSERT_PASS( err, "Failed selecting random child resource." ) ).ok() ) {
358 
359  // =-=-=-=-=-=-=-
360  // call stat on the child
361  err = resc->call< struct stat* >( _ctx.comm(), irods::RESOURCE_OP_STAT, _ctx.fco(), _statbuf );
362  result = ASSERT_PASS( err, "Failed in call to child operation." );
363  }
364 
365  return result;
366 } // random_file_stat
367 
371  irods::plugin_context& _ctx,
372  long long _offset,
373  int _whence ) {
374  irods::error result = SUCCESS();
375 
376  // =-=-=-=-=-=-=-
377  // get the child resc to call
378  irods::resource_ptr resc;
379  irods::error err = random_get_resc_for_call< irods::file_object >( _ctx, resc );
380  if ( ( result = ASSERT_PASS( err, "Failed to select random child." ) ).ok() ) {
381 
382  // =-=-=-=-=-=-=-
383  // call lseek on the child
384  err = resc->call< long long, int >( _ctx.comm(), irods::RESOURCE_OP_LSEEK, _ctx.fco(), _offset, _whence );
385  result = ASSERT_PASS( err, "Failed calling child operation." );
386  }
387 
388  return result;
389 } // random_file_lseek
390 
394  irods::plugin_context& _ctx ) {
395  irods::error result = SUCCESS();
396 
397  // =-=-=-=-=-=-=-
398  // get the child resc to call
399  irods::resource_ptr resc;
400  irods::error err = random_get_resc_for_call< irods::collection_object >( _ctx, resc );
401  if ( ( result = ASSERT_PASS( err, "Failed to select random child resource." ) ).ok() ) {
402 
403  // =-=-=-=-=-=-=-
404  // call mkdir on the child
405  err = resc->call( _ctx.comm(), irods::RESOURCE_OP_MKDIR, _ctx.fco() );
406  result = ASSERT_PASS( err, "Failed calling child operation." );
407  }
408 
409  return result;
410 } // random_file_mkdir
411 
415  irods::plugin_context& _ctx ) {
416  irods::error result = SUCCESS();
417 
418  // =-=-=-=-=-=-=-
419  // get the child resc to call
420  irods::resource_ptr resc;
421  irods::error err = random_get_resc_for_call< irods::collection_object >( _ctx, resc );
422  if ( ( result = ASSERT_PASS( err, "Failed to select random resource." ) ).ok() ) {
423 
424  // =-=-=-=-=-=-=-
425  // call rmdir on the child
426  err = resc->call( _ctx.comm(), irods::RESOURCE_OP_RMDIR, _ctx.fco() );
427  result = ASSERT_PASS( err, "Failed calling child operation." );
428  }
429 
430  return result;
431 } // random_file_rmdir
432 
436  irods::plugin_context& _ctx ) {
437  irods::error result = SUCCESS();
438 
439  // =-=-=-=-=-=-=-
440  // get the child resc to call
441  irods::resource_ptr resc;
442  irods::error err = random_get_resc_for_call< irods::collection_object >( _ctx, resc );
443  if ( ( result = ASSERT_PASS( err, "Failed to select random resource." ) ).ok() ) {
444 
445  // =-=-=-=-=-=-=-
446  // call opendir on the child
447  err = resc->call( _ctx.comm(), irods::RESOURCE_OP_OPENDIR, _ctx.fco() );
448  result = ASSERT_PASS( err, "Failed calling child operation." );
449  }
450 
451  return result;
452 } // random_file_opendir
453 
454 // =-=-=-=-=-=-=-
457  irods::plugin_context& _ctx ) {
458  irods::error result = SUCCESS();
459 
460  // =-=-=-=-=-=-=-
461  // get the child resc to call
462  irods::resource_ptr resc;
463  irods::error err = random_get_resc_for_call< irods::collection_object >( _ctx, resc );
464  if ( ( result = ASSERT_PASS( err, "Failed to select random resource." ) ).ok() ) {
465 
466  // =-=-=-=-=-=-=-
467  // call closedir on the child
468  err = resc->call( _ctx.comm(), irods::RESOURCE_OP_CLOSEDIR, _ctx.fco() );
469  result = ASSERT_PASS( err, "Failed calling child operation." );
470  }
471 
472  return result;
473 } // random_file_closedir
474 
478  irods::plugin_context& _ctx,
479  struct rodsDirent** _dirent_ptr ) {
480  irods::error result = SUCCESS();
481 
482  // =-=-=-=-=-=-=-
483  // get the child resc to call
484  irods::resource_ptr resc;
485  irods::error err = random_get_resc_for_call< irods::collection_object >( _ctx, resc );
486  if ( ( result = ASSERT_PASS( err, "Failed to select random resource." ) ).ok() ) {
487 
488  // =-=-=-=-=-=-=-
489  // call readdir on the child
490  err = resc->call< struct rodsDirent** >( _ctx.comm(), irods::RESOURCE_OP_READDIR, _ctx.fco(), _dirent_ptr );
491  result = ASSERT_PASS( err, "Failed calling child operation." );
492  }
493 
494  return result;
495 } // random_file_readdir
496 
500  irods::plugin_context& _ctx,
501  const char* _new_file_name ) {
502  irods::error result = SUCCESS();
503 
504  // =-=-=-=-=-=-=-
505  // get the child resc to call
506  irods::resource_ptr resc;
507  irods::error err = random_get_resc_for_call< irods::file_object >( _ctx, resc );
508  if ( ( result = ASSERT_PASS( err, "Failed to select random resource." ) ).ok() ) {
509 
510  // =-=-=-=-=-=-=-
511  // call rename on the child
512  err = resc->call< const char* >( _ctx.comm(), irods::RESOURCE_OP_RENAME, _ctx.fco(), _new_file_name );
513  result = ASSERT_PASS( err, "Failed calling child operation." );
514  }
515 
516  return result;
517 } // random_file_rename
518 
522  irods::plugin_context& _ctx ) {
523  irods::error result = SUCCESS();
524 
525  // =-=-=-=-=-=-=-
526  // get the child resc to call
527  irods::resource_ptr resc;
528  irods::error err = random_get_resc_for_call< irods::file_object >( _ctx, resc );
529  if ( ( result = ASSERT_PASS( err, "Failed selecting random resource." ) ).ok() ) {
530 
531  // =-=-=-=-=-=-=-
532  // call freespace on the child
533  err = resc->call( _ctx.comm(), irods::RESOURCE_OP_TRUNCATE, _ctx.fco() );
534  result = ASSERT_PASS( err, "Failed calling child operation." );
535  }
536 
537  return result;
538 } // random_file_truncate
539 
543  irods::plugin_context& _ctx ) {
544  irods::error result = SUCCESS();
545 
546  // =-=-=-=-=-=-=-
547  // get the child resc to call
548  irods::resource_ptr resc;
549  irods::error err = random_get_resc_for_call< irods::file_object >( _ctx, resc );
550  if ( ( result = ASSERT_PASS( err, "Failed selecting random resource." ) ).ok() ) {
551 
552  // =-=-=-=-=-=-=-
553  // call freespace on the child
554  err = resc->call( _ctx.comm(), irods::RESOURCE_OP_FREESPACE, _ctx.fco() );
555  result = ASSERT_PASS( err, "Failed calling child operation." );
556  }
557 
558  return result;
559 } // random_file_getfs_freespace
560 
566  irods::plugin_context& _ctx,
567  const char* _cache_file_name ) {
568  irods::error result = SUCCESS();
569 
570  // =-=-=-=-=-=-=-
571  // get the child resc to call
572  irods::resource_ptr resc;
573  irods::error err = random_get_resc_for_call< irods::file_object >( _ctx, resc );
574  if ( ( result = ASSERT_PASS( err, "Failed to select random resource." ) ).ok() ) {
575 
576  // =-=-=-=-=-=-=-
577  // call stage on the child
578  err = resc->call< const char* >( _ctx.comm(), irods::RESOURCE_OP_STAGETOCACHE, _ctx.fco(), _cache_file_name );
579  result = ASSERT_PASS( err, "Failed calling child operation." );
580  }
581 
582  return result;
583 } // random_file_stage_to_cache
584 
590  irods::plugin_context& _ctx,
591  const char* _cache_file_name ) {
592  irods::error result = SUCCESS();
593 
594  // =-=-=-=-=-=-=-
595  // get the child resc to call
596  irods::resource_ptr resc;
597  irods::error err = random_get_resc_for_call< irods::file_object >( _ctx, resc );
598  if ( ( result = ASSERT_PASS( err, "Failed selecting random resource." ) ).ok() ) {
599 
600  // =-=-=-=-=-=-=-
601  // call synctoarch on the child
602  err = resc->call< const char* >( _ctx.comm(), irods::RESOURCE_OP_SYNCTOARCH, _ctx.fco(), _cache_file_name );
603  result = ASSERT_PASS( err, "Failed calling child operation." );
604  }
605 
606  return result;
607 } // random_file_sync_to_arch
608 
612  irods::plugin_context& _ctx ) {
613  irods::error result = SUCCESS();
614 
615  // =-=-=-=-=-=-=-
616  // get the child resc to call
617  irods::resource_ptr resc;
618  irods::error err = random_get_resc_for_call< irods::file_object >( _ctx, resc );
619  if ( ( result = ASSERT_PASS( err, "Failed selecting random resource." ) ).ok() ) {
620 
621  // =-=-=-=-=-=-=-
622  // call rename on the child
623  err = resc->call( _ctx.comm(), irods::RESOURCE_OP_REGISTERED, _ctx.fco() );
624  result = ASSERT_PASS( err, "Failed calling child operation." );
625  }
626 
627  return result;
628 } // random_file_registered
629 
633  irods::plugin_context& _ctx ) {
634  irods::error result = SUCCESS();
635 
636  // =-=-=-=-=-=-=-
637  // get the child resc to call
638  irods::resource_ptr resc;
639  irods::error err = random_get_resc_for_call< irods::file_object >( _ctx, resc );
640  if ( ( result = ASSERT_PASS( err, "Failed selecting random resource." ) ).ok() ) {
641 
642  // =-=-=-=-=-=-=-
643  // call rename on the child
644  err = resc->call( _ctx.comm(), irods::RESOURCE_OP_UNREGISTERED, _ctx.fco() );
645  result = ASSERT_PASS( err, "Failed calling child operation." );
646  }
647 
648  return result;
649 } // random_file_unregistered
650 
654  irods::plugin_context& _ctx ) {
655  irods::error result = SUCCESS();
656 
657  // =-=-=-=-=-=-=-
658  // get the child resc to call
659  irods::resource_ptr resc;
660  irods::error err = random_get_resc_for_call< irods::file_object >( _ctx, resc );
661  if ( ( result = ASSERT_PASS( err, "Failed selecting random resource." ) ).ok() ) {
662 
663  // =-=-=-=-=-=-=-
664  // call rename on the child
665  err = resc->call( _ctx.comm(), irods::RESOURCE_OP_MODIFIED, _ctx.fco() );
666  result = ASSERT_PASS( err, "Failed calling child operation." );
667  }
668 
669  return result;
670 } // random_file_modified
671 
675  irods::plugin_context& _ctx,
676  const std::string* _opr ) {
677  irods::error result = SUCCESS();
678 
679  // =-=-=-=-=-=-=-
680  // get the child resc to call
681  irods::resource_ptr resc;
682  irods::error err = random_get_resc_for_call< irods::file_object >( _ctx, resc );
683  if ( ( result = ASSERT_PASS( err, "Failed selecting random resource." ) ).ok() ) {
684 
685  // =-=-=-=-=-=-=-
686  // call rename on the child
687  err = resc->call( _ctx.comm(), irods::RESOURCE_OP_NOTIFY, _ctx.fco(), _opr );
688  result = ASSERT_PASS( err, "Failed calling child operation." );
689  }
690 
691  return result;
692 } // random_file_notify
693 
697  irods::plugin_context& _ctx,
698  const std::string* _opr,
699  const std::string* _curr_host,
700  irods::hierarchy_parser* _out_parser,
701  float* _out_vote ) {
702  irods::error result = SUCCESS();
703  irods::error ret;
704 
705  irods::resource_child_map* cmap_ref;
708  cmap_ref );
709 
710  // =-=-=-=-=-=-=-
711  // flag
712  bool child_found = false;
713 
714  // =-=-=-=-=-=-=-
715  // the pool of resources (children) to try
716  std::vector<irods::resource_ptr> candidate_resources;
717 
718  // =-=-=-=-=-=-=-
719  // copy children from _cmap
720  irods::resource_child_map::iterator itr = cmap_ref->begin();
721  for ( ; itr != cmap_ref->end(); ++itr ) {
722  candidate_resources.push_back( itr->second.second );
723  }
724 
725  // =-=-=-=-=-=-=-
726  // while we have not found a child and still have candidates
727  while ( result.ok() && ( !child_found && !candidate_resources.empty() ) ) {
728 
729  // =-=-=-=-=-=-=-
730  // generate random index
731  size_t rand_index = irods::getRandom<unsigned int>() % candidate_resources.size();
732 
733  // =-=-=-=-=-=-=-
734  // pick resource in pool at random index
735  irods::resource_ptr resc = candidate_resources[rand_index];
736 
737  irods::hierarchy_parser hierarchy_copy(*_out_parser);
738 
739  // =-=-=-=-=-=-=-
740  // forward the 'create' redirect to the appropriate child
741  ret = resc->call< const std::string*, const std::string*, irods::hierarchy_parser*, float* >( _ctx.comm(),
743  _ctx.fco(), _opr, _curr_host, &hierarchy_copy,
744  _out_vote );
745  // Found a valid child
746  if ( ret.ok() && *_out_vote != 0 ) {
747  child_found = true;
748  *_out_parser = hierarchy_copy;
749  }
750  else {
751  // =-=-=-=-=-=-=-
752  // remove child from pool of candidates
753  candidate_resources.erase( candidate_resources.begin() + rand_index );
754  }
755  } // while
756 
757  // =-=-=-=-=-=-=-
758  // return appropriately
759  if ( result.ok() ) {
760  result = ASSERT_ERROR( child_found, NO_NEXT_RESC_FOUND, "No valid child found." );
761  }
762 
763  return result;
764 } // get_next_valid_child_resource
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  irods::error result = SUCCESS();
776 
777  // =-=-=-=-=-=-=-
778  // check incoming parameters
779  irods::error err = random_check_params< irods::file_object >( _ctx );
780  if ( ( result = ASSERT_PASS( err, "Invalid resource context." ) ).ok() ) {
781  if ( ( result = ASSERT_ERROR( _opr && _curr_host && _out_parser && _out_vote, SYS_INVALID_INPUT_PARAM,
782  "Invalid parameters." ) ).ok() ) {
783 
784  // =-=-=-=-=-=-=-
785  // get the object's hier string
786  irods::file_object_ptr file_obj = boost::dynamic_pointer_cast< irods::file_object >( _ctx.fco() );
787  std::string hier = file_obj->resc_hier( );
788 
789  // =-=-=-=-=-=-=-
790  // get the object's hier string
791  std::string name;
792  err = _ctx.prop_map().get< std::string >( irods::RESOURCE_NAME, name );
793  if ( ( result = ASSERT_PASS( err, "Failed to get property: \"%s\".", irods::RESOURCE_NAME.c_str() ) ).ok() ) {
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 
805  // =-=-=-=-=-=-=-
806  // get the next child pointer in the hierarchy, given our name and the hier string
807  irods::resource_ptr resc;
808  err = get_next_child_for_open_or_write( name, file_obj, _ctx.prop_map(), resc );
809  if ( err.ok() ) {
810  // =-=-=-=-=-=-=-
811  // forward the redirect call to the child for assertion of the whole operation,
812  // there may be more than a leaf beneath us
813  err = resc->call< const std::string*, const std::string*, irods::hierarchy_parser*, float* >( _ctx.comm(),
815  _ctx.fco(), _opr, _curr_host, _out_parser,
816  _out_vote );
817  result = ASSERT_PASS( err, "Failed calling child operation." );
818  }
819  else if ( err.code() == REPLICA_NOT_IN_RESC ) {
820  *_out_vote = 0;
821  }
822  else {
823  result = err;
824  }
825  }
826  else if ( irods::CREATE_OPERATION == ( *_opr ) ) {
827 
828  // =-=-=-=-=-=-=-
829  // get the next_child resource for create
830  irods::resource_ptr resc;
831  err = get_next_valid_child_resource( _ctx, _opr, _curr_host, _out_parser, _out_vote );
832  result = ASSERT_PASS( err, "Failed getting next valid child." );
833  }
834  else {
835 
836  // =-=-=-=-=-=-=-
837  // must have been passed a bad operation
838  result = ASSERT_ERROR( false, INVALID_OPERATION, "Operation not supported: \"%s\".",
839  _opr->c_str() );
840  }
841  }
842  }
843  }
844 
845  return result;
846 } // random_file_resolve_hierarchy
847 
848 // =-=-=-=-=-=-=-
849 // random_file_rebalance - code which would rebalance the subtree
851  irods::plugin_context& _ctx ) {
852  irods::resource_child_map* cmap_ref;
855  cmap_ref );
856 
857  // =-=-=-=-=-=-=-
858  // forward request for rebalance to children
859  irods::error result = SUCCESS();
860  irods::resource_child_map::iterator itr = cmap_ref->begin();
861  for ( ; itr != cmap_ref->end(); ++itr ) {
862  irods::error ret = itr->second.second->call( _ctx.comm(), irods::RESOURCE_OP_REBALANCE, _ctx.fco() );
863  if ( !( result = ASSERT_PASS( ret, "Failed calling child operation." ) ).ok() ) {
864  irods::log( PASS( result ) );
865  }
866  }
867 
868  if ( !result.ok() ) {
869  return PASS( result );
870  }
871 
872  return SUCCESS();
873 
874 } // random_file_rebalance
875 
876 // =-=-=-=-=-=-=-
877 // 3. create derived class to handle unix file system resources
878 // necessary to do custom parsing of the context string to place
879 // any useful values into the property map for reference in later
880 // operations. semicolon is the preferred delimiter
882  public:
884  const std::string& _inst_name,
885  const std::string& _context ) :
886  irods::resource( _inst_name, _context ) {
887  }
888 
889  // =-=-=-=-=-=-
890  // override from plugin_base
892  _flg = false;
893  return ERROR( -1, "nop" );
894  }
895 
896  // =-=-=-=-=-=-
897  // override from plugin_base
899  return ERROR( -1, "nop" );
900  }
901 
902 }; // class
903 
904 // =-=-=-=-=-=-=-
905 // 4. create the plugin factory function which will return a dynamically
906 // instantiated object of the previously defined derived resource. use
907 // the add_operation member to associate a 'call name' to the interfaces
908 // defined above. for resource plugins these call names are standardized
909 // as used by the irods facing interface defined in
910 // server/drivers/src/fileDriver.c
911 extern "C"
912 irods::resource* plugin_factory( const std::string& _inst_name,
913  const std::string& _context ) {
914  // =-=-=-=-=-=-=-
915  // 4a. create unixfilesystem_resource
916  random_resource* resc = new random_resource( _inst_name, _context );
917 
918  // =-=-=-=-=-=-=-
919  // 4b. map function names to operations. this map will be used to load
920  // the symbols from the shared object in the delay_load stage of
921  // plugin loading.
922 
923  using namespace irods;
924  using namespace std;
925  resc->add_operation(
927  function<error(plugin_context&)>(
928  random_file_create ) );
929 
930  resc->add_operation(
932  function<error(plugin_context&)>(
933  random_file_open ) );
934 
935  resc->add_operation<void*,int>(
937  std::function<
938  error(irods::plugin_context&,void*,int)>(
939  random_file_read ) );
940 
941  resc->add_operation<void*,int>(
943  function<error(plugin_context&,void*,int)>(
944  random_file_write ) );
945 
946  resc->add_operation(
948  function<error(plugin_context&)>(
949  random_file_close ) );
950 
951  resc->add_operation(
953  function<error(plugin_context&)>(
954  random_file_unlink ) );
955 
956  resc->add_operation<struct stat*>(
958  function<error(plugin_context&, struct stat*)>(
959  random_file_stat ) );
960 
961  resc->add_operation(
963  function<error(plugin_context&)>(
964  random_file_mkdir ) );
965 
966  resc->add_operation(
968  function<error(plugin_context&)>(
970 
971  resc->add_operation<struct rodsDirent**>(
973  function<error(plugin_context&,struct rodsDirent**)>(
975 
976  resc->add_operation<const char*>(
978  function<error(plugin_context&, const char*)>(
979  random_file_rename ) );
980 
981  resc->add_operation(
983  function<error(plugin_context&)>(
985 
986  resc->add_operation<long long, int>(
988  function<error(plugin_context&, long long, int)>(
989  random_file_lseek ) );
990 
991  resc->add_operation(
993  function<error(plugin_context&)>(
994  random_file_rmdir ) );
995 
996  resc->add_operation(
998  function<error(plugin_context&)>(
1000 
1001  resc->add_operation<const char*>(
1003  function<error(plugin_context&, const char*)>(
1005 
1006  resc->add_operation<const char*>(
1008  function<error(plugin_context&, const char*)>(
1010 
1011  resc->add_operation(
1013  function<error(plugin_context&)>(
1015 
1016  resc->add_operation(
1018  function<error(plugin_context&)>(
1020 
1021  resc->add_operation(
1023  function<error(plugin_context&)>(
1025 
1026  resc->add_operation<const std::string*>(
1028  function<error(plugin_context&, const std::string*)>(
1029  random_file_notify ) );
1030 
1031  resc->add_operation(
1033  function<error(plugin_context&)>(
1035 
1036  resc->add_operation<const std::string*, const std::string*, irods::hierarchy_parser*, float*>(
1038  function<error(plugin_context&,const std::string*, const std::string*, irods::hierarchy_parser*, float*)>(
1040 
1041  resc->add_operation(
1043  function<error(plugin_context&)>(
1045 
1046  // =-=-=-=-=-=-=-
1047  // set some properties necessary for backporting to iRODS legacy code
1048  resc->set_property< int >( irods::RESOURCE_CHECK_PATH_PERM, 2 );//DO_CHK_PATH_PERM );
1049  resc->set_property< int >( irods::RESOURCE_CREATE_PATH, 1 );//CREATE_PATH );
1050 
1051  // =-=-=-=-=-=-=-
1052  // 4c. return the pointer through the generic interface of an
1053  // irods::resource pointer
1054  return dynamic_cast<irods::resource*>( resc );
1055 
1056 } // plugin_factory
irods_physical_object.hpp
random_file_write
irods::error random_file_write(irods::plugin_context &_ctx, void *_buf, int _len)
Definition: librandom.cpp:283
random_file_rmdir
irods::error random_file_rmdir(irods::plugin_context &_ctx)
Definition: librandom.cpp:414
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")
msParam.h
irods::plugin_context::valid
virtual error valid()
Definition: irods_plugin_context.hpp:77
random_file_close
irods::error random_file_close(irods::plugin_context &_ctx)
Definition: librandom.cpp:306
irods.six.next
next
Definition: six.py:518
irods::resource
Definition: irods_resource_plugin.hpp:25
random_file_rename
irods::error random_file_rename(irods::plugin_context &_ctx, const char *_new_file_name)
Definition: librandom.cpp:499
plugin_factory
irods::resource * plugin_factory(const std::string &_inst_name, const std::string &_context)
Definition: librandom.cpp:912
random_file_sync_to_arch
irods::error random_file_sync_to_arch(irods::plugin_context &_ctx, const char *_cache_file_name)
Definition: librandom.cpp:589
irods::RESOURCE_CHECK_PATH_PERM
const std::string RESOURCE_CHECK_PATH_PERM("resource_property_check_path_perm")
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
random_resource
Definition: librandom.cpp:881
irods::RESOURCE_OP_RESOLVE_RESC_HIER
const std::string RESOURCE_OP_RESOLVE_RESC_HIER("resource_resolve_hierarchy")
generalAdmin.h
irods::RESOURCE_OP_READDIR
const std::string RESOURCE_OP_READDIR("resource_readdir")
irods::hierarchy_parser
Definition: irods_hierarchy_parser.hpp:14
random_file_modified
irods::error random_file_modified(irods::plugin_context &_ctx)
Definition: librandom.cpp:653
get_next_child_for_open_or_write
irods::error get_next_child_for_open_or_write(const std::string &_name, irods::file_object_ptr &_file_obj, irods::plugin_property_map &_props, irods::resource_ptr &_resc)
Definition: librandom.cpp:93
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")
random_file_unlink
irods::error random_file_unlink(irods::plugin_context &_ctx)
Definition: librandom.cpp:327
random_file_rebalance
irods::error random_file_rebalance(irods::plugin_context &_ctx)
Definition: librandom.cpp:850
deploy_schemas_locally.parser
parser
Definition: deploy_schemas_locally.py:59
random_file_mkdir
irods::error random_file_mkdir(irods::plugin_context &_ctx)
Definition: librandom.cpp:393
irods::plugin_context
Definition: irods_plugin_context.hpp:18
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
random_get_next_child_resource
irods::error random_get_next_child_resource(irods::resource_child_map &_cmap, std::string &_next_child)
Definition: librandom.cpp:174
ASSERT_ERROR
#define ASSERT_ERROR(expr_, code_, format_,...)
Definition: irods_error.hpp:123
random_file_closedir
irods::error random_file_closedir(irods::plugin_context &_ctx)
Definition: librandom.cpp:456
irods::lookup_table::size
int size() const
Definition: irods_lookup_table.hpp:38
irods_resource_plugin.hpp
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")
irods::error::code
long long code() const
Definition: irods_error.cpp:194
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
random_file_resolve_hierarchy
irods::error random_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: librandom.cpp:769
irods::hierarchy_parser::add_child
error add_child(const std::string &_resc)
Definition: irods_hierarchy_parser.cpp:88
irods::RESOURCE_OP_CREATE
const std::string RESOURCE_OP_CREATE("resource_create")
irods
Definition: apiHandler.hpp:35
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: librandom.cpp:51
irods::RESOURCE_OP_NOTIFY
const std::string RESOURCE_OP_NOTIFY("resource_notify")
random_get_resc_for_call
irods::error random_get_resc_for_call(irods::plugin_context &_ctx, irods::resource_ptr &_resc)
Definition: librandom.cpp:139
random_file_opendir
irods::error random_file_opendir(irods::plugin_context &_ctx)
Definition: librandom.cpp:435
irods::RESOURCE_CREATE_PATH
const std::string RESOURCE_CREATE_PATH("resource_property_create_path")
random_file_stat
irods::error random_file_stat(irods::plugin_context &_ctx, struct stat *_statbuf)
Definition: librandom.cpp:348
irods::RESOURCE_OP_WRITE
const std::string RESOURCE_OP_WRITE("resource_write")
random_file_notify
irods::error random_file_notify(irods::plugin_context &_ctx, const std::string *_opr)
Definition: librandom.cpp:674
random_file_lseek
irods::error random_file_lseek(irods::plugin_context &_ctx, long long _offset, int _whence)
Definition: librandom.cpp:370
random_resource::need_post_disconnect_maintenance_operation
irods::error need_post_disconnect_maintenance_operation(bool &_flg)
Definition: librandom.cpp:891
ASSERT_PASS
#define ASSERT_PASS(prev_error_, format_,...)
Definition: irods_error.hpp:124
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")
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")
rodsDirent
Definition: rodsType.h:70
irods::RESOURCE_OP_UNLINK
const std::string RESOURCE_OP_UNLINK("resource_unlink")
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
random_file_getfs_freespace
irods::error random_file_getfs_freespace(irods::plugin_context &_ctx)
Definition: librandom.cpp:542
miscServerFunct.hpp
random_resource::random_resource
random_resource(const std::string &_inst_name, const std::string &_context)
Definition: librandom.cpp:883
irods::RESOURCE_OP_REGISTERED
const std::string RESOURCE_OP_REGISTERED("resource_registered")
random_file_unregistered
irods::error random_file_unregistered(irods::plugin_context &_ctx)
Definition: librandom.cpp:632
irods_hierarchy_parser.hpp
random_check_params
irods::error random_check_params(irods::plugin_context &_ctx)
Definition: librandom.cpp:35
random_file_open
irods::error random_file_open(irods::plugin_context &_ctx)
Definition: librandom.cpp:238
irods::RESOURCE_OP_MKDIR
const std::string RESOURCE_OP_MKDIR("resource_mkdir")
irods::RESOURCE_OP_OPENDIR
const std::string RESOURCE_OP_OPENDIR("resource_opendir")
irods::RESOURCE_OP_STAGETOCACHE
const std::string RESOURCE_OP_STAGETOCACHE("resource_stagetocache")
random_file_create
irods::error random_file_create(irods::plugin_context &_ctx)
Definition: librandom.cpp:217
error
int error
Definition: filesystem.cpp:101
irods::file_object_ptr
boost::shared_ptr< file_object > file_object_ptr
Definition: irods_file_object.hpp:145
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")
random_file_readdir
irods::error random_file_readdir(irods::plugin_context &_ctx, struct rodsDirent **_dirent_ptr)
Definition: librandom.cpp:477
CHILD_NOT_FOUND
@ CHILD_NOT_FOUND
Definition: rodsErrorTable.h:753
random_file_truncate
irods::error random_file_truncate(irods::plugin_context &_ctx)
Definition: librandom.cpp:521
irods_random.hpp
irods::RESOURCE_OP_REBALANCE
const std::string RESOURCE_OP_REBALANCE("resource_rebalance")
NO_NEXT_RESC_FOUND
@ NO_NEXT_RESC_FOUND
Definition: rodsErrorTable.h:754
REPLICA_NOT_IN_RESC
@ REPLICA_NOT_IN_RESC
Definition: rodsErrorTable.h:770
random_file_registered
irods::error random_file_registered(irods::plugin_context &_ctx)
Definition: librandom.cpp:611
random_file_stage_to_cache
irods::error random_file_stage_to_cache(irods::plugin_context &_ctx, const char *_cache_file_name)
Definition: librandom.cpp:565
random_file_read
irods::error random_file_read(irods::plugin_context &_ctx, void *_buf, int _len)
Definition: librandom.cpp:259
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")
get_next_valid_child_resource
irods::error get_next_valid_child_resource(irods::plugin_context &_ctx, const std::string *_opr, const std::string *_curr_host, irods::hierarchy_parser *_out_parser, float *_out_vote)
Definition: librandom.cpp:696
irods::UNLINK_OPERATION
const std::string UNLINK_OPERATION("UNLINK")
random_resource::post_disconnect_maintenance_operation
irods::error post_disconnect_maintenance_operation(irods::pdmo_type &)
Definition: librandom.cpp:898