Polling Notifications

Overview

A polling notification is a facility that enables an adapter to initiate activity on Integration Server, based on events that occur in the adapter resource. A polling notification monitors an adapter resource for changes (such as an insert, update, or delete operation) so that the appropriate flow or Java services can react.

The users of the adapter can perform the following:

  • Create a polling notification using Designer. An adapter connection node created earlier is assigned to the notification. At the same time, Designer creates a Document Type that describes the data generated by the polling notification when it executes. The notification publishes this document to Integration Server. For more information on Integration Server publishable documents, see the Publish-Subscribe Developer’s Guide for your release.
  • Create a Integration Server trigger to process a document published by the notification. When Integration Server receives a document, the trigger invokes the flow or Java service registered with the trigger. The service then processes the data contained in the notification's document.
  • Configure the notification scheduling parameters that specify the interval at which Integration Server must invoke the notification, and then enable the notification, using Integration Server Administrator. For instructions on creating and using polling notification nodes, see Configuring and Testing Polling Notification Nodes.
For example, when a record is inserted in the database table, which is monitored by a polling notification:
  • The polling notification publishes the polling notification document to Integration Server messaging system.
  • Integration Server receiving the published document, triggers a flow or Java service that processes the data contained in the document.

Implementing Polling Notifications

The implementation of a polling notification is similar to the implementation of an adapter service. Each implementation includes a Java class extending an ADK base class, and a namespace node in which design-time configuration data is stored. In the Java class, the metadata model for polling notifications is nearly identical to that of adapter services. The parameters to configure a polling notification are built from the polling notifications' metadata.

The primary difference between adapter services and polling notifications is the runtime behavior of polling notifications. Polling notifications cannot be directly invoked from a flow service or from Designer. Instead, Integration Server automatically invokes a polling notification in a fixed time interval. When a polling notification determines that a specified event has occurred in the adapter resource, it produces a document describing the event. These documents are automatically published to Integration Server (or IBM webMethods Broker) as they are generated by the notification. The processing of the published document is based on triggers that are configured to invoke flow services when the given document type is published.

Polling Notification Classes

The following figure shows the classes provided by the ADK to support polling notifications and the com.wm.adk.notification.WmPollingNotifications' implementation class SimpleNotification.

Polling Notification Implementation Classes

Create a polling notification service by extending com.wm.adk.notification.WmPollingNotification base class . You must override the following base class methods in your WmPollingNotification implementation class:

Method Description
fillWmTemplateDescriptor Modifies how metadata parameters are handled during data entry similar to the WmAdapterService.fillWmTemplateDescriptor method. Failing to override this method results in a runtime error. For more information, see WmTemplateDescriptor Interface.
runNotification Receives no input and returns results by calling the WmAsynchronousNotification.doNotify method, and passing it a WmRecord instance that must conform to the output signature of the polling notification node. For more information, see Specifying Notification Signatures (Document Type). The WmRecord is constructed in exactly the same way it is constructed for adapter services. For more information, see Adapter Service Execution.
doNotify The WmAsynchronousNotification class provides two forms of doNotify method:
  1. Process the notification Exactly Once
    public void doNotify(WmRecord rec, String msgID)
    Receives two input parameters: WmRecord object, and String object for message ID. Provides a resource specific msgID value with each notification record:
    • The adapter implementation must guarantee that the value of msgID is unique and constant for each notification event.
    • A notification event is defined as any activity on the adapter resource that causes the WmPollingNotification.runNotification implementation to call WmAsynchronousNotification.doNotify.
    • The msgID is never duplicated for different notification events, but the msgID is the same if the same notification event is retrieved multiple times from the adapter resource, even in a failure-recovery scenario.

    Integration Server guarantees that msgID values generated by different notification nodes are unique. This is accomplished by combining the msgID value provided by the adapter with a GUID created by Integration Server, and associated with the notification node when it is created.

    Note: A fixed number of characters are available in Integration Server to hold a notification ID. Of these, the WmART package reserves a certain number to hold a unique ID that is inserted prior to dispatching a notification. The remaining characters are available to you when calling WmAsynchronousNotification.doNotify(WmRecord rec, String msgId). The length (number of characters) of the value in msgId must not exceed a particular limit. Call the WmAsynchronousNotification.adapterMaxMessageIdLen method to determine this limit. For more information, see the Javadoc.
  2. Process the notification
    public void doNotify(WmRecord rec)
    Receives one input parameters: WmRecord object.

Polling Notification Callbacks

The base class WmPollingNotification defines a set of callback methods that you can override in the notification implementation class. The following table describes when these methods are called, and the impact of an exception thrown from the method. For complete details, see the Javadoc for the WmPollingNotification class.

User Actions Callbacks Received
Notification node is deleted or renamed. deleteCallBack
Notification node is disabled. disableCallBack
Disabled notification node is enabled. enableCallBack
Notification node is created, the package is enabled. initCallBack
Suspended notification node is enabled. resumeCallBack
Notification node is disabled or suspended, the Integration Server is shutdown, the package is disabled. shutdownCallBack
Notification node is enabled or resumed, the Integration Server starts. startupCallBack
Enabled notification node is suspended. suspendCallBack
Notification node is modified, but not called when notification node is created. updateCallBack
Note: In all cases, an AdapterException will cause the associated connection to be destroyed and removed from the pool.

Metadata Model for Polling Notifications

