Skip to content

Commit

Permalink
[ 7577] Add msi_replica_truncate
Browse files Browse the repository at this point in the history
  • Loading branch information
alanking committed Apr 9, 2024
1 parent 379361d commit 91e4126
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 21 deletions.
1 change: 1 addition & 0 deletions doxygen/microservices.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
- #msiCheckPermission - Check if a data object permission is the same as the one given
- #msiCheckOwner - Check if the user is the owner of the data object
- #msiSetReplComment - Sets the data_comments attribute of a data object
- #msi_replica_truncate - Truncate a replica to the desired size
\subsection msicollection Collection Microservices
- #msiCollCreate - Create a collection
Expand Down
1 change: 1 addition & 0 deletions server/re/include/irods/reAction.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ namespace irods
table_[ "msiDataObjPhymv" ] = new irods::ms_table_entry( "msiDataObjPhymv", 6, std::function<int(msParam_t*,msParam_t*,msParam_t*,msParam_t*,msParam_t*,msParam_t*,ruleExecInfo_t*)>( msiDataObjPhymv ) );
table_[ "msiDataObjRename" ] = new irods::ms_table_entry( "msiDataObjRename", 4, std::function<int(msParam_t*,msParam_t*,msParam_t*,msParam_t*,ruleExecInfo_t*)>( msiDataObjRename ) );
table_[ "msiDataObjTrim" ] = new irods::ms_table_entry( "msiDataObjTrim", 6, std::function<int(msParam_t*,msParam_t*,msParam_t*,msParam_t*,msParam_t*,msParam_t*,ruleExecInfo_t*)>( msiDataObjTrim ) );
table_[ "msi_replica_truncate" ] = new irods::ms_table_entry( "msi_replica_truncate", 2, std::function<int(msParam_t*,msParam_t*,ruleExecInfo_t*)>( msi_replica_truncate ) );
table_[ "msiCollCreate" ] = new irods::ms_table_entry( "msiCollCreate", 3, std::function<int(msParam_t*,msParam_t*,msParam_t*,ruleExecInfo_t*)>( msiCollCreate ) );
table_[ "msiRmColl" ] = new irods::ms_table_entry( "msiRmColl", 3, std::function<int(msParam_t*,msParam_t*,msParam_t*,ruleExecInfo_t*)>( msiRmColl ) );
table_[ "msiCollRepl" ] = new irods::ms_table_entry( "msiCollRepl", 3, std::function<int(msParam_t*,msParam_t*,msParam_t*,ruleExecInfo_t*)>( msiCollRepl ) );
Expand Down
2 changes: 2 additions & 0 deletions server/re/include/irods/reDataObjOpr.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,4 +96,6 @@ msiCollRsync( msParam_t *inpParam1, msParam_t *inpParam2,
int
_rsCollRsync( rsComm_t *rsComm, dataObjInp_t *dataObjInp,
char *srcColl, char *destColl );

auto msi_replica_truncate(MsParam* _inp, MsParam* _out, RuleExecInfo* _rei) -> int;
#endif /* RE_DATA_OBJ_OPR_H */
153 changes: 132 additions & 21 deletions server/re/src/reDataObjOpr.cpp
Original file line number Diff line number Diff line change
@@ -1,41 +1,43 @@
/// \file

#include "irods/reDataObjOpr.hpp"

#include "irods/apiHeaderAll.h"
#include "irods/rsApiHandler.hpp"
#include "irods/collection.hpp"
#include "irods/rsDataObjCreate.hpp"
#include "irods/rsDataObjOpen.hpp"
#include "irods/irods_at_scope_exit.hpp"
#include "irods/key_value_proxy.hpp"
#include "irods/rsApiHandler.hpp"
#include "irods/rsCloseCollection.hpp"
#include "irods/rsCollCreate.hpp"
#include "irods/rsCollRepl.hpp"
#include "irods/rsDataObjChksum.hpp"
#include "irods/rsDataObjClose.hpp"
#include "irods/rsDataObjRead.hpp"
#include "irods/rsDataObjWrite.hpp"
#include "irods/rsDataObjUnlink.hpp"
#include "irods/rsDataObjRepl.hpp"
#include "irods/rsDataObjCopy.hpp"
#include "irods/rsDataObjChksum.hpp"
#include "irods/rsDataObjCreate.hpp"
#include "irods/rsDataObjLseek.hpp"
#include "irods/rsDataObjOpen.hpp"
#include "irods/rsDataObjPhymv.hpp"
#include "irods/rsDataObjRead.hpp"
#include "irods/rsDataObjRename.hpp"
#include "irods/rsDataObjTrim.hpp"
#include "irods/rsCollCreate.hpp"
#include "irods/rsRmColl.hpp"
#include "irods/rsPhyPathReg.hpp"
#include "irods/rsObjStat.hpp"
#include "irods/rsDataObjRepl.hpp"
#include "irods/rsDataObjRsync.hpp"
#include "irods/rsOpenCollection.hpp"
#include "irods/rsReadCollection.hpp"
#include "irods/rsCloseCollection.hpp"
#include "irods/rsDataObjTrim.hpp"
#include "irods/rsDataObjUnlink.hpp"
#include "irods/rsDataObjWrite.hpp"
#include "irods/rsExecCmd.hpp"
#include "irods/rsCollRepl.hpp"
#include "irods/rsModDataObjMeta.hpp"
#include "irods/rsStructFileExtAndReg.hpp"
#include "irods/rsModDataObjMeta.hpp"
#include "irods/rsObjStat.hpp"
#include "irods/rsOpenCollection.hpp"
#include "irods/rsPhyPathReg.hpp"
#include "irods/rsReadCollection.hpp"
#include "irods/rsRmColl.hpp"
#include "irods/rsStructFileBundle.hpp"
#include "irods/irods_at_scope_exit.hpp"
#include "irods/key_value_proxy.hpp"
#include "irods/rsStructFileExtAndReg.hpp"
#include "irods/rs_replica_truncate.hpp"

#include <boost/regex.hpp>
#include <boost/algorithm/string/regex.hpp>
#include <boost/regex.hpp>

#include <cstring>
#include <string>
Expand Down Expand Up @@ -3266,3 +3268,112 @@ msiTarFileCreate( msParam_t *inpParam1, msParam_t *inpParam2, msParam_t *inpPara
return rei->status;

}

/// Truncate a replica for the specified data object to the specified size.
///
/// \parblock
/// This API selects a replica to truncate according to the rules of POSIX truncate(2). The caller may provide keywords
/// via condInput in order to influence the hierarchy resolution for selecting a replica to truncate.
/// \endparblock
///
/// \param[in] _inp \parblock
/// MsParam of type DataObjInp_MS_T or a STR_MS_T taken as a msKeyValStr. msKeyValStr has the following general form:
/// keyword=[value][++++keyword=[value]]*
///
/// The following keywords are required:
/// - "objPath": The full logical path to the target data object.
/// - "dataSize": The desired size of the replica after truncating.
///
/// The following keywords are valid, but not required:
/// - "replNum": The replica number of the replica to truncate.
/// - "rescName": The name of the resource with the replica to truncate. Must be a root resource.
/// - "defRescName": The default resource to target in the absence of any other inputs or policy.
/// - "irodsAdmin": Flag indicating that the operation is to be performed with elevated privileges. No value
/// required.
/// \endparblock
/// \param[out] _out \parblock
/// MsParam of type STR_MS_T representing a JSON structure with the following form:
/// \code{.js}
/// {
/// // Resource hierarchy of the selected replica for truncate. If an error occurs before hierarchy resolution is
/// // completed, a null value will be here instead of a string.
/// "resource_hierarchy": <string | null>,
/// // Replica number of the selected replica for truncate. If an error occurs before hierarchy resolution is
/// // completed, a null value will be here instead of an integer.
/// "replica_number": <integer | null>,
/// // A string containing any relevant message the server may wish to send to the user (including error messages).
/// // This value will always be a string, even if it is empty.
/// "message": <string>
/// }
/// \endcode
/// The JSON microservices can be used to parse and examine the output. See #msi_json_parse.
/// \endparblock
/// \param[in,out] rei - The RuleExecInfo structure that is automatically handled by the rule engine. The user does not
/// include rei as a parameter in the rule invocation.
///
/// \usage \parblock
/// \code{c}
/// msi_replica_truncate("objPath=/tempZone/home/alice/science.txt++++dataSize=100++++replNum=0", *json_output_string);
/// \endcode
/// \endparblock
///
/// \return An integer representing an iRODS error code, or 0.
/// \retval 0 on success.
/// \retval <0 on failure; an iRODS error code.
///
/// \since 4.3.2
auto msi_replica_truncate(MsParam* _inp, MsParam* _out, RuleExecInfo* _rei) -> int
{
if (nullptr == _rei || nullptr == _rei->rsComm) {
msi_log::error("{}: Input rei or rei->rsComm is nullptr.", __func__);
return SYS_INTERNAL_NULL_INPUT_ERR;
}

RsComm* comm = _rei->rsComm;

DataObjInp data_obj_inp{};
DataObjInp* data_obj_inp_ptr = &data_obj_inp;
const auto clear_kvp = irods::at_scope_exit{[&data_obj_inp] { clearKeyVal(&data_obj_inp.condInput); }};

if (0 == std::strcmp(_inp->type, STR_MS_T)) {
char* bad_keyword_output_string = NULL;
const auto free_bad_keyword_output_string =
irods::at_scope_exit{[&bad_keyword_output_string] { std::free(bad_keyword_output_string); }};

// DATA_SIZE_FLAGS is not a typo.
const auto valid_keywords =
OBJ_PATH_FLAG | DATA_SIZE_FLAGS | REPL_NUM_FLAG | RESC_NAME_FLAG | DEF_RESC_NAME_FLAG | ADMIN_FLAG;
_rei->status = parseMsKeyValStrForDataObjInp(
_inp, data_obj_inp_ptr, OBJ_PATH_KW, valid_keywords, &bad_keyword_output_string);
if (_rei->status < 0 && bad_keyword_output_string) {
const auto msg = fmt::format(
"{}: Input keyword [{}] error. error code: [{}]", __func__, bad_keyword_output_string, _rei->status);
msi_log::error(msg);
addRErrorMsg(&comm->rError, _rei->status, msg.c_str());
return _rei->status;
}
}
else {
_rei->status = parseMspForDataObjInp(_inp, &data_obj_inp, &data_obj_inp_ptr, 0);
}

if (_rei->status < 0) {
const auto msg = fmt::format(
"{}: Error occurred while parsing microservice parameters. error code: [{}]", __func__, _rei->status);
msi_log::error(msg);
addRErrorMsg(&comm->rError, _rei->status, msg.c_str());
return _rei->status;
}

char* output_string = nullptr;
const auto free_output = irods::at_scope_exit{[&output_string] { std::free(output_string); }};
_rei->status = rs_replica_truncate(comm, data_obj_inp_ptr, &output_string);
if (_rei->status < 0) {
const auto msg = fmt::format(
"{}: rs_replica_truncate failed for [{}]. error code: [{}]", __func__, data_obj_inp.objPath, _rei->status);
msi_log::error(msg);
addRErrorMsg(&comm->rError, _rei->status, msg.c_str());
}
fillStrInMsParam(_out, output_string);
return _rei->status;
} // msi_replica_truncate

0 comments on commit 91e4126

Please sign in to comment.