The lifecycle monitor

The callback methods we just saw are pretty nice, but they're not very reusable. Imagine you wanted to use the same preCreate and postCreate methods in several Grid Services. The only way to do this would be to make a base class with those two common methods, and have all your Grid Services extend that class. Of course, this is a very strong restriction, since our Grid Service might already extend from an existing class (as we saw in the Operation Providers section).

The solution to this in GT3 is the lifecycle monitor. A lifecycle monitor is a class that implements ServiceLifecycleMonitor, an interface with callback methods that are called at specific points in a Grid Service's lifetime. We won't need to extend from this class, or even reference it directly from our code. We'll just add a line to our deployment descriptor saying that we want a certain lifecycle monitor to be called when those special events happen. Of course, we can use the same lifecycle monitor in different Grid Services (including it in their deployment descriptors).

The following would be a very basic lifecycle monitor class, which simply writes messages to a log:

package org.globus.progtutorial.services.core.lifecycle.impl;

import org.globus.ogsa.GridServiceException;
import org.globus.ogsa.ServiceLifecycleMonitor;
import org.globus.ogsa.GridContext;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class MathLifecycleMonitor implements ServiceLifecycleMonitor
{
  // Create this class's logger
  static Log logger = LogFactory.getLog(MathLifecycleMonitor.class.getName());

  public void create(GridContext context) throws GridServiceException
  {
    logger.info("Instance is going to be created (create)");
  }

  public void destroy(GridContext context) throws GridServiceException
  {
    logger.info("Instance is going to be destroyed (destroy)");
  }

  public void preCall(GridContext context) throws GridServiceException
  {
    logger.info("Service is going to be invoked (preCall)");
  }

  public void postCall(GridContext context) throws GridServiceException
  {
    logger.info("Service invocation has finished  (postCall)");
  }

  public void preSerializationCall(GridContext context)
  {
    logger.info("Input parameters are going to be deserialized (preSerializationCall)");
  }

  public void postSerializationCall(GridContext context)
  {
    logger.info("Input parameters have been deserialized (postSerializationCall)");
  }
}
[Note]

This file is $TUTORIAL_DIR/org/globus/progtutorial/services/core/lifecycle/impl/MathLifecycleMonitor.java

To make sure the log messages are printed out, you need to add the following line to the $GLOBUS_LOCATION/ogsilogging.properties file:

org.globus.progtutorial.services.core.lifecycle.impl.MathLifecycleMonitor=console,info

To tell the Grid Services container that you want it to use this lifecycle monitor, you need to add the following parameter to the deployment descriptor:

<parameter name="lifecycleMonitorClass"
  value="org.globus.progtutorial.services.core.lifecycle.impl.MathLifecycleMonitor"/>

To try this out, just recompile and redeploy the Grid Service just as we did in the previous page. If you create an instance, access it with the MathService client, and destroy the instance, you should see the following in the server-side logs: (logs produced by the lifecycle monitor are highlighted in bold)

INFO: Instance is going to be created (preCreate)
INFO: Instance has been created (postCreate)
INFO: Instance is going to be created (create)

INFO: Input parameters are going to be deserialized (preSerializationCall)
INFO: Service is going to be invoked (preCall)
INFO: Addition invoked with parameter a=5
INFO: Service invocation has finished  (postCall)
INFO: Input parameters have been deserialized (postSerializationCall)

INFO: Input parameters are going to be deserialized (preSerializationCall)
INFO: Service is going to be invoked (preCall)
INFO: getValue() invoked
INFO: Service invocation has finished  (postCall)
INFO: Input parameters have been deserialized (postSerializationCall)

INFO: Input parameters are going to be deserialized (preSerializationCall)
INFO: Service is going to be invoked (preCall)
INFO: Instance is going to be destroyed (preDestroy)
INFO: Instance is going to be destroyed (destroy)
INFO: Service invocation has finished  (postCall)
INFO: Input parameters have been deserialized (postSerializationCall)