Learn more about Platform products at http://www.platform.com



Tutorial 6: Create an EGO Service

This tutorial describes how to create and run an EGO service.

Using this tutorial, you will ...

Underlying principles

The sample uses a separate thread to interact with a service. It creates a service and subscribes to service event notifications, which are sent by the Service Controller whenever there is a change in service state. The thread waits until a notification arrives. It also queries the service whenever these notifications occur.


Step 1: Import class references

Import the necessary classes and interfaces that are required by the client to invoke the Web Service.


Step 2: Retrieve resource information

Refer to Tutorial 1: Step 3: Retrieve resource information.


Step 3: Register the client

The register operation takes three input parameters: client ID (processedArgs[2]), description (processedArgs[3]), and the URL for service notification (processedArgs[4]); this URL, derived from the ProcessArgs() method in sample 2, is an endpoint that implements the EGO notification WSDL interface. Platform EGO will then send service notifications to the client using this endpoint. Refer to Tutorial 2: Step 3: Register the client for general information about the registration process.


Step 4: Locate all clients

Refer to Tutorial 2: Step 4: Locate the client


Step 5: Query all EGO services

Create the QueryServiceRequestDocument (qreqDoc) and QueryServiceRequest (qReq) objects. The QueryServiceRequest object has one member variable, which is the service name. In this case, we set the service name to null in order to get information about all services running on Platform EGO.

The EGO WSDLs and Web Service gateway support Web Service Security (WSSE specification). This means that different types of security information can be passed in the header of SOAP messages sent by the clients. The samples use the simplest form, i.e., username and password authentication. The wrappers generated for Java have signatures that provide for multiple types of security information to be included. In this case, we are using just one security document (logonDoc), which we pass along with qreqDoc to the QueryService method.

The response to a service query request consists of a structure that includes the number of services, service names, descriptions, states, and host names amongst others.

public void queryService(String sname)
	 {
	 	 QueryServiceRequestDocument qreqDoc =
 QueryServiceRequestDocument.Factory.newInstance();
	 	 QueryServiceRequest qReq = qreqDoc.addNewQueryServiceRequest();
	 	 qReq.setServiceName(sname);
	 	 QueryServiceResponseDocument qresDoc;
	 	 QueryServiceResponse qres;
	 	 
	 	 try {
	 	   qresDoc = servicePort.QueryService(qreqDoc, logonDoc);
	 	   qres = qresDoc.getQueryServiceResponse();
	 	   print(qres);
	 	 } catch(RemoteException rex) {
	 	 	 rex.printStackTrace();
	 	 }
	 }


Step 6: Create a service definition

The first step in creating an EGO service is to specify a service definition. Each service is described by a service definition that consists of an XML file containing information about the service such as the type of resources required to run the service instances and how to start and monitor them. The serviceDefinition() method creates an instance of the service definition object. Set all the member variables that make up a service definition. (Service name and description are global string variables that have already been initialized.)

Integral parts of the service definition are the activity and allocation specifications. Define and initialize an activity specification including the setting of its resource limits to default values. The activity specification essentially defines a job that the user wants to be executed. The actSpec.setCommand method specifies the actual binary that should be executed. In the sample, we want the program "sleep" to be executed. The sleep command takes the number of seconds to sleep (for unix) as an input argument.

Create an allocation specification. The allocation specification describes a request to Platform EGO for an allocation of resources. The only required variables for the allocation specification are the consumer name to charge this allocation to, and the resource specification of what is being requested.

