Microservice Plugins
September 8-9, 2016
Centers for Disease Control and Prevention
Atlanta, GA
Jason Coposky
@jason_coposky
Interim Executive Director, iRODS Consortium
The iRODS Plugin Architecture
iRODS 4.2 provides 7 plugin interfaces
Anatomy of a Plugin
NOTE: microservices do not require a derived class, the factory can return an instance of ms_table_entry
Follow along in the irods_training repository
The code can be found at:
~/irods_training/advanced/irods_microservice_plugin/src/lib-microservice-example.cpp
Start with the Factory
extern "C" irods::ms_table_entry* plugin_factory() { irods::ms_table_entry* msvc = new irods::ms_table_entry(3); msvc->add_operation< msParam_t*, msParam_t*, msParam_t*, ruleExecInfo_t*>( "msiexample_microservice", std::function<int( msParam_t*, msParam_t*, msParam_t*, ruleExecInfo_t*)>(msiexample_microservice)); return msvc; }
Anatomy of the Plugin Factory
extern "C" irods::ms_table_entry* plugin_factory() { ... return msvc; }
Instantiating a microservice plugin
extern "C"
irods::ms_table_entry* plugin_factory() {
irods::ms_table_entry* msvc = new irods::ms_table_entry(3);
...
return msvc;
}
Wiring a plugin operation
...
msvc->add_operation<
msParam_t*,
msParam_t*,
msParam_t*,
ruleExecInfo_t*>(
"msiexample_microservice",
std::function<int(
msParam_t*,
msParam_t*,
msParam_t*,
ruleExecInfo_t*)>(msiexample_microservice));
...
The microservice definition
int msiexample_microservice( msParam_t* _string_param, msParam_t* _int_param, msParam_t* _double_param, ruleExecInfo_t* _rei ) { char *string_param = parseMspForStr( _string_param ); if( !string_param ) { std::cout << "null _string_param" << std::endl; return SYS_INVALID_INPUT_PARAM; } int int_param = parseMspForPosInt( _int_param ); if( int_param < 0 ) { std::cout << "invalid _int_param" << std::endl; return SYS_INVALID_INPUT_PARAM; } double double_param = 0.0; int ret = parseMspForDouble( _double_param, &double_param ); if( ret < 0 ) { std::cout << "invalid _double_param" << std::endl; return SYS_INVALID_INPUT_PARAM; } std::cout << __FUNCTION__ << " string [" << string_param << "] int [" << int_param << "] double [" << double_param << "]" << std::endl; return 0; }
The signature
int msiexample_microservice( msParam_t* _string_param, msParam_t* _int_param, msParam_t* _double_param, ruleExecInfo_t* _rei ) { ... return 0; }
Parameter parsing and Error Checking
... char *string_param = parseMspForStr( _string_param ); if( !string_param ) { std::cout << "null _string_param" << std::endl; return SYS_INVALID_INPUT_PARAM; } int int_param = parseMspForPosInt( _int_param ); if( int_param < 0 ) { std::cout << "invalid _int_param" << std::endl; return SYS_INVALID_INPUT_PARAM; } double double_param = 0.0; int ret = parseMspForDouble( _double_param, &double_param ); if( ret < 0 ) { std::cout << "invalid _double_param" << std::endl; return SYS_INVALID_INPUT_PARAM; } ....
Highly complex application code
int msiexample_microservice( msParam_t* _string_param, msParam_t* _int_param, msParam_t* _double_param, ruleExecInfo_t* _rei ) { ... std::cout << __FUNCTION__ << " string [" << string_param << "] int [" << int_param << "] double [" << double_param << "]" << std::endl; return 0; }
Many things are possible in a microservice
Building and Installing the Example Code
sudo apt-get -y install irods-externals-*
export PATH=/opt/irods-externals/cmake3.5.2-0/bin:/opt/irods-externals/clang3.8-0/bin:$PATH
which clang++
/opt/irods-externals/clang3.8-0/bin/clang++
which cmake
/opt/irods-externals/cmake3.5.2-0/bin/cmake
sudo apt-get install irods-dev
mkdir ~/build_msvc
cd ~/build_msvc
cmake ~/irods_training/advanced/irods_microservice_plugin
make package
sudo dpkg -i irods-microservice-example-4.2.0-ubuntu14-x86_64.deb
A rule to test the microservice
acPostProcForPut() {
microservice_example("XXXX - test string", 314, 123.4);
if("ufs_cache" == $rescName ) {
writeLine( "serverLog", "XXXX - calling delayed replication" );
delay("<PLUSET>1s</PLUSET><EF>1h DOUBLE UNTIL SUCCESS OR 6 TIMES</EF>") {
*CacheRescName = "comp_resc;ufs_cache";
msisync_to_archive("*CacheRescName", $filePath, $objPath );
}
}
}
Edit the /etc/irods/training.re rulebase
Ensure the iRODS Rule Language plugin is first
Edit /etc/irods/server_config.json
{
"instance_name" : "re-storage-balancing-instance",
"plugin_name" : "re-storage-balancing",
"plugin_specific_configuration" : {}
},
{
"instance_name" : "rule-engine-plugin-python-instance",
"plugin_name" : "rule-engine-plugin-python",
"plugin_specific_configuration" : {}
},
{
"instance_name": "re-irods-instance",
"plugin_name": "re-irods",
Test the microservice
iput VERSION.json
grep -dskip "XXXX -" ./log/*
./log/rodsLog.2016.06.XX:msiexample_microservice string [XXXX - test string] int [314] double [123.4]
Questions?