示例#1
0
    /// =-=-=-=-=-=-=-
    /// @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