The metadata model for polling notifications is identical to the model for adapter services, except for the following:

  • A polling notification has no input signature. The output signature is constructed in the same way, but the server uses it to generate a Document Type node that enables triggers to identify notification data in the node.
  • You register polling notifications in the WmAdapter.fillAdapterTypeInfo method instead of the WmManagedConnectionFactory.fillResourceAdapterMetadataInfo method.

Polling Notification Interactions

Although polling notifications are structurally similar to adapter services, the dynamic model is similar only in the way in which metadata is initialized, which is described as follows

Loading Polling Notification Templates

As with adapter services, Designer caches metadata values for polling notifications. These values include resource domain values and template descriptor information. The following figure shows the interactions within the adapter as Designer loads its cache for a polling notification. This interaction occurs either when a new polling notification node is created, or an existing one is viewed (if the data is not already held in the Designer cache).

Creating and Loading Polling Notification Nodes

When a user of the adapter creates a new polling notification node, or loads an existing node during server startup or package startup, the server instantiates the appropriate class and executes the initCallBack method. The package containing the polling notification node, holds the object reference of the polling notification node for the lifetime of the package. If this interaction is initiated by a package load, and the polling notification node is enabled, the enable/startup interaction occurs immediately afterwards.

Updating Polling Notifications

Unlike with adapter services, polling notification parameter values are updated each time a user of the adapter saves the values in Designer. After the "set" methods pass the modified values to the object instance, the notification calls the updateCallBack method. If that method throws an exception, it prevents the values from being persisted in the notification node.

Enabling Polling Notifications

When a user of the adapter enables a polling notification using Integration Server Administrator, the notification calls the enableCallBack method before the startupCallBack method. If the node was previously enabled, and the user is simply starting up the notification after the package loads, then the enableCallBack call is skipped. An exception from either method call disables the notification node.

The server calls the runNotification method at regular intervals, based on the scheduling parameters that specify the interval at which Integration Server must invoke the notification. The same object instance is always used unless the schedule is configured to allow overlapping, and the previous call to runNotification has not completed.

Disabling Polling Notifications

The figure shows the interactions that occur when a user of the adapter explicitly disables a polling notification node. If a node is shut down by any other means, the disableCallBack is skipped.

Polling Notification Implementation

The tasks for implementing a polling notification are as follows:

  • Defining a WmPollingNotification Implementation Class
  • Specifying Configuration Metadata for Polling Notifications
  • Implementing Configuration Resource Domains for Polling Notifications
  • Specifying Notification Signatures (Document Type)
  • Manipulating Adapter Notification Document Properties
  • Implementing Signature Resource Domains
  • Implementing the WmPollingNotification.runNotification Method and Callbacks
  • Updating the Resource Bundle
  • Registering Polling Notifications in the Adapter
  • Compiling the Adapter
  • Reloading Adapter
  • Refreshing the Designer cache
  • Configuring and Testing Polling Notification Nodes

The example polling notification implementation monitors the contents of a directory and sends notifications when files are added to, or removed from the directory. Although this example is very simple, it demonstrates most of the notification capabilities, except for callbacks.

Note: This example implements a design strategy that enables you to encapsulate the resource domain support inside an adapter service or notification. This strategy is discussed in to-appx_alt_approaches_metadata.html#A52135. You do not need to fully understand this strategy to understand the example code. However, if you are uncomfortable with this strategy, you may implement those methods in your connection implementation. You will have to adjust the method signatures and the "this" references appropriately. The "this" reference refers to the notification. If you move the methods to the connection, then the "this" refers to the connection.

Example Polling Notification Class

package com.wm.MyAdapter.notifications;

import com.wm.adk.cci.record.WmRecord;
import com.wm.adk.cci.record.WmRecordFactory;
import com.wm.adk.connection.WmManagedConnection;
import com.wm.adk.error.AdapterException;
import com.wm.adk.metadata.ResourceDomainValues;
import com.wm.adk.metadata.WmAdapterAccess;
import com.wm.adk.metadata.WmTemplateDescriptor;
import com.wm.adk.notification.WmPollingNotification;

import java.io.File;
import java.util.ArrayList;
import java.util.Locale;
import javax.resource.ResourceException;

import com.wm.MyAdapter.MyAdapter;

public class SimpleNotification extends WmPollingNotification
{
	public static final String NOTIFICATION_SETUP_GROUP = "SimpleNotification";

	public static final String DIRECTORY_PARM = "directory";
	public static final String CHECK_ADDED_PARM = "checkAdded";
	public static final String CHECK_DELETED_PARM = "checkDeleted";
	public static final String SIG_FIELD_NAMES_PARM = "fieldNames";
	public static final String SIG_FIELD_TYPES_PARM = "fieldTypes";
	public static final String SIG_PARM = "signature";

	public static final String DIRECTORIES_RD =
		"SimpleNotification.directories.rd";
	public static final String FIELD_NAMES_RD =
		"SimpleNotification.fieldNames.rd";
	public static final String FIELD_TYPES_RD =
		"SimpleNotification.fieldTypes.rd";

	private String _directory;
	private boolean _checkAdded;
	private boolean _checkDeleted;
	private String[] _fieldNames;
	private String[] _fieldTypes;

