Adapter Development Kit 9.12 | webMethods Adapter Development Kit Documentation | webMethods Adapter Development Kit Installation and User’s Documentation | Usage Scenarios | How to create an adapter service implementation? | How to display adapter service signature?
 
How to display adapter service signature?
1. Update the com.wm.adk.cci.interaction.WmAdapterService implementation class.
a. Create a class attribute, a set method, a constant, and a resource domain for each metadata parameter. For example, a class attribute _fieldNames, a corresponding set method setFieldNames, a corresponding constant FIELD_NAMES_PARM, and a corresponding resource domain FIELD_NAMES_RD (which needs to lookup) for the parameter table name.
Class Attribute Name
Class Attribute Set Method Name
Class Attribute Name Constant
Resource Domain Name Constant
_fieldNames
setFieldNames
FIELD_NAMES_PARM
FIELD_NAMES_RD
_fieldTypes
setFieldTypes
FIELD_TYPES_PARM
FIELD_TYPES_RD
None
setSigIn
SIG_IN_PARM
None
None
setSigOut
SIG_OUT_PARM
None
b. In the fillWmTemplateDescriptor method, call WmTemplateDescriptor.createGroup method, WmTemplateDescriptor.createFieldMap method, and WmTemplateDescriptor.createTuple method for the new tab Signature.
c. In the fillWmTemplateDescriptor method, call WmTemplateDescriptor.setResourceDomain method, and WmTemplateDescriptor.setDescriptions method.
d. Create the private Hashtable[] unpackRequest(WmRecord request) method to process and convert the webMethods's datatype WmRecord to Hashtable[].
e. Create the private WmRecord packResonse(Hashtable[] response) method to process and convert the Hashtable[] to webMethods's datatype WmRecord.
f. In the execute method, call unpackRequest method, and packResonse method.
For example, MockDbUpdate class:
package com.wm.MyAdapter.services;

import com.wm.adk.cci.interaction.WmAdapterService;
import com.wm.adk.cci.record.WmRecord;
import com.wm.adk.cci.record.WmRecordFactory;
import com.wm.adk.connection.WmManagedConnection;
import com.wm.adk.metadata.WmTemplateDescriptor;
import com.wm.data.IData;
import com.wm.data.IDataCursor;
import com.wm.data.IDataFactory;
import com.wm.data.IDataUtil;

import java.util.Hashtable;
import java.util.Locale;
import javax.resource.ResourceException;