ServiceDefinition serviceDefinition()
	 {
	 	 ServiceDefinition sdef = ServiceDefinition.Factory.newInstance();
	 	 sdef.setDescription(serviceDescription);
	 	 sdef.setMaxInstances(2);
	 	 sdef.setMinInstances(1);
	 	 sdef.setServiceName(serviceName);
	 	 sdef.setActivityDescriptionArray(new
 ActivityDescription[]{activityDescription()});
	 	 sdef.setAllocationSpecification(allocationSpecification());
	 	 sdef.setControlPolicy(controlPolicy());
	 	 return sdef;
	 }

	 private ActivityDescription activityDescription()
	 {
	 	 EnvironmentVariable [] env = new EnvironmentVariable [] {};
	 	 Rlimit [] rlimits = new Rlimit[] {};

	 	 ActivityDescription actd = ActivityDescription.Factory.newInstance();
	 	 ActivitySpecification actSpec = actd.addNewActivitySpecification();
	 	 actSpec.setActivityName("Sample6ServiceActivity");
	 	 actSpec.setCommand("/bin/sleep 120");
	 	 actSpec.setEnvironmentVariableArray(env);
	 	 actSpec.setExecutionUser("lsfadmin");
	 	 actSpec.setWorkingDirectory("/tmp");
	 	 actSpec.setUmask("0777");
	 	 actSpec.setRlimitArray(rlimits);
        return actd;
	 }
private AllocationSpecification allocationSpecification()
	 {
	 	 AllocationSpecification alocSpec =
 AllocationSpecification.Factory.newInstance();
	 	 alocSpec.setAllocationName("Sample6ServiceAllocation");
	 	 alocSpec.setConsumerName("SampleApplications/EclipseSamples");
	 	 ResourceSpecification [] resourceSpecs;
	 	 resourceSpecs = createResourceSpecification(1);
	 	 alocSpec.setResourceSpecificationArray(resourceSpecs);
//	 	 alocSpec.setOptionArray(new String[]{"EGO_ALLOC_EXCLUSIVE"});
	 	 return  alocSpec;
	 }


Step 7: Create a Service Controller Client object

Create a ServiceControllerClient object that implements the Runnable interface. The ServiceControllerClient class implements a run() method that enables you to subscribe to service notifications, as well as create and query a service. When this class is instantiated and the run() method is called, a new thread will be spawned. The stop() method will disable and remove the service, and unsubscribe the client to notifications.

The following steps describe the run() and stop() methods of the ServiceControllerClient class in more detail.

public class ServiceControllerClient implements Runnable {
	 private EGOclient egoClient;
	 private boolean finish;
	 public ServiceControllerClient(EGOclient egoClient)
	 {
	 	 this.egoClient = egoClient;
	 }
	 
	 public void run()
	 {
	 	 String id = egoClient.subscribeNotification(egoClient.notificationEndPoint);
	 	 egoClient.createService(egoClient.serviceDefinition());
	 	 
	 	 while(!finish) {
	 	 	 try {
              Notification.notification.wait();
      	 	    ServiceStateChange stateChange =
 Notification.notification.getServiceStateChange();
      	 	    ServiceInstanceStateChange instanceStateChange =
 Notification.notification.getServiceInstanceStateChange();
	 	 	 } catch(InterruptedException ie) {
	 	 	   ie.printStackTrace();
	 	 	 }
	 	 	 egoClient.queryService(egoClient.serviceName);
	 	 }
	 }
	 
	 public void stop()
	 {
	 	 egoClient.controlService(egoClient.serviceName,
 ServiceControlOperation.DISABLE);
	 	 egoClient.removeService(egoClient.serviceName);
	 	 egoClient.unsubscribeNotification(egoClient.subscriptionID);
	 	 
	 	 finish = true;
	 	 this.notify();
	 }
}


Step 8: Subscribe to notifications

In order to receive notifications about service state changes, it is necessary to subscribe to the notification service.

The procedure for issuing a notification subscription request is similar to other requests previously described. Create a subscription request document (nrDoc) and a subscription request object (nr). Set the notification endpoint to tell the Service Controller where to send the notification messages. The notification endpoint is derived from the ProcessArgs() method in Sample 2.

Create a subscription response document (nresDoc), a security document, and a subscription response object (nres). Pass the request and logon documents to the ServiceNotificationSubscribe operation. When the operation is invoked, it returns a subscription ID, which is printed out.

