Skip to content

Commit

Permalink
[irods#7552] Add serialize functionality for ExecMyRuleInp
Browse files Browse the repository at this point in the history
  • Loading branch information
FifthPotato authored and korydraughn committed Apr 19, 2024
1 parent 5e5057b commit b192e00
Show file tree
Hide file tree
Showing 2 changed files with 155 additions and 1 deletion.
56 changes: 56 additions & 0 deletions scripts/irods/test/test_dynamic_peps.py
Original file line number Diff line number Diff line change
Expand Up @@ -492,3 +492,59 @@ def test_if_Genquery2Input_is_exposed__issue_7570(self):
self.user.run_icommand(['imeta', 'rm', '-C', self.user.session_collection, f'{avu_prefix}_1', self.user.zone_name])
self.user.run_icommand(['imeta', 'rm', '-C', self.user.session_collection, f'{avu_prefix}_2', '0'])
self.user.run_icommand(['imeta', 'rm', '-C', self.user.session_collection, f'{avu_prefix}_3', '0'])

@unittest.skipIf(plugin_name != 'irods_rule_engine_plugin-irods_rule_language' or test.settings.RUN_IN_TOPOLOGY, "Requires NREP and single node zone.")
def test_if_ExecMyRuleInp_is_exposed__issue_7552(self):
with temporary_core_file() as core:
avu_prefix = 'test_if_ExecMyRuleInp_is_exposed__issue_7552'

# Add a rule to core.re which when triggered will add AVUs to the user's
# session collection.
core.add_rule(dedent('''
pep_api_exec_my_rule_pre(*INSTANCE, *COMM, *STRUCTINP, *OUT) {{
*v = *STRUCTINP.inpParamArray_0_inOutStruct;
msiModAVUMetadata('-C', '{self.user.session_collection}', 'add', '{avu_prefix}_0', *v, '');
*v = *STRUCTINP.inpParamArray_0_label;
msiModAVUMetadata('-C', '{self.user.session_collection}', 'add', '{avu_prefix}_1', *v, '');
*v = *STRUCTINP.inpParamArray_0_type;
msiModAVUMetadata('-C', '{self.user.session_collection}', 'add', '{avu_prefix}_2', *v, '');
*v = *STRUCTINP.inpParamArray_len;
msiModAVUMetadata('-C', '{self.user.session_collection}', 'add', '{avu_prefix}_3', *v, '');
*v = *STRUCTINP.inpParamArray_oprType;
msiModAVUMetadata('-C', '{self.user.session_collection}', 'add', '{avu_prefix}_4', *v, '');
*v = *STRUCTINP.myRule;
msiModAVUMetadata('-C', '{self.user.session_collection}', 'add', '{avu_prefix}_5', *v, '');
*v = *STRUCTINP.outParamDesc;
msiModAVUMetadata('-C', '{self.user.session_collection}', 'add', '{avu_prefix}_6', *v, '');
}}
'''.format(**locals())))

try:
# Should trigger PEP
self.user.assert_icommand(['irule', "*C=*A++*B", "*A=potato%*B=tomato", "*C="])

self.user.assert_icommand(['imeta', 'ls', '-C', self.user.session_collection], 'STDOUT', [
f'attribute: {avu_prefix}_0\nvalue: potato\n',
f'attribute: {avu_prefix}_1\nvalue: *A\n',
f'attribute: {avu_prefix}_2\nvalue: STR_PI\n',
f'attribute: {avu_prefix}_3\nvalue: 2\n',
f'attribute: {avu_prefix}_4\nvalue: 0\n',
f'attribute: {avu_prefix}_5\nvalue: @external rule {{ *C=*A++*B }}\n',
f'attribute: {avu_prefix}_6\nvalue: *C=\n',
])

finally:
# Remove the AVUs
self.user.run_icommand(['imeta', 'rm', '-C', self.user.session_collection, f'{avu_prefix}_0', "potato"])
self.user.run_icommand(['imeta', 'rm', '-C', self.user.session_collection, f'{avu_prefix}_1', "*A"])
self.user.run_icommand(['imeta', 'rm', '-C', self.user.session_collection, f'{avu_prefix}_2', "STR_PI"])
self.user.run_icommand(['imeta', 'rm', '-C', self.user.session_collection, f'{avu_prefix}_3', "2"])
self.user.run_icommand(['imeta', 'rm', '-C', self.user.session_collection, f'{avu_prefix}_4', "0"])
self.user.run_icommand(['imeta', 'rm', '-C', self.user.session_collection, f'{avu_prefix}_5', "@external rule {{ *C=*A++*B }}"])
self.user.run_icommand(['imeta', 'rm', '-C', self.user.session_collection, f'{avu_prefix}_6', "*C="])
100 changes: 99 additions & 1 deletion server/re/src/irods_re_serialization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include "irods/irods_logger.hpp"
#include "irods/irods_plugin_context.hpp"
#include "irods/msParam.h"
#include "irods/rodsErrorTable.h"

#include <boost/lexical_cast.hpp>
Expand Down Expand Up @@ -1199,6 +1200,102 @@ namespace irods::re_serialization
}
} // serialize_vector_of_strings_ptr