	public void setDirectory(String val){_directory = val;}
	public void setCheckAdded(boolean val){_checkAdded = val;}
	public void setCheckDeleted(boolean val){_checkDeleted = val;}
	public void setFieldNames(String[] val){_fieldNames = val;}
	public void setFieldTypes(String[] val){_fieldTypes = val;}
	public void setSignature(String[] val){}

	private ArrayList _fileList = new ArrayList();

	public SimpleNotification(){}

	public void fillWmTemplateDescriptor(WmTemplateDescriptor descriptor, Locale l)
		throws ResourceException
	{
		descriptor.createGroup(NOTIFICATION_SETUP_GROUP,
			new String[]{DIRECTORY_PARM, CHECK_ADDED_PARM, CHECK_DELETED_PARM,
				SIG_FIELD_NAMES_PARM, SIG_FIELD_TYPES_PARM, SIG_PARM});
		descriptor.createFieldMap(
			new String[]{SIG_FIELD_NAMES_PARM, SIG_FIELD_TYPES_PARM, SIG_PARM},
			false);

		descriptor.setHidden(SIG_FIELD_NAMES_PARM);
		descriptor.setHidden(SIG_FIELD_TYPES_PARM);
		descriptor.setHidden(SIG_PARM);
		descriptor.createTuple(
			new String[]{SIG_FIELD_NAMES_PARM, SIG_FIELD_TYPES_PARM});

		descriptor.setResourceDomain(DIRECTORY_PARM, DIRECTORIES_RD, null);
		descriptor.setResourceDomain(SIG_FIELD_NAMES_PARM, FIELD_NAMES_RD, null);
		descriptor.setResourceDomain(SIG_FIELD_TYPES_PARM, FIELD_TYPES_RD, null);
		descriptor.setResourceDomain(SIG_PARM, WmTemplateDescriptor.OUTPUT_FIELD_NAMES,
			new String[]{SIG_FIELD_NAMES_PARM, SIG_FIELD_TYPES_PARM});
		descriptor.setDescriptions(
			MyAdapter.getInstance().getAdapterResourceBundleManager(),l);
	}

	public void runNotification() throws ResourceException
	{
		File thisDir = new File(_directory);
		File [] newList = thisDir.listFiles();
		ArrayList scratchCopy = new ArrayList(this._fileList);

		for (int nlIndex = 0;nlIndex < newList.length;nlIndex++)
		{
			String name = newList[nlIndex].getName();
			if(newList[nlIndex].isFile())
			{
				if(scratchCopy.contains(name))
					{
						scratchCopy.remove(name);
					}
				else
				{
					this._fileList.add(name);
					if(this._checkAdded)
					{
						this.doNotify(createNotice(name,_directory,true,false));
					}
				}
			}
			else
			{
				scratchCopy.remove(name);
			}

		}
		// now anything left in the scratch copy is missing from the directory

		String[] deadList = new String[scratchCopy.size()];
		scratchCopy.toArray(deadList);
		for(int dlIndex = 0; dlIndex < deadList.length;dlIndex++)
		{
			 this._fileList.remove(deadList[dlIndex]);
			 if(this._checkDeleted)
			 {
				 this.doNotify(createNotice(deadList[dlIndex], _directory,false,true));
			 }
		}

	}


	public Boolean adapterCheckValue(WmManagedConnection connection,
		String resourceDomainName, String[][] values, String testValue)
		throws AdapterException
	{

		boolean result = true;

		if(resourceDomainName.equals(DIRECTORIES_RD))
		{
			File testDir = new File(testValue);
			if (!testDir.exists())
			{
				result = false;
			}
			else if(!testDir.isDirectory())
			{
				result = false;
			}
		}

		return new Boolean(result);
	}

	public ResourceDomainValues[] adapterResourceDomainLookup(
		WmManagedConnection connection, String resourceDomainName,
		String[][] values) 	throws AdapterException
	{
		ResourceDomainValues[] results = null;

		if (resourceDomainName.equals(FIELD_NAMES_RD) || 
			resourceDomainName.equals(FIELD_TYPES_RD))
		{
			ResourceDomainValues names =
				new ResourceDomainValues(FIELD_NAMES_RD,new String[] {
				"FileName", "Path","isAdded","isDeleted"});

			ResourceDomainValues types =
				new ResourceDomainValues(FIELD_TYPES_RD,new String[] {
				"java.lang.String", "java.lang.String",
				"java.lang.Boolean","java.lang.Boolean"});
			results = new ResourceDomainValues[] {names,types};
		}

		return results;
	}

	public void registerResourceDomain(	WmManagedConnection connection,
		WmAdapterAccess access) throws AdapterException
	{
		access.addResourceDomainLookup(this.getClass().getName(),
			FIELD_NAMES_RD,connection);
		access.addResourceDomainLookup(this.getClass().getName(),
			FIELD_TYPES_RD,connection);

		ResourceDomainValues rd = new ResourceDomainValues(DIRECTORIES_RD,
			new String[] {""});
		rd.setComplete(false);
		rd.setCanValidate(true);
		access.addResourceDomain(rd);
		access.addCheckValue(DIRECTORIES_RD, connection);
	}

	private WmRecord createNotice(String file, String dir, boolean isAdded, 
		boolean isDeleted)
	{
		WmRecord notice =
			WmRecordFactory.getFactory().createWmRecord("notUsed");
		notice.put("FileName",file);
		notice.put("Path",dir);
		notice.put("isAdded",new Boolean(isAdded));
		notice.put("isDeleted", new Boolean(isDeleted));

		return notice;
	}

}

