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)  

libmockarchive.cpp
Go to the documentation of this file.
1 // =-=-=-=-=-=-=-
2 // irods includes
3 #include "msParam.h"
4 #include "rcConnect.h"
5 #include "miscServerFunct.hpp"
6 
7 // =-=-=-=-=-=-=-
9 #include "irods_file_object.hpp"
15 #include "irods_stacktrace.hpp"
17 
18 // =-=-=-=-=-=-=-
19 // stl includes
20 #include <iostream>
21 #include <sstream>
22 #include <vector>
23 #include <string>
24 #include <iomanip>
25 
26 // =-=-=-=-=-=-=-
27 // boost includes
28 #include <boost/function.hpp>
29 #include <boost/any.hpp>
30 #include <boost/filesystem/operations.hpp>
31 #include <boost/filesystem/path.hpp>
32 
33 // =-=-=-=-=-=-=-
34 // system includes
35 #include <errno.h>
36 #include <sys/stat.h>
37 #include <string.h>
38 #include <sys/types.h>
39 #include <dirent.h>
40 #include <openssl/md5.h>
41 #if defined(osx_platform)
42 #include <sys/malloc.h>
43 #else
44 #include <malloc.h>
45 #endif
46 #include <fcntl.h>
47 #ifndef _WIN32
48 #include <sys/param.h>
49 #include <sys/file.h>
50 #include <unistd.h>
51 #endif
52 
53 #if defined(solaris_platform)
54 #include <sys/statvfs.h>
55 #endif
56 #if defined(linux_platform)
57 #include <sys/vfs.h>
58 #endif
59 
60 
61 // =-=-=-=-=-=-=-
62 // 2. Define utility functions that the operations might need
63 
64 // =-=-=-=-=-=-=-
65 // NOTE: All storage resources must do this on the physical path stored in the file object and then update
66 // the file object's physical path with the full path
67 
68 // =-=-=-=-=-=-=-
71  irods::plugin_property_map& _prop_map,
72  const std::string& _phy_path,
73  std::string& _ret_string ) {
74  irods::error result = SUCCESS();
75  irods::error ret;
76  std::string vault_path;
77 
78  // TODO - getting vault path by property will not likely work for coordinating nodes
79  ret = _prop_map.get<std::string>( irods::RESOURCE_PATH, vault_path );
80  if ( ( result = ASSERT_PASS( ret, "Resource has no vault path." ) ).ok() ) {
81 
82  if ( _phy_path.compare( 0, 1, "/" ) != 0 &&
83  _phy_path.compare( 0, vault_path.size(), vault_path ) != 0 ) {
84  _ret_string = vault_path;
85  _ret_string += "/";
86  _ret_string += _phy_path;
87  }
88  else {
89  // The physical path already contains the vault path
90  _ret_string = _phy_path;
91  }
92  }
93 
94  return result;
95 
96 } // mock_archive_generate_full_path
97 
98 // =-=-=-=-=-=-=-
101  irods::plugin_context& _ctx ) {
102  irods::error result = SUCCESS();
103  try {
104  irods::data_object_ptr data_obj = boost::dynamic_pointer_cast< irods::data_object >( _ctx.fco() );
105 
106  // =-=-=-=-=-=-=-
107  // NOTE: Must do this for all storage resources
108  std::string full_path;
110  data_obj->physical_path(),
111  full_path );
112  if ( ( result = ASSERT_PASS( ret, "Failed generating full path for object." ) ).ok() ) {
113 
114  data_obj->physical_path( full_path );
115  }
116 
117  return result;
118 
119  }
120  catch ( const std::bad_cast& ) {
121  return ERROR( SYS_INVALID_INPUT_PARAM, "failed to cast fco to data_object" );
122 
123  }
124 
125 } // unix_check_path
126 
127 // =-=-=-=-=-=-=-
129 template< typename DEST_TYPE >
131  irods::plugin_context& _ctx ) {
132 
133  irods::error result = SUCCESS();
134  irods::error ret;
135 
136  // =-=-=-=-=-=-=-
137  // verify that the resc context is valid
138  ret = _ctx.valid< DEST_TYPE >();
139  if ( ( result = ASSERT_PASS( ret, "Resource context is invalid." ) ).ok() ) {
140 
141  result = unix_check_path( _ctx );
142  }
143 
144  return result;
145 
146 } // unix_check_params_and_path
147 
148 // =-=-=-=-=-=-=-
149 //@brief Recursively make all of the dirs in the path
151  const std::string& path,
152  mode_t mode ) {
153  irods::error result = SUCCESS();
154  std::string subdir;
155  std::size_t pos = 0;
156  bool done = false;
157  while ( !done && result.ok() ) {
158  pos = path.find_first_of( '/', pos + 1 );
159  if ( pos > 0 ) {
160  subdir = path.substr( 0, pos );
161  int status = mkdir( subdir.c_str(), mode );
162 
163  // =-=-=-=-=-=-=-
164  // handle error cases
165  result = ASSERT_ERROR( status >= 0 || errno == EEXIST, UNIX_FILE_RENAME_ERR - errno, "mkdir error for \"%s\", errno = \"%s\", status = %d.",
166  subdir.c_str(), strerror( errno ), status );
167  }
168  if ( pos == std::string::npos ) {
169  done = true;
170  }
171  }
172 
173  return result;
174 
175 } // mock_archive_mkdir_r
176 
177 
179  irods::plugin_property_map& _prop_map,
180  const std::string& _path,
181  std::string& _hashed ) {
182  irods::error result;
183 
184  // =-=-=-=-=-=-=-
185  // hash the physical path to reflect object store behavior
186  MD5_CTX context;
187  char md5Buf[ MAX_NAME_LEN ];
188  unsigned char hash [ MAX_NAME_LEN ];
189 
190  strncpy( md5Buf, _path.c_str(), _path.size() );
191  MD5_Init( &context );
192  MD5_Update( &context, ( unsigned char* )md5Buf, _path.size() );
193  MD5_Final( ( unsigned char* )hash, &context );
194 
195  std::stringstream ins;
196  for ( int i = 0; i < 16; ++i ) {
197  ins << std::setfill( '0' ) << std::setw( 2 ) << std::hex << ( int )hash[i];
198  }
199 
200  // =-=-=-=-=-=-=-
201  // get the vault path for the resource
202  std::string path;
203  irods::error ret = _prop_map.get< std::string >( irods::RESOURCE_PATH, path );
204  if ( ( result = ASSERT_PASS( ret, "Failed to get vault path for resource." ) ).ok() ) {
205  // =-=-=-=-=-=-=-
206  // append the hash to the path as the new 'cache file name'
207  path += "/";
208  path += ins.str();
209 
210  _hashed = path;
211  }
212 
213  return result;
214 
215 } // make_hashed_path
216 
217 // =-=-=-=-=-=-=-
218 // 3. Define operations which will be called by the file*
219 // calls declared in server/driver/include/fileDriver.h
220 // =-=-=-=-=-=-=-
221 
222 // =-=-=-=-=-=-=-
223 // NOTE :: to access properties in the _prop_map do the
224 // :: following :
225 // :: double my_var = 0.0;
226 // :: irods::error ret = _prop_map.get< double >( "my_key", my_var );
227 // =-=-=-=-=-=-=-
228 
229 // =-=-=-=-=-=-=-
230 // interface for POSIX mkdir
232  irods::plugin_context& _ctx ) {
233  irods::error result = SUCCESS();
234 
235  // =-=-=-=-=-=-=-
236  // NOTE :: this function assumes the object's physical path is correct and
237  // should not have the vault path prepended - hcj
238 
240  if ( ( result = ASSERT_PASS( ret, "resource context is invalid." ) ).ok() ) {
241 
242  // =-=-=-=-=-=-=-
243  // cast down the chain to our understood object type
244  irods::collection_object_ptr fco = boost::dynamic_pointer_cast< irods::collection_object >( _ctx.fco() );
245 
246  // =-=-=-=-=-=-=-
247  // make the call to mkdir & umask
248  mode_t myMask = umask( ( mode_t ) 0000 );
249  int status = mkdir( fco->physical_path().c_str(), fco->mode() );
250 
251  // =-=-=-=-=-=-=-
252  // reset the old mask
253  umask( ( mode_t ) myMask );
254 
255  // =-=-=-=-=-=-=-
256  // return an error if necessary
257  result.code( status );
258  int err_status = UNIX_FILE_MKDIR_ERR - errno;
259  if ( ( result = ASSERT_ERROR( status >= 0, err_status, "mkdir error for [%s], errno = [%s], status = %d.",
260  fco->physical_path().c_str(), strerror( errno ), err_status ) ).ok() ) {
261  result.code( status );
262  }
263  }
264  return result;
265 
266 } // mock_archive_file_mkdir
267 
270  struct stat* _statbuf ) {
271  irods::error result = SUCCESS();
272  // =-=-=-=-=-=-=-
273  // manufacture a stat as we do not have a
274  // microservice to perform this duty
275  _statbuf->st_mode = S_IFREG;
276  _statbuf->st_nlink = 1;
277  _statbuf->st_uid = getuid();
278  _statbuf->st_gid = getgid();
279  _statbuf->st_atime = _statbuf->st_mtime = _statbuf->st_ctime = time( 0 );
280  _statbuf->st_size = UNKNOWN_FILE_SZ;
281  return SUCCESS();
282 
283 } // mock_archive_file_stat
284 
285 // =-=-=-=-=-=-=-
286 // interface for POSIX readdir
288  irods::plugin_context& _ctx,
289  const char* _new_file_name ) {
290  // =-=-=-=-=-=-=-
291  // Check the operation parameters and update the physical path
292  irods::error result = SUCCESS();
293  irods::error ret = unix_check_params_and_path< irods::data_object >( _ctx );
294  if ( ( result = ASSERT_PASS( ret, "Invalid parameters or physical path." ) ).ok() ) {
295 
296  // =-=-=-=-=-=-=-
297  // manufacture a new path from the new file name
298  std::string new_full_path;
299  ret = mock_archive_generate_full_path( _ctx.prop_map(), _new_file_name, new_full_path );
300  if ( ( result = ASSERT_PASS( ret, "Unable to generate full path for destination file: \"%s\".",
301  _new_file_name ) ).ok() ) {
302  // =-=-=-=-=-=-=-
303  // cast down the hierarchy to the desired object
304  irods::file_object_ptr fco = boost::dynamic_pointer_cast< irods::file_object >( _ctx.fco() );
305 
306  // =-=-=-=-=-=-=-
307  // get hashed names for the old path
308  std::string new_hash;
309  ret = make_hashed_path(
310  _ctx.prop_map(),
311  _new_file_name,
312  new_hash );
313  if ( ( result = ASSERT_PASS( ret, "Failed to gen hashed path" ) ).ok() ) {
314  // =-=-=-=-=-=-=-
315  // make the call to rename
316  int status = rename( fco->physical_path().c_str(), new_hash.c_str() );
317 
318  // =-=-=-=-=-=-=-
319  // handle error cases
320  int err_status = UNIX_FILE_RENAME_ERR - errno;
321  if ( ( result = ASSERT_ERROR( status >= 0, err_status, "Rename error for \"%s\" to \"%s\", errno = \"%s\", status = %d.",
322  fco->physical_path().c_str(), new_hash.c_str(), strerror( errno ), err_status ) ).ok() ) {
323  fco->physical_path( new_hash );
324  result.code( status );
325  }
326  }
327  }
328  }
329 
330  return result;
331 
332 } // mock_archive_file_rename
333 
334 // =-=-=-=-=-=-=-
335 // interface for POSIX Truncate
337  irods::plugin_context& _ctx ) {
338  irods::error result = SUCCESS();
339  // =-=-=-=-=-=-=-
340  // Check the operation parameters and update the physical path
341  irods::error ret = unix_check_params_and_path< irods::file_object >( _ctx );
342  if ( ( result = ASSERT_PASS( ret, "Invalid plugin context." ) ).ok() ) {
343 
344  // =-=-=-=-=-=-=-
345  // get ref to fco
346  irods::file_object_ptr fco = boost::dynamic_pointer_cast< irods::file_object >( _ctx.fco() );
347 
348  // =-=-=-=-=-=-=-
349  // make the call to unlink
350  int status = truncate( fco->physical_path().c_str(), fco->size() );
351 
352  // =-=-=-=-=-=-=-
353  // error handling
354  int err_status = UNIX_FILE_UNLINK_ERR - errno;
355  result = ASSERT_ERROR( status >= 0, err_status, "Truncate error for: \"%s\", errno = \"%s\", status = %d.",
356  fco->physical_path().c_str(), strerror( errno ), err_status );
357  }
358 
359  return result;
360 
361 } // mock_archive_file_truncate
362 
363 // =-=-=-=-=-=-=-
364 // interface for POSIX Unlink
366  irods::plugin_context& _ctx ) {
367  irods::error result = SUCCESS();
368  // =-=-=-=-=-=-=-
369  // Check the operation parameters and update the physical path
370  irods::error ret = unix_check_params_and_path< irods::file_object >( _ctx );
371  if ( ( result = ASSERT_PASS( ret, "Invalid plugin context." ) ).ok() ) {
372 
373  // =-=-=-=-=-=-=-
374  // get ref to fco
375  irods::file_object_ptr fco = boost::dynamic_pointer_cast< irods::file_object >( _ctx.fco() );
376 
377  // =-=-=-=-=-=-=-
378  // make the call to unlink
379  int status = unlink( fco->physical_path().c_str() );
380 
381  // =-=-=-=-=-=-=-
382  // error handling
383  int err_status = UNIX_FILE_UNLINK_ERR - errno;
384  result = ASSERT_ERROR( status >= 0, err_status, "Unlink error for: \"%s\", errno = \"%s\", status = %d.",
385  fco->physical_path().c_str(), strerror( errno ), err_status );
386  }
387 
388  return result;
389 
390 } // mock_archive_file_unlink
391 
392 int
394  int mode,
395  const char* srcFileName,
396  const char* destFileName ) {
397 
398  size_t trans_buff_size;
399  try {
400  trans_buff_size = irods::get_advanced_setting<const int>(irods::CFG_TRANS_BUFFER_SIZE_FOR_PARA_TRANS) * 1024 * 1024;
401  } catch ( const irods::exception& e ) {
402  irods::log(e);
403  return e.code();
404  }
405 
406  int inFd, outFd;
407  std::vector<char> myBuf( trans_buff_size );
408  rodsLong_t bytesCopied = 0;
409  int bytesRead;
410  int bytesWritten;
411  int status;
412  struct stat statbuf;
413 
414 
415  inFd = open( srcFileName, O_RDONLY, 0 );
416  status = stat( srcFileName, &statbuf );
417  if ( inFd < 0 ) {
418  status = UNIX_FILE_OPEN_ERR - errno;
420  "mockArchiveCopyPlugin: open error for srcFileName %s, status = %d",
421  srcFileName, status );
422  return status;
423  }
424  else if ( status < 0 ) {
425  status = UNIX_FILE_STAT_ERR - errno;
427  "mockArchiveCopyPlugin: stat of %s error, status = %d",
428  srcFileName, status );
429  close( inFd ); // JMC cppcheck - resource
430  return status;
431  }
432  else if ( ( statbuf.st_mode & S_IFREG ) == 0 ) {
434  "mockArchiveCopyPlugin: open error for srcFileName %s, status = %d",
435  srcFileName, UNIX_FILE_OPEN_ERR );
436  close( inFd ); // JMC cppcheck - resource
437  return status;
438  }
439 
440  outFd = open( destFileName, O_WRONLY | O_CREAT | O_TRUNC, mode );
441  if ( outFd < 0 ) {
442  status = UNIX_FILE_OPEN_ERR - errno;
444  "mockArchiveCopyPlugin: open error for destFileName %s, status = %d",
445  destFileName, status );
446  close( inFd );
447  return status;
448  }
449 
450  while ( ( bytesRead = read( inFd, ( void * ) myBuf.data(), trans_buff_size ) ) > 0 ) {
451  bytesWritten = write( outFd, ( void * ) myBuf.data(), bytesRead );
452  if ( bytesWritten <= 0 ) {
453  status = UNIX_FILE_WRITE_ERR - errno;
455  "mockArchiveCopyPlugin: write error for srcFileName %s, status = %d",
456  destFileName, status );
457  close( inFd );
458  close( outFd );
459  return status;
460  }
461  bytesCopied += bytesWritten;
462  }
463 
464  close( inFd );
465  close( outFd );
466 
467  if ( bytesCopied != statbuf.st_size ) {
469  "mockArchiveCopyPlugin: Copied size %lld does not match source \
470  size %lld of %s",
471  bytesCopied, statbuf.st_size, srcFileName );
472  return SYS_COPY_LEN_ERR;
473  }
474  else {
475  return 0;
476  }
477 
478 } // mockArchiveCopyPlugin
479 
480 // =-=-=-=-=-=-=-
481 // unixStageToCache - This routine is for testing the TEST_STAGE_FILE_TYPE.
482 // Just copy the file from filename to cacheFilename. optionalInfo info
483 // is not used.
485  irods::plugin_context& _ctx,
486  const char* _cache_file_name ) {
487  irods::error result = SUCCESS();
488 
489  // =-=-=-=-=-=-=-
490  // Check the operation parameters and update the physical path
491  irods::error ret = unix_check_params_and_path< irods::file_object >( _ctx );
492  if ( ( result = ASSERT_PASS( ret, "Invalid plugin context." ) ).ok() ) {
493 
494  // =-=-=-=-=-=-=-
495  // get ref to fco
496  irods::file_object_ptr fco = boost::dynamic_pointer_cast< irods::file_object >( _ctx.fco() );
497 
498  // =-=-=-=-=-=-=-
499  // get the vault path for the resource
500  std::string path;
501  ret = _ctx.prop_map().get< std::string >( irods::RESOURCE_PATH, path );
502  if ( ( result = ASSERT_PASS( ret, "Failed to retrieve vault path for resource." ) ).ok() ) {
503 
504  // =-=-=-=-=-=-=-
505  // append the hash to the path as the new 'cache file name'
506  path += "/";
507  path += fco->physical_path().c_str();
508 
509  int status = mockArchiveCopyPlugin( fco->mode(), fco->physical_path().c_str(), _cache_file_name );
510  result = ASSERT_ERROR( status >= 0, status, "Failed copying archive file: \"%s\" to cache file: \"%s\".",
511  fco->physical_path().c_str(), _cache_file_name );
512  }
513  }
514 
515  return result;
516 } // mock_archive_file_stage_to_cache
517 
518 // =-=-=-=-=-=-=-
519 // unixSyncToArch - This routine is for testing the TEST_STAGE_FILE_TYPE.
520 // Just copy the file from cacheFilename to filename. optionalInfo info
521 // is not used.
523  irods::plugin_context& _ctx,
524  const char* _cache_file_name ) {
525  irods::error result = SUCCESS();
526 
527  // =-=-=-=-=-=-=-
528  // Check the operation parameters and update the physical path
529  irods::error ret = unix_check_params_and_path< irods::file_object >( _ctx );
530  if ( ( result = ASSERT_PASS( ret, "Invalid plugin context." ) ).ok() ) {
531  // =-=-=-=-=-=-=-
532  // get ref to fco
533  irods::file_object_ptr fco = boost::dynamic_pointer_cast< irods::file_object >( _ctx.fco() );
534 
535  // =-=-=-=-=-=-=-
536  // get the vault path for the resource
537  std::string path;
538  ret = make_hashed_path(
539  _ctx.prop_map(),
540  fco->physical_path(),
541  path );
542  if ( ( result = ASSERT_PASS( ret, "Failed to gen hashed path" ) ).ok() ) {
543  // =-=-=-=-=-=-=-
544  // append the hash to the path as the new 'cache file name'
545  rodsLog( LOG_NOTICE, "mock archive :: cache file name [%s]", _cache_file_name );
546 
547  rodsLog( LOG_NOTICE, "mock archive :: new hashed file name for [%s] is [%s]",
548  fco->physical_path().c_str(), path.c_str() );
549 
550  // =-=-=-=-=-=-=-
551  // make the directories in the path to the new file
552  std::string new_path = path;
553  std::size_t last_slash = new_path.find_last_of( '/' );
554  new_path.erase( last_slash );
555  ret = mock_archive_mkdir_r( new_path.c_str(), 0750 );
556  if ( ( result = ASSERT_PASS( ret, "Mkdir error for \"%s\".", new_path.c_str() ) ).ok() ) {
557 
558  }
559  // =-=-=-=-=-=-=-
560  // make the copy to the 'archive'
561  int status = mockArchiveCopyPlugin( fco->mode(), _cache_file_name, path.c_str() );
562  if ( ( result = ASSERT_ERROR( status >= 0, status, "Sync to arch failed." ) ).ok() ) {
563  fco->physical_path( path );
564  }
565  }
566  }
567 
568  return result;
569 
570 } // mock_archive_file_sync_to_arch
571 
572 // =-=-=-=-=-=-=-
573 // redirect_create - code to determine redirection for get operation
574 // Create never gets called on an archive.
575 
576 // =-=-=-=-=-=-=-
577 // redirect_get - code to determine redirection for get operation
579  irods::plugin_property_map& _prop_map,
580  irods::file_object_ptr _file_obj,
581  const std::string& _resc_name,
582  const std::string& _curr_host,
583  float& _out_vote ) {
584  irods::error result = SUCCESS();
585 
586  // =-=-=-=-=-=-=-
587  // initially set a good default
588  _out_vote = 0.0;
589 
590  // =-=-=-=-=-=-=-
591  // determine if the resource is down
592  int resc_status = 0;
593  irods::error get_ret = _prop_map.get< int >( irods::RESOURCE_STATUS, resc_status );
594  if ( ( result = ASSERT_PASS( get_ret, "Failed to get \"status\" property." ) ).ok() ) {
595 
596  // =-=-=-=-=-=-=-
597  // if the status is down, vote no.
598  if ( INT_RESC_STATUS_DOWN != resc_status ) {
599 
600  // =-=-=-=-=-=-=-
601  // get the resource host for comparison to curr host
602  std::string host_name;
603  get_ret = _prop_map.get< std::string >( irods::RESOURCE_LOCATION, host_name );
604  if ( ( result = ASSERT_PASS( get_ret, "Failed to get \"location\" property." ) ).ok() ) {
605 
606  // =-=-=-=-=-=-=-
607  // set a flag to test if were at the curr host, if so we vote higher
608  bool curr_host = ( _curr_host == host_name );
609 
610  // =-=-=-=-=-=-=-
611  // make some flags to clairify decision making
612  bool need_repl = ( _file_obj->repl_requested() > -1 );
613 
614  // =-=-=-=-=-=-=-
615  // set up variables for iteration
616  bool found = false;
617  std::vector< irods::physical_object > objs = _file_obj->replicas();
618  std::vector< irods::physical_object >::iterator itr = objs.begin();
619 
620  // =-=-=-=-=-=-=-
621  // check to see if the replica is in this resource, if one is requested
622  for ( ; !found && itr != objs.end(); ++itr ) {
623 
624  // =-=-=-=-=-=-=-
625  // run the hier string through the parser and get the last
626  // entry.
627  std::string last_resc;
629  parser.set_string( itr->resc_hier() );
630  parser.last_resc( last_resc );
631 
632  // =-=-=-=-=-=-=-
633  // more flags to simplify decision making
634  bool repl_us = ( _file_obj->repl_requested() == itr->repl_num() );
635  bool resc_us = ( _resc_name == last_resc );
636 
637  // =-=-=-=-=-=-=-
638  // success - correct resource and dont need a specific
639  // replication, or the repl nums match
640  if ( resc_us ) {
641  if ( !need_repl || ( need_repl && repl_us ) ) {
642  found = true;
643  if ( curr_host ) {
644  _out_vote = 1.0;
645  }
646  else {
647  _out_vote = 0.5;
648  }
649  }
650 
651  } // if resc_us
652 
653  } // for itr
654  }
655  }
656  }
657 
658  return result;
659 
660 } // mock_archive_redirect_open
661 
662 // =-=-=-=-=-=-=-
663 // used to allow the resource to determine which host
664 // should provide the requested operation
666  irods::plugin_context& _ctx,
667  const std::string* _opr,
668  const std::string* _curr_host,
669  irods::hierarchy_parser* _out_parser,
670  float* _out_vote ) {
671  irods::error result = SUCCESS();
672 
673  // =-=-=-=-=-=-=-
674  // check the context validity
675  irods::error ret = _ctx.valid< irods::file_object >();
676  if ( ( result = ASSERT_PASS( ret, "Invalid plugin context." ) ).ok() ) {
677 
678  if ( ( result = ASSERT_ERROR( _opr && _curr_host && _out_parser && _out_vote, SYS_INVALID_INPUT_PARAM,
679  "Invalid input parameters." ) ).ok() ) {
680 
681  // =-=-=-=-=-=-=-
682  // cast down the chain to our understood object type
683  irods::file_object_ptr file_obj = boost::dynamic_pointer_cast< irods::file_object >( _ctx.fco() );
684 
685  // =-=-=-=-=-=-=-
686  // get the name of this resource
687  std::string resc_name;
688  ret = _ctx.prop_map().get< std::string >( irods::RESOURCE_NAME, resc_name );
689  if ( ( result = ASSERT_PASS( ret, "Failed to get property for resource name." ) ).ok() ) {
690 
691  // =-=-=-=-=-=-=-
692  // add ourselves to the hierarchy parser by default
693  _out_parser->add_child( resc_name );
694 
695  // =-=-=-=-=-=-=-
696  // test the operation to determine which choices to make
697  if ( irods::OPEN_OPERATION == ( *_opr ) || irods::UNLINK_OPERATION == ( *_opr )) {
698  // =-=-=-=-=-=-=-
699  // call redirect determination for 'get' operation
700  result = mock_archive_redirect_open( _ctx.prop_map(), file_obj, resc_name, ( *_curr_host ), ( *_out_vote ) );
701 
702  }
703  else if ( irods::CREATE_OPERATION == ( *_opr ) ) {
704  // =-=-=-=-=-=-=-
705  // call redirect determination for 'create' operation
706  result = ASSERT_ERROR( false, SYS_INVALID_INPUT_PARAM, "Create operation not supported for an archive" );
707  }
708  else {
709 
710  // =-=-=-=-=-=-=-
711  // must have been passed a bad operation
712  result = ASSERT_ERROR( false, SYS_INVALID_INPUT_PARAM, "Operation not supported: \"%s\".",
713  _opr->c_str() );
714  }
715  }
716  }
717  }
718 
719  return result;
720 } // mock_archive_file_resolve_hierarchy
721 
722 // =-=-=-=-=-=-=-
723 // mock_archive_file_rebalance - code which would rebalance the subtree
725  irods::plugin_context& _ctx ) {
726 
727  return SUCCESS();
728 
729 } // mock_archive_file_rebalance
730 
731 // =-=-=-=-=-=-=-
732 // 3. create derived class to handle mock_archive file system resources
733 // necessary to do custom parsing of the context string to place
734 // any useful values into the property map for reference in later
735 // operations. semicolon is the preferred delimiter
737  // =-=-=-=-=-=-=-
738  // 3a. create a class to provide maintenance operations, this is only for example
739  // and will not be called.
741  public:
742  maintenance_operation( const std::string& _n ) : name_( _n ) {
743  }
744 
746  name_ = _rhs.name_;
747  }
748 
750  name_ = _rhs.name_;
751  return *this;
752  }
753 
755  rodsLog( LOG_NOTICE, "mockarchive_resource::post_disconnect_maintenance_operation - [%s]",
756  name_.c_str() );
757  return SUCCESS();
758  }
759 
760  private:
761  std::string name_;
762 
763  }; // class maintenance_operation
764 
765  public:
766  mockarchive_resource( const std::string& _inst_name,
767  const std::string& _context ) :
768  irods::resource( _inst_name, _context ) {
769  } // ctor
770 
771 
773  _b = false;
774  return SUCCESS();
775  }
776 
777 
778  // =-=-=-=-=-=-=-
779  // 3b. pass along a functor for maintenance work after
780  // the client disconnects, uncomment the first two lines for effect.
782  return ERROR( -1, "nop" );
783  }
784 
785 }; // class mockarchive_resource
786 
787 // =-=-=-=-=-=-=-
788 // 4. create the plugin factory function which will return a dynamically
789 // instantiated object of the previously defined derived resource. use
790 // the add_operation member to associate a 'call name' to the interfaces
791 // defined above. for resource plugins these call names are standardized
792 // as used by the irods facing interface defined in
793 // server/drivers/src/fileDriver.c
794 extern "C"
795 irods::resource* plugin_factory( const std::string& _inst_name, const std::string& _context ) {
796 
797  // =-=-=-=-=-=-=-
798  // 4a. create mockarchive_resource
799  mockarchive_resource* resc = new mockarchive_resource( _inst_name, _context );
800 
801  // =-=-=-=-=-=-=-
802  // 4b. map function names to operations. this map will be used to load
803  // the symbols from the shared object in the delay_load stage of
804  // plugin loading.
805  using namespace irods;
806  using namespace std;
807 
808  resc->add_operation(
810  function<error(plugin_context&)>(
812 
813  resc->add_operation<const char*>(
815  function<error(plugin_context&, const char*)>(
817 
818  resc->add_operation<const char*>(
820  function<error(plugin_context&, const char*)>(
822 
823  resc->add_operation(
825  function<error(plugin_context&)>(
827 
828  resc->add_operation<const char*>(
830  function<error(plugin_context&, const char*)>(
832 
833  resc->add_operation<struct stat*>(
835  function<error(plugin_context&, struct stat*)>(
837 
838  resc->add_operation(
840  function<error(plugin_context&)>(
842 
843  resc->add_operation<const std::string*, const std::string*, irods::hierarchy_parser*, float*>(
845  function<error(plugin_context&,const std::string*, const std::string*, irods::hierarchy_parser*, float*)>(
847 
848  resc->add_operation(
850  function<error(plugin_context&)>(
852 
853  // =-=-=-=-=-=-=-
854  // set some properties necessary for backporting to iRODS legacy code
855  resc->set_property< int >( irods::RESOURCE_CHECK_PATH_PERM, 2 );//DO_CHK_PATH_PERM );
856  resc->set_property< int >( irods::RESOURCE_CREATE_PATH, 1 );//CREATE_PATH );
857 
858  // =-=-=-=-=-=-=-
859  // 4c. return the pointer through the generic interface of an
860  // irods::resource pointer
861  return dynamic_cast<irods::resource*>( resc );
862 
863 } // plugin_factory
rodsLog
void rodsLog(int level, const char *formatStr,...)
Definition: rodsLog.cpp:86
UNIX_FILE_WRITE_ERR
@ UNIX_FILE_WRITE_ERR
Definition: rodsErrorTable.h:303
rcComm_t
Definition: rcConnect.h:95
irods_physical_object.hpp
irods::RESOURCE_LOCATION
const std::string RESOURCE_LOCATION("resource_property_location")
plugin_factory
irods::resource * plugin_factory(const std::string &_inst_name, const std::string &_context)
Definition: libmockarchive.cpp:795
mockarchive_resource::maintenance_operation::maintenance_operation
maintenance_operation(const std::string &_n)
Definition: libmockarchive.cpp:742
irods::lookup_table< boost::any >
UNKNOWN_FILE_SZ
#define UNKNOWN_FILE_SZ
Definition: rodsDef.h:92
irods::RESOURCE_NAME
const std::string RESOURCE_NAME("resource_property_name")
irods_server_properties.hpp
irods::RESOURCE_OP_STAT
const std::string RESOURCE_OP_STAT("resource_stat")
msParam.h
mock_archive_file_rebalance
irods::error mock_archive_file_rebalance(irods::plugin_context &_ctx)
Definition: libmockarchive.cpp:724
irods::plugin_context::valid
virtual error valid()
Definition: irods_plugin_context.hpp:77
irods::CFG_TRANS_BUFFER_SIZE_FOR_PARA_TRANS
const std::string CFG_TRANS_BUFFER_SIZE_FOR_PARA_TRANS("transfer_buffer_size_for_parallel_transfer_in_megabytes")
irods::resource
Definition: irods_resource_plugin.hpp:25
mock_archive_generate_full_path
irods::error mock_archive_generate_full_path(irods::plugin_property_map &_prop_map, const std::string &_phy_path, std::string &_ret_string)
Definition: libmockarchive.cpp:70
irods::RESOURCE_CHECK_PATH_PERM
const std::string RESOURCE_CHECK_PATH_PERM("resource_property_check_path_perm")
mock_archive_file_unlink
irods::error mock_archive_file_unlink(irods::plugin_context &_ctx)
Definition: libmockarchive.cpp:365
irods_file_object.hpp
irods_stacktrace.hpp
irods::pdmo_type
std::function< irods::error(rcComm_t *) > pdmo_type
Definition: irods_plugin_base.hpp:29
irods::data_object_ptr
boost::shared_ptr< data_object > data_object_ptr
Definition: irods_data_object.hpp:17
irods_collection_object.hpp
mock_archive_file_mkdir
irods::error mock_archive_file_mkdir(irods::plugin_context &_ctx)
Definition: libmockarchive.cpp:231
irods::RESOURCE_OP_RESOLVE_RESC_HIER
const std::string RESOURCE_OP_RESOLVE_RESC_HIER("resource_resolve_hierarchy")
irods::hierarchy_parser
Definition: irods_hierarchy_parser.hpp:14
irods::collection_object_ptr
boost::shared_ptr< collection_object > collection_object_ptr
Definition: irods_collection_object.hpp:85
mockarchive_resource
Definition: libmockarchive.cpp:736
rcConnect.h
mockarchive_resource::need_post_disconnect_maintenance_operation
irods::error need_post_disconnect_maintenance_operation(bool &_b)
Definition: libmockarchive.cpp:772
irods::RESOURCE_PATH
const std::string RESOURCE_PATH("resource_property_path")
mock_archive_file_stage_to_cache
irods::error mock_archive_file_stage_to_cache(irods::plugin_context &_ctx, const char *_cache_file_name)
Definition: libmockarchive.cpp:484
deploy_schemas_locally.parser
parser
Definition: deploy_schemas_locally.py:59
irods::plugin_context
Definition: irods_plugin_context.hpp:18
LOG_ERROR
#define LOG_ERROR
Definition: rodsLog.h:43
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::RESOURCE_STATUS
const std::string RESOURCE_STATUS("resource_property_status")
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
mock_archive_file_rename
irods::error mock_archive_file_rename(irods::plugin_context &_ctx, const char *_new_file_name)
Definition: libmockarchive.cpp:287
mock_archive_redirect_open
irods::error mock_archive_redirect_open(irods::plugin_property_map &_prop_map, irods::file_object_ptr _file_obj, const std::string &_resc_name, const std::string &_curr_host, float &_out_vote)
Definition: libmockarchive.cpp:578
ASSERT_ERROR
#define ASSERT_ERROR(expr_, code_, format_,...)
Definition: irods_error.hpp:123
irods_resource_plugin.hpp
SUCCESS
#define SUCCESS()
Definition: irods_error.hpp:121
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")
UNIX_FILE_OPEN_ERR
@ UNIX_FILE_OPEN_ERR
Definition: rodsErrorTable.h:300
irods::error::code
long long code() const
Definition: irods_error.cpp:194
mockarchive_resource::maintenance_operation::maintenance_operation
maintenance_operation(const maintenance_operation &_rhs)
Definition: libmockarchive.cpp:745
irods::plugin_context::prop_map
virtual irods::plugin_property_map & prop_map()
Definition: irods_plugin_context.hpp:99
SYS_COPY_LEN_ERR
@ SYS_COPY_LEN_ERR
Definition: rodsErrorTable.h:95
mock_archive_mkdir_r
irods::error mock_archive_mkdir_r(const std::string &path, mode_t mode)
Definition: libmockarchive.cpp:150
irods::hierarchy_parser::add_child
error add_child(const std::string &_resc)
Definition: irods_hierarchy_parser.cpp:88
irods
Definition: apiHandler.hpp:35
UNIX_FILE_RENAME_ERR
@ UNIX_FILE_RENAME_ERR
Definition: rodsErrorTable.h:318
make_hashed_path
irods::error make_hashed_path(irods::plugin_property_map &_prop_map, const std::string &_path, std::string &_hashed)
Definition: libmockarchive.cpp:178
irods::RESOURCE_CREATE_PATH
const std::string RESOURCE_CREATE_PATH("resource_property_create_path")
MAX_NAME_LEN
#define MAX_NAME_LEN
Definition: rodsDef.h:61
terminate_irods_processes.e
e
Definition: terminate_irods_processes.py:19
UNIX_FILE_UNLINK_ERR
@ UNIX_FILE_UNLINK_ERR
Definition: rodsErrorTable.h:305
ASSERT_PASS
#define ASSERT_PASS(prev_error_, format_,...)
Definition: irods_error.hpp:124
irods::collection_object
Definition: irods_collection_object.hpp:14
irods.pypyodbc.status
status
Definition: pypyodbc.py:467
irods::log
void log(const error &)
Definition: irods_log.cpp:13
irods::RESOURCE_OP_UNLINK
const std::string RESOURCE_OP_UNLINK("resource_unlink")
LOG_NOTICE
#define LOG_NOTICE
Definition: rodsLog.h:33
ERROR
#define ERROR(code_, message_)
Definition: irods_error.hpp:117
mockarchive_resource::post_disconnect_maintenance_operation
irods::error post_disconnect_maintenance_operation(irods::pdmo_type &)
Definition: libmockarchive.cpp:781
irods::error
Definition: irods_error.hpp:23
miscServerFunct.hpp
int
typedef int((*funcPtr)())
INT_RESC_STATUS_DOWN
#define INT_RESC_STATUS_DOWN
Definition: rodsDef.h:282
mock_archive_file_stat
irods::error mock_archive_file_stat(irods::plugin_context &, struct stat *_statbuf)
Definition: libmockarchive.cpp:268
unix_check_params_and_path
irods::error unix_check_params_and_path(irods::plugin_context &_ctx)
Definition: libmockarchive.cpp:130
unix_check_path
irods::error unix_check_path(irods::plugin_context &_ctx)
Definition: libmockarchive.cpp:100
mockarchive_resource::maintenance_operation::operator()
irods::error operator()(rcComm_t *)
Definition: libmockarchive.cpp:754
irods_hierarchy_parser.hpp
mock_archive_file_resolve_hierarchy
irods::error mock_archive_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: libmockarchive.cpp:665
irods::file_object
Definition: irods_file_object.hpp:19
irods::RESOURCE_OP_MKDIR
const std::string RESOURCE_OP_MKDIR("resource_mkdir")
mockarchive_resource::maintenance_operation::name_
std::string name_
Definition: libmockarchive.cpp:761
irods::RESOURCE_OP_STAGETOCACHE
const std::string RESOURCE_OP_STAGETOCACHE("resource_stagetocache")
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::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::exception
Definition: irods_exception.hpp:15
mock_archive_file_truncate
irods::error mock_archive_file_truncate(irods::plugin_context &_ctx)
Definition: libmockarchive.cpp:336
mockarchive_resource::maintenance_operation
Definition: libmockarchive.cpp:740
irods::experimental::filesystem::client::rename
auto rename(rcComm_t &_comm, const path &_from, const path &_to) -> void
Definition: filesystem.cpp:805
UNIX_FILE_STAT_ERR
@ UNIX_FILE_STAT_ERR
Definition: rodsErrorTable.h:306
irods::RESOURCE_OP_REBALANCE
const std::string RESOURCE_OP_REBALANCE("resource_rebalance")
mode
int mode
Definition: filesystem.cpp:104
mockarchive_resource::maintenance_operation::operator=
maintenance_operation & operator=(const maintenance_operation &_rhs)
Definition: libmockarchive.cpp:749
irods::error::ok
bool ok()
Definition: irods_error.cpp:258
mockArchiveCopyPlugin
int mockArchiveCopyPlugin(int mode, const char *srcFileName, const char *destFileName)
Definition: libmockarchive.cpp:393
irods::CREATE_OPERATION
const std::string CREATE_OPERATION("CREATE")
irods::UNLINK_OPERATION
const std::string UNLINK_OPERATION("UNLINK")
UNIX_FILE_MKDIR_ERR
@ UNIX_FILE_MKDIR_ERR
Definition: rodsErrorTable.h:310
mock_archive_file_sync_to_arch
irods::error mock_archive_file_sync_to_arch(irods::plugin_context &_ctx, const char *_cache_file_name)
Definition: libmockarchive.cpp:522
mockarchive_resource::mockarchive_resource
mockarchive_resource(const std::string &_inst_name, const std::string &_context)
Definition: libmockarchive.cpp:766
rodsLong_t
long long rodsLong_t
Definition: rodsType.h:32