public String subscribeNotification(String endpoint)
	 {
	 	 String id = null;
	 	 ServiceNotificationSubscribeRequestDocument nrDoc =
 ServiceNotificationSubscribeRequestDocument.Factory.newInstance();
	 	 ServiceNotificationSubscribeRequest nr =
 nrDoc.addNewServiceNotificationSubscribeRequest();
	 	 nr.setNotificationEndpoint(endpoint);
	 	 ServiceNotificationSubscribeResponseDocument nresDoc;
	 	 ServiceNotificationSubscribeResponse nres;
	 	 try {
	 	   nresDoc = servicePort.ServiceNotificationSubscribe(nrDoc, logonDoc);
	 	   nres = nresDoc.getServiceNotificationSubscribeResponse();
	 	   print(nres);
	 	   id = nres.getSubscriptionID();
	 	 } catch (RemoteException rex) {
	 	 	 rex.printStackTrace();
	 	 }
	 	 subscriptionID = id;
	 	 return id;
	 }


Step 9: Create and start an EGO service

Pass the service definition object to the createService() method. The createService() method creates a new service object and starts the service based on the service definition provided. Once the service is started, the Service Controller allocates resources and starts service instances.

Create the CreateServiceRequestDocument (sreqDoc) and CreateServiceRequest (sReq) objects. The CreateServiceRequest object has one member variable, which is the service name. In this case, we set the service name to null in order to get information about all services running on Platform EGO.

Pass sreqDoc and the logonDoc security document to the CreateService method and print out the response.

public void createService(ServiceDefinition serviceDef)
	 {
	 	 CreateServiceRequestDocument sreqDoc = 
 CreateServiceRequestDocument.Factory.newInstance();
	 	 CreateServiceRequest sreq = sreqDoc.addNewCreateServiceRequest();
	 	 sreq.setServiceDefinition(serviceDef);
	 	 

	 	 CreateServiceResponseDocument sresDoc;
	 	 CreateServiceResponse sres;
	 	 
        try {
	 	   sresDoc = servicePort.CreateService(sreqDoc, logonDoc);
	 	   sres = sresDoc.getCreateServiceResponse();
	 	   print(sres);
        } catch(RemoteException rex) {
        	 rex.printStackTrace();
        }
	 }


Step 10: Check for service state changes

Once the service has been created and is running, the Service Controller Client thread will pause execution while it waits for service state change notifications from the Service Controller. If either a service state change or a service instance state change occurs, thread execution resumes and retrieves the notification message.

When the state change information is retrieved, the service is queried. Refer to Step 5: Query all EGO services.

	 	 	 try {
              Notification.notification.wait();
      	 	    ServiceStateChange stateChange =
 Notification.notification.getServiceStateChange();
      	 	    ServiceInstanceStateChange instanceStateChange =
 Notification.notification.getServiceInstanceStateChange();
	 	 	 } catch(InterruptedException ie) {
	 	 	   ie.printStackTrace();
}


Step 11: Stop an EGO service

Create the respective documents and objects for the ControlService request and response. Set the service name and control operation for the control service request object. In this case, set the control operation to disable the service. Create the security documents and pass the documents with the logon document and ControlService request document to the ControlService operation. The Service Controller stops all service instances and de-allocates resources.

Remove the service by specifying the service name while invoking the removeService operation. The Service Controller destroys the service object and removes the service definition from the configuration.

