Adapter Definition

Overview

An adapter definition is the framework of an adapter. The adapter definition is recognized as an adapter by Integration Server, but lacks functionality. This chapter describes how to create an adapter definition.

To create an adapter definition, perform the following tasks:

  • Create a IBM webMethods package for the adapter definition.
  • Create an adapter definition implementation class by extending the com.wm.adk.WmAdapter base class. The adapter definition implementation class represents the main class of the adapter. In this class, create services and methods that:
    • Describe the adapter to Integration Server.
    • Describe the adapter's resources to Integration Server, including its connection factories, notification templates, and its default resource bundle implementation class.
    • Initialize resources and properties referenced by the adapter definition when the adapter is enabled, and clean up the resources when the adapter is disabled (optional).
    • Load the adapter onto Integration Server when the adapter is enabled, and unload the adapter when the adapter is disabled.

    For more information, see Creating a WmAdapter Implementation Class.

  • Create one or more resource bundles.

    The resource bundle class must extend the java.util.ListResourceBundle base class, and contain all the display strings and messages used by the adapter at run time and at design time. A resource bundle is specific to a particular locale. If you plan to run your adapter in multiple locales, you can include a resource bundle for each locale. Creating a resource bundle for each locale enables you to internationalize an adapter quickly, without having to change any code in the adapter. Each adapter must have one or more resource bundles. For more information, see Creating Resource Bundles.

  • Deploy the adapter.
    • Create the startup and shutdown Java Services.
    • Compile the adapter definition.

      Compile your implementation class and construct the Java service nodes for your startup and shutdown services. The ADK provides a sample ANT script that you can run from the packages folder.

    • Configure the startup and shutdown Java Service in Designer.

    For more information, see Deploying the adapter.

Finally, the users of the adapter use Integration Server Administrator to load the adapter by enabling the adapter package. For more information, see Package Management.

Creating an Adapter Package

Create an adapter package in the same way you create any webMethods package, using Designer. If you need instructions for creating a package, see the IBM webMethods Service Development Help for your release.

Designer creates a folder structure in which you can develop your adapter, as shown.
Note:
  • You must use the adapterPackageName\code\source folder as your source base and create directories corresponding to your Java package structure (for example, com\mycompany\adapter\myadapter).
  • You must set the package dependency as follows:
    Field Value
    Package WmART
    Version *.*
    The WmART package is installed when you install Integration Server.

The following figure shows the webMethods package structure:

Adapter Definition Classes

Adapter Definition Implementation Classes (Example MyAdapter)

Creating a WmAdapter Implementation Class

Create an adapter definition by extending the com.wm.adk.WmAdapter base class. This class represents the main class of the adapter. In this class, you create services and methods that:

  • Describe the adapter to Integration Server.
  • Describe the adapter's resources to Integration Server.
  • Initialize and cleanup resources.
  • Add custom Dynamic Server Pages (DSPs) to your adapter's administrative interface.

This section describes the basic steps for implementing an adapter definition.

Describing the Adapter to Integration Server

Create an adapter definition by extending the com.wm.adk.WmAdapter base class. You must override the following base class methods in your WmAdapter implementation class:

Name Description
getAdapterName Returns the internal name of the adapter. This name is used to identify the text fields in the resource bundle, and to identify the relationship between the adapter and its associated namespace nodes. For this reason, it is important that the value returned by this method does not change after namespace nodes have been created. This name must be unique within the scope of Integration Server.
getAdapterVersion Returns the current version of the adapter. This value appears in the adapter's About page. This must not be confused with the package version used when setting package dependencies.
getAdapterJCASpecVersion Returns the JCA standard version supported by the adapter. This value must always be 1.0.
getAdapterMajorCode Must return a unique numeric value (if required) that you can obtain from IBM.

Every adapter built using the ADK requires an internal ID called a major code. A major code is an integer ID that Integration Server uses to distinguish journal log information between different adapter types. The major code is a four digit number between 1 and 9999.

Each adapter implementation must have a major code that is unique from all other adapters built using the ADK that might be present in the same webMethods environment. Adapters with identical major codes generate an error in the Integration Server log. More importantly, Integration Server log entries from same code adapters is indistinguishable.

The major code ranges are reserved as follows:

Major Code Range Description
1-6999 This range is reserved for Software AG built webMethods commercial adapters.
7000-8999 This range is reserved for adapters built by IBM Development Partners. If you are a Development Partner, you must register your major code with IBM.
9000-9999 This range is reserved for adapters you build for use within your own organization. You do not have to register the major codes for these adapters unless you are running them in an environment where the adapters' major codes conflict with other adapters in your webMethods environment.
getAdapterResourceBundleName Returns the name of your ListResourceBundle implementation class. The value must be the fully qualified name of the resource's associated implementation class rather than an object instance.
fillAdapterTypeInfo Sets the names of all connection factory and notification implementation classes in an AdapterTypeInfo object.
supportsParallelAssetInitialization Indicates if the adapter supports parallel asset initialization. The default return value is false. Override this method and use the watt property for the adapter to enable or disable parallel asset initialization.

Describing the Adapter's Resources to Integration Server

The adapter resources that you must describe to Integration Server include:
  • All connection factories and notification templates that the adapter supports. You set the names of all connection factory and notification implementation classes in an AdapterTypeInfo object in your adapter's implementation of the fillAdapterTypeInfo method. Set these names later, when you implement the connections and notifications.
  • The default resource bundle implementation class. Create a default resource bundle by extending the java.util.ListResourceBundle base class. Deliver the name of your ListResourceBundle implementation class in your adapter's implementation of the getAdapterResourceBundleName method.