static irods::error serialize_execMyRuleInp_ptr(boost::any _p, serialized_parameter_t& _out)
{
try {
log_re::trace(__func__);
const auto* casted_ptr = boost::any_cast<execMyRuleInp_t*>(_p);
if (!casted_ptr) {
_out["execMyRuleInp_ptr"] = "nullptr";
return SUCCESS();
}
_out["myRule"] = casted_ptr->myRule;
_out["addr_hostAddr"] = casted_ptr->addr.hostAddr;
_out["addr_zoneName"] = casted_ptr->addr.zoneName;
_out["addr_portNum"] = boost::lexical_cast<std::string>(casted_ptr->addr.portNum);
_out["addr_dummyInt"] = boost::lexical_cast<std::string>(casted_ptr->addr.dummyInt);
serialize_keyValPair(casted_ptr->condInput, _out);
_out["outParamDesc"] = casted_ptr->outParamDesc;

const auto* msparamarray_ptr = casted_ptr->inpParamArray;
if (!msparamarray_ptr) {
_out["inpParamArray"] = "nullptr";
return SUCCESS();
}
_out["inpParamArray_len"] = boost::lexical_cast<std::string>(msparamarray_ptr->len);
_out["inpParamArray_oprType"] = boost::lexical_cast<std::string>(msparamarray_ptr->oprType);
for (int i = 0; i < msparamarray_ptr->len; i++) {
std::string prefix = fmt::format("inpParamArray_{}_", i);
const auto* lbl = msparamarray_ptr->msParam[i]->label;
const auto* typ = msparamarray_ptr->msParam[i]->type;
_out[prefix + "label"] = lbl ? lbl : "nullptr";
_out[prefix + "type"] = typ ? typ : "nullptr";
const auto* msparam_ptr = msparamarray_ptr->msParam[i];

if (msparam_ptr == nullptr || msparam_ptr->inOutStruct == nullptr || !typ) {
_out[prefix + "inOutStruct"] = "nullptr";
}
else if (strcmp(msparam_ptr->type, STR_MS_T) == 0) {
_out[prefix + "inOutStruct"] = static_cast<char*>(msparam_ptr->inOutStruct);
}
else if (strcmp(msparam_ptr->type, INT_MS_T) == 0) {
_out[prefix + "inOutStruct"] = std::to_string(parseMspForPosInt(const_cast<MsParam*>(msparam_ptr)));
}
else if (strcmp(msparam_ptr->type, DOUBLE_MS_T) == 0) {
double out = 0.0;
if (parseMspForDouble(const_cast<MsParam*>(msparam_ptr), &out)) {
THROW(SYS_INVALID_INPUT_PARAM, "Failed to convert microservice argument to float.");
}
_out[prefix + "inOutStruct"] = std::to_string(out);
}
else if (strcmp(msparam_ptr->type, FLOAT_MS_T) == 0) {
float out = 0.0;
if (parseMspForFloat(const_cast<MsParam*>(msparam_ptr), &out)) {
THROW(SYS_INVALID_INPUT_PARAM, "Failed to convert microservice argument to float.");
}
_out[prefix + "inOutStruct"] = std::to_string(out);
}
else {
_out[prefix + "inOutStruct"] = fmt::format("unrepresentable_type_{}", msparam_ptr->type);
}
const auto* ptr = msparamarray_ptr->msParam[i]->inpOutBuf;
if (ptr) {
_out[prefix + "inpOutBuf_len"] = boost::lexical_cast<std::string>(ptr->len);
std::string& str = _out[prefix + "inpOutBuf_buf"];

for (int j = 0; j < ptr->len; j++) {
unsigned char c = *(static_cast<unsigned char*>(ptr->buf) + j);

if (isprint(c) || isspace(c) || isblank(c)) {
str += c;
}
else {
str += fmt::format("\\x{0:02x}", c);
}
}
}
else {
_out[prefix + "null_value"] = "null_value";
}
}
return SUCCESS();
}
catch (const boost::bad_any_cast& e) {
return ERROR(INVALID_ANY_CAST,
fmt::format("{}: failed to cast pointer to [execMyRuleInp_t*]: {}", __func__, e.what()));
}
catch (const irods::exception& e) {
return ERROR(
e.code(),
fmt::format(
"{}: failed to cast pointer to [execMyRuleInp_t*]: {}, ec: {}", __func__, e.what(), e.code()));
}
catch (const std::exception& e) {
return ERROR(
SYS_LIBRARY_ERROR, fmt::format("{}: failed to serialize [execMyRuleInp_t*]: {}", __func__, e.what()));
}
} // serialize_execMyRuleInp_ptr

#if 0
static error serialize_XXXX_ptr(
boost::any _p,
Expand Down Expand Up @@ -1255,7 +1352,8 @@ namespace irods::re_serialization
{std::type_index(typeid(bytesBuf_t*)), serialize_bytesBuf_ptr},
{std::type_index(typeid(Genquery2Input*)), serialize_Genquery2Input_ptr},
{std::type_index(typeid(const std::vector<std::string>*)), serialize_const_vector_of_strings_ptr},
{std::type_index(typeid(std::vector<std::string>*)), serialize_vector_of_strings_ptr}};
{std::type_index(typeid(std::vector<std::string>*)), serialize_vector_of_strings_ptr},
{std::type_index(typeid(execMyRuleInp_t*)), serialize_execMyRuleInp_ptr}};
return the_map;

} // get_serialization_map
Expand Down

0 comments on commit b192e00

Please sign in to comment.