Defining a WmPollingNotification Implementation Class

About this task

Procedure

  1. Create a directory structure for the Java package for adapter polling notification implementation. For example: com\mycompany\adapter\myadapter\notifications. In the example, the Java package created is com\wm\MyAdapter\notifications.
    Note: You must create your Java package and classes in the adapterPackageName\code\source directory in the IBM webMethods package you created using Designer.
  2. Create a class by extending com.wm.adk.notification.WmPollingNotification base class.
    In the example, the class created is SimpleNotification.
    Important: You can make a callback to the connection factory using WmManagedConnection.getFactory. If you do this, do not call the set methods on the connection factory which produces unpredictable results.
  3. Implement the runNotification method.
  4. Override the base class implementation of the fillWmTemplateDescriptor method.

Specifying Configuration Metadata for Polling Notifications

The next step for implementing a polling notification is to create the metadata constructs that the users of the adapter use for entering data when they create polling notification nodes. To do this, you perform the following:

  • Create metadata parameters appropriate for the function of the polling notification. Each parameter has:
    • A variable to hold the configured values.
    • A String constant containing the name of the parameter.
    • An accessor method.
    • A set of resource bundle entries with a localizable parameter name and description as shown in Updating the Resource Bundle.

    For more information on metadata parameters, see Metadata Model for Connection.

  • Describe presentation for those metadata parameters.
  • Set the data entry rules for those metadata parameters.

The example implementation includes three metadata parameters that the users of the adapter use to create polling notification nodes. The following table describes the purpose of each of these parameters for data entry:

Parameter Description
directory Directory to monitor.
checkAdded Indicates whether notifications must be sent when files are added to the specified directory.
checkDeleted Indicates whether notifications must be sent when files are deleted from the specified directory.

Specifying the Display and Data Entry Attributes of the Data Entry Parameters

  • After creating the parameters, specify the display and data entry attributes by calling various methods of the WmTemplateDescriptor interface from the service's fillWmTemplateDescriptor method.
  • The example code places each data entry parameter into a single group (in display order) referenced by the NOTIFICATION_SETUP_GROUP constant. A constant instead of a string is used to name the group, because the same value is used in the resource bundle to specify a localizable group name.

Implementing Configuration Resource Domains for Polling Notifications

About this task

The next steps for implementing a polling notification are:

  • Define and implement the resource domains required for the metadata parameters that you created.
  • Identify the values on which those resource domains depend.

For each parameter that requires a resource domain to supply a value, or that requires a validity check for values supplied by the users of the adapter, you must perform the following:

Procedure

  1. In the WmPollingNotification.fillWmTemplateDescriptor method, call WmTemplateDescriptor.setResourceDomain method, passing the name of the parameter, the name of the resource domain, and an array of the names of any parameters on which the resource domain depends.
  2. In the WmPollingNotification.registerResourceDomain method, call WmAdapterAccess.addResourceDomain(ResourceDomainValues) method to register the resource domain support.
  3. In the WmPollingNotification.registerResourceDomain method, implement code to populate the resource domain values and/or the adapter check values. For more information about adapter check values, see Adapter Check Value Callbacks.
  4. In the associated connection class's WmManagedConnection.registerResourceDomain method, call WmAdapterAccess.addResourceDomainLookup method to add the polling notification metadata parameters with resource domain lookup.

Results

package com.wm.MyAdapter.connection;

import com.wm.adk.connection.WmManagedConnection;
import com.wm.adk.metadata.*;
import com.wm.adk.error.AdapterException;

import com.wm.MyAdapter.MyAdapter;
import com.wm.MyAdapter.services.MockDbUpdate;
import com.wm.MyAdapter.notifications.SimpleNotification;


public class SimpleConnection extends WmManagedConnection {
..
..

	public void registerResourceDomain(WmAdapterAccess access)
		throws AdapterException
	{
..
..
..

		//Simple Polling Notification Registering Resource Domain
		access.addResourceDomainLookup(SimpleNotification.DIRECTORIES_RD, this);
		access.addResourceDomainLookup(SimpleNotification.FIELD_NAMES_RD, this);
		access.addResourceDomainLookup(SimpleNotification.FIELD_TYPES_RD, this);

	}

}

In this example, there are no preset values, but adapter's user supplied data for the directory parameter is validated to ensure that the directory exists.

Specifying Notification Signatures (Document Type)

After you implement the configuration logic for the polling notification, you implement the logic that defines the signature of the polling notification node. It is used to create a document type node that enables triggers to identify notification data in the node.

Note: A polling notification only has an output signature.

To define an output signature, you create additional metadata parameters as follows:

Parameter Description
signature Used with the reserved signature resource domain.
fieldName Dependency parameters in which you build the signature data. The relationship between these parameters is established in the WmTemplateDescriptor interface. For more information about the mechanics of signature construction, see Adapter Service Node Signatures.
fieldType

Manipulating Adapter Notification Document Properties

With few exceptions, the document properties for an adapter's polling and listener notifications are managed and manipulated the same way as they are for an adapter service's signature. For the three template based features (signature wrapping, override connection name, and pass full pipeline), only the pass full pipeline feature applies to notification documents, and then, only for synchronous notifications. When the pass full pipeline option is enabled for a synchronous listener notification, then the notification can pass fields to the invoked service that are not defined in its request document, and receive fields from that service that are not defined in the notification's reply document. Template-based signature manipulation features have no other effect on notification documents.

