From 1d34d9a9dc2bc60771165be655fdb4d15563245c Mon Sep 17 00:00:00 2001 From: Kory Draughn Date: Fri, 29 Sep 2023 09:32:22 -0400 Subject: [PATCH] [#7256] Documentation, clang-tidy, and other tweaks for new API endpoint. --- .../irods/get_resource_info_for_operation.h | 72 +++++++++++------- .../rs_get_resource_info_for_operation.hpp | 73 ++++++++++++++----- .../rs_get_resource_info_for_operation.cpp | 61 ++++++++-------- 3 files changed, 132 insertions(+), 74 deletions(-) diff --git a/lib/api/include/irods/get_resource_info_for_operation.h b/lib/api/include/irods/get_resource_info_for_operation.h index 5c096de441..51bdbdd9cf 100644 --- a/lib/api/include/irods/get_resource_info_for_operation.h +++ b/lib/api/include/irods/get_resource_info_for_operation.h @@ -1,5 +1,6 @@ #ifndef IRODS_GET_RESOURCE_INFO_FOR_OPERATION_H #define IRODS_GET_RESOURCE_INFO_FOR_OPERATION_H + /// \file #include "irods/dataObjInpOut.h" @@ -9,56 +10,75 @@ struct RcComm; #ifdef __cplusplus extern "C" { #endif + /// Get preferred-resource information for the specified operation. /// -/// \param[in] _comm An rcComm_t connection handle to the server. +/// \param[in] _comm An RcComm connection handle to the server. /// \param[in] _dataObjInp \parblock A DataObjInp describing the data object operation. /// - \p objPath: The logical path of the target data object. /// - \p condInput: A list of options that influence the results of the operation. -/// - \p REPL_NUM_KW - The replica number of the copy to upload. -/// - \p GET_RESOURCE_INFO_FOR_OPERATION_KW - The operation of interest. The following values are supported: -/// - "CREATE" -/// - "WRITE" -/// - "OPEN" -/// - "UNLINK" -/// - \p RESC_NAME_KW - Resource name hint. Given the name of a root resource, influences voting to select the appropriate replica. -/// - \p RESC_HIER_STR_KW - Resource hierarchy hint. Given a hierarchy string, specifies the desired replica. +/// - \p GET_RESOURCE_INFO_FOR_OPERATION_KW: The operation of interest. This option is required. The following +/// values are supported: +/// - \p "CREATE" +/// - \p "WRITE" +/// - \p "OPEN" +/// - \p "UNLINK" +/// - \p RESC_NAME_KW: Resource name hint. Given the name of a root resource, influences voting to select the +/// appropriate replica. +/// - \p RESC_HIER_STR_KW: Resource hierarchy hint. Given a hierarchy string, specifies the desired replica. +/// - \p REPL_NUM_KW: Replica number hint. Given a replica number, specifies the desired replica. /// \endparblock -/// \param[out] _out_info \parblock a JSON string with keys "host" and "resource_hierarchy", identifying target server and supplying a -/// resource hierarchy string denoting a specific data object replica for the logical path given as input. -/// \endparblock -/// -/// \b Example _out_info: +/// \param[out] _out_info \parblock a JSON string with keys \p "host" and \p "resource_hierarchy", identifying target +/// server and supplying a resource hierarchy string denoting a specific data object replica for +/// the logical path given as input. /// +/// On success, \p _out_info will have the following structure: /// \code{.js} /// { -/// "host": , -/// "resource_hierarchy": +/// "host": string, +/// "resource_hierarchy": string /// } /// \endcode +/// \endparblock /// -/// \b Example usage: -/// +/// \b Example /// \code{.cpp} +/// RcComm* comm = // Our iRODS connection handle. +/// /// DataObjInp inp; /// memset(&inp, 0, sizeof(DataObjInp)); +/// +/// // Set the full logical path to the data object of interest. +/// // The data object may or may not exist depending on what the client is +/// // attempting to do. /// strncpy(inp.objPath, "/tempZone/home/rods/data_object", MAX_NAME_LEN); -/// char* char_buffer = 0; -/// addKeyVal(&input.condInput, "GET_RESOURCE_INFO_OP_TYPE_KW", "CREATE"); -/// addKeyVal(&input.condInput, "RESC_NAME_KW", "my_root_resource"); -/// const int ec = rc_get_resource_info_for_operation(&comm, &inp, &char_buffer); -/// if (ec < 0 || NULL == char_buffer) { +/// +/// // Set the operation type for resource hierarchy resolution. This is required. +/// // This influences how voting is carried out. +/// addKeyVal(&inp.condInput, GET_RESOURCE_INFO_OP_TYPE_KW, "CREATE"); +/// +/// // A pointer that will point to a heap-allocated buffer holding the JSON +/// // string if the API call succeeds. +/// char* char_buffer = NULL; +/// +/// const int ec = rc_get_resource_info_for_operation(comm, &inp, &char_buffer); +/// if (ec < 0) { /// // Handle error. /// } -/// // Here, we can parse and use the JSON-formatted _out_info parameter value contained in char_buffer. +/// +/// // Here, we can parse and use the JSON-formatted string contained in char_buffer. +/// +/// // Free the buffer when we're done. /// free(char_buffer); /// \endcode /// -/// \return integer -/// \retval 0 on success. +/// \return An integer. +/// \retval 0 On success. +/// \retval <0 On failure. /// /// \since 4.3.1 int rc_get_resource_info_for_operation(struct RcComm* _comm, const struct DataObjInp* _dataObjInp, char** _out_info); + #ifdef __cplusplus } // extern "C" #endif diff --git a/server/api/include/irods/rs_get_resource_info_for_operation.hpp b/server/api/include/irods/rs_get_resource_info_for_operation.hpp index a82f841e95..399e2ace8e 100644 --- a/server/api/include/irods/rs_get_resource_info_for_operation.hpp +++ b/server/api/include/irods/rs_get_resource_info_for_operation.hpp @@ -1,5 +1,6 @@ #ifndef IRODS_RS_GET_RESOURCE_INFO_FOR_OPERATION_HPP #define IRODS_RS_GET_RESOURCE_INFO_FOR_OPERATION_HPP + /// \file #include "irods/dataObjInpOut.h" @@ -8,36 +9,70 @@ struct RsComm; /// Get preferred-resource information for the specified operation. /// -/// \param[in] _rsComm An rsComm_t connection handle to the server. +/// \param[in] _comm An RsComm connection handle to the server. /// \param[in] _dataObjInp \parblock A DataObjInp describing the data object operation. /// - \p objPath: The logical path of the target data object. /// - \p condInput: A list of options that influence the results of the operation. -/// - \p REPL_NUM_KW - The replica number of the copy to upload. -/// - \p GET_RESOURCE_INFO_FOR_OPERATION_KW - The operation of interest. The following values are supported: -/// - "CREATE" -/// - "WRITE" -/// - "OPEN" -/// - "UNLINK" -/// - \p RESC_NAME_KW - Resource name hint. Given the name of a root resource, influences voting to select the appropriate replica. -/// - \p RESC_HIER_STR_KW - Resource hierarchy hint. Given a hierarchy string, specifies the desired replica. -/// \endparblock -/// \param[out] _out_info \parblock a JSON string with keys "host" and "resource_hierarchy", identifying target server and supplying a -/// resource hierarchy string denoting a specific data object replica for the logical path given as input. +/// - \p GET_RESOURCE_INFO_FOR_OPERATION_KW: The operation of interest. This option is required. The following +/// values are supported: +/// - \p "CREATE" +/// - \p "WRITE" +/// - \p "OPEN" +/// - \p "UNLINK" +/// - \p RESC_NAME_KW: Resource name hint. Given the name of a root resource, influences voting to select the +/// appropriate replica. +/// - \p RESC_HIER_STR_KW: Resource hierarchy hint. Given a hierarchy string, specifies the desired replica. +/// - \p REPL_NUM_KW: Replica number hint. Given a replica number, specifies the desired replica. /// \endparblock +/// \param[out] _out_info \parblock a JSON string with keys \p "host" and \p "resource_hierarchy", identifying target +/// server and supplying a resource hierarchy string denoting a specific data object replica for +/// the logical path given as input. /// -/// \b Example _out_info: -/// +/// On success, \p _out_info will have the following structure: /// \code{.js} /// { -/// "host": , -/// "resource_hierarchy": +/// "host": string, +/// "resource_hierarchy": string +/// } +/// \endcode +/// \endparblock +/// +/// \b Example +/// \code{.cpp} +/// RsComm* comm = // Our iRODS connection handle. +/// +/// DataObjInp inp; +/// memset(&inp, 0, sizeof(DataObjInp)); +/// +/// // Set the full logical path to the data object of interest. +/// // The data object may or may not exist depending on what the client is +/// // attempting to do. +/// strncpy(inp.objPath, "/tempZone/home/rods/data_object", MAX_NAME_LEN); +/// +/// // Set the operation type for resource hierarchy resolution. This is required. +/// // This influences how voting is carried out. +/// addKeyVal(&inp.condInput, GET_RESOURCE_INFO_OP_TYPE_KW, "CREATE"); +/// +/// // A pointer that will point to a heap-allocated buffer holding the JSON +/// // string if the API call succeeds. +/// char* char_buffer = NULL; +/// +/// const int ec = rs_get_resource_info_for_operation(comm, &inp, &char_buffer); +/// if (ec < 0) { +/// // Handle error. /// } +/// +/// // Here, we can parse and use the JSON-formatted string contained in char_buffer. +/// +/// // Free the buffer when we're done. +/// free(char_buffer); /// \endcode /// -/// \return integer -/// \retval 0 on success. +/// \return An integer. +/// \retval 0 On success. +/// \retval <0 On failure. /// /// \since 4.3.1 -int rs_get_resource_info_for_operation(RsComm* _rsComm, DataObjInp* _dataObjInp, char** _out_info); +int rs_get_resource_info_for_operation(RsComm* _comm, DataObjInp* _dataObjInp, char** _out_info); #endif // IRODS_RS_GET_RESOURCE_INFO_FOR_OPERATION_HPP diff --git a/server/api/src/rs_get_resource_info_for_operation.cpp b/server/api/src/rs_get_resource_info_for_operation.cpp index da830d2a03..bcec456f8c 100644 --- a/server/api/src/rs_get_resource_info_for_operation.cpp +++ b/server/api/src/rs_get_resource_info_for_operation.cpp @@ -1,34 +1,39 @@ -#include "irods/get_resource_info_for_operation.h" +#include "irods/rs_get_resource_info_for_operation.hpp" #include "irods/getRemoteZoneResc.h" +#include "irods/get_resource_info_for_operation.h" +#include "irods/irods_error.hpp" #include "irods/irods_logger.hpp" #include "irods/irods_resource_backport.hpp" #include "irods/irods_resource_redirect.hpp" +#include "irods/rcMisc.h" +#include "irods/rodsConnect.h" #include "irods/rodsError.h" +#include "irods/rodsErrorTable.h" -#include #include +#include +#include #include #include // for strdup #include -namespace +int rs_get_resource_info_for_operation(RsComm* _comm, DataObjInp* _dataObjInp, char** _out_info) { using log_api = irods::experimental::log::api; -} // anonymous namespace -int rs_get_resource_info_for_operation(rsComm_t* _rsComm, dataObjInp_t* _dataObjInp, char** _out_info) -{ - using log_api = irods::experimental::log::api; - if (_rsComm == nullptr || _dataObjInp == nullptr || _out_info == nullptr) { + if (nullptr == _comm || nullptr == _dataObjInp || nullptr == _out_info) { log_api::error("{}:{} Invalid input. Received one or more null pointers.", __func__, __LINE__); return SYS_NULL_INPUT; } + + *_out_info = nullptr; + rodsServerHost_t* rodsServerHost = nullptr; - const int remoteFlag = getAndConnRemoteZone(_rsComm, _dataObjInp, &rodsServerHost, REMOTE_OPEN); + const int remoteFlag = getAndConnRemoteZone(_comm, _dataObjInp, &rodsServerHost, REMOTE_OPEN); if (remoteFlag < 0) { - log_api::error("{}: getAndConnRemoteZone returned error: {}", __func__, remoteFlag); + log_api::error("{}: getAndConnRemoteZone returned error: [{}]", __func__, remoteFlag); return remoteFlag; } @@ -37,39 +42,37 @@ int rs_get_resource_info_for_operation(rsComm_t* _rsComm, dataObjInp_t* _dataObj } const char* op_type = getValByKey(&_dataObjInp->condInput, GET_RESOURCE_INFO_OP_TYPE_KW); - if (op_type == nullptr) { + if (nullptr == op_type) { constexpr auto ec = SYS_INVALID_INPUT_PARAM; - const auto message{ - fmt::format("{}:{} GET_RESOURCE_INFO_OP_TYPE_KW must be set to a valid operation.", __func__, __LINE__)}; + const auto message{fmt::format( + "{}: GET_RESOURCE_INFO_OP_TYPE_KW must be set to a valid operation. Received a null pointer.", __func__)}; log_api::error(message); - addRErrorMsg(&_rsComm->rError, ec, message.c_str()); + addRErrorMsg(&_comm->rError, ec, message.c_str()); return ec; } const std::array allowed_ops{ - irods::CREATE_OPERATION, irods::WRITE_OPERATION, irods::UNLINK_OPERATION, irods::OPEN_OPERATION}; + irods::CREATE_OPERATION, irods::OPEN_OPERATION, irods::WRITE_OPERATION, irods::UNLINK_OPERATION}; + // NOLINTNEXTLINE(readability-qualified-auto) const auto found_operation = std::find(allowed_ops.begin(), allowed_ops.end(), op_type); if (allowed_ops.end() == found_operation) { constexpr auto ec = INVALID_OPERATION; - const auto message{ - fmt::format("{}:{} GET_RESOURCE_INFO_OP_TYPE_KW must be set to a valid operation. Received instead: {}", - __func__, - __LINE__, - *found_operation)}; + const auto message{fmt::format( + "{}: GET_RESOURCE_INFO_OP_TYPE_KW must be set to a valid operation. Received [{}].", __func__, op_type)}; log_api::error(message); - addRErrorMsg(&_rsComm->rError, ec, message.c_str()); + addRErrorMsg(&_comm->rError, ec, message.c_str()); return ec; } std::string hier; - if (const char* hier_cstr = getValByKey(&_dataObjInp->condInput, RESC_HIER_STR_KW); hier_cstr == nullptr) { + if (const char* hier_cstr = getValByKey(&_dataObjInp->condInput, RESC_HIER_STR_KW); nullptr == hier_cstr) { try { - auto result = irods::resolve_resource_hierarchy(*found_operation, _rsComm, *_dataObjInp); + auto result = irods::resolve_resource_hierarchy(*found_operation, _comm, *_dataObjInp); hier = std::get(result); } catch (const irods::exception& e) { - log_api::error(e.what()); - return e.code(); + log_api::error(e.client_display_what()); + return static_cast(e.code()); } - } // if keyword + } else { hier = hier_cstr; } @@ -77,9 +80,9 @@ int rs_get_resource_info_for_operation(rsComm_t* _rsComm, dataObjInp_t* _dataObj // extract the host location from the resource hierarchy irods::error ret = irods::get_loc_for_hier_string(hier, location); if (!ret.ok()) { - auto error = PASSMSG(fmt::format("{} - failed in get_loc_for_hier_string", __func__), ret); + auto error = PASSMSG(fmt::format("{} - failed in get_loc_for_hier_string.", __func__), ret); log_api::error(error.result()); - return ret.code(); + return static_cast(ret.code()); } nlohmann::json resc_info; @@ -87,4 +90,4 @@ int rs_get_resource_info_for_operation(rsComm_t* _rsComm, dataObjInp_t* _dataObj resc_info["resource_hierarchy"] = hier; *_out_info = strdup(resc_info.dump().c_str()); return 0; -} +} // rs_get_resource_info_for_operation