/// =-=-=-=-=-=-=- /// @brief used to allow the resource to determine which host /// should provide the requested operation irods::error random_redirect( irods::resource_plugin_context& _ctx, const std::string* _opr, const std::string* _curr_host, irods::hierarchy_parser* _out_parser, float* _out_vote ) { irods::error result = SUCCESS(); // =-=-=-=-=-=-=- // check incoming parameters irods::error err = random_check_params< irods::file_object >( _ctx ); if ( ( result = ASSERT_PASS( err, "Invalid resource context." ) ).ok() ) { if ( ( result = ASSERT_ERROR( _opr && _curr_host && _out_parser && _out_vote, SYS_INVALID_INPUT_PARAM, "Invalid parameters." ) ).ok() ) { // =-=-=-=-=-=-=- // get the object's hier string irods::file_object_ptr file_obj = boost::dynamic_pointer_cast< irods::file_object >( _ctx.fco() ); std::string hier = file_obj->resc_hier( ); // =-=-=-=-=-=-=- // get the object's hier string std::string name; err = _ctx.prop_map().get< std::string >( irods::RESOURCE_NAME, name ); if ( ( result = ASSERT_PASS( err, "Failed to get property: \"%s\".", irods::RESOURCE_NAME.c_str() ) ).ok() ) { // =-=-=-=-=-=-=- // add ourselves into the hierarchy before calling child resources _out_parser->add_child( name ); // =-=-=-=-=-=-=- // test the operation to determine which choices to make if ( irods::OPEN_OPERATION == ( *_opr ) || irods::WRITE_OPERATION == ( *_opr ) || irods::UNLINK_OPERATION == ( *_opr )) { // =-=-=-=-=-=-=- // get the next child pointer in the hierarchy, given our name and the hier string irods::resource_ptr resc; err = get_next_child_for_open_or_write( name, file_obj, _ctx.child_map(), resc ); if ( err.ok() ) { // =-=-=-=-=-=-=- // forward the redirect call to the child for assertion of the whole operation, // there may be more than a leaf beneath us err = resc->call< const std::string*, const std::string*, irods::hierarchy_parser*, float* >( _ctx.comm(), irods::RESOURCE_OP_RESOLVE_RESC_HIER, _ctx.fco(), _opr, _curr_host, _out_parser, _out_vote ); result = ASSERT_PASS( err, "Failed calling child operation." ); } else if ( err.code() == REPLICA_NOT_IN_RESC ) { *_out_vote = 0; } else { result = err; } } else if ( irods::CREATE_OPERATION == ( *_opr ) ) { // =-=-=-=-=-=-=- // get the next_child resource for create irods::resource_ptr resc; err = get_next_valid_child_resource( _ctx, _opr, _curr_host, _out_parser, _out_vote ); result = ASSERT_PASS( err, "Failed getting next valid child." ); } else { // =-=-=-=-=-=-=- // must have been passed a bad operation result = ASSERT_ERROR( false, INVALID_OPERATION, "Operation not supported: \"%s\".", _opr->c_str() ); } } } } return result; } // random_redirect
/// =-=-=-=-=-=-=- /// @brief used to allow the resource to determine which host /// should provide the requested operation irods::error round_robin_redirect( irods::resource_plugin_context& _ctx, const std::string* _opr, const std::string* _curr_host, irods::hierarchy_parser* _out_parser, float* _out_vote ) { // =-=-=-=-=-=-=- // check incoming parameters irods::error err = round_robin_check_params< irods::file_object >( _ctx ); if ( !err.ok() ) { return PASSMSG( "round_robin_redirect - bad resource context", err ); } if ( !_opr ) { return ERROR( SYS_INVALID_INPUT_PARAM, "round_robin_redirect - null operation" ); } if ( !_curr_host ) { return ERROR( SYS_INVALID_INPUT_PARAM, "round_robin_redirect - null host" ); } if ( !_out_parser ) { return ERROR( SYS_INVALID_INPUT_PARAM, "round_robin_redirect - null outgoing hier parser" ); } if ( !_out_vote ) { return ERROR( SYS_INVALID_INPUT_PARAM, "round_robin_redirect - null outgoing vote" ); } // =-=-=-=-=-=-=- // get the object's hier string irods::file_object_ptr file_obj = boost::dynamic_pointer_cast< irods::file_object >( _ctx.fco() ); std::string hier = file_obj->resc_hier( ); // =-=-=-=-=-=-=- // get the object's hier string std::string name; err = _ctx.prop_map().get< std::string >( irods::RESOURCE_NAME, name ); if ( !err.ok() ) { return PASSMSG( "failed to get property 'name'.", err ); } // =-=-=-=-=-=-=- // add ourselves into the hierarch before calling child resources _out_parser->add_child( name ); // =-=-=-=-=-=-=- // test the operation to determine which choices to make if ( irods::OPEN_OPERATION == ( *_opr ) || irods::WRITE_OPERATION == ( *_opr ) ) { // =-=-=-=-=-=-=- // get the next child pointer in the hierarchy, given our name and the hier string irods::resource_ptr resc; err = get_next_child_for_open_or_write( name, file_obj, _ctx.child_map(), resc ); if ( !err.ok() ) { (*_out_vote) = 0.0; return PASS( err ); } // =-=-=-=-=-=-=- // forward the redirect call to the child for assertion of the whole operation, // there may be more than a leaf beneath us return resc->call < const std::string*, const std::string*, irods::hierarchy_parser*, float* > ( _ctx.comm(), irods::RESOURCE_OP_RESOLVE_RESC_HIER, _ctx.fco(), _opr, _curr_host, _out_parser, _out_vote ); std::string hier; _out_parser->str( hier ); rodsLog( LOG_DEBUG, "open :: resc hier [%s] vote [%f]", hier.c_str(), _out_vote ); } else if ( irods::CREATE_OPERATION == ( *_opr ) ) { // =-=-=-=-=-=-=- // get the next available child resource irods::resource_ptr resc; irods::error err = get_next_valid_child_resource( _ctx.prop_map(), _ctx.child_map(), resc ); if ( !err.ok() ) { return PASS( err ); } // =-=-=-=-=-=-=- // forward the 'put' redirect to the appropriate child err = resc->call < const std::string*, const std::string*, irods::hierarchy_parser*, float* > ( _ctx.comm(), irods::RESOURCE_OP_RESOLVE_RESC_HIER, _ctx.fco(), _opr, _curr_host, _out_parser, _out_vote ); if ( !err.ok() ) { return PASSMSG( "forward of put redirect failed", err ); } std::string hier; _out_parser->str( hier ); rodsLog( LOG_DEBUG, "round robin - create :: resc hier [%s] vote [%f]", hier.c_str(), _out_vote ); std::string new_hier; _out_parser->str( new_hier ); // =-=-=-=-=-=-=- // update the next_child appropriately as the above succeeded err = update_next_child_resource( _ctx.prop_map() ); if ( !err.ok() ) { return PASSMSG( "update_next_child_resource failed", err ); } return SUCCESS(); } // =-=-=-=-=-=-=- // must have been passed a bad operation std::stringstream msg; msg << "round_robin_redirect - operation not supported ["; msg << ( *_opr ) << "]"; return ERROR( -1, msg.str() ); } // round_robin_redirect