Document field properties are managed in exactly the same way as the signature field properties as described earlier. In the case of notifications, the setSignatureProperties method is called setDocumentProperties method. For asynchronous notifications, only one PipelineRecordProperties argument exists.

Implementing Signature Resource Domains

The resource domain implementation for the signature parameters in this example is straightforward. The signature in this case is static, but it is implemented as a lookup, to facilitate maintenance of the class.

Implementing the WmPollingNotification.runNotification Method and Callbacks

The final task for implementing a polling notification is to add the runNotification method and any callback methods. This example implements some very basic logic as previously described. It relies on the fact that the object instance is reused between runNotification calls. This may not be a good technique if the runNotification call runs for a long time or if overlapping calls occur. A more robust model would probably use a persistent store instead of an instance variable to track the current directory snapshot.

Updating the Resource Bundle

Update the resource bundle with display names, and descriptions to make the polling notification more usable, as follows:

package com.wm.MyAdapter;
..
..
import com.wm.MyAdapter.notifications.SimpleNotification;

public class MyAdapterResource extends ListResourceBundle implements MyAdapterConstants{
   ..
   .. 
 static final Object[][] _contents = {	
   ..
   .. 	
		//Polling Notifications
		,{SimpleNotification.class.getName() + ADKGLOBAL.RESOURCEBUNDLEKEY_DISPLAYNAME,
			"Simple Polling Notification"}
		,{SimpleNotification.class.getName() + ADKGLOBAL.RESOURCEBUNDLEKEY_DESCRIPTION,
			"Looks for file updates to a specified directory"}
		,{SimpleNotification.NOTIFICATION_SETUP_GROUP + ADKGLOBAL.RESOURCEBUNDLEKEY_GROUP, 
			"Simple Notification Settings"}
		,{SimpleNotification.DIRECTORY_PARM + ADKGLOBAL.RESOURCEBUNDLEKEY_DISPLAYNAME,
			"Directory Path"}
		,{SimpleNotification.DIRECTORY_PARM + ADKGLOBAL.RESOURCEBUNDLEKEY_DESCRIPTION,
			"Directory to monitor"}
		,{SimpleNotification.CHECK_ADDED_PARM + ADKGLOBAL.RESOURCEBUNDLEKEY_DISPLAYNAME,
			"Notify on Add"}
		,{SimpleNotification.CHECK_ADDED_PARM + ADKGLOBAL.RESOURCEBUNDLEKEY_DESCRIPTION,
			"Check if notification must be generated when file added"}
		,{SimpleNotification.CHECK_DELETED_PARM + ADKGLOBAL.RESOURCEBUNDLEKEY_DISPLAYNAME,
			"Notify on Delete"}
		,{SimpleNotification.CHECK_DELETED_PARM + ADKGLOBAL.RESOURCEBUNDLEKEY_DESCRIPTION,
			"Check if notification must be generated when file deleted"}

  }
  protected Object[][] getContents() {
		 // TODO Auto-generated method stub
		 return _contents;
  }
}

Registering Polling Notifications in the Adapter

You must register each polling notification class in the WmAdapter implementation class. You do this by passing the class name to the AdapterTypeInfo.addNotificationType method in the WmAdapter.fillAdapterTypeInfo method in WmAdapter implementation class. In the example, the polling notification SimpleNotification class is registered in the MyAdapter adapter implementation class:

For example:

package com.wm.MyAdapter;
..
..
import com.wm.MyAdapter.notifications.*;  
..
..  
public class MyAdapter extends WmAdapter implements MyAdapterConstants {
..
.. 
	public void fillAdapterTypeInfo(AdapterTypeInfo info, Locale locale)  
	{
    ..
    ..
    info.addNotificationType(SimpleNotification.class.getName());
 }
}

Refreshing the Designer cache

About this task

Refresh the Designer cache.

Configuring and Testing Polling Notification Nodes

Now you are ready to configure a polling notification node as follows:

  • Configuring Polling Notification Nodes
  • Scheduling and Enabling Polling Notification Nodes
  • Testing Polling Notification Nodes

Before you configure a polling notification node, ensure that you have configured a connection node as described in Configuring and Testing Connection Nodes. This section provides procedures for:

Configuring Polling Notification Nodes

About this task

Perform the following procedure to configure a polling notification node. You can use Designer to configure a polling notification node.

To configure a polling notification node

Procedure

  1. Start Designer.
    Note: Ensure that the Integration Server connected to the Designer is running.
  2. Select a namespace node package where you want to create the polling notification node.
  3. Create a folder in the selected package, and navigate to that folder in Package Navigator.
  4. Select File > New.
  5. Select Adapter Notification from the list of elements.
  6. In the Create a New Adapter Notification screen, type a name for your polling notification in the Element name field, and click Next.
  7. In the Select Adapter Type screen, select the name of your adapter, and click Next.
  8. In the Select a Template screen, select an adapter notification template, and click Next.
  9. In the Select an Adapter Connection Alias screen, select the appropriate adapter connection name, and click Next.
  10. In the Publish Document Name, select Finish.
  11. Select File > Save.

    The adapter creates the notification node and a document named notificationNamePublishDocument. This document contains the data of the affected portion of the adapter resource such as a database row, and is used to inform Integration Server of the changes.

  12. In the Adapter Notification Editor's notificationNameSetting tab, select a polling event and polling location to monitor. Configure the Adapter Notification Editor fields as applicable to your adapter resource. For information about using the Adapter Notification Editor, see the IBM webMethods Service Development Help for your release.
  13. Select File > Save.
  14. Schedule and enable the notification at runtime.

