MFT resource monitor user exits

Resource monitor user exits allow you to configure custom code to run when a monitor's trigger condition is satisfied, before the associated task is started.

It is not recommended to invoke new transfers directly from user exit code. In some circumstances this causes files to be transferred multiple times as user exits are not resilient to agent restarts.

Resource monitor user exits use the existing infrastructure for user exits. The monitor user exits are called after a monitor has triggered but before the corresponding task has been run by the monitor's task. This allows the user exit to modify the task to be run and decide whether a task should proceed or not. You can modify the monitor task by updating the monitor metadata, which is then used for variable substitution in the task document created by the creation of the original monitor. Alternatively, the monitor exit can replace or update the task definition XML string passed as a parameter. The monitor exit can return a result code of either 'proceed' or 'cancel' for the task. If cancel is returned, the task will not be started and the monitor will not start again until the monitored resource matches the trigger conditions. If the resource has not changed, the trigger will not start. As with the other user exits, you can chain monitor exits together. If one of the exits returns a cancel result code, the overall result is cancel and the task is not started.

  • A map of environment metadata (same as other user exits)
  • A map of monitor metadata including immutable system metadata and mutable user metadata. The immutable system metadata is as follows:
    • FILENAME - name of the file that satisfied the trigger condition
    • FILEPATH - path to the file that satisfied the trigger condition
    • FILESIZE (in bytes - this metadata might not be present) - size of the file that satisfied the trigger condition
    • LASTMODIFIEDDATE (Local) - date that the file that satisfied the trigger condition was last changed. This date is expressed as the local date of the time zone the agent is running in and is formatted as an ISO 8601 date.
    • LASTMODIFIEDTIME (Local) - time in local format that the file that satisfied the trigger condition was last changed. This time is expressed as the local time of the time zone the agent is running in and is formatted as an ISO 8601 time.
    • LASTMODIFIEDDATEUTC - date in universal format that the file that satisfied the trigger condition was last changed. This date is expressed as the local date converted to the UTC time zone and is formatted as an ISO 8601 date.
    • LASTMODIFIEDTIMEUTC - time in universal format that the file that satisfied the trigger condition was last changed. This time is expressed the local time converted to the UTC time zone and is formatted as an ISO 8601 time.
    • AGENTNAME - the monitor agent name
  • An XML string representing the task to be run as a result of the monitor trigger.
Monitor exits return the following data:
  • An indicator that specifies whether to progress further (proceed or cancel)
  • A string to insert into the trigger-satisfied log message

As a result of running the monitor exit code, the monitor metadata and task definition XML string that were originally passed as parameters might also have been updated.

The value of the agent property monitorExitClasses (in the agent.properties file) specifies which monitor exit classes to load, with each exit class separated by a comma. For example:


monitorExitClasses=testExits.TestExit1,testExits.testExit2

The interface to the monitor user exit is:


package com.ibm.wmqfte.exitroutine.api;

import java.util.Map;

/**
 * An interface that is implemented by classes that want to be invoked as part of
 * user exit routine processing.  This interface defines a method that will be
 * invoked immediately prior to starting a task as the result of a monitor trigger
 */
public interface MonitorExit {

	/**
	 * Invoked immediately prior to starting a task as the result of a monitor 
	 * trigger.
	 * 
	 * @param environmentMetaData
	 *            meta data about the environment in which the implementation
	 *            of this method is running.  This information can only be read,
	 *            it cannot be updated by the implementation.  The constant
	 *            defined in <code>EnvironmentMetaDataConstants</code> class can 
	 *            be used to access the data held by this map.
	 * 
	 * @param monitorMetaData
	 *            meta data to associate with the monitor. The meta data passed
	 *            to this method can be altered, and the changes will be
	 *            reflected in subsequent exit routine invocations. This map
	 *            also contains keys with IBM reserved names.  These entries are
	 *            defined in the <code>MonitorMetaDataConstants</code> class and
	 *            have special semantics. The the values of the IBM reserved names
	 *            cannot be modified by the exit 
	 * 
	 * @param taskDetails
	 *            An XML String representing the task to be executed as a result of
	 *            the monitor triggering. This XML string may be modified by the 
	 *            exit   
	 * 
	 * @return    a monitor exit result object which is used to determine if the
	 *            task should proceed, or be cancelled.
	 */
	MonitorExitResult onMonitor(Map<String, String> environmentMetaData,
			                    Map<String, String> monitorMetaData, 
				                Reference<String> taskDetails);
}

The constants for the IBM-reserved values in the monitor metadata are as follows:


package com.ibm.wmqfte.exitroutine.api;