Initializing and Cleaning Up

Initialize and clean up the resources used in your adapter implementation. In your WmAdapter implementation class, you can initialize resources and properties specific to your adapter when the adapter is enabled and release the resources when the adapter is disabled. Resources held by connections, adapter services, and notifications have their own cleanup mechanisms.

For example, you might initialize the ARTLogger resource.
  • There can be only one ArtLogger instance per adapter (that is, per major code). You must manage the ArtLogger instance in your WmAdapter implementation class, but it is optional. You must use a static accessor method, which facilitates access to the ArtLogger instance. In the example, this is accomplished using the getLogger method.
  • You must release the ArtLogger instance (and the adapter's major code) using the ArtLogger.close method when the adapter is disabled,. In the example, this is accomplished using MyAdapter.cleanup, which is called from AdapterAdmin.unregisterAdapter.
  • You can also use an ARTLogger object to generate journal log entries for your adapter.

Adding Custom DSPs to the Adapter Interface

By default, the adapter's administrative interface includes DSPs for connections, polling notifications, listeners, and listener notifications. You may add custom DSPs by overriding the following public methods provided in the com.wm.adk.WmAdapter abstract class:
Method Description
getUiItemNames Returns a list of the label strings to insert in the left hand panel of the Integration Server Administrator page for the adapter. Each label represents a link to the DSP to be executed.
getUiItemUrl
(String itemName)
Returns the URL of the DSP associated with the given itemName. This effectively binds the displayable item link/label name with the DSP to launch when the users of the adapter select that link. The URL is relative to the packages folder of the server installation. For example, if your adapter name is WmFoo and your DSP is bar.dsp, the URL would be \WmFoo\bar.dsp. In the file system, however, the .dsp file actually resides in packages\WmFoo\pub\bar.dsp; the pub folder is not included in the URL. You may also append arguments to the URL, using the standard notation ?=.
getUiItemHelp
(String itemName)
Returns the URL of the help file describing the custom DSP page associated with the given itemName. The pathname requirements are the same as for getUiItemUrl(). For example, if your help file is located in \WmFoo\pub\bar_dsp.html, the path returned by this method must be \WmFoo\bar_dsp.html.

The labels for these DSPs appear in the navigation area in the left hand window of the interface, immediately below the default labels (the Connections, Polling Notifications, Listeners, and Listener Notifications labels) but above the About label.

For information about creating DSPs, see Dynamic Server Pages and Output Templates Developer’s Guide.

Internationalization Considerations for Custom DSPS

You are responsible for implementing these methods (and the associated DSPs) in a manner that takes into consideration the client's locale. In particular, the implementation of getUiItemNames method must perform the necessary resource domain lookups in order to return locale specific values. The system does not automatically perform these lookups for you.

Creating WmAdapter Implementation Class with example

Procedure

  1. Create a folder structure for the Java package for adapter implementation. For example: com\mycompany\adapter\myadapter. In the example, the Java package created is com\wm\MyAdapter.
    Note: You must create your Java package and classes in the adapterPackageName\code\source folder in the IBM webMethods package you created using Designer.
  2. Create an interface that contains the constants for the adapter implementation.
    In the example, create MyAdapterConstants interface:
    
    package com.wm.MyAdapter;
    
    public interface MyAdapterConstants {
    	
    	static final int ADAPTER_MAJOR_CODE = 9001;
     static final String ADAPTER_JCA_VERSION = "1.0";
    	static final String ADAPTER_NAME = "MyAdapter";
    	static final String ADAPTER_VERSION = "9.12";
    			
    	//Using next statement creates cyclic class loading dependency issue
    	//therefore, the resource bundle class name is fully spelled out
    	//static final String ADAPTER_SOURCE_BUNDLE_NAME = MyAdapterResource.class.getName();
     static final String ADAPTER_SOURCE_BUNDLE_NAME =
    		"com.wm.MyAdapter.MyAdapterResource";
    }
  3. Create a class by extending the com.wm.adk.WmAdapter base class.
    • Your WmAdapter implementation class (MyAdapter) must call the base class constructor (super()). The base class constructor calls several of the implementation class's methods and instantiates your resource bundle.
    • The base class constructor calls several of the implementation class's methods after the first call to getInstance. It is vital that they do not invoke another call to getInstance which results in an endlessly recursive call to the constructor, and ultimately crashes the JVM and bring down Integration Server. This must be avoided in static initializers in your resource bundle as some of the resource bundles are keyed on the same string that is returned from MyAdapter.getAdapterName. Do not populate the string in a static initializer. This line of code in a static initializer of a resource bundle produces an undesirable results:
      {MyAdapter.getInstance().getAdapterName() +  
      ADKGLOBAL.RESOURCEBUNDLEKEY_DISPLAYNAME, "My Adapter"}
    • When specifying any resource, you must use the fully qualified name of the resource's associated implementation class (rather than an object instance).

    In the example, create MyAdapter class:

    
    package com.wm.MyAdapter;
    
    import java.util.Locale;
    
    import com.wm.adk.WmAdapter;
    import com.wm.adk.error.AdapterException;
    import com.wm.adk.info.AdapterTypeInfo;
    import com.wm.adk.log.ARTLogger;
    
    
    public class MyAdapter extends WmAdapter implements MyAdapterConstants{
    
    	public static MyAdapter _instance = null;
    	public static ARTLogger _logger = null;
    	
    	public MyAdapter() throws AdapterException {		super();	}
    
    	public void fillAdapterTypeInfo(AdapterTypeInfo arg0, Locale arg1) {}
    	public String getAdapterJCASpecVersion() {		return ADAPTER_JCA_VERSION; 	}
    	public int getAdapterMajorCode() {  return ADAPTER_MAJOR_CODE; 	}
    	public String getAdapterName() {		return ADAPTER_NAME; 	}
    	public String getAdapterResourceBundleName() { 		return ADAPTER_SOURCE_BUNDLE_NAME;	}
    	public String getAdapterVersion() {		return ADAPTER_VERSION;	}
     public static ARTLogger getLogger() { 		return _logger;	}
    
    	
    public void initialize() throws AdapterException {
    		// TODO Auto-generated method stub
    		_logger = new ARTLogger(getAdapterMajorCode(),
    				getAdapterName(),
    				getAdapterResourceBundleName());
    		_logger.logDebug(9999,"My Adapter Initialized");
    	}
    
    	public void cleanup() {
    		if (_logger != null)
    			_logger.close();
    	}
    	
    public static MyAdapter getInstance() {
    		// TODO Auto-generated method stub
    		if (_instance != null)
    			return _instance;
    		else {
    			synchronized (MyAdapter.class) {
    				if (_instance != null) {
    					return _instance;
    				}
    				try {
    					_instance = new MyAdapter();
    					return _instance;
    				} catch (Throwable t) {
    					t.printStackTrace();
    					return null;
    				}
    			}
    		}
    	}
    }

Creating Resource Bundles

A resource bundle describes the adapter resources to Integration Server. For example, connection factories, notification templates. You set the names of all connection factories and notification implementation classes in an AdapterTypeInfo object in your adapter's implementation of the fillAdapterTypeInfo method. Set these names when you implement the connections and notifications.

  • A resource bundle contains all the display strings and messages used by the adapter at run time and at design time.
  • A resource bundle is specific to a particular locale. If you plan to run your adapter in multiple locales, you can include multiple locale specific resource bundles. Creating a resource bundle for each locale enables you to internationalize an adapter quickly, without having to change any code in the adapter. An adapter must have one or more resource bundles.
  • A resource bundle consists of lookup keys that provide locale specific objects (normally text strings). A lookup key consists of a constant provided by the com.wm.adk.ADKGLOBAL class (a class provided by the ADK's API) combined with your adapter's class name or a parameter name. For a list of these constants, see Resource Bundle Lookup Keys. For example, the ADK uses the following lookup key whenever the display name of the adapter is required. (Assume that the MyAdapter.getAdapterName method returns the class name MyAdapter where MyAdapter is the WmAdapter implementation class.)
    MyAdapter.class.getName() + ADKGLOBAL.RESOURCEBUNDLEKEY_DISPLAYNAME

    The following lookup key produces a description for a parameter named password, which is used to configure a connection pool:

    "password" + ADKGLOBAL.RESOURCEBUNDLEKEY_DESCRIPTION

    The adapter automatically references lookup keys to provide the following:

    • Display names, and property descriptions of the:
      • Adapter definition
      • Connection types
      • Adapter service templates
      • Polling notification templates
    • Text, display names, and property descriptions for the following elements of your adapter:
      • Parameters used to configure nodes
      • Metadata group names
      • Log entries
      • Exception text
Note: You may also make explicit use of a resource bundle to localize other data, such as resource domain values, especially if those values are known at development time (for example, a list of known record status values). In these cases, the strategy for key composition is left to your discretion. For more information, see Using Resource Bundles with Resource Domain Values. Resource domain values are discussed in detail in Resource Domains.

Resource Bundle Lookup Keys

The following table describes the automatic resource bundle lookups performed for each type of adapter element, and describes how the results are used.

Adapter Element Key Format Usage
Adapter definition
adapterName + 
ADKGLOBAL.
RESOURCEBUNDLEKEY_DISPLAYNAME
Required. Displays adapter name in Integration Server Administrator and in adapter interface.
adapterName + 
ADKGLOBAL.
RESOURCEBUNDLEKEY_DESCRIPTION
Required. Displays adapter description in adapter interface's About window.
adapterName + 
ADKGLOBAL.
RESOURCEBUNDLEKEY_VENDORNAME
Optional. Displays adapter vendor name in adapter interface's About window.
adapterName + 
ADKGLOBAL.
RESOURCEBUNDLEKEY_
THIRDPARTYCOPYRIGHTURL
Optional. Displays adapter's copyright for third parties in the adapter interface's About window.
adapterName + 
ADKGLOBAL.
RESOURCEBUNDLEKEY_
COPYRIGHTENCODING
Optional. Encoding used to display adapter's copyright for third parties in the adapter interface's About window.
Required only if the
ADKGLOBAL.
RESOURCEBUNDLEKEY_
THIRDPARTYCOPYRIGHTURL

is specified.
Connection type
ConnectionFactoryName.class.getName() +
ADKGLOBAL.
RESOURCEBUNDLEKEY_DISPLAYNAME
Displays connection type column in adapter interface.
ConnectionFactoryName.class.getName() +
ADKGLOBAL.
RESOURCEBUNDLEKEY_DESCRIPTION
Displays description column in connection type listing when configuring connections.
Adapter service template
AdapterServiceName.class.getName() +
ADKGLOBAL.
RESOURCEBUNDLEKEY_DISPLAYNAME
Displays adapter service template name when selecting a template to create an adapter service in Designer.
AdapterServiceName.class.getName() +
ADKGLOBAL.
RESOURCEBUNDLEKEY_DESCRIPTION
Displays adapter service template description when selecting a template to create an adapter service in Designer.
Polling notification template
AdapterNotificationName.class.getName() +
ADKGLOBAL.
RESOURCEBUNDLEKEY_DISPLAYNAME
Displays template name column when selecting a template to create polling notification in Designer.
AdapterNotificationName.class.getName() +
ADKGLOBAL.
RESOURCEBUNDLEKEY_DESCRIPTION
Displays template description column when selecting a template to create polling notification in Designer.
Parameters used to configure nodes
parameterName +
ADKGLOBAL.
RESOURCEBUNDLEKEY_DISPLAYNAME
Displays property display name when editing connection, adapter service, and polling notification properties in adapter interface and Designer.
parameterName + 
ADKGLOBAL.
RESOURCEBUNDLEKEY_DESCRIPTION
Displays tool tip when mouse is over parameter name when editing service and polling notification properties in Designer.
Metadata group names
groupName + 
ADKGLOBAL.RESOURCEBUNDLEKEY_DISPLAYNAME
Displays property display name when editing parameter group for polling notification in Designer.
groupName + 
ADKGLOBAL.
RESOURCEBUNDLEKEY_GROUPURL
Overrides Designer help hyperlink on each tab associated with group.
Log entries
new Integer(minorCode).toString()
Text in all log repositories (server locale)
Exception text
new Integer(minorCode).toString()
Text in all log repositories (server locale)
Note: By default, if you do not specify the DISPLAYNAME lookup key in your resource bundle, the parameter or class name is used as the display name. Other lookup keys that are not specified, display nothing.
Considerations for Adapter Definition Lookup Keys

As specified in the preceding table, the lookup keys specifying the adapter's display name, description, and vendor name are required. All other lookup keys are optional, but not specifying the optional lookup keys, can result in generating error messages in the log, thereby making the adapter more difficult to use.

The adapterName reference in the Key Format column of the preceding table refers to the name of the adapter returned by the WmAdapter implementation class's method getAdapterName. You may use the name of your WmAdapter implementation class if it is also returned by the getAdapterName method.
Note: The adapter name must be unique within the scope of Integration Server.

Alternatively, you may define a constant that both the lookup key and getAdapterName use. However, do not call WmAdapter implementation class's getInstance.getAdapterName method to retrieve the adapter name from either of these static initializers, or in the resource bundle constructor. Integration Server instantiates the resource bundle data during execution of the WmAdapter implementation class's constructor super(); calling getInstance method from that point produces undesirable results.

Considerations for Specifying URLs in Resource Bundles

Some lookup keys reference documents, such as copyright and other information. If you include these document files with your adapter, place them under adapterPackageName\pub (where adapterPackageName is the file system folder under the Integration Server's packages folder where your adapter resides). For more information about the Integration Server file system structure, see Creating an Adapter Package.

In your lookup key, identify the resource file using the file path relative to the pub subfolder. For example, to specify the location of the copyright file for MyAdapter, a resource bundle would include the data value:

{ADAPTER_NAME + 
ADKGLOBAL.RESOURCEBUNDLEKEY_THIRDPARTYCOPYRIGHTURL, 
IS_PKG_NAME + "copyright.html"}

This relative path is equivalent to the following path:

Integration Server_directory\instance\<instance_name>\packages\MyAdapter\pub\copyright.html

This relative path scheme must be used for all URL references used by Designer as well as for the ADKGLOBAL. RESOURCEBUNDLEKEY_ THIRDPARTYCOPYRIGHTURL clause. Other URL references accessed through the Integration Server Administrator or the adapter's administrative interface may use other URL referencing schemes such as absolute paths or valid Internet addresses.

Creating Resource Bundles Class With Example

About this task

To create a resource bundle implementation class

Procedure

  1. Create a class by extending the base class java.util.ListResourceBundle in the same Java package that you created for WmAdapter implementation class. For example: com\mycompany\adapter\myadapter.
    Note: You must create your class in the same adapterPackageName\code\source folder in which you created your WmAdapter implementation class in the IBM webMethods package you created using Designer.
    In the example, the MyAdapterResource class in folder com\wm\MyAdapter. In the example, the Java package created is com\wm\MyAdapter.
    
    package com.wm.MyAdapter;
    
    import java.util.ListResourceBundle;
    import com.wm.adk.ADKGLOBAL;
    
    
    public class MyAdapterResource extends ListResourceBundle implements MyAdapterConstants{
    
      static final String IS_PKG_NAME = "/MyAdapter/";
    
    	 static final Object[][] _contents = {
       // adapter type display name.
       {ADAPTER_NAME + ADKGLOBAL.RESOURCEBUNDLEKEY_DISPLAYNAME, "My Adapter"}
       // adapter type descriptions.
       ,{ADAPTER_NAME + ADKGLOBAL.RESOURCEBUNDLEKEY_DESCRIPTION,
        "Adapter for MyAdapter Server (a Sample System)"}
       // adapter type vendor.
       ,{ADAPTER_NAME + ADKGLOBAL.RESOURCEBUNDLEKEY_VENDORNAME, "Software AG"}
       //Copyright URL Page
       ,{ADAPTER_NAME + ADKGLOBAL.RESOURCEBUNDLEKEY_THIRDPARTYCOPYRIGHTURL, 
        IS_PKG_NAME + "copyright.html"}
       //Copyright Encoding
       ,{ADAPTER_NAME + ADKGLOBAL.RESOURCEBUNDLEKEY_COPYRIGHTENCODING, "UTF-8"}
    		 //About URL Page
       ,{ADAPTER_NAME + ADKGLOBAL.RESOURCEBUNDLEKEY_ABOUT, IS_PKG_NAME + "About.html"}
       //Release Notes URL Page
       ,{ADAPTER_NAME + ADKGLOBAL.RESOURCEBUNDLEKEY_RELEASENOTEURL, IS_PKG_NAME + "ReleaseNotes.html"}
      };
    
      protected Object[][] getContents() {
       // TODO Auto-generated method stub
       return _contents;
      }
    }
  2. You can create multiple resource bundle classes.
    Use the following naming convention to create multiple resource bundle classes:
    ResourceBundleName ResourceBundleName_locale

    For example, a default resource bundle and a corresponding locale specific bundle for use in Japan might be named:

    MyAdapterResourceBundle  
    MyAdapterResourceBundle_ja
    For more information about resource bundle naming conventions, see the Javadoc for java.util.ResourceBundle.
    Note: For each resource bundle lookup, the adapter uses the default resource bundle if a bundle specific to the target locale is not available.
  3. In your subclass, create resource bundle lookup keys.
  4. Specify the adapter’s default resource bundle in your WmAdapter implementation class. You can return the name of your default resource bundle using the getAdapterResourceBundleName method in your WmAdapter implementation class.
    In the example, the MyAdapter class's getAdapterResourceBundleName method returns the constant ADAPTER_SOURCE_BUNDLE_NAME, which is initialized in interface MyAdapterConstants interface.

    Example of getAdapterResourceBundleName method in MyAdapter class:

    	
     @Override
    	public String getAdapterResourceBundleName() {
    		// TODO Auto-generated method stub
    		return ADAPTER_SOURCE_BUNDLE_NAME;
    	}

    Example ofADAPTER_SOURCE_BUNDLE_NAME constant in MyAdapterConstants interface:

    	
    static final String ADAPTER_SOURCE_BUNDLE_NAME =
    		"com.wm.MyAdapter.MyAdapterResource";
  5. Create the reference pages for copyright, and index page for the adapter in adapterPackageName/pub folder.
    • In the adapters administrative interface, select About, the about page appears with the display name, description and copyright.
    • In the Integration Server Administrator, select Packages > MyAdapter > Home, the index page appears.
    Note: You must create your reference pages in the same adapterPackageName/pub folder in the IBM webMethods package you created using Designer.

Deploying the adapter

The users of the adapter explicitly load and unload an adapter by enabling and disabling the adapter package, using Integration Server Administrator. This section describes:

  • Creating Adapter Startup and Shutdown Java Services.
  • Compiling the Adapter.
  • Registering the Adapter Startup and Shutdown Java Services in Integration Server.
  • Debugging the Adapter.
  • Loading the Adapter.
  • Unloading the Adapter.

This section describes the basic steps for deploying, and debugging an adapter definition.

Creating Adapter Startup and Shutdown Java Services

The adapter must have one Java Service each for startup and shutdown.
  • The startup method must retrieve an instance of your WmAdapter implementation class and pass it to AdapterAdmin.registerAdapter method.
  • The shutdown service must perform the following:
    • Retrieve an instance of your WmAdapter implementation class and pass it to AdapterAdmin.unregisterAdapter method.
    • Perform the cleanup operations needed by your adapter. In most cases, this is accomplished by calling MyAdapter.cleanup method before the call to AdapterAdmin.unregisterAdapter method.
You can create the startup and shutdown Java Services in two ways:
  1. Create adapter admin Java class, which is used to generate corresponding Java Services using jcode utility.
  2. Create Java Services using Designer, which is compiled using Integration Server Administrator.

Creating Java Classes for Adapter Startup and Shutdown

Procedure
  1. Create a folder structure for the Java package for adapter admin class. For example: adapterPackageName\code\source\wm\mycompany\adapteradmin. In the example, the Java package created is adapterPackageName\code\source\wm\MyAdapter.
    Note: You must create your Java package and classes in the adapterPackageName\code\source folder in the IBM webMethods package you created using Designer.
  2. Create adapter admin Java class.
    In the example, class MyAdapterAdmin is created:
    
    package wm.MyAdapter;
    
    //--- <<IS-START-IMPORTS>> ---
    import com.wm.MyAdapter.*;
    import com.wm.adk.admin.AdapterAdmin;
    import com.wm.app.b2b.server.ServiceException;
    import com.wm.data.IData;
    //--- <<IS-END-IMPORTS>> ---
    
    public class MyAdapterAdmin {
        
        public static final void startUp (IData pipeline)
                throws ServiceException
        {
            // --- <<IS-START(startUp)>> ---
            AdapterAdmin.registerAdapter(MyAdapter.getInstance());
            // --- <<IS-END>> ---         
        }
        public static final void shutDown (IData pipeline)
                throws ServiceException
        {
            // --- <<IS-START(shutDown)>> ---
    		      MyAdapter instance = MyAdapter.getInstance();
            instance.cleanup();
            AdapterAdmin.unregisterAdapter(instance);
            // --- <<IS-END>> ---                
        }
    }
    Note: Tags are used to mark the beginning and end of imports and methods. For more information, see IBM webMethods Service Development Help.

Creating Java Services for Adapter Startup and Shutdown using Designer

Procedure
  1. Start Designer.
  2. Select the IBM webMethods package you created using Designer.
  3. Create a folder structure for the Java package for adapter admin Java Services. In the example, the folder structure created is adapterPackageName\code\source\wm\MyAdapter\MyAdapterAdmin.
    Note: You must create your Java package and classes in the adapterPackageName\code\source folder in the IBM webMethods package you created using Designer.
  4. Create a new Java Service for adapter startup. In the example, the Java Service created is startUp.
    1. Add the following Java code.
      public static final void startUp(IData pipeline) throws ServiceException {
      				// --- <<IS-START(startUp)>> ---
      				AdapterAdmin.registerAdapter(MyAdapter.getInstance());
      				// --- <<IS-END>> --- 
      	}
      Note: Tags are used to mark the beginning and end of imports and methods. For more information, see IBM webMethods Service Development Help.
  5. Create a new Java Service for adapter shutdown. In the example, the Java Service created is shutDown.
    1. Add the following Java code.
      public static final void shutDown(IData pipeline) throws ServiceException {
      	  // --- <<IS-START(shutDown)>> ---
      	  MyAdapter instance = MyAdapter.getInstance();
      	  instance.cleanup();
      	  AdapterAdmin.unregisterAdapter(instance);
      	// --- <<IS-END>> ---
      }
      Note: Tags are used to mark the beginning and end of imports and methods. For more information, see IBM webMethods Service Development Help.

Compiling the Adapter

About this task

Before you load your adapter, you must compile your implementation classes and construct the Java Service nodes for your startup and shutdown services.

Procedure

  1. Create an ANT script to compile the adapter implementation and admin classes, and deploy these classes in Integration Server as Java Services. In the example, the ANT script created is build.xml and build.properties.
    Note: You must create your ANT script in the adapterPackageName\code\source folder in the IBM webMethods package you created using Designer.
    For example build.properties:
    # The Site Name
    debug=on
    optimize=off
    deprecation=off
    webM.home=C:/softwareag/912
    server.home=${webM.home}/IntegrationServer
    package=MyAdapter
    instance_name=default
    srcdir=${server.home}/instances/${instance_name}/packages/${package}/code/source
    destdir=${server.home}/instances/${instance_name}/packages/${package}/code/classes
    
    For example build.xml:
    <?xml version="1.0"?>
    <project name="Adapter using ADK" default="deploy" basedir=".">
    	<property file="build.properties" />
    	<!-- classes belonging to this package -->
    	<path id="this.package.classpath">
    		<fileset dir="${server.home}/instances/${instance_name}/packages/${package}/">
    			<include name="code/classes"/>
    		</fileset>
    	</path>
    
    	<!-- All classes that need to be found by this script -->
    	<path id="total.classpath">
    		<pathelement location="${server.home}/instances/${instance_name}/packages/WmART/code/jars/wmart.jar"/>
    		<pathelement location="${server.home}/lib/wm-isserver.jar"/>
    		<pathelement location="${webM.home}/common/lib/wm-isclient.jar"/>
    		<pathelement location="${webM.home}/common/lib/glassfish/gf.jakarta.resource.jar"/>
    		<pathelement location="${server.home}/instances/${instance_name}/packages/WmART/code/classes/"/>		
    		<path refid="this.package.classpath"/>
    	</path>
    	
    <!-- Compile the java files of this package -->
    	<target name="createclasses" depends="init">
    		<echo>Creating classes</echo>
    		<mkdir dir="${destdir}/"/>
    		<javac debug="${debug}" optimize="${optimize}"
    			deprecation="${deprecation}" srcdir="${srcdir}"
    			destdir="${destdir}">
    			<classpath>
    				<path refid="total.classpath"/>
    			</classpath>
    		</javac>
    	</target>
    
    	<!-- Execute jcode -->
    	<target name="execjcode" depends="createclasses">
    		<echo>Deploying classes</echo>
    		<exec executable="${server.home}/instances/${instance_name}/bin/jcode"
    				vmlauncher="false" failonerror="true">
    			<arg value="fragall" />
    			<arg value="${package}" />
    		</exec>
    	</target>
    
    	<!-- delete .class files built in this package -->
    	<target name="cleanclasses">
    		<echo>Cleaning classes</echo>
    		<mkdir dir="${destdir}"/>
    		<delete quiet="false">
    			<fileset dir="${destdir}" includes="**/*.class"/>
    		</delete>
    	</target>
    	
    	<!-- if this package depends on classes found in other packages,
    		add targets to build those classes here. -->
    	<target name="init">
    		<tstamp/>
    	</target>	
    	
    	<target name="packageDependencies" depends="" />
    	<target name="clean" depends="cleanclasses" />
    	<target name="classes" depends="cleanclasses, createclasses" />
    	<target name="deploy" depends="execjcode" />
    	<target name="all" depends="packageDependencies, cleanclasses, execjcode" />
    	<target name="remake" depends="packageDependencies, cleanclasses, createclasses" />
    
    </project>
  2. Set the classpath in total.classpath in the ANT script.

    The JAR files required to compile your source code are as follows:

    • IBMwebMethods_directory\common\lib\wm-isclient.jar
    • IBMwebMethods_directory\common\lib\glassfish\gf.jakarta.resource.jar
    • Integration Server_directory\lib\wm-isserver.jar
    • Integration Server_directory\instances\<instance_name>\packages\WmART\code\jars\wmart.jar

    The folder containing the class files required to compile your source code is as follows:

    • Integration Server_directory\instances\<instance_name>\packages\WmART\code\classes

    IBMwebMethods_directory is the folder in which IBM webMethods components are installed and Integration Server_directory is the folder in which Integration Server is installed.

    Note:
    • Add the required folders location to your classpath, or package all folders in a JAR and then add the JAR to your classpath.
    • You must specify JDK version 1.8 or higher in your classpath.
  3. Run the ANT script to compile the Java classes.
    ant classes
  4. Compile the classes and deploy in Integration Server..
    1. Run the ANT script to create classes and deploy in Integration Server as Java Services.
      ant deploy
      Note: If you have created adapter admin Java class for adapter startup and shutdown, then the corresponding Java Services are deployed using jcode utility. The jcode utility is provided with Integration Server. For more information, see IBM webMethods Service Development Help.
    2. If you have created Startup and Shutdown Java Services using Designer, you must compile it using Integration Server Administrator.
      • Start Integration Server Administrator.
      • Select Settings > Extended > Edit Extended Settings.
      • Set the property watt.server.compile to include the path to Java compiler and the classpath to include the wmart.jar in Integration Server_directory\instances\<instance_name>\packages\WmART\code\jars\wmart.jar. For example:
        watt.server.compile=C:\softwareag\912\jvm\jvm\bin\javac 
        -classpath {0};C:\softwareag\912\IntegrationServer\instances\default\packages\
        WmART\code\jars\wmart.jar; -d {1} {2}
  5. Restart Integration Server.
    If your startup and shutdown Java Services do not appear in the adapter package, there has been an error either in compiling your code or in creating the Java Services.

Registering the Adapter Startup and Shutdown Java Services in Integration Server

Before you begin

Before you register the adapter startup and shutdown Java Services for the adapter package, make sure that you have:
  • Created your adapter startup and shutdown Java Service.
  • Successfully compiled the adapter.

Procedure

  1. Start Designer.
  2. In the Package Navigator, select the IBM webMethods package you created.
  3. Set the Startup Services and Shutdown Services.
    Perform the following operations:
    • In the Properties > StartUp/Shutdown Services > Startup Services, add the startup service created.
    • In the Properties > StartUp/Shutdown Services > Shutdown Services, add the shutdown service created.
  4. Restart Integration Server.
  5. Start Integration Server Administrator.
  6. In Integration Server Administrator, select Adapters.
    You can see the adapter you have created in the dropdown.

Debugging the Adapter

Procedure

  1. Shut down your Integration Server .
  2. Modify the script IBMwebMethods_directory\profiles\IS_<instance_name>\bin\startDebugMode.bat (or startDebugMode.sh in a UNIX environment).
    Set SUSPEND_MODE to n.

    set SUSPEND_MODE=n

  3. Start Integration Server in the debug mode by executing startDebugMode.bat (or startDebugMode.sh in a UNIX environment).
  4. Create a script to attach the debugger to Integration Server.
    For example debug.bat:
    rem @echo off
    set TARGET="C:\softwareag\912\IntegrationServer\instances\default\packages\MyAdapter\code\source"
    set JAVA_MIN_MEM=64M
    set JAVA_MAX_MEM=64M
    set JAVA_MEMSET=-ms%JAVA_MIN_MEM% -mx%JAVA_MAX_MEM%
    set JAVA_DBG="C:\softwareag\912\jvm\jvm\bin\jdb"
    set ARGS=com.sun.jdi.SocketAttach:hostname=localhost,port=10033
    %JAVA_DBG% -sourcepath %TARGET% -connect %ARGS%
  5. Run the debug script.
    debug.bat (or debug.sh in a UNIX environment).

    You can attach to Integration Server and "step" your code (assuming you compiled your code to include debug symbols (for example, javac -g) ) using your favorite debugger.

Adapter Load Process

The users of the adapter explicitly load and unload an adapter by enabling and disabling the adapter package, using Integration Server Administrator. This figure shows how MyAdapter loads the adapter into Integration Server at run time.

The loading process is described as follows:

  1. The system calls AdapterAdmin.registerAdapter. This method is the designated package startup service.
  2. The implementation of registerAdapter instantiates the MyAdapter class by calling its getInstance method. It then registers the MyAdapter object as an adapter by passing it to the registerAdapter method of the AdapterAdmin class provided by the ADK.
  3. During the construction of the MyAdapter instance, super() calls the base class com.wm.adk.WmAdapter constructor, which instantiates the default resource bundle, calls MyAdapter.initialize, and retrieves basic information about the adapter. (The com.wm.adk.WmAdapter constructor only instantiates the default resource bundle; it instantiates and reads other resource bundles if a request is received using the locale of that supplementary resource bundle.)
  4. The adapter load process is completed with a call to the static method AdapterAdmin.registerAdapter, which reads and evaluates the adapter's default resource bundle, and updates the Integration Server list of registered adapters. If the resource bundle does not provide the required resource bundle elements, the registration process fails, with an error log entry explaining the failure.
  5. Upon completion of the adapter's registration, the adapter loads any dependant node packages. See the chapters about connections, adapter services, polling notifications, and listener notifications for descriptions of their respective load processes.
  6. If the load was successful, the adapter name (as specified in the resource bundle) appears in the list of adapters in Integration Server Administrator. If it does not appear, refresh your browser page. If it still does not appear, check the log for errors.

Adapter Unload Process

During server shutdown or package reload, the system disables the adapter's dependant nodes (or their packages) before it disables the adapter. When you explicitly disable an adapter's package using Integration Server Administrator, disable its dependant nodes first. The diagram shows how MyAdapter unloads the adapter from Integration Server at run time.

To unload an adapter, the server calls AdapterAdmin.unregisterAdapter. This method is the designated package shutdown service. This method performs the following tasks:

  1. Retrieves the adapter instance.
  2. Calls the adapter's cleanup method (if implemented).
  3. Calls AdapterAdmin.unregisterAdapter.

Reporting Adapter Fix Levels

After you deploy an adapter, you may need to deliver a fix. You can identify the fix to Integration Server through the adapter's package manifest file. Whenever the adapter package is loaded, the patch_history field is read from the file and displayed on the adapter's About page. The management of this field is the responsibility of the adapter developer. The Integration Server facilities for creating partial package installations can be used to deliver adapter fixes. For more information, see the IBM webMethods Integration Server Administrator’s Guide for your release.

Package Management

A namespace node package is a package in which the user of the adapter creates the adapter's namespace nodes for connections, adapter services, polling notifications, listener notifications, and listeners. The user of the adapter must not create nodes in the adapter package. Keeping namespace nodes separate from the adapter package simplifies the process of upgrading a deployed adapter.

The procedure for creating a namespace node package is identical to the procedure for creating any webMethods package. For instructions for creating packages, see the IBM webMethods Service Development Help for your release.

All the nodes of an adapter may be located in one package, or they may be distributed among multiple packages. Namespace node packages management tasks include:

  • Setting package dependencies for namespace node packages.
  • Setting package dependencies for namespace nodes.
  • Using access control lists (ACLs) to control which development group has access to which adapter services
  • Enabling and Disabling Packages.
  • Loading, Reloading, and Unloading Packages.

To perform these tasks, the user of the adapter must use IBM webMethods Integration Server, Designer, and a web browser.

Note: You must have Integration Server administrator privileges to access an adapter's management screen. For information about setting user privileges, see the IBM webMethods Integration Server Administrator’s Guide for your release.

Package Dependency Considerations for Namespace Node Packages

Following are dependency requirements and guidelines for namespace node packages:

  • A namespace node package must have a dependency on its associated adapter package, and the adapter package must have a dependency on the WmART package. For more information about setting package dependencies, see the IBM webMethods Service Development Help for your release.
    Setting these dependencies ensures that at startup Integration Server automatically loads or reloads all packages in the proper order:
    • WmART package.
    • Adapter package.
    • Node package(s).
    The WmART package is automatically installed when you install Integration Server. You must not manually reload the WmART package.
  • Keep connections for different adapters in separate packages so that you do not create interdependencies between adapters. If a package contains connections for two different adapters, and you reload one of the adapter packages, the connections for both adapters is reloaded automatically.
  • You cannot enable a package if it has a dependency on another package that is disabled. That is, before you can enable your package, you must enable all packages on which your package depends. For information about enabling packages, see Enabling and Disabling Packages.
  • You can disable a package even if another package that is enabled has a dependency on it. Therefore, you must manually disable any user-defined packages that have a dependency on your adapter package before you disable the adapter package.

If the namespace nodes of an adapter are located in multiple packages, see Package Dependency Considerations for Namespace Nodes. For more information about setting package dependencies, see the IBM webMethods Service Development Help for your release.

Package Dependency Considerations for Namespace Nodes

If all the namespace nodes of an adapter are located in the same package, there is no need to set package dependencies.

However, if the nodes of an adapter are located in multiple packages, then:

  • A package that contains the connection node(s) must depend on the adapter package.
  • Packages that contain other nodes must depend on their associated connection package.

For more information about setting package dependencies, see the IBM webMethods Service Development Help for your release.

Group Access Control

To control which development group has access to which adapter services, use access control lists (ACLs). You can use ACLs to prevent one development group from inadvertently updating the work of another group, or to allow or deny access to services that are restricted to one group but not to others.

For general information about assigning and managing ACLs, see the IBM webMethods Service Development Help for your release.

Enabling and Disabling Packages

All packages are automatically enabled by default. To prevent Integration Server from loading a particular package, you must manually disable that package.

Enabling Packages

To enable the package:

  • Start Integration Server Administrator.
  • Click Packages > Management.
  • In the Management screen, click No in the Enabled column for the package. The No changes to Yes (enabled).
Note: Enabling an adapter package will not cause its associated node package(s) to be reloaded.
Important: Before you manually enable a node package, you must first enable its associated adapter package. Similarly, if your adapter has multiple node packages, and you want to disable some of them, disable the adapter package first. Otherwise, errors will be issued when you try to access the remaining enabled node packages.

Disabling Packages

To disable the package:

  • Start Integration Server Administrator.
  • Click Packages > Management.
  • In the Management screen, click Yes in the Enabled column for the package. The Yes changes to No (disabled).
Disabled packages are not listed in Designer. A disabled adapter will remain disabled until you explicitly enable it using Integration Server Administrator.

Loading, Reloading, and Unloading Packages

Loading Packages

If the node packages are properly configured with a dependency on the adapter package, at startup Integration Server automatically loads or reloads all packages in the proper order:
  • WmART package.
  • Adapter package.
  • Node package(s).
You must not manually reload the WmART package.

Reloading Packages Manually

You must typically reload the adapter package manually as you make changes to the adapter code. Similarly, the users of the adapter must reload their node packages manually when they modify the nodes. Reloading a node package will not cause its associated adapter package to be reloaded.

You can reload the adapter packages and the node packages by performing either of the following:
  • In Integration Server Administrator, in the Management screen, click the reload icon in the Reload column.
  • In Designer, right click the package and select the Reload Package option from the menu.

Unloading Packages

At shutdown, Integration Server unloads the packages in the reverse order in which it loaded them:

  • Node package(s).
  • Adapter package.
  • WmART package (assuming the dependencies are correct).