Scheduling and Enabling Polling Notification Nodes

About this task

Before you can use a notification, you must schedule and enable it.

To schedule and enable a polling notification node

Procedure

  1. Start Integration Server Administrator.
  2. In Adapters screen, select the name of your adapter.
  3. Select Polling Notifications.
  4. In the Polling Notifications screen, use the following options to schedule and enable each polling notification:
    Note: If you use an XA-Transaction connection, you cannot enable a notification.
    Option Description/Action
    Notification Name Name of the notification.
    Package Name Name of the package for the notification.
    State
    Note: Before you can enable a polling notification, you must schedule it. Click on the icon in the Edit Schedule column to edit the schedule.

    Once you schedule a polling notification, you can select the option Enabled to enable, and Disabled to disable a polling notification. Click the current value in this field to change its value.

    Use the Edit Schedule icon to create a polling notification as described in step 5.

    Edit Schedule
    Note: You must disable a polling notification before you can edit it.
    Click on the icon in the Edit Schedule column to create or modify polling notification parameters.
    View Schedule Click on the icon in the View Schedule column to review the scheduled parameters for the selected polling notification. Click Return to Notifications to go back to the main polling notification page.
  5. To create or modify schedule parameters for the selected notification, click the Edit Schedule icon and set the following options:
    Option Description/Action
    Interval (seconds) Type the polling interval time in seconds.
    Overlap This option determines when the scheduled interval time you set in the Interval field begins. Enable this option to allow for executions of the scheduled notification to overlap. With the Overlap option enabled, the next scheduled execution does not wait for the current execution to end.
    Note:
    • If your notification requires the preservation of the notification ordering, do not enable this option.
    • This option is enabled for clustered notifications.
    Immediate Enable this option to start polling immediately.
  6. Click Save Schedule.

Testing Polling Notification Nodes

Creating the Flow Service for the Polling Notification Node

About this task

Perform the following procedure to create the flow service for the Polling notification node.

To create the flow service for the Polling notification node

Procedure
  1. Start Designer.
  2. In the Package Navigator, select the folder where you want to create the flow service.
  3. Select File > New.
  4. Select Flow Service from the list of elements.
  5. In the Create a New Flow Service screen, type TestMyAdapterFlowService in the Element name field, and click Next.
  6. On the Select the Source Type screen, select Empty Flow, and click Finish.
  7. Click to insert a flow step.
  8. Navigate to the pub.flow:savePipelineToFile service in the WmPublic package, and click OK.
    Note: The savePipelineToFile service saves the contents of the pipeline (from the polling notification event) to the file that you specify in the fileName parameter.
  9. Click the Pipeline tab.
  10. Open the fileName parameter in the pipeline and set its value to MonitorPollingNotificationPipeline.log.

    Click OK.

Creating the Trigger for the Polling Notification Node

About this task

Perform the following procedure to create the trigger for the Polling notification node.

To create the trigger for the Polling notification node

Procedure
  1. Start Designer.
  2. In the Package Navigator, select the folder where you want to create the trigger.
  3. Select File > New.
  4. Select webMethods Messaging Trigger from the list of elements.
  5. On the webMethods Messaging Trigger screen, type TestMyAdapterMsgTrigger in the Element name field and click Finish.
  6. In the trigger editor, in the Conditions section, accept the default Condition1.
  7. In the Condition detail section, in the Service field, select or type the flow service name TestMyAdapterFlowService.
  8. Click to insert document types. Select TestMyPollingNotificationPublishDocument and click OK.
  9. Click to save your trigger.

Scheduling and Enabling the Polling Notification Node

About this task

Perform the following procedure to schedule and enable the Polling notification node.

To schedule and enable the Polling notification node

Procedure
  1. Start Integration Server Administrator.
  2. In Adapters screen, select the name of your adapter.
  3. Select Polling Notifications.
  4. Click Edit Schedule.
  5. Set the Interval to 10 and click the Save Schedule button.
  6. Enable the node by selecting Enabled in the State column.

Testing the Polling Notification Node

About this task

Perform the following procedure to test the polling notification node.

To test the Polling notification node

Procedure
Add a file to the directory that is monitored. In this example, the directory is C:\Monitor and file added is Testing-1.txt.
Results
The file MonitorPollingNotificationPipeline.log is created in Integration Server_directory/instances/<instance_name>/pipeline. This file contains the following entry for the file added in C:\Monitor:
<?xml version="1.0" encoding="UTF-8"?>

<IDataXMLCoder version="1.0">
  <record javaclass="com.wm.data.ISMemDataImpl">
    <value name="fileName">MonitorPollingNotificationPipeline.log</value>
    <record name="TestMyAdapter:TestMyAdapterNotificationPublishDocument" javaclass="com.wm.data.ISMemDataImpl">
      <value name="FileName">Testing-1.txt</value>
      <value name="Path">C:\Monitor</value>
      <jboolean name="isAdded">true</jboolean>
      <jboolean name="isDeleted">false</jboolean>
      <record name="_env" javaclass="com.wm.data.ISMemDataImpl">
        <value name="locale"></value>
        <value name="activation">wm6bfd23a95-1c84-4e3e-b687-5858453777bc</value>
        <value name="businessContext">wm6:bfd23a95-1c84-4e3e-b687-5858453777bc\snull\