/**
* Constants for IBM reserved values placed into the monitor meta data
* maps used by the monitor exit routines.
*/
public interface MonitorMetaDataConstants {

/**
* The value associated with this key is the name of the trigger 
* file associated with the monitor. Any modification performed 
* to this property by user exit routines will be ignored.
*/
final String FILE_NAME_KEY = "FILENAME";

/**
* The value associated with this key is the path to the trigger 
* file associated with the monitor. Any modification performed 
* to this property by user exit routines will be ignored.
*/
final String FILE_PATH_KEY = "FILEPATH";

/**
* The value associated with this key is the size of the trigger 
* file associated with the monitor. This will not be present in 
* the cases where the size cannot be determined. Any modification 
* performed to this property by user exit routines will be ignored.
*/
final String FILE_SIZE_KEY = "FILESIZE";

/**
* The value associated with this key is the local date on which 
* the trigger file associated with the monitor was last modified.
* Any modification performed to this property by user exit routines 
* will be ignored.
*/
final String LAST_MODIFIED_DATE_KEY = "LASTMODIFIEDDATE";

/**
* The value associated with this key is the local time at which 
* the trigger file associated with the monitor was last modified.
* Any modification performed to this property by user exit routines 
* will be ignored.
*/
final String LAST_MODIFIED_TIME_KEY = "LASTMODIFIEDTIME";

/**
* The value associated with this key is the UTC date on which 
* the trigger file associated with the monitor was last modified.
* Any modification performed to this property by user exit routines 
* will be ignored.
*/
final String LAST_MODIFIED_DATE_KEY_UTC = "LASTMODIFIEDDATEUTC";

/**
* The value associated with this key is the UTC time at which 
* the trigger file associated with the monitor was last modified.
* Any modification performed to this property by user exit routines 
* will be ignored.
*/
final String LAST_MODIFIED_TIME_KEY_UTC = "LASTMODIFIEDTIMEUTC"; 

/**
* The value associated with this key is the name of the agent on which
* the monitor is running. Any modification performed to this property by 
* user exit routines will be ignored.
*/
final String MONITOR_AGENT_KEY = "AGENTNAME";

} 

Example monitor user exit

This example class implements the MonitorExit interface. This example adds a custom substitution variable into the monitor metadata called REDIRECTEDAGENT that will be populated with a value of LONDON if the hour of the day is odd, and a value of PARIS for even hours. The monitor exit result code is set to always return proceed.

package com.ibm.wmqfte.monitor;

import java.util.Calendar;
import java.util.Map;

import com.ibm.wmqfte.exitroutine.api.MonitorExit;
import com.ibm.wmqfte.exitroutine.api.MonitorExitResult;
import com.ibm.wmqfte.exitroutine.api.Reference;

/**
 * Example resource monitor user exit that changes the monitor mutable 
 * metadata value between 'LONDON' and 'PARIS' depending on the hour of the day.
 *
 */
public class TestMonitorExit implements MonitorExit {

	// custom variable that will substitute destination agent
	final static String REDIRECTED_AGENT = "REDIRECTEDAGENT";

	public MonitorExitResult onMonitor(
Map<String, String> environmentMetaData,
			Map<String, String> monitorMetaData, 
Reference<String> taskDetails) {
		
		// always succeed
		final MonitorExitResult result = MonitorExitResult.PROCEED_RESULT;
				
		final int hour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
		
		if (hour%2 == 1) {
			monitorMetaData.put(REDIRECTED_AGENT, "LONDON");
		} else {
			monitorMetaData.put(REDIRECTED_AGENT, "PARIS");	
		}
		
		return result;
	}
}
The corresponding task for a monitor that makes use of the REDIRECTEDAGENT substitution variable could look similar to the following:

<?xml version="1.0" encoding="UTF-8"?>
<request version="4.00"
         xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="FileTransfer.xsd">
  <managedTransfer>
    <originator>
        <hostName>reportserver.com</hostName>
        <userID>USER1</userID>
    </originator>
    <sourceAgent agent="AGENT1"
                 QMgr="QM1"/>
    <destinationAgent agent="${REDIRECTEDAGENT}"
                      QMgr="QM2"/>
    <transferSet>
      <item mode="binary" checksumMethod="MD5">
        <source recursive="false" disposition="delete">
          <file>c:\sourcefiles\reports.doc</file>
        </source>
        <destination type="file" exist="overwrite">
          <file>c:\destinationfiles\reports.doc</file>
        </destination>
      </item>
    </transferSet>
  </managedTransfer>
</request>

Before this transfer is started, the value of the <destinationAgent> element's agent attribute is replaced with either LONDON or PARIS.

You must specify the substitution variable in the monitor exit class and the task definition XML in uppercase.