import com.wm.MyAdapter.MyAdapter;
public class MockDbUpdate extends WmAdapterService {
//MockDB Group
public static final String UPD_SETTINGS_GRP = "Mock Settings";
public static final String TABLE_NAME_PARM = "tableName";
public static final String COLUMN_NAMES_PARM = "columnNames";
public static final String COLUMN_TYPES_PARM = "columnTypes";
public static final String REPEATING_PARM = "repeating";
public static final String OVERRIDE_TYPES_PARM = "overrideTypes";

private String _tableName;
private String[] _columnNames;
private String[] _columnTypes;
private boolean _repeating;
private String[] _overrideTypes;

public void setTableName(String val){ _tableName = val;}
public void setColumnNames(String[] val){ _columnNames = val;}
public void setColumnTypes(String[] val){ _columnTypes = val;}
public void setRepeating(boolean val){ _repeating = val;}
public void setOverrideTypes(String[] val){_overrideTypes = val;}

public static final String TABLES_RD = "tablesRD";
public static final String COLUMN_NAMES_RD = "columnNamesRD";
public static final String COLUMN_TYPES_RD = "columnTypesRD";
public static final String OVERRIDE_TYPES_RD = "overrideTypesRD";
//MockDB Signature Group
public static final String SIG_SETTINGS_GRP = "Signature";
public static final String FIELD_NAMES_PARM = "fieldNames";
public static final String FIELD_TYPES_PARM = "fieldTypes";
public static final String SIG_IN_PARM = "sigIn";
public static final String SIG_OUT_PARM = "sigOut";
private String[] _fieldNames;
private String[] _fieldTypes;
public void setFieldNames(String[] val){ _fieldNames = val;}
public void setFieldTypes(String[] val){ _fieldTypes = val;}
public void setSigIn(String[] val){}
public void setSigOut(String[] val){}

public static final String FIELD_NAMES_RD = "fieldNamesRD";
public static final String FIELD_TYPES_RD = "fieldTypesRD";
public void fillWmTemplateDescriptor(WmTemplateDescriptor d,Locale l)
throws ResourceException {
//MockDB Grouping and resource domain setup
d.createGroup(UPD_SETTINGS_GRP, new String [] {
TABLE_NAME_PARM,
REPEATING_PARM,
COLUMN_NAMES_PARM,
COLUMN_TYPES_PARM,
OVERRIDE_TYPES_PARM}
);
d.createFieldMap(new String[] {
COLUMN_NAMES_PARM,
COLUMN_TYPES_PARM,
OVERRIDE_TYPES_PARM},
true);
d.createTuple(new String[]{COLUMN_NAMES_PARM,COLUMN_TYPES_PARM});

d.setResourceDomain(TABLE_NAME_PARM,TABLES_RD,null);
d.setResourceDomain(COLUMN_NAMES_PARM,COLUMN_NAMES_RD,
new String[]{TABLE_NAME_PARM});
d.setResourceDomain(COLUMN_TYPES_PARM,COLUMN_TYPES_RD,
new String[]{TABLE_NAME_PARM});
d.setResourceDomain(OVERRIDE_TYPES_PARM,OVERRIDE_TYPES_RD,null);

//MockDB Signature Grouping and resource domain setup
d.createGroup(SIG_SETTINGS_GRP, new String [] {
FIELD_NAMES_PARM,
FIELD_TYPES_PARM,
SIG_IN_PARM,
SIG_OUT_PARM}
);
d.createFieldMap(new String [] {
FIELD_NAMES_PARM,
FIELD_TYPES_PARM,
SIG_IN_PARM,
SIG_OUT_PARM},
false);
d.createTuple(new String[]{FIELD_NAMES_PARM,FIELD_TYPES_PARM});

String [] fieldTupleDependencies = {TABLE_NAME_PARM,
REPEATING_PARM,
COLUMN_NAMES_PARM,
COLUMN_TYPES_PARM,
OVERRIDE_TYPES_PARM};
d.setResourceDomain(FIELD_NAMES_PARM,FIELD_NAMES_RD, fieldTupleDependencies);
d.setResourceDomain(FIELD_TYPES_PARM,FIELD_TYPES_RD, fieldTupleDependencies);
d.setResourceDomain(SIG_IN_PARM,WmTemplateDescriptor.INPUT_FIELD_NAMES,
new String[] {FIELD_NAMES_PARM, FIELD_TYPES_PARM});
d.setResourceDomain(SIG_OUT_PARM,WmTemplateDescriptor.OUTPUT_FIELD_NAMES,
new String[] {FIELD_NAMES_PARM, FIELD_TYPES_PARM});

//Call to setDescriptions
d.setDescriptions(MyAdapter.getInstance().
getAdapterResourceBundleManager(),l);
}

public WmRecord execute(WmManagedConnection connection, WmRecord input)
throws ResourceException {
Hashtable[] request = this.unpackRequest(input);
return this.packResonse(request);
}
private Hashtable[] unpackRequest(WmRecord request) throws ResourceException {
Hashtable data[] = null;
IData mainIData = request.getIData();
IDataCursor mainCursor = mainIData.getCursor();
try {
String tableName = this._tableName;
String[] columnNames = this._columnNames;
if(mainCursor.first(tableName)) {
IData[] recordIData;
if(this._repeating) {
recordIData = IDataUtil.getIDataArray (mainCursor,tableName);
data = new Hashtable[recordIData.length];
}
else {
recordIData = new IData[] {IDataUtil.getIData(mainCursor)};
data = new Hashtable[1];
}
for(int rec=0;rec<recordIData.length;rec++) {
IDataCursor recordCursor = recordIData[rec].getCursor();
data[rec] = new Hashtable();
for(int c = 0; c < columnNames.length;c++) {
if(recordCursor.first(columnNames[c])) {
data[rec].put(tableName + "." + columnNames[c],
recordCursor.getValue());
}
}
recordCursor.destroy();
}
}
else {
throw MyAdapter.getInstance().createAdapterException(9999,
new String[] {"No Request Data"});
}
}
catch (Throwable t) {
throw MyAdapter.getInstance().createAdapterException(9999,
new String[] {"Error unpacking request data"},t);
}
finally {
mainCursor.destroy();
}
return data;
}
private WmRecord packResonse(Hashtable[] response) throws ResourceException {
WmRecord data = null;
try {
IData[] recordIData = new IData[response.length];
String tableName = this._tableName;
String[] columnNames = this._columnNames;
for(int rec = 0; rec < response.length; rec++) {
recordIData[rec] = IDataFactory.create();
IDataCursor recordCursor = recordIData[rec].getCursor();
for(int col = 0; col < columnNames.length;col++) {
IDataUtil.put(recordCursor,columnNames[col],
response[rec].get(tableName + "." +
columnNames[col]));
}
recordCursor.destroy();
}
IData mainIData = IDataFactory.create();
IDataCursor mainCursor = mainIData.getCursor();
if(this._repeating) {
IDataUtil.put(mainCursor,tableName,recordIData);
}
else {
IDataUtil.put(mainCursor,tableName,recordIData[0]);
}
mainCursor.destroy();
data = WmRecordFactory.getFactory().createWmRecord("nameNotUsed");
data.setIData(mainIData);
}
catch (Throwable t) {
throw MyAdapter.getInstance().createAdapterException(9999,
new String[] {"Error packing response data"},t);
}
return data;
}
}
2. Update the WmManagedConnection implementation class.
*Add the data for the mock tables in the adapter service.
*Add the methods adapterCheckValue, adapterResourceDomainLookup, and registerResourceDomain
For example, SimpleConnection class
package com.wm.MyAdapter.connections;

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;