snull:wm6bfd23a95-1c84-4e3e-b687-5858453777bc:null:IS_61:null</value>
        <value name="uuid">wm:c3fb4d30-2f23-11ec-8723-000000000002</value>
        <value name="trackId">wm:c3fb4d30-2f23-11ec-8723-000000000002</value>
        <value name="pubId">islocalpubid</value>
        <Date name="enqueueTime" type="java.util.Date">Sun Oct 17 13:55:20 IST 2021</Date>
        <Date name="recvTime" type="java.util.Date">Sun Oct 17 13:55:20 IST 2021</Date>
        <number name="age" type="java.lang.Integer">0</number>
      </record>
    </record>
  </record>
</IDataXMLCoder>

Cluster Support for Polling Notifications

When Integration Servers are deployed in a cluster, the servers in that cluster automatically share information about the registered polling notifications. The adapter runtime automatically coordinates polling and some callbacks among instances of the same polling notification node on different servers in a cluster.

This coordination of clustered polling notifications requires no special coding by the adapter developers. However, there are design considerations for adapters that is used in a cluster. There are also global, adapter-specific, and node-specific configuration options that control how coordination is performed. At a minimum, adapter developers must specify configuration values that are appropriate for the adapter.

Callback Coordination

When a callback is coordinated across the cluster, that callback is only executed on one instance of the polling notification in the cluster. For example, if the enableCallBack is coordinated, the first polling notification in the cluster that is enabled, executes the enableCallBack. When subsequent instances of that notification are enabled, the enableCallBack call is suppressed. If the callbacks were not coordinated, each instance executes the enableCallBack when the node instance is enabled.

The purpose of callback coordination is to prevent redundant updates to the backend associated with starting or stopping a notification. For example, when the disableCallBack is called on a polling notification for the Adapter for JDBC, a database trigger that gathers information for the notification is removed. Without coordination, all instances of that notification would be effectively disabled as soon as the first instance is disabled. With coordination, the disableCallBack is not executed until the last instance of that notification in the cluster is disabled.

From a design standpoint, it is important to segregate management of resources on the backend in separate callbacks from management of resources that are local to the notification instance. Callback coordination is configured so that related pairs of callbacks are either coordinated, or not. The following pairs of callbacks may be coordinated:

Coordinated Callback Pairs Description
enableCallBack and disableCallBack This occurs when the persistent node state is changed from disabled or changed to disabled. When coordinated, the first instance to go from disabled to enabled executes the enableCallBack method and the last instance to go from either suspended or enabled to disabled executes the disableCallBack method.
startupCallBack and shutdownCallBack This occurs when the node becomes active or inactive for any reason, including when the node is enabled, disabled, suspended, or resumed (if the node is enabled, it also includes Integration Server and package startup or shutdown). When coordinated, the first instance to become active will execute the startupCallBack and the last instance to become inactive executes the shutdownCallBack.
suspendCallBack and resumeCallBack This occurs when the node is suspended or resumed. When coordinated, the first instance to go from enabled to suspended executes the suspendCallBack and the last instance to go from either suspended to enabled executes the resumeCallBack.

For information on how to configure callback coordination, see Configuration Settings.

Polling Coordination

When a polling notification is started, it executes polls in an interval according to its schedule configuration. When polling is coordinated across a cluster, a poll is executed on only one of the active instances at each scheduled interval. Which instance executes depends on the configuration and timing.

Integration Server supports a coordination mode configuration setting for each polling notification node. This configuration is normally set from Integration Server Administrator on the same page where the schedule is set. The following coordination mode values are supported:

Coordination Mode Setting Description
Disabled Disables all cluster coordination for this node (both polling and callback coordination). Instances of this node act independently without considering the cluster.
Standby The first instance of this notification to start executes all polls until that instance either shuts down or fails. When that occurs, the first active notification instance that detects that the original instance is no longer polling take its place.
Distributed Behaves much like standby, except that at the end of each interval, the instance that first detects that the time to poll has arrived executes the poll. When the Integration Server clocks are properly synchronized, generally the server with the lightest load executes the poll.

The coordination information for clustered polling notifications is stored in the cluster’s shared cache.

All coordination of clustered polling notifications is done through an entry specific to the node in the cluster's shared cache. When the first instance of a notification (with coordination enabled) is introduced into a cluster, a new shared cache session is created and populated with the name of the server hosting the node, and the state of the node. As that node is copied to other servers in the cluster, each instance is registered in the same shared cache session. The states of these respective instances are used to determine when coordinated callbacks must be executed.

Important: Always copy polling notification nodes instead of creating new nodes with the same name and configuration. Each polling notification node is created with a GUID that forms part of the message ID of all documents published by the notification. If the instances do not have the same GUID, it can interfere with duplicate-message detection facilities.

When the first instance of a clustered polling notification is started, that instance is marked as "primary", its schedule and coordination settings are recorded, and the time calculated for the next poll are all recorded in the shared cache session. Being "primary" means that first instance executes the first poll (barring failures). When the "primary" schedules the next poll, it releases the "primary" status if coordination is distributed, or retains it if coordination is configured for standby mode.

