Creating a noninteractive task - simplified method


NOTE: If you followed through the steps in Creating an extension: details, then you already know how to create classes, folders, and files in Eclipse.

The APIs for creating noninteractive tasks in IBM Director are extensive. There are many methods of programming the server portion of a noninteractive task.

There are two recommended methods. The first is to create a class that implements the TWGTaskServer interface. This is a powerful, and therefore complex interface; it requires the programmer to deal with multi-threading issues and contains several methods that must be implemented.

Starting in IBM Director 5.1, there is a new and simplified method of creating a task server using a new base class called TWGDefaultTaskServer. TWGDefaultTaskServer implements the TWGTaskServer interface for you. To make it work, you will need to override at most 3 TWGDefaultTaskServer methods.

The steps below describe how to create a task server with the simplified method. Note that if you were to use the TWGTaskServer interface, you would use all the same steps except that you would implement a different set of methods in your task server.

Before you create the task server, you need to be aware of the lifecycle of a task server. A default task server works as follows:

  1. The user activates the task. Usually this is done from the IBM Director Console. but there are meny other ways it can happen. For your programming it does not matter; all that matters is that you task has been activated.
  2. The IBM Director Server checks to see if there is already an instance of your task server class. If there is NOT already an instance of your task server, then the IBM Director Server creates one and calls pInit() method.
  3. Your processActivation() method is called with the activation as a parameter.
  4. At this point, if your task is activated again, then the existing instance or your task server will be reused and the only thing that will happen is that your processActivation() method will be called again with a different parameter.
  5. When the IBM Director Server determines that your task server is idle, it will deactivate the task server and call your pCleanUp() method.

Steps to create a noninteractive task

  1. Create the task server class
  2. Create the task properties
  3. Implement methods in the task server
  4. Update the resource bundle
  5. Add code in the extension class to create the task
  6. Deploy and test

Create the Task Server class

The Task Server is your main class for a noninteractive Task. This class runs on inside the IBM Director Server and it allows IBM Director to call your code on the Server when the Task is activated. The idea is that you create a class that extends TWGTaskServer and implement a few key methods. When the user activates the task, The code in the Director Server will create an instance (or reuse an existing instance) of your Task Server and then call your code.