public class SimpleConnection extends WmManagedConnection {
String hostName;
int port;

//Adapter Services variables
private String[] mockTableNames ={ "CUSTOMERS","ORDERS","LINE_ITEMS"};
private String[][] mockColumnNames ={
{"name","id", "ssn"},
{"id","date","customer_id"},
{"order_id","item_number","quantity","description"}
};

private String [][] mockDataTypes = {
{"java.lang.String","java.lang.Integer", "java.lang.String"},
{"java.lang.Integer", "java.util.Date", "java.lang.Integer"},
{"java.lang.Integer", "java.lang.Integer", "java.lang.Integer",
"java.lang.String"}
};

public SimpleConnection(String hostNameValue, int portValue)
{
super();
hostName = hostNameValue;
port = portValue;
MyAdapter.getInstance().getLogger().logDebug(9999,
"Simple Connection created with hostName = "
+ hostName + "and port = " +
Integer.toString(port));
}
public void destroyConnection()
{
MyAdapter.getInstance().getLogger().logDebug(9999,"Simple Connection Destroyed");
}

// The remaining methods support metadata for related services, etc.
// Implement content as needed.
public Boolean adapterCheckValue(String serviceName,
String resourceDomainName,
String[][] values,
String testValue) throws AdapterException
{
Boolean result = new Boolean(false);
if(resourceDomainName.equals(MockDbUpdate.OVERRIDE_TYPES_RD))
{
try
{
Object o = Class.forName(testValue).getConstructor(
new Class[] {String.class}).newInstance(new Object[]{"0"});
result = new Boolean(true);
}
catch (Throwable t){}
}
return result;
}
public ResourceDomainValues[] adapterResourceDomainLookup(String serviceName,
String resourceDomainName, String[][] values) throws AdapterException
{
ResourceDomainValues[] results = null;

//MockDB Group Lookup
if(resourceDomainName.equals(MockDbUpdate.COLUMN_NAMES_RD)||
resourceDomainName.equals(MockDbUpdate.COLUMN_TYPES_RD))
{
String tableName = values[0][0];
for(int x = 0; x < this.mockTableNames.length;x++)
{
if(this.mockTableNames[x].equals(tableName))
{
ResourceDomainValues columnsRdvs = new ResourceDomainValues(
MockDbUpdate.COLUMN_NAMES_RD,this.mockColumnNames[x]);
columnsRdvs.setComplete(true);
ResourceDomainValues typesRdvs = new ResourceDomainValues(
MockDbUpdate.COLUMN_TYPES_RD, this.mockDataTypes[x]);
typesRdvs.setComplete(true);
results = new ResourceDomainValues[] {columnsRdvs,typesRdvs};
break;
}
}
//MockDB Signature Group Lookup
else if (resourceDomainName.equals(MockDbUpdate.FIELD_NAMES_RD)||
resourceDomainName.equals(MockDbUpdate.FIELD_TYPES_RD))
{
String tableName = values[0][0];
boolean repeating = Boolean.valueOf(values[1][0]).booleanValue();
String[] columnNames = values[2];
String[] columnTypes = values[3];
String[] overrideTypes = values[4];

String[] fieldNames = new String[columnNames.length];
String[] fieldTypes = new String[columnTypes.length];
String optBrackets;

if(repeating)
optBrackets ="[]";
else
optBrackets = "";


for (int i = 0; i< fieldNames.length;i++)
{
fieldNames[i] = tableName + optBrackets + "." + columnNames[i];
fieldTypes[i] = columnTypes[i] + optBrackets;

if(overrideTypes.length > i)
{
if (!overrideTypes[i].equals(""))
{
fieldTypes[i] = overrideTypes[i] + optBrackets;
}
}

}
results = new ResourceDomainValues[]{
new ResourceDomainValues(MockDbUpdate.FIELD_NAMES_RD,fieldNames),
new ResourceDomainValues(MockDbUpdate.FIELD_TYPES_RD,fieldTypes)};
}

return results;
}

public void registerResourceDomain(WmAdapterAccess access)
throws AdapterException
{
//MockDB Group Registering Resource Domain
ResourceDomainValues tableRdvs = new ResourceDomainValues(
MockDbUpdate.TABLES_RD,mockTableNames);
tableRdvs.setComplete(true);
access.addResourceDomain(tableRdvs);

access.addResourceDomainLookup(MockDbUpdate.COLUMN_NAMES_RD,this);
access.addResourceDomainLookup(MockDbUpdate.COLUMN_TYPES_RD,this);

ResourceDomainValues rdvs = new ResourceDomainValues(
MockDbUpdate.OVERRIDE_TYPES_RD, new String[] {""});
rdvs.setComplete(false);
rdvs.setCanValidate(true);
access.addResourceDomain(rdvs);
access.addCheckValue(MockDbUpdate.OVERRIDE_TYPES_RD,this);

//MockDB Signature Group Registering Resource Domain
access.addResourceDomainLookup(MockDbUpdate.FIELD_NAMES_RD,this);
access.addResourceDomainLookup(MockDbUpdate.FIELD_TYPES_RD,this);
}
}
3. Update the resource bundle implementation class to add the display name and description of the adapter service.
In the example, update MyAdapterResource class:
package com.wm.MyAdapter;
..
..

import com.wm.MyAdapter.services.MockDbUpdate;

public class MyAdapterResource extends ListResourceBundle implements MyAdapterConstants{
..
..
static final Object[][] _contents = {
..
..
//MockDB Group Resource Domain Values
,{MockDbUpdate.class.getName() + ADKGLOBAL.RESOURCEBUNDLEKEY_DISPLAYNAME,
"Mock Update Service"}
,{MockDbUpdate.class.getName() + ADKGLOBAL.RESOURCEBUNDLEKEY_DESCRIPTION,
"Simulates a database update service"}
,{MockDbUpdate.UPD_SETTINGS_GRP + ADKGLOBAL.RESOURCEBUNDLEKEY_GROUP,
MockDbUpdate.UPD_SETTINGS_GRP}
,{MockDbUpdate.TABLE_NAME_PARM +
ADKGLOBAL.RESOURCEBUNDLEKEY_DISPLAYNAME, "Table Name"}
,{MockDbUpdate.TABLE_NAME_PARM +
ADKGLOBAL.RESOURCEBUNDLEKEY_DESCRIPTION, "Select Table Name"}
,{MockDbUpdate.COLUMN_NAMES_PARM + ADKGLOBAL.RESOURCEBUNDLEKEY_DISPLAYNAME,
"Column Names"}
,{MockDbUpdate.COLUMN_NAMES_PARM + ADKGLOBAL.RESOURCEBUNDLEKEY_DESCRIPTION,
"Name of column updated by this service"}
,{MockDbUpdate.COLUMN_TYPES_PARM + ADKGLOBAL.RESOURCEBUNDLEKEY_DISPLAYNAME,
"Column Types"}
,{MockDbUpdate.COLUMN_TYPES_PARM + ADKGLOBAL.RESOURCEBUNDLEKEY_DESCRIPTION,
"Default data type for column"}
,{MockDbUpdate.OVERRIDE_TYPES_PARM +
ADKGLOBAL.RESOURCEBUNDLEKEY_DISPLAYNAME, "Override Data Types"}
,{MockDbUpdate.OVERRIDE_TYPES_PARM +
ADKGLOBAL.RESOURCEBUNDLEKEY_DESCRIPTION, "Type to override column default"}
,{MockDbUpdate.REPEATING_PARM +
ADKGLOBAL.RESOURCEBUNDLEKEY_DISPLAYNAME, "Update Multiple Rows?"}
,{MockDbUpdate.REPEATING_PARM +
ADKGLOBAL.RESOURCEBUNDLEKEY_DESCRIPTION,
"Select if input will include multiple rows to update"}
//MockDB Signature Group Resource Domain Values
,{MockDbUpdate.SIG_SETTINGS_GRP + ADKGLOBAL.RESOURCEBUNDLEKEY_GROUP,
MockDbUpdate.SIG_SETTINGS_GRP}
,{MockDbUpdate.FIELD_NAMES_PARM + ADKGLOBAL.RESOURCEBUNDLEKEY_DISPLAYNAME,
"Field Names"}
,{MockDbUpdate.FIELD_NAMES_PARM + ADKGLOBAL.RESOURCEBUNDLEKEY_DESCRIPTION,
"Name of Field"}
,{MockDbUpdate.FIELD_TYPES_PARM + ADKGLOBAL.RESOURCEBUNDLEKEY_DISPLAYNAME,
"Field Type"}
,{MockDbUpdate.FIELD_TYPES_PARM + ADKGLOBAL.RESOURCEBUNDLEKEY_DESCRIPTION,
"Type of Field"}
,{MockDbUpdate.SIG_IN_PARM + ADKGLOBAL.RESOURCEBUNDLEKEY_DISPLAYNAME,
"Input Signature"}
,{MockDbUpdate.SIG_IN_PARM + ADKGLOBAL.RESOURCEBUNDLEKEY_DESCRIPTION,
"Input Signature"}
,{MockDbUpdate.SIG_OUT_PARM + ADKGLOBAL.RESOURCEBUNDLEKEY_DISPLAYNAME,
"Output Signature"}
,{MockDbUpdate.SIG_OUT_PARM + ADKGLOBAL.RESOURCEBUNDLEKEY_DESCRIPTION,
"Output Signature"}
}
protected Object[][] getContents() {
// TODO Auto-generated method stub
return _contents;
}
}
4. Register the adapter service by updating your fillResourceAdapterMetadataInfo method in your WmManagedConnectionFactory implementation class.
In the example, MockDbUpdate class is registered using the fillResourceAdapterMetadataInfo method in the SimpleConnectionFactoryconnection factory class:
package com.wm.MyAdapter.connections;

import com.wm.adk.connection.WmManagedConnectionFactory;
import com.wm.adk.connection.WmManagedConnection;
import com.wm.adk.info.ResourceAdapterMetadataInfo;
import com.wm.adk.metadata.WmDescriptor;
import com.wm.adk.error.AdapterException;

import java.util.Locale;

import com.wm.MyAdapter.MyAdapter;
import com.wm.MyAdapter.MyAdapterConstants;
import com.wm.MyAdapter.services.MockDbUpdate;

public class SimpleConnectionFactory extends WmManagedConnectionFactory implements MyAdapterConstants {
..
..
..
public void fillResourceAdapterMetadataInfo(ResourceAdapterMetadataInfo info, Locale locale) {
info.addServiceTemplate(MockDbUpdate.class.getName());
}
}
5. Execute the ANT script created in the adapter definition to compile, and deploy the adapter in Integration Server.
Use the files build.xml and build.properties.
ant deploy
6. Restart Integration Server.
7. Start Integration Server Administrator.
8. In Designer, create the adapter service.
You will see the Mock Settings, and Signature tab
a. In the Mock Settings tab, select a table and then select Signature tab. For example: In Mock Settings tab, select table Customer and then select Signature tab.
You will see the following in the Mock Settings tab, Signature tab, and Input/Output tab.
b. In the Mock Settings tab, for a table, populate the rows using Insert Row or Fill in all rows to the table and then select Signature tab. For example: In the Mock Settings tab, select the table Customer, populate the rows using Insert Row or Fill in all rows to the table and then select Signature tab.
You will see the following in the Mock Settings tab, Signature tab, and Input/Output tab.
Note:
The Signature tab shown is for demonstration purposes only. In most cases, the fields in the Signature are hidden. Select the Input/Output tab to view the signature.
An adapter service of type MyAdapter is created with two user defined tabs Mock Settings, and Signature.