When another instance of a clustered polling notification starts, that instance first detects that a previous instance is already started. Since this instance is not the first, it overwrites its own cluster and schedule settings with those recorded in the shared cache. This instance then schedules itself to "wake up" at the next scheduled poll time. When it wakes up, if another instance is marked as "primary", the notification instance will verify that the indicated instance is still active, then reschedule itself to wake up periodically until it detects that the poll was completed within the configured time limit. It then reschedules itself to wake up at the next scheduled poll and repeats the process. If the polling time arrives and no instance is marked as "primary", or it detects that the "primary" instance is no longer functioning, then the local instance assumes the "primary" role and executes the poll as described above. Since all coordination is based on timestamps recorded in the shared cache, it is very important for server clocks to be synchronized.

Configuration Settings

Cluster coordination is controlled by a number of configuration settings to control behavior and tune failure detection using timeouts.

Global Settings

The following parameters are set in the server.cnf file and apply globally to all clustered notifications for all adapters:

Parameter Name Description
watt.art.
clusteredPollingNotification.
keepAliveInterval
Interval in milliseconds, with which a secondary instance will check to see if an executing instance is still alive. If not set, the secondary instance will change to the default maxLockDuration value of 180000 for the shared cache.
watt.art.
clusteredPollingNotification.
keepAliveExpireTimeout
Time in milliseconds, that an executing node can be late before it is assumed to have failed. In general, this setting must be equal to the amount of drift anticipated on the server clocks. If not set, the secondary instance will change to the default maxLockDuration value of 180000 for the shared cache.
Note: The parameters can also be set using Integration Server Administrator. For more information, see IBM webMethods Integration Server Administrator’s Guide.

Adapter-Specific Settings

In the configuration directory of the adapter's package, the clusterProperties.cnf provides settings that specify a callback scheme, and place limits on which coordination modes can be applied to notification nodes for the adapter. The clusterProperties.cnf file is an XML file in which settings may be provided globally for the adapter or specifically to a particular notification template. Template-specific settings use the template class name to set the scope of the setting. The clusterProperties.cnf file is located in the Integration Server_directory\instances\instance_name\packages\AdapterName\config folder.

The following example includes all of the major constructs of a clusterProperties.cnf file:

<?xml version="1.0"?>  
<clusterProps>  
  <pollingNotifications>  
    <callbackScheme>1</callbackScheme>  
    <runtimeModeLimit>distribute</runtimeModeLimit>  
    <template className="com.wm.adapter.wmarttest.notification.LatchedPollingNotification">  
       <callbackScheme>1</callbackScheme>  
       <runtimeModeLimit>standby</runtimeModeLimit>  
    </template>  
  </pollingNotifications>  
  <listenerNotifications>  
    <callbackScheme>1</callbackScheme>  
  </listenerNotifications>  
  <listeners>  
    <runtimeModeLimit>standby</runtimeModeLimit>  
  </listeners>  
</clusterProps>

The outer <clusterProps> wrapper contains the following three elements:

  • <pollingNotifications> wraps settings for clustered polling notifications. The <pollingNotifications> wrapper must contain the following global settings that provide the adapter's default values:
    • A <callbackScheme>
    • A <runtimeModeLimit>

    These can be followed by any number of template wrappers, which contain the <callbackScheme> and <runtimeModeLimit> settings specific to each template. Template specific settings are applied to notification nodes created from the associated template name.

    The <callbackScheme> setting controls how callback coordination is performed, while <runtimeModeLimit> constrains the coordination mode setting that can be set for a notification node. Valid values for these settings are included in the following tables.

    Table 1. Values for callbackScheme Setting
    Coordination Modes
    callbackScheme Enable/Disable Startup/Shutdown Resume/Suspend
    0 No Coordination No Coordination No Coordination
    1. Default Coordinated No Coordination No Coordination
    2 No Coordination Coordinated No Coordination
    3 Coordinated Coordinated No Coordination
    4 No Coordination No Coordination Coordinated
    5 No Coordination Coordinated Coordinated
    6 Coordinated No Coordination Coordinated
    7 Coordinated Coordinated Coordinated
    Table 2. Values for runtimeModeLimit Setting
    runtimeModelLimit Result
    disable Nodes created using this template cannot be coordinated across a cluster. Nodes are forced into the disabled coordination mode.
    standby. Default Nodes can be coordinated in standby mode or coordination may be disabled.
    distribute Nodes can be coordinated in distributed or standby mode, or coordination may be disabled.

    When a polling notification is created or registered on a cluster-aware Integration Server, the Integration Server looks for a clusterProperties.cnf file in the adapter's config directory. If the file contains no entry for the notification's template, a new <template> entry is created using the settings specified globally for all polling notifications. If the file is completely absent or unreadable, a new file is created using the default settings identified earlier.

  • <listenerNotifications> is for future use. Copy wrapper and contents from the example.
  • <listeners> is for future use. Copy wrapper and contents from the example.

Node-Specific Settings

The polling notification schedule page in Integration Server Administrator includes cluster settings that are only editable in a clustered environment. On this page, the coordination mode may be set to one of the values supported by its template. For more information, see runtimeModeLimit earlier. In addition, timeouts may be separately configured for polling and setup callback operations.