Under the source Directory, create a new class in the com.bobco package. (Right click on the package and select New->Class. Enter the classname, and ensure the class extends com.tivoli.twg.engine.TWGDefaultTaskServer. Later, we will implement the necessary methods in the Task Server. For our example, we will call the class BobCoTaskServer1.

Create the task properties file

Create a new file under the folder deploy/classes/com/bobco make sure the file extension is .properties. For our example, we will call the file BobCoNonInteractiveTask.properties

Again, task properties files can be very complex and powerful but most interactive tasks can be defined simply by using only these properties:

Property How to set the property
TaskID This is a unique ID for the task. to avoid naming collisions with other extensions, the naming convention BobCo|NonInteractive where BobCo representsour extension and the "NonInteractive" part of the string is a unique ID within our extension.
ParentTaskID This is the TaskID that was specified in the Task Properties file for the parent task. In our case: BobCo|Parent
Title This is a key to the task title within the Resource Bundle. in our case: NonInteractiveTaskTitle Wewill add this string to the Resource Bundle later.
ResourceBundle The same resource bundle that has the translated strings for the task. In our case, we have only one Resoruce Bundle for the extension: com.bobco.BobCoResourceBundle
Server This is the string "class:" followed by the name of the Task Server class (the one that implements TWGTaskServer In our case, class:com.bobco.BobCoTaskserver1
Other attributes in the Server line are:
  • auto-load:false - tells the IBM Director server to only load the TaskServer when it's needed. If we had specified auto-load:true then the Task Server would have been activated when the director Server started.
  • sameJVM:true - tells then
Attributes on the Server line are separated with a "|" character.
Icon.Large
Icon.Large.Selected
Icon.Small
Icon.Small.Selected
These are the images to use for the IBM Director Console. To save time, we will reuse the icons from the paranet task. Note that for child tasks, you do not need a toolbar icon.
Subtask.0.ID Internally, IBM Director actually represents a task with a combination of two classes: TWGTask and TWGSubTask. It is possible to create a TWGTask with two TWGSubtasks,but for now, the differences between the two do not matter. All that is important is that we have to fill in a few properties. Subtask.0.ID must be unique within the Task; since we have only one, it does not matter. Set it to InteractiveSubtask
Subtask.0.Context Set this to "interactive:true | server:false | targeted:none"
The "|" characters are separators so in this line, we are specifying three things:
1. Interactive:true -
2. server:false - This means that we do not want tostart any extra code on the IBM Director Server for this Task
3. targeted:none - This means that it is not necessary to select a Managed Object before activating the task.
Subtask.0.Actions Set this to double-click. This means that the user will activate this task by double clicking on the Task icon.

So the final BobCoNonInteractiveTask.properties file will look like this:

# The task identifier uniquely identifies the task 
# from all other tasks.
# Notice the naming  of the TaskId to avoid ID conflicts
# with other extensions.
TaskID = BobCo|NonInteractive
ParentTaskID = BobCo|Parent

# The Title property specifies the title to use on the  
# Console it is a key into the Resource Bundle.
Title = NonInteractiveTaskTitle
ResourceBundle = com.bobco.BobCoResourceBundle

Server = class:com.bobco.BobCoTaskServer1 | auto-load:false | sameJVM:true

# Icons for the IBM Director Console
# 32x32 bit images
Icon.Large              = /com/bobco/images/bobco32.gif
Icon.Large.Selected     = /com/bobco/images/bobco32.gif

# 16x16 bit images
Icon.Small              = /com/bobco/images/bobco16.gif
Icon.Small.Selected     = /com/bobco/images/bobco16.gif

Subtask.0.ID    = NonInteractiveSubtask
Subtask.0.Context = interactive:false | server:true | targeted:none
Subtask.0.Actions = double-click  
Subtask.0.Menu = NonInteractive,150
Subtask.0.MenuLocation = TaskIcon

Override/Implement the Task Frame Methods


To make a basic user interface, you will override/implement these methods:

Method Description
public BobCoTaskFrame() This is the constructor for the Task Frame. Remember, you never actually call
new BobCoTaskFrame();
because the IBM Director Console will do that for you when the user activates the task.
public boolean pInit() This method is called after the constructor. The important thing to know about this method is that if you should return true when the initialization for the Task Server is Complete. You only need to implement this method if you actually have something to do inside in it. If you don't require a place for initialization, then you do not have to override it.
public void processActivation(TWGTaskActivation act) This is is called once for each time the SubTask is activated. The TWGTaskActivation parameter contains information about how the task was activated.
public boolean pCleanUp() This method is called when the Task Server is being deactivated. The Task server will be deactivated when the IBM Director Server is stopped or when the IBM Director Server determines that the Task Server is idle and no longer needed.

Let's looks at the methods one at a time:

The Constructor

The constructor requires no parameters. Here is the code:

/** Constructor. */
public BobCoTaskServer1() {
	if (TWGRas.isTraceEX0)
		TWGRas.debug(TWGRas.EX0, "BobCoTaskServer1 constructor");
}

pInit

This method is called when the Task Server is activated. Be sure to return true after initializing your Task Server.

public boolean pInit() {
	if (TWGRas.isTraceEX0)
		TWGRas.debug(TWGRas.EX0, "BobCoTaskServer1.pInit()");
		// TODO ADD YOUR TASK SERVER'S INITIALIZATION PROCESSING HERE
	return true;
}


processActivation()

This is where you put your code to handle a SubTask being activated. This is where the "action" of your Task goes.

Here's the Code

1  public void processActivation(TWGTaskActivation act) {
2	if (TWGRas.isTraceEX0)
3		TWGRas.debug(TWGRas.EX0,
4				"BobCoTaskServer1.processActivation() processing");
5	// log a message to the activation log
6	act.logMessage("com.bobco.BobCoResourceBundle", "testLogMessage", 0);
7	
8	// TODO ADD YOUR TASK'S FUNCTION HERE
9
10	if (TWGRas.isTraceEX0)
11		TWGRas.debug(TWGRas.EX0,
12				"BobCoTaskServer1.processActivation() done");
13		act.setStatus(TWGTaskConstants.ACT_STATUS_COMPLETE);
14 }	

Looking at the code above, line 1 shows that there is a TWGTaskActivation object that is passed to this method.

For noninteractive tasks, you may want to write a message into the Activation Log. The Activation Log allows the user to see the results of your task. In line 6, there is a sample call to logMessage to write a line to the Activation Log. Note that, since the user will see this message, uses the Resource Bundle (parameter 1) to get the string (identified by parameter 2) for the log. The last parameter is a "level", for now, simply use zero.

When you create a Task in Director, you do it to perform some sort of action. Line number 8 is where you write the code that performs the action.

pCleanUp()

This method give you a chance to do clean up processing when you Task Server is deactivated:

public void pCleanUp() {
	if (TWGRas.isTraceEX0)
		TWGRas.debug(TWGRas.EX0, "BobCoTaskServer1.pCleanUp()");
	// TODO ADD YOUR TASK SERVER'S CLEANUP PROCESSING HERE
}

Adding strings to the Resource Bundle

We referenced somm new strings in the Resource Bundle which we must now create. Edit the BobCoResourceBundle.class file and add the strings for "NonInteractive" and "testLogMessage"

The BobCoResourceBundle.java file will now have additional strings as follows:

public class BobCoResourceBundle extends ListResourceBundle {
.
.
.
			{ "NonInteractive", "BobCo noninteractive  Task" },
			{ "testLogMessage", "Bob Co is processing the noninteractive task."}
}

Add code in the extension class to create the task

All that remains is to put the call to new TWGDefaultTask() in the Extension Class. Edit the BobCoExtension.java file and add this code to the initInstances() method:

	    /* Create the Parent task if it does not already exist*/
	    if ( ! TWGTask.isTaskID( BOB_CO_NONINTERACTIVE_TASK_ID ) ) { 
	      try {
            TWGDefaultTask testTask = 
            	new TWGDefaultTask("com/bobco/BobCoNonInteractiveTask.properties");
	        }
	      catch ( TWGTaskCreationException exception ) { 
	        TWGRas.error( TWGRas.EX0, 
	        		"BobCoExtension.InitClassInstances: exception!", 
					exception );
	        /* Throwing an exception will stop the entire IBM Director Server */
	        throw new TWGExtensionInitException( "unable to create BobCo NonInteractive Task" );
	        }
	      }

Define a constant for BOB_CO_NONINTERACTIVE_TASK_ID:

	public static final String BOB_CO_NONINTERACTIVE_TASK_ID = "BobCo|NonInteractive";

Ensure that the value of this constant matches the TaskID in the task properties file.

Remember that tasks are persistent, so add
if ( ! TWGTask.isTaskID( BOB_CO_NONINTERACTIVE_TASK_ID ) )
to ensure that the task does not already exist before we try to create it. Also, remember to catch the TWGTaskCreationException and log a TWGRas error so that you can debug the problem if you have errors.

Redeploy the extension and test it.

Instructions for redeploying are here .

You should be able to double-click the Bob Co noninteractive Task under your null parent task:

When you double-click the noninteractive task, you will see the scheduler dialog:

Before you click Execute Now, open a command window and run the command raswatch -EX0

Now click Execute Now. In the raswatch output, you should see your debug messages:

You should also see the Window with the task execution history:

Note there are several "Not Applicable" lines, this is because the task does not have a target. We will add targeting later.

Now, if you activate the task again, the raswatch output will look like this:

Note that pInit() was not called because the task server was already active.

Now, if you stop the IBM Director Server, you will see that the task server is deactivated and your pCleanUp() method was called.