public void controlService(String sname, ServiceControlOperation.Enum op)
	 {
	 	 ControlServiceRequestDocument reqDoc =
 ControlServiceRequestDocument.Factory.newInstance();
	 	 ControlServiceRequest req = reqDoc.addNewControlServiceRequest();
	 	 req.setServiceName(sname);
	 	 req.setServiceControlOperation(op);
	 
	 	 ControlServiceResponseDocument resDoc;
	 	 ControlServiceResponse res;

	 	 SecurityDocument sdoc2 = SecurityDocument.Factory.newInstance();
	 	 SecurityHeaderType sec2 = sdoc2.addNewSecurity();
	 	 SecurityDocument sdoc3 = SecurityDocument.Factory.newInstance();
	 	 SecurityHeaderType sec3 = sdoc3.addNewSecurity();
	 	 SecurityDocument sdoc4 = SecurityDocument.Factory.newInstance();
	 	 SecurityHeaderType sec4 = sdoc4.addNewSecurity();
	 	 SecurityDocument sdoc5 = SecurityDocument.Factory.newInstance();
	 	 SecurityHeaderType sec5 = sdoc5.addNewSecurity();
	 	 SecurityDocument sdoc6 = SecurityDocument.Factory.newInstance();
	 	 SecurityHeaderType sec6 = sdoc6.addNewSecurity();
	 	 SecurityDocument sdoc7 = SecurityDocument.Factory.newInstance();
	 	 SecurityHeaderType sec7 = sdoc7.addNewSecurity();
	 	 SecurityDocument sdoc8 = SecurityDocument.Factory.newInstance();
	 	 SecurityHeaderType sec8 = sdoc8.addNewSecurity();
	 	 
	 	 try {
	 	 	 resDoc = servicePort.ControlService(reqDoc, logonDoc, sdoc2, sdoc3, sdoc4,
 sdoc5, sdoc6, sdoc7, sdoc8);
	 	 	 res = resDoc.getControlServiceResponse();
	 	 	 print(res);
	 	 } catch (RemoteException rex) {
	 	 	 rex.printStackTrace();
	 	 }
	 }


Step 12: Unsubscribe to service notifications

Create the respective documents and objects for the ServiceNotificationUnsubscribe request and response. Use the subscription ID previously obtained during the subscription process to unsubscribe to service notifications.

Create the security documents and pass the documents with the logon document and ServiceNotificationUnsubscribe request document to the ServiceNotificationUnsubscribe operation. The Service Controller will no longer communicate service state change notifications to the notification endpoint.

public void unsubscribeNotification(String id)
	 {
	 	 ServiceNotificationUnsubscribeRequestDocument nrDoc =
 ServiceNotificationUnsubscribeRequestDocument.Factory.newInstance();
	 	 ServiceNotificationUnsubscribeRequest nr =
 nrDoc.addNewServiceNotificationUnsubscribeRequest();
	 	 nr.setSubscriptionID(id);
	 	 ServiceNotificationUnsubscribeResponseDocument nresDoc;
	 	 ServiceNotificationUnsubscribeResponse nres;
	 	 SecurityDocument sdoc2 = SecurityDocument.Factory.newInstance();
	 	 SecurityHeaderType sec2 = sdoc2.addNewSecurity();
	 	 SecurityDocument sdoc3 = SecurityDocument.Factory.newInstance();
	 	 SecurityHeaderType sec3 = sdoc3.addNewSecurity();
	 	 SecurityDocument sdoc4 = SecurityDocument.Factory.newInstance();
	 	 SecurityHeaderType sec4 = sdoc4.addNewSecurity();
	 	 try {
	 	   nresDoc = servicePort.ServiceNotificationUnsubscribe(nrDoc, logonDoc, sdoc2,
 sdoc3, sdoc4);
	 	   nres = nresDoc.getServiceNotificationUnsubscribeResponse();
	 	   print(nres);
	 	 } catch (RemoteException rex) {
	 	 	 rex.printStackTrace();
	 	 }
	 }


Run the client application

  1. Select Run > Run.

    The Run dialog appears.

  2. In the Configurations list, either select a Java Application or click New for a new configuration.

    For a new configuration, enter the configuration name.

  3. Enter the project name and Main class.
  4. Click the Arguments tab and enter the following arguments in the given order:
    1. URL of the web service gateway
    2. Port number (string) for the notification interface
    3. Client ID (string)
    4. Client description (string).
      note:   

      Arguments must be separated by a space.

  5. Click Apply and then Run.

Sample Output

[ Top ]


[ Platform Documentation ]


      Date Modified: July 12, 2006
Platform Computing: www.platform.com

Platform Support: support@platform.com
Platform Information Development: doc@platform.com

Copyright © 1994-2006 Platform Computing Corporation. All rights reserved.