Adding targeting to a noninteractive task

Adding targeting to a noninteractive task will be very similar to adding targeting to an interactive task.

Use these steps to add targeting to a noninteractive task:
  1. Change the task properties
  2. Change the task server code to find the targets
  3. Examining the task activation processing code
  4. Add any new translated strings to the resource bundle
  5. Redeploy and test

Change the task properties

Use the following procedure to change task properties:

  1. Tell IBM Director that the task requires a target.

    Edit the task properties file and modify the Subtask.0.Context line. Change it from this:

    Subtask.0.Context = interactive:false | server:true | targeted:none

    to this:

    Subtask.0.Context = interactive:false | server:true | client:ignore | targeted:one
  2. Modify the action. If the task is targeted then having the user double-click to activate the task does not make sense, so you need to allow the user to drag-drop the task onto a managed object. Find the line for Subtask.0.Actions chage it from:

    Subtask.0.Actions = double-click 

    to:

    Subtask.0.Actions =  drag-drop 

    Note that in this case, you are making a task that is only targeted. That is, double-click no longer works, so the user must drag-drop or use the toolbar to activate.

  3. Tell IBM Director something about the targets that are valid for this class. For now, make the task valid for all managed objects. The Client.0.Class property will describe the Java classname for valid targets. The base class for all managed objects is com.tivoli.twg.engine.TWGManagedObject, so specify that. The Client.0.Bind can allow for even more granularity on of the valid task targets but for now, specify Class.soft which is the least restrictive.
    Add these two lines:
    Client.0.Class = com.tivoli.twg.engine.TWGManagedObject
    Client.0.Bind  = Class.soft
  4. Add menu information. Add these two lines:
    Subtask.0.Menu = NonInteractive,150
    Subtask.0.MenuLocation = TaskIcon

    Note that TargetedInteractive is a key in the resource bundle. The 150 is a weight value; use the range 100 to 199 for your extensions. A lower number places the menu high up in the list of menu items.

  5. Save the file.
  6. Change the task server code to find the targets

    When a subtask is activated, your code will be passed a TWGTaskActivation object. The most important piece of information that this object has is the list of targets.

    There are a few important points to note:

    To put all this together, you will modify the code that processes the TWGTaskActivation. Here is an example of single targeted task activation processing inside a pIinit() method (from a task server that extended TWGDefaultTaskServer.

    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		LongValueSet moidSet = act.getMoid(); /* Get target set */
    7		long moid = moidSet.GetValue(0);
    8		boolean taskActionWasSuccessful = true;
    9		TWGLocalTaskClients clients = act.getClients();
    10		Object[] objArray = clients.getAllClients();
    11		TWGLocalManagedObject lmo = (TWGLocalManagedObject)objArray[0];
    12		TWGManagedObject mo = lmo.getMO();
    13		String moName = mo.getName();
    14		if (TWGRas.isTraceEX0)
    15			TWGRas.debug(TWGRas.EX0,
    16					"BobCoTaskServer1.processActivation() for Managed Object: " 
    17					+ moName);
    18	
    19		clients.setClientTaskStatus(moid, TWGTaskConstants.CLIENT_TASK_ACTIVE);
    20
    21		act.logMessage("com.bobco.BobCoResourceBundle", 
    22				"HelloMsgTarget" + "|" + moName, 
    23				0, 
    24				(int) moid);
    
    
    25		// TODO ADD YOUR TASK'S FUNCTION FOR THIS MOID HERE
    26		// Set the taskActionWasSuccessful variable with the 
    27		// result.
    28		
    29		// Now set the status for the client
    30		if (taskActionWasSuccessful) {
    31			clients.setClientTaskStatus(moid,
    32					TWGTaskConstants.CLIENT_TASK_COMPLETE);
    33		} else {
    34			clients.setClientTaskStatus(moid,
    35					TWGTaskConstants.CLIENT_TASK_FAILED_ERROR);
    36		}
    
    37		// set the status for the entire activation
    38		act.setStatus(TWGTaskConstants.ACT_STATUS_COMPLETE);
    
    39		if (TWGRas.isTraceEX0)
    40			TWGRas.debug(TWGRas.EX0,
    41					"BobCoTaskServer1.processActivation() done");
    42
    
    
    
    43	}
    

    Examining the task activation processing code

    The following information discusses the task activation processing code:

    Line 6: Returns a LongValueSet of MOIDs that are the targets. Since the code specified targeted:one, line 7 simply retrieves the first value in the LongValueSet.

    Line 9: Gets the TWGLocalTaskClients object from the activation. The TWGLocalTaskClients is used to track the status of the activation for each individual target.

    Line 10. through 13: Since the task server is running inside of the IBM Director Server, it is possible to access the actual TWGManagedObject that represents the target. These lines use the TWGLocalTaskClients to get the target TWGMangedObject. Line 13 uses the TWGManagedObject to get the name of the target.

    Line 19: Since the code is processing an activation that has targets, the status is set for each target as well as setting the status for the entire activation. Line 19 sets the activation status for the target to mean "processing has started but is not yet complete".

    Line 21 through 24: Because there are targets, we can write log messages specific to the target. This line reused the Hello message and writes it to the log for the target. The target is identified by it's MOID. Notice that for this API it is necessary to typecast the mOID to an int. This message uses a substitution string for the message. The logMessage() method has it's own way of doing this:

    1. Start with the resource bundle key of the message string
    2. Append a "|" character
    3. Append the substitution value, and pass the final string in parameter 2 of logMessage().

    Line 25: Location of code to perform the task's action on the given managed object.

    Line 30 through 36: Depending on the outcome of the task's action, this code sets the final activation status for the target.

    Line 38: Sets the final activation status for the entire activation.

    Add new strings to the resource bundle

    In this case, reuse the following message from the BobCoResourceBundle.

    { "HelloMsgTarget", "Hello From Bob Co target moid = {0}" },

    Redeploy and test

    After you redeploy your extension, Log in with the IBM Director Console and drag the Bob Co noninteractive task onto a managed object. Click Execute Now. You see this output.

    Open the log for the target and you see:

    Now, open the Log for the entire activation. It looks like this:

    If you ran raswatch -ex0 you would see this output:

    Adding multitargeting

    Multitargeting is a very powerful feature of IBM Director tasks. It makes it possible for an IBM Director user to, with one action, activate a single task on a whole group of managed objects. To provide multitargeting in your task frame, you need to do two things:

    1. Modify your task properties to tell IBM Director that your task supports multitargeting.
    2. Modify your code to handle more than one MOID in the task activation.


    Modifying the task properties

    To change the properties for a targeted task, change the "targeted:one" to "targeted:multi". The full change looks like this:

    Change the subtask context from:

    Subtask.0.Context = interactive:false | server:true | client:ignore | targeted:one

    to:

    Subtask.0.Context = interactive:false | server:true | client:ignore | targeted:multi

    Also, change the action to drag-drop-multi like this:

    Subtask.0.Actions = drag-drop-multi 

    Modifying the task server to handle more than one MOID

    In a single, targeted noninteractive task, retrieve the MOID of the target with code like this:

    LongValueSet moidSet = act.getMoid();
    long moid = moidSet.GetValue(0);
    TWGLocalTaskClients clients = act.getClients();
    Object[] objArray = clients.getAllClients();
    TWGLocalManagedObject lmo = (TWGLocalManagedObject)objArray[0];

    In a multitargeted task, use a loop to process all values in the LongValueSet of MOIDs and in the array of clients. It looks like this:

    
    LongValueSet moidSet = act.getMoid();
    for (int i = 0; i < moidSet.Length(); i++) {
    	long moid = moidSet.GetValue(i);
    	TWGLocalManagedObject lmo = (TWGLocalManagedObject) objArray[i];
    	TWGManagedObject mo = lmo.getMO();
    	String moName = mo.getName();
    	// TODO ADD YOUR TASK'S FUNCTION FOR THIS MOID HERE
    }


    An entire processActivation() method looks like this:

    	public void processActivation(TWGTaskActivation act) {
    		if (TWGRas.isTraceEX0)
    			TWGRas.debug(TWGRas.EX0,
    					"BobCoTaskServer1.processActivation() processing");
    
    		// log a message to the activation log
    		LongValueSet moidSet = act.getMoid(); /* Get target set */
    		boolean taskActionWasSuccessful = true;
    		TWGLocalTaskClients clients = act.getClients();
    		Object[] objArray = clients.getAllClients();
    
    		for (int i = 0; i < moidSet.Length(); i++) {
    
    			long moid = moidSet.GetValue(i);
    			TWGLocalManagedObject lmo = (TWGLocalManagedObject) objArray[i];
    			TWGManagedObject mo = lmo.getMO();
    			String moName = mo.getName();
    			if (TWGRas.isTraceEX0)
    				TWGRas.debug(TWGRas.EX0,
    						"BobCoTaskServer1.processActivation() for Managed Object: "
    								+ moName);
    
    			clients.setClientTaskStatus(moid,
    					TWGTaskConstants.CLIENT_TASK_ACTIVE);
    			act.logMessage("com.bobco.BobCoResourceBundle", "HelloMsgTarget"
    					+ "|" + moName, 0, (int) moid);
    
    			// TODO ADD YOUR TASK'S FUNCTION FOR THIS MOID HERE
    			// Set the taskActionWasSuccessful variable with the
    			// result.
    			if (taskActionWasSuccessful) {
    				clients.setClientTaskStatus(moid,
    						TWGTaskConstants.CLIENT_TASK_COMPLETE);
    			} else {
    				clients.setClientTaskStatus(moid,
    						TWGTaskConstants.CLIENT_TASK_FAILED_ERROR);
    			}
    
    		}
    
    		// set the status for the entire activation
    		act.setStatus(TWGTaskConstants.ACT_STATUS_COMPLETE);
    
    		if (TWGRas.isTraceEX0)
    			TWGRas.debug(TWGRas.EX0,
    					"BobCoTaskServer1.processActivation() done");
    	}

    When you redeploy and test, (remember the twgreset), you can drag the task onto either a group or a set of multiselected managed objects and see all the system names in the execution history.

    Drag the noninteractive task onto a group:


    Click execute now and you see the execution history dialog:


    Open the system Log for the first system and see it's specific log messages:


    Open the system Log for the entire activation and see all of the log messages:


    If you run twgras -ex0, you see this result: