Developing services
From NorduGrid
Developing services
Contents |
Security
Linux FHS
The Linux Filesystem Hierarchy Standard dictates where files should go
init.d
logrotate.d
cron.d
Signals
Signals are sent from users or the system to your service, the important ones that need to be handled are:
- HUP - when it should reload configurations and reopen files (logs, etc)
- TERM - the nice way of terminating a program, handling this needs to end up with a exit(0) or exit(1)
In C
Minimal program for handling a SIGHUP
#include <signal.h> // signal handling in this header
#include <stdio.h>
void signal_handler(int sig){
switch(sig){
case SIGHUP:
printf("hangup signal catched\n");
break;
}
}
int main(int argc, char** argv){
signal(SIGHUP,signal_handler); /* catch hangup signal */
while(1) sleep(1);
}
In Perl
In Python
In Bash/Sh
Creating a Daemon/Service
New service within HED
HED is the Hosting Environment Daemon and is a container for services. See "The Hosting Environment of the Advanced Resource Connector middleware" for a general description of it. For configuration information and how Message Chain Components (MCCs) work please read "WS-ARC service configuration manual".
At a minimum a HED service must:
- Define a sub-class of RegisteredService
- Implement the process() method - this is the method that is called when the service is invoked
- Provide the factory method get_service which enables HED to create an instance of the service
- Define the PLUGINS_TABLE_NAME array with this service
- Optionally define a RegistrationCollector() method to enable the service to be registered in the information system
The following code is a minimal example of such a service
NewService.h
#include <arc/infosys/RegisteredService.h>
#include <arc/message/Message.h>
#include <arc/XMLNode.h>
#include <string>
namespace NewService {
class NewService: public Arc::RegisteredService {
public:
NewService(Arc::Config *cfg);
virtual Arc::MCC_Status process(Arc::Message &inmsg, Arc::Message &outmsg);
bool RegistrationCollector(Arc::XMLNode &doc);
};
} // namespace NewService
NewService.cpp
#include <arc/message/MessageAttributes.h>
#include <arc/message/PayloadRaw.h>
#include <arc/message/PayloadStream.h>
namespace NewService {
static Arc::Plugin *get_service(Arc::PluginArgument* arg)
{
Arc::ServicePluginArgument* srvarg =
arg?dynamic_cast<Arc::ServicePluginArgument*>(arg):NULL;
if(!srvarg) return NULL;
NewService* s = new NewService((Arc::Config*)(*srvarg));
return s;
}
NewService::NewService(Arc::Config *cfg) : RegisteredService(cfg) {}
Arc::MCC_Status NewService::process(Arc::Message &inmsg, Arc::Message &outmsg) {
return Arc::MCC_Status(Arc::STATUS_OK);
}
bool NewService::RegistrationCollector(Arc::XMLNode &doc) {
Arc::NS isis_ns; isis_ns["isis"] = "http://www.nordugrid.org/schemas/isis/2008/08";
Arc::XMLNode regentry(isis_ns, "RegEntry");
regentry.NewChild("SrcAdv").NewChild("Type") = "org.nordugrid.execution.newservice";
regentry.New(doc);
return true;
}
} // namespace NewService
Arc::PluginDescriptor PLUGINS_TABLE_NAME[] = {
{ "newservice", "HED:SERVICE", 0, &NewService::get_service },
{ NULL, NULL, 0, NULL }
};
The Arc::Config object passed to the constructor contains configuration information for that service. One persistent instance of the service class is created upon HED startup and is used for the lifetime of the HED process. When a client invokes the service, HED calls the process method of the service instance. The inmsg Message in process() contains the XML message sent to the service from the client and in this method the actions should be defined depending on the client requests. outmsg is what is sent back to the client and should be filled appropriately. For working examples of services one can browse the src/services folder of the ARC subversion repository.