Hi John.
Thanks for your suggestions. I started out using pep_api_data_obj_put_post, and like you pointed out it doesn't cover all the ways a replica can be created. From what I recall, there are on the order of 10 API calls that look like that could create a replica. I wasn't sure, since they aren't documented. That meant that I would have to attach rules to 10 API dynamic PEPs. The database dynamic PEPs seemed more promising. Through experimentation, I found that the two I mentioned above would handle all cases. I'll get over my embarrassment and share a reduced and cleaned up form of the rules that work in iRODS 4.2.8.
pep_database_mod_data_obj_meta_post(*INSTANCE, *CONTEXT, *OUT, *DATA_OBJ_INFO, *REG_PARAM) {
# If the data size was set in the catalog, then the final size of the replica is known
# and the replica is in storage, so we can compute its checksum.
if (errorcode(*REG_PARAM.dataSize) == 0) {
# Don't checksum a replica twice.q
*logicalPath = _ipc_getObjPath(*DATA_OBJ_INFO);
*pathVar = _ipc_mkDataObjSessVar(*logicalPath);
if (
if errorcode(temporaryStorage.'*pathVar') == 0
then temporaryStorage.'*pathVar' != 'HAS CHECKSUM'
else true
) {
_ipc_chksumRepl(*logicalPath, int(*REG_PARAM.replica_number));
}
}
}
pep_database_reg_data_obj_post(*INSTANCE, *CONTEXT, *OUT, *DATA_OBJ_INFO) {
# When a data object is created due to file registration, the size of the file is known.
# Otherwise, the size isn't known yet, and iRODS will report a size of zero. Compute the
# checksum if the size is greater than zero.
if (int(*DATA_OBJ_INFO.data_size) > 0) {
*logicalPath = _ipc_getObjPath(*DATA_OBJ_INFO);
_ipc_chksumRepl(*logicalPath, int(*DATA_OBJ_INFO.replica_number));
*pathVar = _ipc_mkDataObjSessVar(*logicalPath);
temporaryStorage.'*pathVar' = 'HAS CHECKSUM';
}
}
For iRODS 4.2.11, when a file is transferred through streaming (e.g. iput -N0), pep_database_mod_data_obj_meta_post is not called. Maybe this is a bug. The ICAT entry is created, and it's size is updated in two separate SQL statements.
Cheers,
Tony