Adapter Toolkit
WebSphere Adapter Toolkit
The IBM WebSphere Adapter Toolkit provides the development tools, libraries, and sample code to assist you in creating JCA resource adapters.
With the toolkit, you can create either of the following adapter types:
- A resource adapter based on the interfaces defined by the JCA Resource Adapter 1.5 specification. Choose this path if your goal is to develop a resource adapter that can run either in the unmanaged or managed mode, within any JCA 1.5 compliant container.
- A resource adapter that extends the WebSphere Adapter Foundation Classes library. Select this path if your goal is to create a resource adapter implementation that can run in a managed server run time environment like IBM Business Process Manager and when you want a common functionality and extended qualities of service, offered specifically by WebSphere Adapters. WebSphere Adapters are based on the JCA 1.5 specification. These adapters are supported on multiple run time environments and brokers.
Implementing a WebSphere adapter allows you to take advantage of the quality of services offered in the WebSphere Adapter Foundation classes (AFC) and the flexibility to deploy the adapter on run time environments other than IBM Business Process Manager.
In either case, the toolkit provides a project creation wizard that generates the code that you then implement. In addition, the toolkit provides a specialized editor that facilitates the task of creating and configuring a resource adapter deployment descriptor.
This document focuses primarily on development of resource adapters and artifacts that extend the WebSphere Adapter Foundation Class library.
The following figure illustrates the process of developing a JCA resource adapter using WebSphere Adapter Toolkit.
![]()
Use the WebSphere Adapter Toolkit
The development process using IBM WebSphere Adapter Toolkit includes the following as shown in the illustration:
- Run the New JCA Resource Adapter Project wizard.
The wizard generates a resource adapter deployment descriptor and code. The code includes sequence of calls, log and trace messages, and comments.
- Use the Resource Adapter Deployment Descriptor Editor to configure the deployment descriptor.
- Implement the code to correctly interface with your Enterprise Information system (EIS).
- Export the resource adapter as a Resource Adapter Archive (RAR), or Enterprise Application Archive (EAR) file.
The purpose of this documentation
To integrate an adapter development requires some amount of customization, depending on customer requirements. The process of integrating adapter functionality into your business processes requires you to design, build, and test the solution that uses the adapter. WebSphere Adapter Toolkit documentation helps you to understand the architecture requirements, and provide guidance to implement the various facets of the toolkit, for specific requirements.
- IBM WebSphere Adapter Toolkit technology overview IBM WebSphere Adapter Toolkit helps developers implement the Adapter Foundation Classes, which establish a WebSphere Adapters standard for building resource adapters that conform to the Java™ Platform, Enterprise Edition (JEE) Connector Architecture (JCA) 1.5 specification.
- IBM WebSphere Adapter Toolkit overview WebSphere Adapter Toolkit contains everything you need to create a resource adapter. The adapters are metadata-driven components designed for bidirectional communication with external services on enterprise information systems, such as transaction or ERP systems, as well as bidirectional communication with an email or Flat File.
- IBM WebSphere Adapter Toolkit tasks The tasks range from installing the toolkit, samples, and Adapter Foundation Classes (using the Eclipse Update Manager in Integration Designer) to implementing and validating your code.
- IBM WebSphere Adapter Toolkit installation requirements You can install Adapter Toolkit on Windows or Linux operating systems and work with Integration Designer.
- Samples overview When you install WebSphere Adapter Toolkit, an EIS Simulator sample adapter is placed on your system. This sample serves as a reference to create WebSphere adapters.
- Use the New Connector Project wizard You use the wizard to create a Connector Project which contains a deployment descriptor and classes. The classes either extend the WebSphere Adapter Foundation Classes or implement the JCA 1.5 Interface specification.
- Use the Resource Adapter Deployment Descriptor editor The Resource Adapter Deployment Descriptor editor provides an easy and convenient way to configure your resource adapter.
- Implementing code from the IBM WebSphere Adapter Toolkit
- Validating the code Validate your adapter implementation by unit testing it outside of a JCA container (unmanaged testing mode). You can then deploy to the target runtime server and test instances of the adapter (managed testing mode).
- Packaging and exporting a resource adapter You can create a Resource Adapter Archive (RAR) file, with the help of JAR files. You must first add the required JAR files to your project workspace.
- Import a resource adapter The External Service wizard also gives you an option to import a RAR.
- Troubleshooting and support Common troubleshooting techniques and self-help information help you identify and solve problems quickly. For information about configuring logging properties and changing the log and trace file names, see Configure logging and tracing.
- Reference
- Adapter documentation in PDF format Documentation in PDF format for WebSphere Adapter Toolkit is available at the following location.
IBM WebSphere Adapter Toolkit technology overview
IBM WebSphere Adapter Toolkit helps developers implement the Adapter Foundation Classes, which establish a WebSphere Adapters standard for building resource adapters that conform to the Java™ Platform, Enterprise Edition (JEE) Connector Architecture (JCA) 1.5 specification.
- IBM WebSphere Adapters WebSphere Adapters implement the Java Platform, Enterprise Edition (JEE) Connector Architecture (JCA), version 1.5. WebSphere Adapters enable managed, bidirectional connectivity between enterprise information systems (EIS) and Java Platform, Enterprise Edition components supported by multiple server run time environments, including IBM Business Process Manager and WAS.
- Architectural overview With the appropriate enterprise information system-specific subclasses, WebSphere Adapter Foundation Classes provide a JCA-compliant resource adapter implementation that can be managed by the application server to enable bidirectional connectivity to an enterprise information system.
- How metadata is used at build time and run time Metadata is a set of characteristics that describe the structure of a WebSphere Business Integration component, such as a business object, collaboration, or adapter. Metadata describes facets common across an entire class of objects. For example, attributes, properties, verbs, and application-specific information constitute the metadata for a business object. Application-specific information is the part of metadata of a business object that enables the adapter to interact with its application or a data source.
- Use Enterprise Metadata Discovery to build services In addition to using enterprise metadata discovery to discover existing services, you can use it to build services that include integrated processes to exchange information with an email or a file system.
IBM WebSphere Adapters
WebSphere Adapters implement the Java™ Platform, Enterprise Edition (JEE) Connector Architecture (JCA), version 1.5. WebSphere Adapters enable managed, bidirectional connectivity between enterprise information systems (EIS) and Java Platform, Enterprise Edition components supported by multiple server run time environments, including IBM Business Process Manager and WAS.
WebSphere Adapters support outbound request processing and inbound event processing.
WebSphere Adapters support outbound and inbound processing for BPM and outbound processing only for IBM WAS.
Outbound processing refers to a process in which request data flows from a client application to an enterprise information system. In an outbound processing scenario, the adapter acts as the connector between the application component and an enterprise information system. The adapter provides a set of standard operations, which process either an after-image or Delta style business objects. An outbound request can read data from or write data to an enterprise information system.
Inbound event processing refers to a process that is initiated by an event on an enterprise information system. During inbound event processing, the adapter converts events generated from an enterprise information system into business objects and sends the business object to the client application. Inbound event notification complements outbound request processing, enabling adapters to provide bidirectional communication between business processes and enterprise information system applications.
Figure 1. A WebSphere Adapter
![]()
The IBM WebSphere Adapters portfolio of adapters is based on the Java Platform, Enterprise Edition (JEE) Connector Architecture (JCA) standard. JCA is a standard architecture for integrating Java Platform, Enterprise Edition applications with enterprise information systems. Each of these systems provides native APIs for identifying a function to call, specifying its key data, and processing its output data. The goal of the JCA standard is to provide an independent API for coding these functions, to facilitate data sharing, and to integrate Java Platform, Enterprise Edition applications with existing and other enterprise information systems. The JCA standard accomplishes this goal by defining a series of contracts that govern interactions between an enterprise information system and Java Platform, Enterprise Edition component within an application server.
WebSphere Adapters are developed to run on multiple server run times, to perform the following actions:
- Integrate with multiple server run times, including IBM Business Process Manager, WebSphere Enterprise Service Bus, and WAS.
- Connect an application running on IBM Business Process Manager with an enterprise information system.
- Enable data exchange between the application and an enterprise information system.
WebSphere Adapters comprise:
- An implementation of the Java Platform, Enterprise Edition (JEE) Connector Architecture (JCA), version 1.5, which supports IBM Business Process Manager and WAS.
- An enterprise metadata discovery component.
You use this component with the external service wizard to introspect an enterprise information system to discover and generate business objects and other service component architecture (SCA) artifacts that are compiled in a standard enterprise application archive file. You can also use the external service wizard to build a service (rather than discover a service). For example, you can use the enterprise service discovery wizard to build services (based on search criteria you provide), and generate business objects and interfaces.
The enterprise metadata discovery component implements version 1.2 of the enterprise metadata discovery specification.
WebSphere Adapters use a format-independent data model for representing data objects. In IBM Business Process Manager or WebSphere Enterprise Service Bus run time environment, WebSphere Adapters use an extension of the service data objects (SDO) for representing data objects.
Architectural overview
With the appropriate enterprise information system-specific subclasses, WebSphere Adapter Foundation Classes provide a JCA-compliant resource adapter implementation that can be managed by the application server to enable bidirectional connectivity to an enterprise information system.
You can send outbound requests intended for an enterprise information system, to the resource adapter by any Java™ EE component through the Common Client Interface (CCI) defined by the JCA specification. For inbound events, message-driven beans that implement the InboundListener interface are registered with the adapter by the application-server, enabling them to receive any appropriate inbound events from an enterprise information system through the adapter.
Regardless of whether the data is intended for inbound or outbound delivery, the resource adapter (Adapter Foundation Classes and enterprise information system-specific subclasses) acts as a conduit for any Java EE application to communicate with an enterprise information system.
Figure 1. Architecture overview
![]()
Runtime architecture component model
The adapter run time architecture is a collection of components interacting through well-defined interfaces and based on the Java Platform, Enterprise Edition (JEE) Connector Architecture (JCA) specification version 1.5.
At run time, the adapters implement both the Data Exchange Service Provider Interface (DESPI) contracts to interact with the run time container and the CCI contracts to interact with the application component. The JCA architecture has been extended with the data exchange component that allows efficient data exchange between the adapter and the server run time and supports multiple run time environments.
The layered approach provides a set of elements that can be assembled to provide the required functionality and quality of service. The componentized approach allows the separate, independent development of each element, as well as their reuse. The following illustration presents the run time architecture component model. The processing performed by each component (and subcomponent) in the model is described in sections that follow the illustration.
Figure 2. Runtime architecture component model
![]()
The component model allows for a single architecture for adapter development and evolution. It uses recognized standards but extends them as necessary, for example with high performance, run time independent data exchange interface that enables full adapter functionality in various environments. The layered component model reduces complexity and allows extensibility. The use of the adapter foundation classes (the standard library for building adapters) supports common adapter capabilities and ensures adapter consistency.
JCA connector component
The JCA connector component provides the standard architecture for connecting the Java EE platform to heterogeneous enterprise information systems, facilitating bidirectional data exchange with an enterprise information system. The JCA connector component can be driven by the metadata that describes the interaction with an enterprise information system. The JCA connector component includes separate subcomponents for connecting to an enterprise information system, and exchanging data.
JCA connector connectivity subcomponent
The connectivity subcomponent of the JCA connector component includes functionality for establishing, maintaining, and closing connections to the target enterprise information system and provides support for transactions and security for these connections.
The connectivity subcomponent interacts with the target enterprise information system-specific libraries and functionality. The subcomponent is exposed to the application interface component through standard JCA CCI interfaces, which include Connection, ConnectionFactory, Interaction, and InteractionSpec for outbound processing and ResourceAdapter and ActivationSpecWithXid for the inbound event processing.
JCA connector Data exchange SPI (DESPI) subcomponent
The data exchange subcomponent of the JCA connector component includes functionality for sending or receiving data from the application component through the data exchange interface (DESPI). This interface is format and run time neutral, and permits any structured or streamed data to be moved between the connector and the application. The connector component understands the data format of the enterprise information system, and converts it to invocations of Data Exchange SPI. The main advantage of DESPI is its high efficiency rate of passing data between components without introducing any intermediate format.
Common services and Adapter Foundation Classes
The adapter foundation classes provide base adapter implementation ensuring that all the interfaces required by the contracts supported by the Connector component are provided.
As shown in Figure 2, the adapter foundation classes provide support across all the elements of the connector component, including the JCA interfaces, as well as data exchange interfaces.
The adapter foundation classes support all the required JCA contracts for outbound and inbound connectivity. For outbound interactions, the support includes standard create, retrieve, update, and delete operations through the Command Manager, the application sign-on and transactions when supported by an enterprise information system. For inbound connectivity, support includes reliable event delivery to the endpoint, support for polling as well as event listening pattern.
The adapter foundation classes provide full support for DESPI with full implementation of required interfaces including abstract representation of the metadata. An important component of the run time environments, and thus architecture, is monitoring and problem determination support. The adapter foundation classes provide a set of utility classes for robust and consistent logging and tracing in different deployment scenarios by hiding the underlying run time implementation.
The adapter foundation classes also support various monitoring and events and allow all adapters take advantage of that functionality. The supported quality of service includes Performance Monitoring Infrastructure (PMI), Application Response Measurement (ARM) and Common Event Infrastructure (CEI). For more information about the monitoring capabilities available, see Monitor and measuring performance.
Application interface component
The application interface component bridges the run time environment and the connector component. The interface enables invocation of the connector from the clients, using the appropriate programming model. It maps the specific invocations between the connector component and the JCA common client interface (CCI). The application component consists of data exchange, application interface, and metadata elements.
Metadata
The metadata subcomponent describes the structure of the data exchanged with the enterprise information system through the data exchange interfaces. The metadata can also provide information to the connector component about how the data can be exchanged with an enterprise information system. For more information about the metadata subcomponent, seeHow metadata is used at build time and run time.
How metadata is used at build time and run time
Metadata is a set of characteristics that describe the structure of a WebSphere Business Integration component, such as a business object, collaboration, or adapter. Metadata describes facets common across an entire class of objects. For example, attributes, properties, verbs, and application-specific information constitute the metadata for a business object. Application-specific information is the part of metadata of a business object that enables the adapter to interact with its application or a data source.
At build time, use the adapter to access data on an EIS, and from that data to generate metadata in the form of annotated XML schemas. This build time representation of the metadata contains the annotations with application-specific information (ASI) the adapter needs at run time to associate objects or individual properties with their equivalent in the external resource.
The application-specific information portion of metadata identifies key fields, mappings to external types, or for any other purpose the adapter dictates. At run time, an appropriate run time representation of the metadata is passed to the adapter. The adapter generates the data as XML annotations. All other components apart from the adapter itself ignore the XML annotations. The run time representation must correspond to the XML schemas that were the result of the import during enterprise metadata discovery. However their method of creations can be specific to the given environment.
The XML schema generated as part of enterprise metadata discovery can be thought of as the canonical form.
You can construct the data object metadata programmatically from its own metadata representation, which would have been created from the original XML schemas. In other cases, different representations, such as records are used. However, it is required that any application-specific information annotations in the schemas to be preserved by such environments, and then provided along with the type definition for consumption by the adapter.
Use Enterprise Metadata Discovery to build services
In addition to using enterprise metadata discovery to discover existing services, you can use it to build services that include integrated processes to exchange information with an email or a file system.
Version 1.2 of Enterprise metadata discovery includes enhancements for configurable data handlers, function selectors, and data bindings, and a way to build service descriptions with these configured artifacts and existing schemas. For information about implementing interfaces for technology-style adapters, see Enterprise Metadata Discovery interfaces and implementation for technology adapters.
IBM WebSphere Adapter Toolkit overview
WebSphere Adapter Toolkit contains everything you need to create a resource adapter. The adapters are metadata-driven components designed for bidirectional communication with external services on enterprise information systems, such as transaction or ERP systems, as well as bidirectional communication with an email or Flat File.
Developing application components or processes that interact with the enterprise information system through an adapter requires tools that allow you to discover the services available on enterprise information systems. When an enterprise information system does not include a metadata repository, the tool allows you to build the appropriate interactions with the enterprise information system using adapters. The enterprise metadata discovery specification implemented by WebSphere Adapters enables you to discover services from an existing metadata repository or build the appropriate interactions with an enterprise information system. The specification defines the interaction between adapters and tools and enables plugging adapters into a compatible tool implementation that supports the specification.
The enterprise metadata discovery-compliant tools are based on the Eclipse platform and include IBM Integration Designer and IBM Rational Application Developer for WebSphere Software. These tools supports generation of SCA and Java™ EE programming model artifacts, and other artifacts for programming models and server run times. Enterprise metadata discovery provides plugability for artifact writers, which store the metadata and configuration information, to be compatible with the tools and run time requirements. The current enterprise metadata discovery implementation supports SCA artifacts, but other artifacts can also be generated by implementing a writer plug-in. Such implementations can choose to write the configuration information and metadata directly to their native repository, or create classes or configuration files that contain properties required during run time.
In the service discovery mode, use the adapter to connect to the enterprise information system metadata repository and browse its contents. You can select objects or services required by the business application from the repository, specify properties for the objects and import them (as business objects) into the development environment.
The enterprise metadata discovery process defines an abstract representation of the imported services that allows the external service wizard to generate artifacts that are specific to the programming model and the supported server run time.
If you need to build a service (rather than discover a service), you can use the external service wizard to create services from existing artifacts in the context of the particular adapter to be used at run time. You can select the existing data types to be exchanged and define the transformation to be performed on these data types.
The toolkit includes the following:
- An adapter development wizard and editor - Both are Eclipse plug-ins targeted for use with Integration Designer, version 7.5.1.1:
- The New Connector Project wizard - The wizard prompts you to specify information about the resource adapter you want to develop, and then generates code and a deployment descriptor.
The code generated by the wizard can include sequence of calls, log and trace messages, and comments.
- Resource Adapter Deployment Descriptor Editor - An Eclipse multi-page form editor that allows you to display and configure the deployment descriptor. As changes are made to configuration properties using the editor, the appropriate JavaBeans properties are added to your code.
- Adapter Foundation Classes - A common set of services for all WebSphere resource adapters.
- Samples - To assist you in creating custom WebSphere resource adapters.
New Connector Project wizard overview
The wizard installed with the WebSphere Adapter Toolkit guides you through creation of a Connector Project, including the generation of code and a deployment descriptor for a custom JCA resource adapter.
Figure 1. New Connector Project wizard
![]()
The New Connector Project wizard is an Eclipse plug-in intended for use with Integration Designer. The wizard allows you to create code in a Java™ Connector Project for a custom resource adapter. Working with the wizard, you can do the following:
- Generate implementations of the JCA 1.5 interface specification or extensions to the Adapter Foundation Classes API
The wizard prompts you for information that is then used to create the appropriate code for your adapter.
- Generate a resource adapter deployment descriptor
You can view and edit this deployment descriptor using the Resource Adapter Deployment Descriptor Editor.
Resource Adapter Deployment Descriptor Editor overview
This multi-page editor allows you to display, configure, and validate the resource adapter deployment descriptor generated by the wizard.
Figure 1. Resource Adapter Deployment Descriptor
![]()
The Resource Adapter Deployment Descriptor is an Eclipse plug-in for use with Integration Designer. The editor allows you to do the following:
- Display and configure the resource adapter deployment descriptor without having to modify the XML file directly
- Generate JavaBeans properties automatically in the generated source code that correspond to the configuration properties you add using the editor
- Validate the deployment descriptor against the JCA 1.5 deployment descriptor schema.
Adapter Foundation Classes overview
Adapter Foundation Classes installed with the WebSphere Adapter Toolkit provide the foundation services for a custom JCA resource adapter that can run on multiple server run times, including IBM Business Process Manager.
The New Connector Project wizard uses the Adapter Foundation Classes to generate an implementation of classes for your custom adapter. The Adapter Foundation Classes conform to, and extend, the Java™ 2 Connector Architecture JCA 1.5 specification. The foundation classes include generic contracts and methods to develop a working resource adapter. The New Connector Project wizard collects information to create enterprise information system-specific extensions to the foundation classes.
This document contains implementation guidelines for the Adapter Foundation Classes. The Javadoc for the Adapter Foundation Classes, as well as the Javadoc for the data exchange service provider interface and the Javadoc for the enterprise metadata discovery, are included as part of the WebSphere Adapter Toolkit installation. See IBM WebSphere Adapter Toolkit tasks.
IBM WebSphere Adapter Toolkit tasks
The tasks range from installing the toolkit, samples, and Adapter Foundation Classes (using the Eclipse Update Manager in Integration Designer) to implementing and validating your code.
You can now install WebSphere Adapter Toolkit during the installation of Integration Designer as WebSphere Adapter Toolkit is delivered in a product-based form. During installation, you can find WebSphere Adapter Toolkit under Additional IBM WebSphere Adapters.
WebSphere Adapter Toolkit tasks
Task Task description Validating WebSphere Adapter Toolkit installation requirements See the developerWorks site for WebSphere Adapter Toolkit for hardware and software prerequisites for the toolkit and for specific information about how to integrate the toolkit with IBM Integration Designer or IBM Rational Application Developer.
Make sure that you select the tab for version 7.5.0.2 of WebSphere Adapter Toolkit.
Install WebSphere Adapter Toolkit For IBM Integration Developer Users
WebSphere Adapter Toolkit installation is packaged with IBM Integration Designer.
To install the toolkit, or to check the installation, select Help > IBM Installation Manager > Modify. The Modify Packages screen will list the components already installed, and give options to install additional components.
Access the Javadoc for the Adapter Foundation Classes, EMD 1.2 and DESPI.
To access the Javadoc.
- From the Rational Application Developer for WebSphere Software or Integration Designer menu, select Help > Help Contents
- Choose Websphere Adapter Toolkit documentation and then select the Javadoc you want to view.
To view the Javadoc for JCA 1.5, go to the download section of the Java™ EE Connector Architecture site.
Use the New Connector Project wizard How to launch the wizard, specify properties, choose generation options, and generate classes. Use the Resource Adapter Deployment Descriptor editor How to launch the editor, display features, change and add properties, and edit the source content. Implementing code from WebSphere Adapter Toolkit How to implement the generated code. Validating the code How to validate your code. Create and exporting a resource adapter How to export a standalone (RAR file) or embedded (EAR file) resource adapter.
IBM WebSphere Adapter Toolkit installation requirements
You can install Adapter Toolkit on Windows or Linux operating systems and work with Integration Designer.
Operating system requirements
The following table lists the operating system requirements.
Operating system Versions Linux Red Hat Enterprise Linux AS/ES/WS 3 Update 4, Version 3.0 SUSE Linux Enterprise Server (SLES and SLSS), Version 9.0
Windows 2000 Windows 2000 Professional (SP4) Windows 2000 Server (SP4) Windows 2000 Advanced Server (SP 4)
Windows XP Windows XP SP 2 Windows 2003 Windows Server 2003 Standard Windows Server 2003 Enterprise
Hardware requirements
The following table lists the hardware requirements that support the operating systems.
Operating system Hardware requirements Linux Windows 2000 Windows 2003 Windows XP
- Intel Pentium III 800 MHZ processor or faster
- 1024 x 768 display or higher resolution monitor
- Memory: requirements
- 768 MB minimum
- 1 GB recommended
- Disk space requirements:
- 3.5 GB minimum to installing software prerequisites
- Additional disk space for the development resources.
You can reduce the minimum disk space if optional features and the required run time are not installed.
Software requirements
Eclipse plug-ins are part of WebSphere Adapter Toolkit.
For developing a WebSphere resource adapter on Rational Application Developer for WebSphere Software, make sure you have installed the JET Transformation Authoring and Runtime component. JET Transformation Authoring and Runtime component is an Eclipse plug-in that can be downloaded from http://www.eclipse.org/modeling/m2t/?project=jet. Extract the content of this plug-in into the respective folders under the <installation_root>/eclipse directory.
Additional information
The following links provide additional information you might need to configure and deploy your adapter:
- The compatibility matrix for WebSphere Business Integration Adapters and WebSphere Adapters identifies the supported versions of required software for your adapter. To view this document, go to the WebSphere Adapters support page: http://www.ibm.com/support/docview.wss?uid=swg27006249.
- Technotes for WebSphere Adapters provide workaround and additional information not included in the product documentation. To view the technotes for your adapter, go to the following web page, select the name of your adapter from the Product category list, and click the search icon: http://www.ibm.com/support/search.wss?tc=SSMKUK&rs=695&rank=8&dc=DB520+D800+D900+DA900+DA800+DB560&dtm.
Samples overview
When you install WebSphere Adapter Toolkit, an EIS Simulator sample adapter is placed on your system. This sample serves as a reference to create WebSphere adapters.
To help you use WebSphere Adapters, samples and tutorials are available from the BPM Samples and Tutorials website.
You can access the samples and tutorials in either of the following ways:
- From the home page of IBM Business Process Manager, select Introduction tab and click Sample Exchange Home. Browse the displayed categories to make your selection.
- From the BPM Samples and Tutorials website: IBM Business Process Management Wiki - Samples Exchange Home. Refer to the sample documentation that describes how to generate, implement, deploy, and test the EISS sample adapter.
Use the New Connector Project wizard
You use the wizard to create a Connector Project which contains a deployment descriptor and classes. The classes either extend the WebSphere Adapter Foundation Classes or implement the JCA 1.5 Interface specification.
Launching the New Connector Project wizard
You launch the wizard from IBM Integration Designer.
Make sure that you have met all the installation requirements and that you have successfully installed IBM Integration Designer and the WebSphere Adapter Toolkit plug-ins.
Launch the New Connector Project wizard to create an adapter project.
- Start IBM Integration Designer. IBM Integration Designer
Click Start > Programs > IBM > IBM Integration Designer > IBM Integration Designer version, where version is the version of IBM Integration Designer, for example, 7.5. The Workspace Launcher dialog is displayed.
![]()
Workspace Launcher dialog
- Enter a workspace directory for your project, or click Browse to select a location for your project in the Workspace field.
The workspace is a directory where IBM Integration Designer stores your project.
Optional: Select the Use this as the default and do not ask again check box to always use this workspace for new projects. You can change the workspace by choosing File > Switch Workspace.
- Make sure that you are in either the Business Integration or Java™ EE perspective.
- Select the wizard.
Click File > New > Other. The Select a wizard dialog is displayed.
![]()
Select a wizard dialog
- Start the wizard.
Expand the Java EE folder, select Connector Project, and click Next to start the New Connector Project wizard and display the Connector Project dialog.
![]()
Connector Project dialog
You are ready to describe your project and resource adapter properties.
Specify project properties
You name your connector project, optionally adding it to an Enterprise Application project. You also specify the configuration used for developing the resource adapter.
You perform all these tasks from the Connector Project dialog.
![]()
Connector Project dialog
- Name your Connector Project.
Enter a project name in the Project name field. The name is automatically appended to the workspace location.
- Set Target Runtime to Process Server v7.5 and select Configuration for IBM Websphere Adapter for the Configuration
The Configuration for IBM Websphere Adapter contains the IBM WebSphere Adapter Foundation Classes 7.5.0.3, J2C Module 1.5, and Java™ 5.0 Project Facets. You can modify these facets by clicking the Modify button.
- Optional: Specify an Enterprise Application Archive (EAR) project name.
- In the EAR Membership section, click the Add project to an EAR check box. Enter or select a name in the EAR project Name field or click New and then name the new EAR project.
You can generate an EAR file later, after building and testing the adapter.
- Click Next to display the Project facets dialog.
You are ready to specify project facet properties.
Specify project facets
As part of the process of creating a project, you specify project facets. A project facet represents a unit of functionality in the project. Project facets define characteristics and requirements for projects. When you add a facet to a project, that project is configured to perform a certain task, fulfill certain requirements, or have certain characteristics.
- From the New Connector Project screen, make sure Configuration for IBM WebSphere Adapter displays in the Configurations field and do not change the configuration or clear any of the project facets. The project facets preselected are the facets run the WebSphere Adapter Toolkit.
![]()
- Select Next to go to the Connector Project module settings panel.
Now you can configure the Connector Project Module settings.
Specify connector project module settings
Specify connector project module settings for your adapter.
- From the Configure Connector Module setting page, accept the name assigned to the connector project.
![]()
- Click Next to advance to the Resource adapter properties page.
Now you are ready to set the properties for the resource adapter.
Specify resource adapter properties
Resource adapter properties describe the properties that you assign an adapter, and an adapter class. You name the adapter and qualify its Java™ class with a package name and class prefix.
You perform these tasks in the J2C Resource Adapter Properties window.
Figure 1. J2C Resource Adapter Properties window
![]()
- In Adapter name, type the name of the adapter.
- In Adapter shortname, type a one- to four-character short name for the adapter. The short name is used to create the component name used in the log and trace files as follows:
shortname + the characters "RA" + the value of the adapter ID property, which the user specifies when configuring the adapter
For example, if you specify the short name BO and the user specifies the adapter ID of 001, then the component name used in log and trace files is BORA001.
- In Package name, type the package name.
- In Class name prefix, type the prefix to be used in adapter class names. Class name displays the resulting fully qualified ResourceAdapter class name.
- Click Next to display the Generation Options window to specify the adapter type, operations, and components.
To create a default connector project without selecting the adapter type, operations, and components, click Finish.
You can now specify generation options for your resource adapter.
Specify generation options
You can generate classes for the Generation options components. You specify adapter components in the Generation Options dialog.
To determine the generation options, you must specify the adapter you want to implement from either of the following types:
- IBM WebSphere Resource Adapter
- Java™ EE JCA Resource Adapter
For information about the characteristics of an IBM WebSphere Resource Adapter and a Java EE JCA Resource Adapter, see Introduction to JCA.
From the Develop drop-down, select the type of adapter you want to create:
- Select IBM WebSphere Resource Adapter in the Develop list to generate code that extends the Adapter Foundation Classes.
- Select Java EE JCA Resource Adapter in the Develop list to generate code that implements the JCA 1.5 interface specification.
The wizard displays the generation options that correspond to your adapter.
You are ready to specify generation options that match your adapter requirements.
Generating an IBM WebSphere Resource Adapter
You use the wizard to generate adapter classes that correspond to the adapter capabilities you require. This involves choosing the types of adapter classes (outbound, inbound, data binding, or enterprise metadata discovery) you want to generate and then choosing the component properties associated with the adapter classes.
Use the Component Addition option in the Resource Adapter Deployment Descriptor editor to append the code for the newly specified components to the current implementation without override. See Component Addition option in Use the Overview pane.
The following sections describe the adapter classes and their associated component properties.
Outbound adapter classes and associated properties
Generate outbound adapter classes creates code (and in some cases sequence of calls, log and trace messages, and comments) for the methods that must be implemented to produce a resource adapter that can send business events to an EIS. The Adapter Foundation Classes that are extended in your Connector Project when you generate outbound adapter classes, is as follows:
- Connection extends com.ibm.j2ca.base.WBIConnection
- ConnectionFactory extends com.ibm.j2ca.base.WBIConnectionFactory
- ConnectionRequestInfo extends com.ibm.j2ca.base.WBIConnectionRequestInfo
- Interaction extends com.ibm.j2ca.base.WBIInteraction
- InteractionSpec extends com.ibm.j2ca.base.WBIInteractionSpec
- ManagedConnection extends com.ibm.j2ca.base.WBIManagedConnection
- ManagedConnectionFactory extends com.ibm.j2ca.base.WBIManagedConnectionFactory
In addition the following outbound adapter classes are generated directly from the JCA 1.5 interface specification:
- ConnectionSpec implements javax.resource.cci.ConnectionSpec
- ConnectionMetaDataImpl implements javax.resource.cci.ConnectionMetaData
- LocalTransaction implements javax.resource.spi.LocalTransaction
You can select the following properties when generating outbound adapter classes:
- Local transaction support
Generate outbound adapter classes with local transaction support means the transaction is managed and performed by the EIS. LocalTransaction indicates the IBM WebSphere adapter supports local transactions. Local transaction support methods provide a LocalTransaction implementation and return the wrapper.
WBILocalTransaction implementation covers the following requirements:
- Notifies the JCA container
- Updates the state of transactions on the WBIManagedConnection
When you choose the Local Transaction Support component property from the list of outbound adapter component properties, the wizard creates the following method in the ManagedConnection class:
/** * Does the EIS support local transaction? Provide a LocalTransaction * implementation and return the wrapper. * * @return new instance of WBILocalResourceWrapper * @see javax.resource.spi.ManagedConnection#getLocalTransaction() */ public LocalTransaction getLocalTransaction() throws ResourceException { FooLocalTransaction transaction = new FooLocalTransaction(this); return new WBILocalTransactionWrapper(transaction, this); }For information about how to generate an outbound adapter with local transaction support, see Generating outbound local transaction support methods.
- XA transaction support
Generate outbound adapter classes with XA transaction support means the transaction spans multiple heterogeneous systems. It uses global or two-phase-commit protocol. If a transaction manager coordinates a transaction, that transaction is considered a global transaction.
Use the WBILocalTransaction covers the following requirements:
- Notifies the JCA container
- Updates the state of transactions on the WBIManagedConnection
The getXAResource() method gets the XAResource from your EIS and return the wrapper. The WBIXAResourceWrapper acts as a thin layer delegating all calls to the underlying EIS XAResource instance, at the same time tracking the sequence of calls to monitor and determine when the connection is involved in a transaction and when it is not.
The wizard creates getXAResource() and getLocaltransaction() methods as follows:
Local method
/** * Does the EIS support local transaction? * * @return new instance of WBIXAResourceWrapper * @see javax.resource.spi.ManagedConnection#getLocalTransaction() */ public LocalTransaction getLocalTransaction() throws ResourceException { <AdapterPrefixName>Transaction transaction = new <AdapterPrefixName>LocalTransaction(this); return new WBILocalTransactionWrapper(transaction, this);}XA method
/** * Does the EIS support XA transaction? * Get the XAResource from your EIS and return the wrapper. * * @return new instance of WBIXAResourceWrapper * @see javax.resource.spi.ManagedConnection#getXAResource() */ public XAResource getXAResource() throws ResourceException { return new WBIXAResourceWrapper(null, this);}Further implementation of these methods is needed to support XA transactions.
For information about how to generate XA Transaction support methods, see Generating XA Transaction support methods.
- Command pattern
Generate command pattern classes allows you to break down a hierarchical update into a series of nodes and then generate a collection of subcommands to manage the nodes. An interpreter processes the subcommands, retrieving, and executing the corresponding code. If you choose this option, the wizard generates code for the following classes:
- BaseCommand extends com.ibm.j2ca.extension.commandpattern.CommandForCursor
- CommandFactory implements com.ibm.j2ca.extension.commandpattern.CommandFactoryForCursor
- CreateCommand extends <your package name>.outbound.commandpattern.<your class prefix>BaseCommand
- DeleteCommand extends <your package name>.outbound.commandpattern.<your class prefix>BaseCommand
- NoOperationCommand extends <your package name>.outbound.commandpattern.<your class prefix>BaseCommand
- RetrieveCommand extends <your package name>.outbound.commandpattern.<your class prefix>BaseCommand
- RetrieveAllCommand extends <your package name>.outbound.commandpattern.<your class prefix>BaseCommand
- UpdateCommand extends <your package name>.outbound.commandpattern.<your class prefix>BaseCommand
For information about how to generate command pattern classes, see Generating command pattern classes.
Inbound adapter classes and associated methods
Generate inbound adapter classes creates code for the methods that must be implemented to produce a resource adapter that can send events from an EIS to a business process. The list of Adapter Foundation Classes that are extended in your Connector Project when you choose to generate inbound adapter classes is as follows:
- ActivationSpecWithXid extends com.ibm.j2ca.base.WBIActivationSpecWithXid
- EventStoreWithXid extends com.ibm.j2ca.extension.eventmanagement.EventStoreWithXid
You can select the following properties when generating inbound adapter classes:
- Connection pooling
When you choose the connection pooling component property the wizard creates the ActivationSpecWithXid class that extends WBIActivationSpecForPooling.
For information about how to generate inbound connection pooling support, see Generating inbound connection pooling support.
- Event polling support
Generate inbound adapter classes for event polling support creates code for the methods that must be implemented to produce a resource adapter that can send polling events from an EIS to a business process.
The Adapter Foundation Classes that are extended in your Connector Project when you generate inbound adapter classes for event polling support, is as follows:
- ActivationSpecWithXid extends com.ibm.j2ca.base.WBIActivationSpecWithXid
- EventStoreWithXid extends com.ibm.j2ca.extension.eventmanagement.EventStoreWithXid
When the CommException exception is logged during adapter startup because the EIS is down, stopped, or unreachable, the adapter automatically try the connection if the RetryConnectionOnStartup activation specification property is enabled. If the property is not enabled, the adapter immediately reports the failure. This support is provided by the Adapter Foundation Classes. An adapter user enables this property in the external service wizard by selecting Retry EIS connection on startup on the Service Generation and Deployment Configuration window. The RetryConnectionOnStartup property works with the RetryLimit and RetryInterval properties, which specify the number of times the adapter tries the connection, and the time intervals.
For information about how to generate event polling support, see Generating inbound event polling support.
- Generating inbound callback event support
Generate inbound adapter classes for callback event support creates code for the methods that must be implemented to produce a resource adapter that can send callback events from an EIS to a business process.
The Adapter Foundation Classes that are extended in your Connector Project when you generate inbound adapter classes for callback event support, is as follows:
- ActivationSpecWithXid extends com.ibm.j2ca.base.WBIActivationSpecWithXid
- InboundListener that imports in com.ibm.j2ca.extension.eventmanagment.external.CallbackEventSender
For information about how to generate inbound callback event support, see Generating inbound callback event support.
Data Binding classes
There are no properties associated with data binding classes.
Generate data binding classes creates code for the methods needed to marshall data from SDO to CCI record and from CCI record to SDO.
The Adapter Foundation Classes that are extended in your Connector Project when you generate data binding classes, is as follows:
- DataBinding implements
commonj.connector.runtime.RecordHolderDataBinding
- DataBindingGenerator extends
com.ibm.j2ca.extension.databinding.WBIDataBindingGenerator
For information about how to generate data binding classes, see Generating Data Binding Classes.
Enterprise Metadata Discovery classes
There are no properties associated with Enterprise Metadata Discovery classes.
Generate enterprise metadata discovery classes creates code for the methods needed to produce a service that you can use to glean business object structure and other data from an EIS.
The Adapter Foundation Classes that are extended in your Connector Project when you generate enterprise metadata discovery classes, is as follows:
- AdapterType extends
com.ibm.j2ca.extension.emd.discovery.WBIAdapterTypeImpl
- DataDescription extends
com.ibm.j2ca.extension.emd.description.WBIDataDescriptionImpl
- InboundConnectionConfiguration extends
com.ibm.j2ca.extension.emd.discovery.connection.WBIInboundConnectionConfigurationImpl
- InboundConnectionType extends
com.ibm.j2ca.extension.emd.discovery.connection.WBIInboundConnectionTypeImpl
- InboundServiceDescription extends
com.ibm.j2ca.extension.emd.description.WBIInboundServiceDescriptionImpl
- MetadataDiscovery extends
com.ibm.j2ca.extension.emd.discovery.WBIMetadataDiscoveryImpl
- MetadataEdit extends
com.ibm.j2ca.extension.emd.discovery.WBIMetadataEditImpl
- MetadataImportConfiguration extends
com.ibm.j2ca.extension.emd.discovery.WBIMetadataImportConfigurationImpl
- MetadataObject extends
com.ibm.j2ca.extension.emd.discovery.WBIMetadataObjectImpl
- MetadataSelection extends
com.ibm.j2ca.extension.emd.discovery.WBIMetadataSelectionImpl
- MetadataTree extends
com.ibm.j2ca.extension.emd.discovery.WBIMetadataTreeImpl
- OutboundConnectionConfiguration extends
com.ibm.j2ca.extension.emd.discovery.connection.WBIOutboundConnectionConfiguration
- OutboundConnectionType extends
com.ibm.j2ca.extension.emd.discovery.connection.WBIOutboundConnectionTypeImpl
- OutboundServiceDescription extends
com.ibm.j2ca.extension.emd.description.WBIOutboundServiceDescriptionImpl
In addition to the Adapter Foundation Classes listed above, the following classes are also generated, to help you:
- Constants
Contains enterprise metadata discovery constant variables.
- StringCaseChanger
A formatting utility to modify a business object or attribute name.
For information about how to generate Enterprise Metadata Discovery classes, see Generating Enterprise Metadata Discovery classes .
Generating outbound adapter classes
Generate outbound adapter classes for an adapter that sends requests from a client application to an enterprise information system.
Review the section on outbound adapter classes and associated properties in Generating an IBM WebSphere Resource Adapter. When you generate outbound adapter classes, the wizard creates a code (and in some cases sequence of calls, log and trace messages, and comments) for the methods that you implement, to create a resource adapter that can send business events to an enterprise information system.
- From the Available components area of the Generation Options window, select the Generate outbound adapter classes check box.
![]()
- Review the available component property options associated with outbound adapter classes.
Each of the component property options are described in the sections that follow.
Generate the outbound adapter classes for the selected component property.
Generating outbound local transaction support methods
With a local transaction support, an enterprise information system manages and completes a transaction. WebSphere adapter supports local transactions, and these methods provide a LocalTransaction implementation and return a wrapper.
Consider your strategy for implementing transaction behavior in the adapter before generating outbound classes. You cannot regenerate the code to add XA transactional behavior to the adapter, if you click Finish to generate the code for this task.
Review the section on local transaction support in Generating an IBM WebSphere Resource Adapter. For more information about transaction support, see Implementing transaction support.
- Select the Generate outbound adapter classes check box and then select Local transaction support in the right pane.
![]()
Before clicking Finish, be aware that when you generate transactional support for the outbound classes you will not be able to modify the transaction support automatically after generating the classes.
- Click Finish.
You can generate outbound XA transaction support methods.
Generating outbound XA transaction support methods
With XA transaction support, the transaction spans multiple heterogeneous systems. It uses a global or a two-phase-commit protocol. If a transaction manager coordinates a transaction, that transaction is considered a global transaction.
Review the section on XA transaction support in Generating an IBM WebSphere Resource Adapter. The getLocalTransaction() method provides a LocalTransaction implementation and returns the wrapper.
For more information about transaction support, see Implementing transaction support.
- Select the Generate outbound adapter classes check box and then select XA transaction support in the right pane.
![]()
- Click Finish.
Now, you can generate command pattern classes.
Generating command pattern classes
Command pattern classes help reduce the complexity associated with comparing and managing dynamic object hierarchies.
Review the section on command pattern classes in Generating an IBM WebSphere Resource Adapter. The command pattern classes allow you to break down a hierarchical update into a series of nodes and then generate a collection of subcommands to manage the nodes. An interpreter processes the subcommands, retrieves, and executes the corresponding code.
- Select theGenerate outbound adapter classes option and then select theCommand pattern component property on the right pane.
![]()
- Click Finish.
Generating inbound adapter classes
Generate inbound adapter classes for notifying a business process of an inbound event from the EIS.
Review the section on inbound adapter classes and associated properties in Generating an IBM WebSphere Resource Adapter. When you select generate inbound adapter classes, the wizard creates code for the methods that must be implemented to produce a resource adapter that can send events from an EIS to a business process.
- From the Available components area of the Generation Options window, select the Generate inbound adapter classes check box.
![]()
- Review the available component property options associated with inbound adapter classes.
Each of the component property options were described in the sections that follow.
Generate the inbound adapter classes for the component property selected.Before deploying your adapter to IBM Business Process Manager version 7.5.0.3, you must populate all inbound properties with default values. You can also assign dummy values to properties that are generated but not implemented by your adapter.
Generating inbound connection pooling support
Generate inbound connection pooling is used to create code that support XA transactions. When you choose the connection pooling component property the wizard creates the ActivationSpecWithXid class that extends WBIActivationSpecForPooling.
Further implementation of this method is needed to support XA transactions.
- Select the Generate inbound adapter classes check box and then select the Connection pooling check box in the right pane.
The Event polling support property is selected automatically when you select theConnection pooling check box. Connection pooling is not supported for Callback Events.
![]()
- Click Finish.
Now, you can generate inbound event polling support.
Generating inbound event polling support
Event polling refers to the adapter polling the event records from the event store at regular intervals. In each poll call, a number of events are processed by the adapter.
Review the information about inbound adapter classes and the information about inbound event polling support in Generating an IBM WebSphere Resource Adapter. When you choose to generate inbound adapter classes for event polling support, the wizard creates code for the methods that must be implemented to produce a resource adapter that can send polling events from an EIS to a business process.
- Select the Generate inbound adapter classes check box and then select Event polling support in the right pane.
![]()
- Click Finish.
Now, you can generate inbound callback event classes.
Generating inbound callback event support
Inbound callback event support alerts business processes when there is a change in an EIS. Callback refers to the ability of the EIS system to directly notify the adapter or business processes of a change, as opposed to the polling mechanism used in event notification.
Review the information about inbound adapter classes and the information about inbound callback event support in Inbound callback event notification. When you select generate inbound adapter classes for callback event support, the wizard creates code for the methods that must be implemented to produce a resource adapter that can send callback events from an EIS to a business process.
- Select the Generate inbound adapter classes check box and then select Callback event support in the right pane.
![]()
- Click Finish.
Now you can generate enterprise metadata discovery classes.
Generating enterprise metadata discovery classes
The enterprise metadata discovery classes are used by the external service discovery tool in Integration Designer to introspect an EIS to create business objects and other artifacts.
Review the information about enterprise metadata discovery classes in Generating an IBM WebSphere Resource Adapter. When you choose to generate enterprise metadata discovery classes, the wizard generates code for the methods needed to produce a service that you can use to glean business object structure and other data from an EIS.
- Select the Generate Enterprise Metadata Discovery classes check box.
![]()
- Click Finish.
Generate data binding classes.
Generating data binding classes
You can generate data binding classes separately from the data binding classes that are generated from enterprise metadata discovery.
Review the section on data binding classes in Generating an IBM WebSphere Resource Adapter. When you choose to generate data binding classes, the wizard generates code for the methods needed to marshall data from SDO to CCI record and from CCI record to SDO.
- Select the Data binding classes for SCA check box.
![]()
- Click Finish.
Learn how to generate a JCA resource adapter.
Generating a JCA resource adapter
You use the wizard to generate adapter classes that correspond to the properties and options you specify.
The following sections describe the JCA resource adapter classes.
Outbound JCA resource adapter classes
Generate outbound JCA resource adapter classes creates code for the methods that must be implemented to produce a JCA resource adapter that can send business events to an EIS. When you generate outbound adapter classes, the following list of JCA 1.5 interfaces are implemented in your Connector Project::
- ConnectionFactory implements javax.resource.cci.ConnectionFactory
- Connection implements javax.resource.cci.Connection
- ConnectionMetaData implements javax.resource.cci.ConnectionMetaData
- ConnectionRequestInfo implements javax.resource.cci.ConnectionRequestInfo
- ConnectionSpec implements javax.resource.cci.ConnectionSpec
- Interaction implements javax.resource.cci.Interaction
- InteractionSpec implements javax.resource.cci.InteractionSpec
- LocalTransaction implements javax.resource.cci.LocalTransaction
- ManagedConnectionFactory implements javax.resource.spi.ResourceAdapterAssociation, javax.ValidatingManagedConnectionFactory, ManagedConnectionFactory
- MangedConnection implements javax.resource.spi.DissasociatableManagedConnection, ManagedConnection
- ManagedConnectionMetaData implements ManagedConnectionMetaData
For information about how to generate outbound JCA resource adapter classes, see Generating outbound JCA adapter classes.
Inbound JCA resource adapter classes
Generate inbound JCA resource adapter classes creates code for the methods that must be implemented to produce a resource adapter that can send events from an EIS to a business process. When you generate inbound adapter classes, the following JCA 1.5 interface class is implemented in your Connector Project:
- ActivationSpec Implements javax.resource.spi.ActivationSpec
For information about how to generate inbound JCA resource adapter classes, see Generating inbound JCA adapter classes.
JCA Enterprise Metadata Discovery classes
Generate enterprise metadata discovery classes creates code for the methods needed to produce a service that you can use to glean business object structure and other data from an EIS. The wizard also generates a discovery-service.xml file.
When you generate the enterprise metadata discovery classes, the following JCA interfaces are implemented in your Connector Project::
- DataBindingDescription implements commonj.connector.description.DataBindingDescription
- DataBindingGenerator implements commonj.connector.description.DataBindingGenerator
- DataDescription implements commonj.connector.description.DataDescription
- DataFile implements commonj.connector.description.DataFile
- FunctionDescription implements commonj.connector.description.FunctionDescription
- InboundFunctionDescription implements commonj.connector.description.InboundFunctionDescription
- InboundServiceDescription implements commonj.connector.description.InboundServiceDescription
- OutboundFunctionDescription implements commonj.connector.description.OutboundFunctionDescription
- OutboundServiceDescription implements commonj.connector.description.OutboundServiceDescription
- SchemaDefinition implements commonj.connector.SchemaDefinition
- ServiceDescription implements commonj.connector.description.ServiceDescription
- AdapterType implements commonj.connector.discovery.AdapterType
- AdapterTypeSummary implements commonj.connector.discovery.AdapterTypeSummary
- EditableType implements commonj.connector.discoveryEditableType
- MetadataDiscovery implements commonj.connector.discovery.MetadataDiscovery
- MetadataEdit implements commonj.connector.discovery.MetadataEdit
- MetadataImportConfiguration implements commonj.connector.discovery.MetadataImportConfiguration
- MetadataObject implements commonj.connector.discovery.MetadataObject
- MetadataObjectIterator implements commonj.connector.discovery.MetadataObjectIterator
- MetadataObjectResponse implements commonj.connector.discovery.MetadataObjectResponse
- MetadataSelection implements commonj.connector.discovery.MetadataSelection
- MetadataTree implements commonj.connector.discovery.MetadataTree
- ConnectionConfiguration implements commonj.connector.discovery.ConnectionConfiguration
- ConnectionPersistence implements commonj.connector.discovery.ConnectionPersistence
- ConnectionType implements commonj.connector.discovery.ConnectionType
- InboundConnectionConfiguration implements commonj.connector.discovery.InboundConnectionConfiguration
- InboundConnectionType implements javax.resource.emd.discovery.InboundConnectionType
- MetadataConnection implements commonj.connector.discovery.MetadataConnection
- OutboundConnectionConfiguration implements commonj.connector.discovery.OutboundConnectionConfiguration
- OutboundConnectionType implements commonj.connector.discovery.OutboundConnectionType
- Action implements commonj.connector.discovery.Action
- ObjectWizard implements commonj.connector.discovery.ObjectWizard
- ObjectWizardStatus implements commonj.connector.discovery.ObjectWizardStatus
- ObjectWizardStep implements commonj.connector.discovery.ObjectWizardStep
- Operation implements commonj.connector.discovery.Operation
- OperationType implements commonj.connector.discovery.OperationType
- DataBinding implements javax.resource.runtime.DataBinding
- FunctionSelector implements javax.resource.runtime.FunctionSelector
- InboundListener implements javax.resource.runtime.InboundListener
- InboundNativeDataRecord implements javax.resource.runtime.InboundNativeDataRecord
- RecordDataBindingImpl implements javax.resource.runtime.RecordDataBinding
- RecordHolderDataBinding implements javax.resource.runtime.RecordHolderDataBinding
- PropertyDescriptor implements javax.resource.runtime.PropertyDescriptor
- PropertyType implements javax.resource.runtime.PropertyType
- Property implements javax.resource.runtime.Property and javax.resource.runtime.PropertyDescriptor
- SingleTypedProperty
implements javax.resource.runtime.SingleTypedProperty and javax.resource.runtime.PropertyDescriptor
- SingleValuedProperty implements javax.resource.runtime.SingleValedProperty and javax.resource.runtime.PropertyDescriptor
- PropertyGroup implements javax.resource.runtime.PropertyGroup and javax.resource.runtime.PropertyDescriptor
- MultiValuedProperty implements javax.resource.runtime.MultiValuedPropertyProperty and javax.resource.runtime.PropertyDescriptor
- BoundedMultiValuedProperty implements javax.resource.runtime.BoundedMultiValuedProperty and javax.resource.runtime.PropertyDescriptor
- NodeProperty implements javax.resource.runtime.NodeProperty and javax.resource.runtime.PropertyDescriptor
- TreeProperty implements javax.resource.runtime.TreeProperty and javax.resource.runtime.PropertyDescriptor
- TableProperty implements javax.resource.runtime.TableProperty and javax.resource.runtime.PropertyDescriptor
For information about how to generate Enterprise Metadata Discovery classes, see Generating JCA Enterprise Metadata Discovery classes.
If you select the IBM WebSphere Adapter Foundation Classes Support feature check box in the Project Facets screen, then the created JCA resource adapter project automatically includes the IBM WebSphere Adapter Foundation Classes library in the project libraries list of the Java™ Build path.
- Generating outbound JCA adapter classes The outbound adapter classes are responsible for notifying an EIS of outbound events from a business process.
- Generating inbound JCA adapter classes The inbound adapter classes are responsible for notifying a business process of an inbound event from the EIS.
- Generating JCA enterprise metadata discovery classes The enterprise metadata discovery classes are used by the external service discovery tool in Integration Designer to introspect an EIS to create business objects and other artifacts.
Generating outbound JCA adapter classes
The outbound adapter classes are responsible for notifying an EIS of outbound events from a business process.
Review the section on outbound JCA resource adapter classes in Generating a JCA resource adapter. When you select the generate outbound adapter classes, the wizard creates code for the methods that must be implemented to produce a resource adapter that can send business events to an EIS.
- Select the Generate Outbound Adapter classes check box.
![]()
- Click Finish.
Generate inbound JCA adapter classes.
Generating inbound JCA adapter classes
The inbound adapter classes are responsible for notifying a business process of an inbound event from the EIS.
Review the section on inbound JCA resource adapter classes in Generating a JCA resource adapter. When you choose to generate inbound adapter classes, the wizard creates code for the methods that must be implemented to produce a resource adapter that can send events from an EIS to a business process.
- Select the Generate Inbound Adapter classes check box.
![]()
- Click Finish.
Generate JCA enterprise metadata discovery classes.
Generating JCA enterprise metadata discovery classes
The enterprise metadata discovery classes are used by the external service discovery tool in Integration Designer to introspect an EIS to create business objects and other artifacts.
Review the section on JCA enterprise metadata discovery classes in Generating a JCA resource adapter When you choose to generate enterprise metadata discovery classes, the wizard generates code for the methods needed to produce a service that you can use to glean business object structure and other data from an EIS. The wizard also generates a discovery-service.xml file.
When you generate JCA enterprise metadata discovery classes, the wizard adds a prefix to each. The prefix is the Class name prefix that you entered when specifying properties on the Resource adapter properties page of the wizard.
- Select the Generate Enterprise Metadata Discovery classes check box.
![]()
- Click Finish.
Generated code and deployment descriptor
The generated artifacts reflect the adapter classes with the properties and options you specified.
After you specify options for your resource adapter, the wizard generates code and a deployment descriptor in a Connector Project and then switches to the Java™ EE perspective in the workspace. The wizard then automatically launches the Resource Adapter Deployment Descriptor editor.
For a complete description of the editor, see the Resource Adapter Deployment Descriptor Editor overview.
Use the Resource Adapter Deployment Descriptor editor
The Resource Adapter Deployment Descriptor editor provides an easy and convenient way to configure your resource adapter.
![]()
Resource Adapter Deployment Descriptor editor
You configure the resource adapter by using a deployment descriptor. The deployment descriptor—the ra.xml file— is generated by the wizard and included in your Java™ Connector Project.
The editor is made up multiple pages each of which represents a major section of the ra.xml file. Changes made in the editor are saved directly to the ra.xml file in your Java Connector Project.
The editor allows you to display and modify all elements of the ra.xml file. You can also add properties. After each modification, this file is validated against its schema definition to ensure its validity.
Any validation problems with the ra.xml file are displayed in the Problems view of the development environment.
- Displaying the deployment descriptor Once you complete the New Connector Project wizard your workspace is switched to the Java EE perspective and the deployment descriptor displays using the Resource Adapter Deployment Descriptor editor.
- Modify deployment descriptor properties When you modify configuration properties, the Resource Adapter Deployment Descriptor automatically updates source code with corresponding JavaBeans properties.
- Editing deployment descriptor source You can view and edit the deployment descriptor of your adapter directly.
Displaying the deployment descriptor
Once you complete the New Connector Project wizard your workspace is switched to the Java™ EE perspective and the deployment descriptor displays using the Resource Adapter Deployment Descriptor editor. Displaying the deployment descriptor in the editor provides you with several different views.
![]()
Deployment descriptor Overview pane
Alternatively, you can view the deployment descriptor in the editor by highlighting the file in the Project Explorer and selecting Open With > Deployment Descriptor Editor.
![]()
Displaying the descriptor editor from the pop-up menu
- Use the Overview pane The Overview pane provides access to general information about your resource adapter. You can display it at any time by clicking the Overview tab at the bottom of this pane.
- Use the Resource Adapter pane The Resource Adapter pane displays information that is stored in the <resourceadapter> element of the ra.xml file.
- Use the Outbound Adapter pane The Outbound Adapter pane displays information that is stored in the <outboundresourceadapter> element of the ra.xml.
- Use the Inbound Adapter pane The Inbound Adapter pane displays information that is stored in the <inbound-resourceadapter> element of the ra.xml file.
You can display each of the four views by using the tabs at the bottom of the Overview pane, which is the default view.
![]()
Descriptor editor tabs
Use the Overview pane
The Overview pane provides access to general information about your resource adapter. You can display it at any time by clicking the Overview tab at the bottom of this pane. In addition to providing general information about your resource adapter, you can generate components that you have not originally specified when working with the wizard.
![]()
Overview pane
The General Information section summarizes general information about the resource adapter.
The License Information section allows you to specify and display license descriptions and requirements, if any, for the resource adapter.
The Components section provides navigation links to other panes of the editor.
The Component Addition section allows you to generate components that you have not originally specified when working with the wizard. Click the Add to display the Add Component dialog box. Only those options not previously generated is enabled for you to select.
For example, after generating the outbound adapter classes in first run, if you select Generate inbound adapter classes and generate the inbound adapter classes using the Add Component option, then the generated inbound adapter classes get appended to the existing implementation without override.
To display the Add button for Add Component, maximize the Overview pane. The Add button does not display when this pane is minimized.
![]()
Add component dialog
The Icons section of the overview pane allows you to associate icons with the resource adapter. You can specify a large or small icon in jpg or gif format. To fit into the allotted area, the large icons must be 32 x 32 pixels and the small icon 16 x 16 pixels.BPM does not use these icons.
Use the Resource Adapter pane
The Resource Adapter pane displays information that is stored in the <resourceadapter> element of the ra.xml file. You can navigate to this pane by clicking ResourceAdapter in the Components section of the Overview pane or by clicking the ResourceAdapter tab at the bottom of the pane.
The following section describes the Resource Adapter pane:
![]()
Resource adapter pane
The General Information section allows you to specify deployment descriptor values for the entire resource adapter. This section displays the name of the ResourceAdapter class with which this deployment descriptor is associated. This class must directly or indirectly implement the javax.resource.spi.ResourceAdapter interface.
The Components section provides navigation links to other parts of the editor. The Resource Adapter pane displays links to the Outbound Adapter and Inbound Adapter panes.
The Config Properties section allows you to specify resource-adapter-level configuration properties. By default, all configuration properties inherited by the class specified in the Resource Adapter Classname field in the General Information section are shown here. You can specify default values for these inherited properties. In addition, you can add or delete your own user-defined configuration properties using the Add and Remove buttons on the left side of the editor. You can also edit these properties using the widgets on the right side of the editor.
![]()
Add Config property dialog
When you add, modify, or delete user-defined properties in this section, the editor creates (or removes) the corresponding JavaBeans properties in your code. See Modify properties.
The Admin Objects section allows you to specify administered objects for this resource adapter and configure their properties. You can add, update, or delete administered objects and specify properties for each object. The information you specify here is stored at the resource adapter level of the deployment descriptor.
The Security Permissions section allows you to specify the permissions required by the resource adapter to process within the application server. You can add, update, or delete security permissions. The information you specify here is stored at the resource adapter level of the deployment descriptor.
You can change or delete the existing value for Permission Class only by using the browse button provided. You cannot delete the permission class from the text field directly.
Use the Outbound Adapter pane
The Outbound Adapter pane displays information that is stored in the <outboundresourceadapter> element of the ra.xml. You can navigate to this pane by clicking OutboundResourceAdapter in the Components section of the Overview pane or by clicking the Outbound Adapter tab at the bottom of the pane.
The sections of the Outbound Adapter pane are described as:
![]()
Outbound resource adapter pane
The General Information section allows you to specify deployment descriptor values associated with the outbound resource adapter. You can specify the level of transaction support, if any, and whether reauthentication is supported.
The Connection Definitions section allows you to specify an outbound connection definition. This connection definition is used by the application server to obtain a physical connection to the EIS. Clicking the Add button under the Connection Definitions list on the left side of the editor displays the following dialog box, which allows you to specify all required connection definition information.
![]()
Add Connection Definition dialog
A Connection Definition requires the following information:
- ConnectionFactory Interface
- ConnecitonFactory Implementation Class
- Connection Interface
- Connection Implementation Class
- ConnectionRequestInfo Class
- ManagedConnectionFactory Class
Once a connection definition is defined all properties inherited by the specified ManangedConnectionFactory are shown in the properties list directly under the ManagedConnectionFactory Class. You can specify default values and descriptions for these inherited properties. In addition, you can add, update or delete your own user-defined configuration properties using the Add, Edit, and Remove buttons on the right side of the editor.
![]()
Add Config property dialog
When you add, modify, or delete user-defined properties in this section, the editor creates (or removes) the corresponding JavaBeans properties in your code. See Modify properties.
The Authentication Mechanisms section allows you to specify the authentication mechanisms supported by the resource adapter.
Use the Inbound Adapter pane
The Inbound Adapter pane displays information that is stored in the <inbound-resourceadapter> element of the ra.xml file. You can navigate to this pane by clicking InboundResourceAdapter in the Components section of the Overview pane or by clicking the Inbound Adapter tab at the bottom of the pane.
The Inbound Adapter pane contains a Message Listeners section.
![]()
Inbound Resource Adapter pane
The Message Listeners section allows you to specify message listeners for inbound event processing. Specify a MessageListener type and an Activation Spec class. Clicking the Add button under the list of Message Listeners on the left side of the editor displays the following dialog box.
![]()
Add Message Listener dialog
Once a message listener is defined all properties inherited by the specified ActivationSpecWithXid are shown in the properties list directly under the ActivationSpecWithXid Class.
You can specify default values and descriptions for these inherited properties. In addition, you can add, update, or delete your own user-defined configuration properties using the Add, Edit, or Remove buttons on the right side of the editor.
![]()
Add Required Config Property dialog
When you add, modify, or delete user-defined properties in this section, the editor creates (or removes) the corresponding JavaBeans properties in your code. See Modify properties.
Modify deployment descriptor properties
When you modify configuration properties, the Resource Adapter Deployment Descriptor automatically updates source code with corresponding JavaBeans properties. When you define configuration properties, you typically must also add them to the source code as JavaBeans properties. The Resource Adapter Deployment Descriptor performs adding the source code and other tasks automatically:
- When you add a property using the editor, the editor adds the appropriate field and accessor methods to the Java™ code for you.
- When you delete a property, the editor removes the field and accessor methods for you.
- When you modify the type of a property, the editor adjusts the field and accessor methods accordingly.
Removing or modifying properties can cause compilation errors in your code that you must resolve.
Generated bean properties
The editor maps resource adapter properties to class code. When you modify the resource adapter, the editor performs automatic source code updates. The table shows the generated code affected when you add, delete, or modify a configuration property:
Class code affected by configuration property change
Configuration property Affected class code Config Property (Resource adapter panel) ResourceAdapter Connection Definition Property (Outbound adapter panel) ManagedConnectionFactory ConnectionRequestInfo Message Listener Property (Inbound adapter panel) ActivationSpecWithXid
Editing deployment descriptor source
You can view and edit the deployment descriptor of your adapter directly. Although the Resource Adapter Deployment Descriptor editor provides a fully functional and convenient method for viewing and editing the deployment descriptor, you can find it useful to view or edit the ra.xml file directly. The steps for editing the deployment descriptor of your adapter is as follows:
- Verify the ra.xml file is not currently displayed in the editor.
You cannot open the file if it is already open in the editor.
- From the Project Explorer pane, select the Deployment Descriptor: Connector <your connector name> file.
- Right click and choose Open With > XML Source Page Editor
The XML Source Page Editor displays the ra.xml file.
![]()
You can now view or modify the raw ra.xml file using the default editor provided by IBM Integration DesignerWhen you use this editor to save this file, the file is automatically validated against the Resource Adapter XML schema definition (or.xsd) file. Any errors are displayed in the Problems pane.
When using the Resource Adapter Deployment Descriptor editor provided by the WebSphere Adapter Toolkit, you can open valid deployment descriptors only. If you attempt to open a deployment descriptor that is not valid (as defined by the schema), the XML Source Page Editor displays the file so that you can fix the problem before attempting to open it in the Resource Adapter Deployment Descriptor editor.
Implementing code from the IBM WebSphere Adapter Toolkit
- Foundation Classes implementation overview To develop a WebSphere resource adapter, you identify the JCA classes for your project, generate subclasses of all the corresponding Foundation Classes, and then modify or override methods as described in the individual class subsections. Subclasses that override methods in the Foundation Classes should invoke the super method so that generic logic is still invoked (unless explicitly indicated otherwise).
- Data model In any system where heterogeneous components exchange data, a common data model or object format is crucial. With a common data model, system components know what to send and what to expect in return.
- Inbound event notification When you enable inbound event-notification, business processes are alerted to changes in, or new information about, an EIS.
- Inbound callback event notification An EIS application's capability to call the adapter directly, by registering a listener, is known as a callback. If your application supports the callback capability, you can make use of callback event notification support in the adapter foundation classes.
- Outbound support Outbound support enables application components to process operations on an EIS and retrieve the results. Input data passed by the application component is processed by the adapter to make changes or call functions on the underlying EIS.
- Data and metadata Adapter Foundation Classes (AFC) implement DESPI APIs and support two data formats, service data objects (SDO) and JavaBeans.
- Enterprise Metadata Discovery general interfaces and implementation for application adapters Enterprise metadata discovery is a discovery service, or a component within an adapter that enables the generation of business object definitions and other artifacts required by service component architecture.
- Enterprise Metadata Discovery interfaces and implementation for technology adapters Version 1.2 of Enterprise Metadata Discovery includes enhancements for configurable data handlers, function selectors, and data bindings, and a way to build service descriptions using these configured artifacts and existing schemas.
- Structured record implementation StructuredRecord class needs to be implemented by adapters when the data exchanged with backend application can be well-defined. Extend foundation class com.ibm.j2ca.base.WBIStructuredRecord and implement the associated methods.
- Data binding implementation Adapters must provide implementations for DataBinding interface in order to work with BPM. The marshalling of data from SDO to CCI record and from CCI record to SDO occurs through DataBinding implementation.
- Bidirectional language support Specifying bidirectional properties allows your adapter to exchange data in various bidirectional formats.
- Problem determination You can implement messages to accompany a range events.
Foundation Classes implementation overview
To develop a WebSphere resource adapter, you identify the JCA classes for your project, generate subclasses of all the corresponding Foundation Classes, and then modify or override methods as described in the individual class subsections. Subclasses that override methods in the Foundation Classes should invoke the super method so that generic logic is still invoked (unless explicitly indicated otherwise). The steps shown below provide an overview of how to build an adapter from the Foundation Classes. Note these steps focus on the major classes to extend. In some cases, you must provide yet another JCA interface implementation to extend a class; when this occurs, locate the appropriate Adapter Foundation class and extend it for your purposes. Typically this requires minor changes only.
When developing a WebSphere resource adapter on Rational Application Developer for WebSphere Software, you may face the following problems:
- You may not find the built-in configuration for IBM WebSphere Adapter in the configuration drop-down list after clicking New > Connector Project from the New Connector Project wizard.
- You may not find the facet IBM WebSphere Adapter Foundation Classes Support after clicking Modify from the Project Facets panel.
The above problem is due to the component Extensibility features > JET Transformation Authoring and Runtime is not checked during the Rational Application Developer for WebSphere Software installation.
Workaround: Use the Rational Application Developer for WebSphere Software installation kit and install the Extensibility features > JET Transformation Authoring and Runtime component.
- Decide which configuration properties you need for the resource adapter to support the enterprise information system (EIS):
- Identify configuration properties for connecting to the EIS instance for outbound processing ( hostname, port).
- Identify configuration properties suitable for use by a client for a specific outbound connection instance ( username, password, language).
- Identify configuration properties for inbound event processing in general–this will probably be a combination of those you've defined in 1a and 1b for outbound.
- Establish a list of remaining adapter configuration properties–those not related or relevant to inbound or outbound configurations.
- Extend class WBIResourceAdapter and provide accessor methods for configuration properties defined in 1d. Add these same properties to the resource adapter deployment descriptor.
- If the resource adapter supports inbound event processing through the event manager quality of service (QoS) as described later in this user guide, modify your WBIResourceAdapter subclass to implement interface WBIPollableResourceAdapterWithXid and provide an implementation of interface EventStore. If you defined additional inbound properties in 1c, beyond what is already defined for class WBIActivationSpec, extend WBIActivationSpecWithXid and update the deployment descriptor to reflect this new subclass class under the supported activation specs.
- Extend class WBIManagedConnectionFactory and add accessor methods for any properties defined in 1A. Add these same properties to the resource adapter deployment descriptor.
- Extend classes WBIConnection and WBIInteraction. In your WBIInteraction subclass, provide logic for processing requests (create, retrieve, update, and delete operations). In your WBIConnection subclass, simply provide the ability to generate a new WBIInteraction instance.
- Extend WBIStructuredRecord and implement the getNext() and extract() methods. If the adapter is intended to be used in an SCA environment, implement data bindings.
- Extend class WBIManagedConnection and provide logic to physically connect and disconnect to the EIS. In the getConnection methods, simply return the WBIConnection subclass created above.
- If you defined additional connection-specific properties in 1b beyond what is already defined in classes WBIConnectionRequestInfo and WBIConnectionRequest extend both and add these properties.
For more information on Javadoc, see table 1 in IBM WebSphere Adapter Toolkit tasks.
Data model
In any system where heterogeneous components exchange data, a common data model or object format is crucial. With a common data model, system components know what to send and what to expect in return.
For IBM Business Process Managerand WebSphere Enterprise Service Bus, this data model is called a business object. The adapters handle data internally, in a format-independent manner, using the Data Exchange Service Provider Interface (DESPI). In the BPM and WebSphere Enterprise Service Bus environment, a data binding produces and consumes the business objects, and communicates with the adapter using the Data Exchange SPI.
The JCA 1.5 specification defines an optional CCI Record model.
The business object data model provides for the following:
- A full, working implementation, as opposed to the CCI Record model that simply defines interfaces that must be implemented by the adapter developer.
- A built-in support for tracking changes at both the object and property levels, which allows for improved efficiency in processing and reduced bandwidth requirements for exchanging data.
- The business object data model is based upon the open-standard service data object (SDO) model that is supported by IBM and others (visit www.eclipse.org for more information).
- The business object data model aligns well with the larger WebSphere service-oriented architecture (SOA) strategy which, going forward, will better enable interpretability with other WebSphere-based applications.
Relationship of business objects to service data objects
At the technical level, the WebSphere business object model maps directly to the service data object (SDO) model: a WebSphere business graph and business object correspond to an SDO data graph and data object.
A business graph is a top-level structure that defines a single child business object which can itself contain zero or more child business objects.
Use a business graph optional. Use it to provide a change summary for applying a delta updates to hold metadata about its child business objects.
![]()
Business graph
After-images versus deltas
Two distinct types of business objects, after-image and delta, are used to convey different kinds of information.
After-Image business objects can be thought of as a snapshot of the data in time; they reflect how the EIS entity looks (for inbound events) or is expected to look (for outbound requests). An after-image business object should represent the entire entity structure in the EIS. For example, if an ORDER object with UPDATE verb is sent to the adapter, and the order has two ORDER_LINE children, the object in the EIS should be modified to reflect the input; if the EIS's representation of that object had only one ORDER_LINE, it will have two after the processing has completed.
Delta business objects reflect the specific changes that have occurred (for inbound events) or the user wants affected (for outbound requests) in the EIS. Each business object contains a changeSummary structure that can store all the pending changes. For outbound requests, the adapter must interpret the change summary, making all applicable changes to the data. For example, if an ORDER_LINE has been added to an ORDER object, the ORDER_LINE will appear as Created in the change summary. The adapter is responsible for finding that ORDER, and adding the ORDER_LINE to it.
Verbs
A verb is a property of a business graph.
If the data object being processed by the adapter has no business graph, there will be no verb.
The AppplyChanges function, when passed a business graph, can perform either an after-image function or a delta update. If the verb is populated, the adapter will perform the operation indicated by the verb. If no verb is present, the change summary will be used to perform a delta update.
When encountering a delta business object, a component can introspect the change summary to determine what actually occurred.
Verbs versus operations
Verbs and operations are similar conceptually but serve different purposes. Operations reflect the functions that an adapter can perform. An operation is directly related to the adapter performing it. By contrast, a verb is directly related to the business object in which it is specified. In general, the verb defined for a business object should match the operation but not always; some operations are unrelated to the verb.
An example helps illustrate the difference between verbs and operations. If you wanted to create a new entity in the EIS using an after-image business object, you would specify an object verb of Create. Accordingly, a Create operation would invoke the adapter. If you invoke an adapter Delete operation with an object that had a Create verb, the adapter would report an error.
However, some operations, specifically those that do not fall under Create, Update, or Delete, do not require verbs. For example, the Retrieve operation of adapters, which has the adapter query the EIS to find an entity that matches the business object, does not expect a verb. This Retrieve operation is unconcerned with what action lead to the business object being created (the information reflected by the verb); rather it is concerned only with retrieving an EIS entity that is reflected by the object.
The only time verbs are part of adapter processing is when the object has a business graph, and the function used is applyChanges. In that case, and only that case, the verb dictates the processing to be performed by adapter.
Business object standards
- Business object naming EIS object names are extracted during the metadata import process. These names often must be modified for use with a resource adapter. Business object names, such as Customer or Address, must reflect the data structures they represent and follow a camel case initial capitalization format.
- Standard operations As described by the JCA specification, a resource adapter is generally intended to expose low-level, EIS-specific operations. These EIS-specific operations range from create, retrieve, update, and delete (for database-type applications) to those that are unique to customer EIS instances (for function-based adapters such as SAP).
- Standard processing logic Each adapter should enable operations that are supported by the EIS.
EIS object names are extracted during the metadata import process. These names often must be modified for use with a resource adapter. Business object names, such as Customer or Address, must reflect the data structures they represent and follow a camel case initial capitalization format.
Convert business object names from EIS-assigned formats to a camel case format (remove separators such as spaces or underscores and capitalize first letter of each word). For example, convert the EIS name, ORDER_LINE_ITEM, to OrderLineItem.
As described in the WebSphere business object specification, name the parent business object graph for the contained business object followed by BG. For example, CustomerBG is the parent object graph for a Customer business object.
Business objects names as well as property names should have no semantic value to the adapter. When you develop your adapter logic, be sure that it is based on metadata as opposed to naming conventions.
Standard operations
As described by the JCA specification, a resource adapter is generally intended to expose low-level, EIS-specific operations. These EIS-specific operations range from create, retrieve, update, and delete (for database-type applications) to those that are unique to customer EIS instances (for function-based adapters such as SAP).
The WebSphere business object model and a variety of WebSphere components (such as the relationship management service) assume that most adapters support a set of standard create, retrieve, update, and delete operations. This leaves a gap for most adapters where the supported low-level operations do not natively meet the expectations of other WebSphere components. To fill this gap, all adapters should support higher-level create, retrieve, update, and delete operations, depending on what is provided by the EIS. With such support, a Create operation for one adapter follows the same naming conventions and behavior as a Create operation for another adapter. The result is better tooling and consistency in terms of user experience.
The following are the supported, standard top-level operations:
Supported standard top-level operations
Inbound Operation Signatures Notes emitCreateAfterImage<BOType> emitUpdateAfterImage<BOType> emitDeleteAfterImage<BOType> These operations should generate after-image business objects with verbs that match the operation signature; for example, emitCreateAfterImageCustomer should generate a Customer object with verb Create. emitDelta<BOType> This operation should generate a delta business object with a summary depicting the changes that occurred in the EIS.
Outbound Operation Signatures Notes applyChanges<BOType> create<BOType> update<BOType> delete<BOType>
These operations can handle delta or after-image business objects. The assumption is the adapter can consume either type of object or, if not, can convert after-image and delta as required by the business object structure.
For applyChanges, the adapter determines the operation (create, update, or delete) based on the top-level verb or the change summary.
applyChanges allows users to pass any create, update, or delete business objects.
The create, applyUpdate and delete operations are specific to one operation. Note that applyChanges, for after-images, should invoke the appropriate <x> operation.
Exceptions: If the adapter cannot support delta for a given business object type (because it lacks retrieve capability to convert), a signature of applyAfterImage<BOType> may be substituted.
retrieve<BOType> Retrieve one object based on key values. retrieveAll<BOType> Retrieve multiple objects that match some user-defined predicate; this is a query option intended to replace RetrieveByContent.
RetrieveAll should always return a top-level container with 0..n matching child business objects. It should never return a single top-level matching business object as with the Retrieve operation.
Standard processing logic
Each adapter should enable operations that are supported by the EIS.
General guidelines for operations with adapters include the following
- All operations should be atomic: if an operation fails for any reason, the adapter should roll back any partial changes made to the EIS as part of the request.
- For all operations, adapters should never modify the input business object passed by the client (per JCA standards). Instead, if the operation requires the same object passed as input to be returned as output, use WebSphere Business Integration utilities to create, modify, and return a deep copy of the input object.
- If child objects are included in the input business object, the order of child objects should be maintained in the output business object. Doing so enables relationship management service support.
- If an after-image is passed to the adapter as input, an after-image should be returned as output. The same applies for deltas.
- Adapters should follow strict conventions in processing business objects. This includes failing if an entity is marked as updated in the input business object but does not exist in the EIS (rather than attempting to create the entity in the EIS).
- isSet property WebSphere business objects support an isSet property.
- Strict interpretation of requests An adapter should always fail if the user provides data that is inconsistent with either the behavior of the adapter or the state of the EIS. This requires more effort from maps or users to ensure that data is appropriate before exposing it to an adapter. That effort also reduces the chance of miscommunication (that is, the adapter will do something unintended).
- ApplyChanges operation The applyChanges operation is a catch-all operation that enables users to send any create, update, or delete business object to the resource adapter for processing based on the verb.
- After-image Create operation The after-image Create operation generates a new entity in the EIS that matches the data and structure of the input business object. The business object returned by this operation should accurately reflect the newly created entity in the EIS.
- After-image Update operation The after-image update operation modifies an EIS entity so that it and its child objects match the data and structure of the input business object. It requires an explicit comparison of the input business object to the EIS system.
- After-image Delete operation The after-image Delete operation removes an existing entity and any contained child entities from the EIS.
- Retrieve This operation rebuilds the complete business object hierarchy. The adapter ensures the returned hierarchical business object matches exactly the database state of the application entity.
- RetrieveAll RetrieveAll returns a batch of records that match the values provided in the request business object. The records are returned as a collection of business objects through a top-level container business object.
- Custom operations Adapters support custom operations that enable more robust means of interrogating or modifying the EIS. Custom operations include Execute (to execute a stored procedure or script) or Lock (to lock an entity in the EIS).
isSet property
WebSphere business objects support an isSet property.
isSet property
The isSet() API of the DESPI InputAccessor determines if a given business object property has been set. When isSet() is false the adapters ignore the specific attribute while processing the request.
Strict interpretation of requests
An adapter should always fail if the user provides data that is inconsistent with either the behavior of the adapter or the state of the EIS. This requires more effort from maps or users to ensure that data is appropriate before exposing it to an adapter. That effort also reduces the chance of miscommunication (that is, the adapter will do something unintended).
If an adapter receives a request in which a business object is marked as created but, in fact, an entity already exists in the EIS with the given key values, the adapter should fail immediately.
Some WebSphere Adapters have historically made a best effort and defaulted to an update in such cases. Such adapters attempted to interpret the request and make every effort to complete it.
ApplyChanges operation
The applyChanges operation is a catch-all operation that enables users to send any create, update, or delete business object to the resource adapter for processing based on the verb.
The applyChanges operation saves effort and simplifies mapping with simple logic: for after-image business objects, the applyChanges operation should look at top-level verb in the business object and then call create, update or delete as appropriate; when applyChanges is invoked without a verb, this is a delta operation. The adapter should read the SDO change summary and perform all the changes indicated in the change summary.
After-image Create operation
The after-image Create operation generates a new entity in the EIS that matches the data and structure of the input business object. The business object returned by this operation should accurately reflect the newly created entity in the EIS.
Processing overview
The processing of the after-image create operation, which starts at the top-level business object, is as follows:
- Create an entity in the EIS corresponding to the type of the input business object
- If the EIS does not generate its own primary key (or keys), insert the key values from the input business object into the appropriate key column (or columns) of the EIS entity.
- Update the output business object to reflect the values of the newly created EIS entity; this includes any EIS-generated key values or properties marked as having potential side-effects (see property-level metadata).
- Recursively create the EIS entities corresponding to the first-level child business objects, and continue recursively creating all child business objects at all subsequent levels in the business object hierarchy.
Operation return value
The output written to the output cursor should contain any newly-created key values and other side effects.
Error handling
The DuplicateRecordException exception is thrown if the EIS already contains an entity with the same key values as a business object to be created.
The InvalidRequestException exception is thrown if any of the following inputs to the operation are not supported:
- If key values are specified in the input business object but the EIS supports auto-creation only
- If key values are not specified in the input business object but the EIS requires them
- If the top-level verb, if provided, is not Create (assertion optional)
The EISSystemException exception is thrown if the EIS reports any unrecoverable errors.
After-image Update operation
The after-image update operation modifies an EIS entity so that it and its child objects match the data and structure of the input business object. It requires an explicit comparison of the input business object to the EIS system.
Processing overview
After-image update processing is as follows:after-image Update
- Compare the existing business object in the EIS with the input business object and create, update, or delete entities to match the input as follows:
- If child entities exist in the application, they are modified as needed.
- Any child business objects contained in the hierarchical business object that do not have corresponding entities in the EIS are added to the EIS.
- Any child entities that exist in the EIS but are not contained in the business object are deleted from the application.
- Update the output business object to reflect the modified EIS entities; this includes any EIS-generated key values or properties marked as having potential side-effects (see property-level metadata).
Operation return value
When writing the output values to the output cursor, be sure to include any generated keys or other side effects.
Error handling
Error handling behavior includes any and all exceptions thrown by create and delete operations plus the following:
RecordNotFoundException is thrown if the EIS does not contain an entity with the same key values as the business object to be updated.
EISSystemException is thrown if the EIS reports any unrecoverable errors.
MissingDataException is thrown during adapter operations to indicate that not all the necessary information has been provided as required.
InvalidRequestException is thrown during adapter operations to indicate poorly formatted data was provided.
After-image Delete operation
The after-image Delete operation removes an existing entity and any contained child entities from the EIS.
Processing overview
The after-image Delete operation is processed as follows:
- Perform a recursive retrieve on the input business object to obtain all data in the EIS that is associated with the top-level business object.
- Perform a recursive delete on the entities represented by the input business object, starting from the lowest-level entities and ascending to the top-level entity; non-contained entities should be left intact although any relationships to deleted objects should be removed if explicitly defined in the EIS.
Adapters should also delete any and all contained children whether or not they are reflected in the input business object. For example, if just a top-level business object is provided with keys and no children, the adapter should still check for contained children in the EIS and delete them.
Operation return value
Since the deletion of an entity in the EIS only requires a return that indicates the success (or failure) of the operation, the goal is to convey this with as little overhead as possible. The Delete operation might or might not return anything. The adapter should handle the case where the output record is initialized with the same metadata as the input cursor. In this case, it is not necessary to populate the output data on getNext, apart from the key information.
Error handling
The RecordNotFoundException exception is thrown if the EIS does not contain an entity with the same key values as the business object to be deleted.
The InvalidRequestException exception is thrown if input to the operation is not supported.
The EISSystemException exception is thrown if the EIS reports any unrecoverable errors.
Retrieve
This operation rebuilds the complete business object hierarchy. The adapter ensures the returned hierarchical business object matches exactly the database state of the application entity.
The Retrieve operation accepts either an after-image or delta business object. The comparison in either case will be by equality only. Non-key values are allowed as match criteria.
The request business object can contain any of the following:
- A top-level business object but no child objects, even though the business object definition includes children.
- A business object that contains the top-level business object and some of its defined children.
- A complete hierarchical business object containing all child business objects.
The difference between Retrieve and RetrieveAll is that Retrieve is intended to return a single, unique business object that meets user-defined criteria whereas RetrieveAll returns multiple matching business objects. For example, use Retrieve to find Customer where id="abc123" and RetrieveAll to find all Customers where state="NY".
Processing overview
Retrieve processing is as follows:
When the retrieve operation is invoked, it is preferable to retrieve the record information from the EIS and put it into the output structured record, where getNext() will populate that information into the output cursor. If it is not possible to retrieve the information from the EIS until getNext() is called, it is acceptable to perform the entire retrieve operation inside of the getNext() method.
Error handling
RecordNotFoundException is thrown if any populated properties in the input business object does not exist in the EIS.
MultipleMatchingRecordsException is thrown if more than one record match input criteria.
EISSystemException is thrown if the EIS reports any unrecoverable errors.
RetrieveAll
RetrieveAll returns a batch of records that match the values provided in the request business object. The records are returned as a collection of business objects through a top-level container business object.
CCI clients of resource adapters that support batch results must be capable of recognizing a top-level container and iterating through the child objects that represent the results of the query. The client can then extract any individual business object in the container and deliver it to the rest of the system as with any single business object. This obviously requires the creation of additional business object container structure definitions by the user or during metadata import for each business object type the user intends to query in batch. The business object container is shown in the illustration.
![]()
Business object container
This approach is favored over that of the JDBC-style ResultSet support as described in the JCA specification. However, if an EIS provides native ResultSet support or if it makes sense then adapter developers are encouraged to implement the CCI ResultSet interfaces to provide customers with a high-performance alternative to the generic batch retrieval approach described in this document.
The container object is produced by the data binding for use in the BPM or Websphere Enterprise Service Bus environment. Internally, the adapter will model the multiple retrieved records as a list of top-level records that can be iterated over using the getNext() method of the output Record.
The use of the operation name RetrieveAll rather than RetrieveByContent (as used by the WebSphere Business Integration adapters) distinguishes this operation as a new and clear standard. Support for RetrieveByContent was inconsistent across previous adapters: some would retrieve a single object and return special error codes if there were more objects that matched while other adapters would create special containers to return multiple values.
The RetrieveAll operation always returns a result set regardless of how many (if any) matches are found.
Processing overview
RetrieveAll processing is as follows:
RetrieveAll should make the adapter ready to return multiple objects. For each of the objects that will be returned, the "getNext()" method will be called. Each call to "getNext" should advance the cursor to the next top-level record.
Adapters should check the property MaxRecords in the WBIInteractionSpec instance to determine the maximum number of records to return in order to avoid out-of-memory issues.
Operation return value
The adapter performs a query and retrieves a result set of all objects that match a given set of values. The output object is a container that holds an 0..n objects of the same type as the input object.
Error handling
RecordNotFoundException is thrown if any populated properties in the input business object do not exist in the EIS.
MatchesExceededLimitException is thrown if the number of hits in the EIS exceeds the value of MaxRecords as defined in the interaction specification. The property MatchCount will contain the actual number of hits the adapter had in the EIS so that users can either increase their limit or refine their search appropriately.
EISSystemException is thrown if the EIS reports any unrecoverable errors.
Custom operations
Adapters support custom operations that enable more robust means of interrogating or modifying the EIS. Custom operations include Execute (to execute a stored procedure or script) or Lock (to lock an entity in the EIS).
For custom operations, implementations should accept both after-image and delta business objects and simply use the values provided in the data portion of the business graph. For example, if a delta is provided without enough information to perform a custom request operation, the adapter should attempt to retrieve the necessary information from the EIS application when possible or throw an InvalidRequestException that expands missing data.
For custom operations, implementations can interpret the data coming in the input cursor in any way that is desirable. Be sure to throw the appropriate exceptions if the input data is insufficient.
Inbound event notification
When you enable inbound event-notification, business processes are alerted to changes in, or new information about, an EIS.
Inbound event notification complements outbound request processing, enabling adapters to provide bidirectional communication between business processes and EIS applications. Depending on the underlying EIS, the business events an adapter generates may span the set of changes that have occurred to a given entity in the EIS, such a customer changing the quantity in their order from 10 to 100, to a complete document or binary payload such as an insurance claim form submitted in XML.
Although each EIS application is unique, most adapters implement inbound event-notification in similar ways:
- Create an event store in the target EIS to persist changes or other relevant event data that is published by the adapter.
- Implement an event detection mechanism in the EIS. This mechanism is responsible for detecting any changes of interest (to the adapter) in the EIS and recording them in the event store.
- Implement an event retrieval mechanism in the adapter that can detect and retrieve events from the event store described in (1) above.
- Implement a data transformation mechanism in the adapter to convert EIS events to WebSphere business objects for use by target business processes.
![]()
Inbound event notification
Use the IBM WebSphere Foundation Classes for inbound event notification
Although not required, use of the IBM WebSphere Foundation Classes is strongly recommended for adapters that need to provide event notification.
Use the Foundation Classes can dramatically simplify the often complicated implementation of event retrieval and publication. The Foundation Classes can automatically track endpoints (the consumers of events) for the adapter, control the polling for and delivery of events, handle recovery of events if the adapter unexpectedly terminates, and assure once-and-only-once event delivery. This allows developers to provide greater quality of service (QoS) in less time and also ensure that behavior across adapters is consistent.
In order to employ the Foundation Classes for event-notification, the adapter and EIS application must meet requirements described in the following sections.
Event Store Requirements
- Event data must be persistent. Once detected in the event store, an event should remain available there until deleted by the adapter regardless of connection failure or time elapsed.
- The event store must allow the adapter to both identify and change the state of event records in the event store.
Adapter Requirements
To manage application-specific events, the Foundation Classes require that you provide application-specific logic, if any. To do this, you must:
- Ensure that any subclass of com.ibm.j2ca.base.WBIResourceAdapter implements interface com.ibm.j2ca.WBIPollableResourceAdapter. This interface allows the Foundation Classes to acquire an EventStore implementation that specifically reflects the EIS application.
- Provide an implementation of the com.ibm.j2ca.extensions.eventmanagement.EventStore interface. This interface allows the Foundation Classes to manage events in the store without requiring specific knowledge of how and where the event store is implemented.
- Extend WBIActivationSpecForXid to include the base polling properties.
There is an alternate ActivationSpec, called WBIActivationSpecForPooling, that contains two additional properties; Minimum connections, and MaximumConnections. These properties are used by the event manager to establish a connection pool of EventStoreWithXid instances. Each instance of EventStoreWithXid is treated as a "connection".
If the user sets MaximumConnections to a value greater than 1, and the delivery type is set to a value other than "ORDERED", multiple threads will be used in delivery, and each delivery thread can potentially be assigned a discrete connection.
If you decide to use WBIActivationSpecForPooling, keep in mind that "createEventStore" can be called multiple times on your adapter, so be sure to handle this appropriately.
Application Requirements
In many cases–and even when your adapter does not implement the Foundation Classes–an application must also be configured or modified before the adapter can use the event-notification mechanism.
Modifications to the application might include setting up a user account in the application, creating an event store, and event table in the application database, inserting stored procedures in the database, or setting up an inbox. If the application generates event records, you might need to configure their text. You might also need to configure the adapter to use the event-notification mechanism. For example, a system administrator might need to set adapter-specific configuration properties to the names of the event store, and event table.
Assured once-and-once-only event delivery
XA transactions support once-and-only-once event delivery.
Assured once-and-only-once delivery is implemented with an XAResource. The XAResource tracks the transaction IDs in the event table. The event table contains an XID (string) field. The adapter queries and updates that XID field. During recovery, WebSphere Application Server calls the resource adapter, queries it for XAResources, and then performs transaction recovery as follows:
- Transactions the Java EE container rolls back have not been delivered and are marked NEW.
- Transactions the Java EE container commits have been delivered and are deleted.
Implementing an event store in the EIS
An event store is a persistent storage area in the EIS application where event records are saved until the adapter can process them. The event store might be a database table, application event queue, email inbox, or any type of persistent store. A persistent event store enables the application to detect and save event records for the adapter even when the adapter is not operational.
Always consider performance implications and scalability when choosing where and how to implement an event store. For example, if you are building an adapter for a database application, an event store represented as a table in the database will most likely perform more efficiently than an event store implemented in an external event inbox.
- Event records There are no hard and fast rules governing the structure or content of an event record in the event store. The goal is to provide enough information for the EventStore interface implementation to successfully generate a business object that represents the event.
- Event object An event object is an instance of the com.ibm.j2ca.extensions.eventmanagement.Event class as defined in the Foundation Classes. An event object is the common representation of an event in the Adapter Foundation Classes and it is populated from an event record in the getSpecificEvent(String eventId) method described in the Implementing the EventStore Interface section.
- Event detection Events detection mechanisms reflect the sources that trigger them: user actions in the application, batch processes that add or modify application data, or database administrator actions.
Event records
There are no hard and fast rules governing the structure or content of an event record in the event store. The goal is to provide enough information for the EventStore interface implementation to successfully generate a business object that represents the event.
Common event record fields
Field Description Event Identifier (ID) A unique identifier for the event Object Key The application-specific data that uniquely identifies the entity that occasioned the event. Business Object Name The type of the business object that maps to the entity. Verb The operation that triggered this event: create, update, delete, and so on. Timestamp The time at which the application generated the event. Status The status of the event. This is used by the Foundation Classes to track which events are new, in process, or processed. XID The transaction ID.
Event Identifier (ID)
Each event requires a unique identifier for tracking purposes. This identifier can be a number generated by the application or a number generated by a scheme that your adapter uses. The event might generate a sequential identifier, such as 00123, to which the adapter adds its name. In such an event ID numbering scheme, the resulting object event ID is MyAdapterName_00123. Another technique might generate a timestamp to identify an event, producing an identifier such as MyAdapterName_06139833001005.
Object Key
Each event should contain enough key information to enable the adapter event-retrieval mechanism to locate and retrieve the full entity in the EIS for which this event was originally recorded. The structure and content of this key is up to you.
For reference, a key is typically consists of easily-parsed values such as name-value pairs. For example, Customer_ID=123 or, for a composite key, Model=Widget;Color=CanaryYellow.
Business Object Name
Since the EIS entity identified in each event is converted to a business object instance, the type of the business object must either be specified or derivable at run time by the event-retrieval mechanism.
The most straightforward approach is to include the business object name value in the event record. Specifically, the business object graph type should be included; for example, CustomerBG or OrderBG.
The namespace, which is also required for business object creation, need not be included in the event; the namespace is user-defined and should be retrieved by the adapter from the adapter ActivationSpecWithXid instance.
If, as an adapter developer, you choose to derive the business object graph type, you are strongly advised against mandating any specific EIS entity name to business object type mapping schemes. Business object properties and names are unreliable because they can be modified by users. To avoid such problems, adapters should always process business objects using metadata.
Verb
The verb should reflect the operation that this event represents. For example, if this event reflects the creation of an entity in the application, the verb would be Create. This value should be one of the standard verbs used by adapters (including Create, Retrieve, Update, Delete) and specified in the business object generated for the event. When properly specified in the business object, the verb allows consumers of the business object event to determine what action to take on the event.
The default function selector implementation (WBIFunctionSelector) uses the verb passed in the event business object to determine the appropriate SCA EIS import operation. Be sure that verbs used here correspond to the operations defined by your adapter enterprise metadata discovery implementation.
Timestamp
The Foundation classes use the timestamp to ensure proper ordering of events. For example, use of a timestamp prevents an event describing the deletion of an Order from being published before an event describing the creation of that same Order. The timestamp should provide detail sufficient to distinguish events occurring close in time.
Status
The event status is used to track the state of an event. It allows the Foundation Classes to distinguish among events that are new from those in process or ineligible.
The adapter must support five different event status values as described in the table below. All events generated by the event detection mechanism in the EIS should be in the initial state of New. Only the Foundation Classes, through the EventStore.updateEventStatus method, change event status.
Possible Event Statuses
Event Status Description Foundation Class Constant New The event is ready to be processed. NEWEVENT In Progress The adapter is processing this event. Note that an event in this state may or may not yet be delivered. INPROGRESS Processed The adapter successfully processed and delivered the event. PROCESSED Failed The adapter was unable to process this event due to one or more problems. FAILED Unsubscribed The adapter processed the event but found no interested subscribers UNSUBSCRIBED
XID
The XAResource uses this string field to track transaction IDs in the event table. The adapter queries and updates that XID field. During recovery, WebSphere Application Server calls the resource adapter, queries it for XAResources, and then performs transaction recovery based on the XID.
Event object
An event object is an instance of the com.ibm.j2ca.extensions.eventmanagement.Event class as defined in the Foundation Classes. An event object is the common representation of an event in the Adapter Foundation Classes and it is populated from an event record in the getSpecificEvent(String eventId) method described in the Implementing the EventStore Interface section.
Event object fields
Field Description eventID Corresponds to the Event Identifier field of the event record eventKeys Corresponds to the Object Key field of the event record eventType Corresponds to the Business Object Name field of the event record timeStamp Corresponds to the Timestamp field of the event record eventStatus Corresponds to the Status field of the event record
Event detection
Events detection mechanisms reflect the sources that trigger them: user actions in the application, batch processes that add or modify application data, or database administrator actions.
When an event detection mechanism is set up in an application and an application event associated with a business object occurs, the application must detect the event and write it to the event store.
Event detection mechanisms are application-dependent. Some applications provide an event detection mechanism for use by clients such as adapters. The event detection mechanism may include an event store, and a prescribed way of inserting information about application changes into the event store. For example, one type of implementation uses an event message box that receives messages from the application when it processes an event of interest to the adapter. The adapter application-specific component periodically polls the message box for new event messages.
Other applications have no built-in event detection mechanism but have other ways of providing information when application entities change. If an application does not provide an event detection mechanism, use whatever mechanism is available to extract information about entity changes for the adapter. Among those mechanisms are database triggers, exit calls to programs that write to event stores, or extracting information from flat files that aggregate application changes.
In all cases, the event detection mechanism should ensure data integrity between an application event and the event record written to the event store. For example, the generation of an event record should not occur until all required data transactions for the event have completed successfully.
Steps Involved
In general, an application event detection mechanism should take the following steps:
- Detect an event on an application entity.
- Create an event record.
To create the record, the event detection mechanism should:
- Generate a unique event identifier (ID).
- Set the object key to the primary key of the application entity.
- Set the verb to the action that occurred in the database.
- Set the event timestamp.
- Set the name of the WebSphere business object complexType corresponding to this application entity
- Set the event status to New.
Implementing event retrieval in the adapter
The careful work of implementing event retrieval in the adapter uses two Foundation Classes interfaces. The goals are setting up event polling and a safe, reliable connection to the event store.
Adapters that employ the Foundation Classes for event retrieval must meet the following requirements:
- Implementing interface com.ibm.j2ca.base.WBIPollableResourceAdapterWithXid in any WBIResourceAdapter subclass.
- Implementing interface com.ibm.j2ca.extensions.eventmanagement.EventStoreWithXid
The first requirement identifies (for the Foundation Classes) the adapter for event polling. If this interface is implemented, the Foundation Classes automatically begin checking for and publishing events as dictated by polling-related configuration properties such as PollPeriod and PollQuantity and as specified by active adapter endpoints.
The second requirement, implementation of the EventStoreWithXid interface, typically requires the most (adapter) development effort. As the location and structure of each event store is application-specific, the EventStoreWithXid interface provides the Foundation Classes with a common means of querying and modifying an event store.
Implementing an EventStore Interface
An EventStore implementation is responsible for establishing and managing a connection, if necessary, to the underlying EIS application. The EventStore implementation should be thread-safe because it will be accessed on multiple threads in Unordered delivery mode.
The table below describes the methods that each EventStore implementation must provide:
EventStore methods
Method Description public void setEventTransactionID(Event event, XidImpl xid) throws ResourceException, CommException This method should store the xid in the Event table in the same row specified by event. xid.toString() will serialize the Xid for easy storage.
public Xid[] getPendingTransactions() throws ResourceException, CommException This method should return the XIDs for events that have an associated XID, but are still in NEWEVENT status.
public Event getEventForXid(XidImpl xid) throws ResourceException, CommException This method should return the event associated with the given Xid.
ArrayList getEvents(int quantity, int eventStatus, String[] typeFilter) This method enables the adapter to determine if there are any new events available or old events that need re-sending. Implement this method to query the event store, and return a list of event instances (up to the limit specified by thequantity parameter ) that have a status matching the value of parameter eventStatus. The order of events returned in ArrayList should reflect the sequence of events as intended for publication.
If this EventStore implementation supports filtering as specified by method implementsFiltering, this method should inspect the value of parameter typeFilter. If typeFilter is not null, the method should return events that match the type(s) specified only. If typeFilter is null (or filtering is not supported), the method should simply return events of all types.
boolean implementsFiltering() This method provides the Foundation Classes with information about the capability of the EventStore implementation. If it can filter events by type in method getEvents, the implementation should return true; otherwise it should return false. Event getSpecificEvent(String eventId) This method should reconstruct a complete event object for the event identifier. This will most likely require the EventStore implementation query to retrieve the missing information from the event record in the EIS ( object type, status, and so on). Object getObjectForEvent(Event event) The EventStore implementation should inspect the event passed and return a business object instance reflecting the changed entity in the EIS application. For example, if the event specifies an object type of CustomerBG and a key value of CustomerID=123, this method might be expected to return a CustomerBG instance populated with the values from customer 123 in the EIS. void deleteEvent(Event event) The EventStore implementation should delete the event record identified from the underlying EIS event store. void updateEventStatus(Event event, int newstatus) The EventStore implementation should modify the event record identified with the provided status code.
Transaction Support Methods
If the implementation of the event store supports transactions, the EventStore implementation should provide access to that transaction control using the following methods:
EventStore transaction control methods
Method Description boolean isTransactional() Is the event store transactional? If so, this method should return true. void commitWork() This method should commit the pending transaction. It is required only if transactions are supported. void rollbackWork() This method should rollback any uncommitted work. It is required only if transactions are supported.
Possible event store implementations
An event store is typically implemented in a database, however, any structured persistence mechanism could be used.
Implementing the event store with a database
If an EIS application incorporates a database, you can use the database to store event information.
Where to store events
To locate the event store in the EIS application database, create a new, separate WebSphere event table there. The table then functions as the event store for event records. Each column of the table would reflect one of the fields mentioned in Table 1; each row would reflect a unique event.
Implementing event detection
If the application has no built-in method for detecting events and the database the application is running on provides database triggers, you could implement row-level triggers to detect changes to application tables. When changes occur in one of these tables, the triggers would write new event records to the event table.
If possible, avoid full table scans of existing application tables as a way of determining whether application tables have changed.
Retrieve events
The EventStore implementation would need to employ the available database APIs to gain access to the contents of the event table.
![]()
Event store implementation
Function selector
Function selectors map resource adapter events to corresponding SCA export function names.
The WebSphere Adapter component that exposes resource adapters as SCA components requires what is known as a function selector. This selector maps events generated by resource adapters to a SCA export function name. For example, an adapter may generate an after-image Customer event with top-level verb Update, which the user expects to be published using the function emitCreateAfterImageCustomer.
public interface FunctionSelector { public String generateFunctionName(Object[] argObjects) throws MetadataException;}The StructuredDataFunctionSelector class looks at metadata within the StructuredRecord to generate a function name. It will create a function name as follows "emit[OperationName]AfterImage[RecordName]", where OperationName is an operation stored in the record as the operationName property, and RecordName is the value stored in the recordName property.
For more information about the FunctionSelector interface, see the Metadata Discovery Specification.
For example, if the StructuredDataFunctionSelector received an event such as CustomerBG with TopLevelVerb Create and containing a business object of type Customer, the WBIFunctionSelector class would generate a function name such as emitCreateAfterImageCustomer. For the same business graph with no TopLevelVerb, the function name emitted might be emitDeltaCustomer.
Error handling for events
Event error handling depends on the delivery type and the kind of endpoint involved.
If the endpoint throws an exception during delivery, the event manager will stop delivering events to that endpoint, and the timer task for polling stops. If the delivery type is ORDERED, the remaining events polled in that cycle are not delivered until the event with the error is processed. If the delivery type is UNORDERED, the event manager attempts to deliver the remaining events in the current poll cycle. When the endpoint is taken offline and reactivated, the event(s) in which the error occurred is re-delivered, and normal delivery of subsequent events resumes. If the endpoint is transactional and the transaction rolls back, the event manager responds as if the endpoint threw an exception.
If the implementation throws an exception during the getObjectForEvent call (for retrieval of the full event), the event manager marks the status of that event in the event table asERROR_PROCESSING_EVENT. If the delivery type is ORDERED, the polling task stops until the endpoint is reactivated. If the delivery type is UNORDERED, the polling task continues.
Inbound callback event notification
An EIS application's capability to call the adapter directly, by registering a listener, is known as a callback. If your application supports the callback capability, you can make use of callback event notification support in the adapter foundation classes.
When you enable inbound callback event notification, business processes are alerted to changes in, or new information about, an EIS. The phrase callback refers to the ability of the EIS system to directly notify the adapter or business processes of a change, as opposed to the polling mechanism used in event notification.
Callback event notification complements outbound request processing, enabling adapters to provide bidirectional communication between business processes and EIS applications.
Generally, in a callback scenario, the adapter will need to setup event listeners to receive callback events from the EIS. Callback event processing could be either synchronous (REQUEST-RESPONSE) or asynchronous (ONE-WAY).
Request and response callback events
A request and response callback event is a synchronous operation in which the EIS sends a callback call to the adapter and waits for the adapter to respond to the call.
Since the EIS expects a response from the adapter, event delivery to multiple endpoints cannot be supported.
The following is an illustration of synchronous callback event processing.
![]()
One-way callback events
One-way callback events are asynchronous operations in which the EIS sends an event to the adapter and then goes on with its processing, not waiting for the adapter to send a response back.
An illustration of asynchronous callback event processing is as follows:
![]()
Use the IBM WebSphere adapter foundation classes for inbound callback event processing
The adapter foundation classes can automatically track endpoints (the consumers of events) for the adapter, control the event pickup and delivery of events, handle recovery of events if the adapter unexpectedly terminates, and assure once-and-only-once event delivery.
This allows developers to provide greater quality of service (QoS) in less time and also ensure that behavior across adapters is consistent.
Although not required, it is a recommended practice that you use IBM WebSphere adapter foundation classes (AFC) for adapters that have to provide callback event notification.
Adapter foundation classes make the process of callback event delivery in an assured manner easier for the developer creating the adapter, by providing the event delivery API called the CallBackEventSender.
The following diagram depicts the usage of adapter foundation classes (common component). The CallbackEventSender API is integral to the adapter foundation classes.
![]()
Callback event sender
CallbackEventSender in com.ibm.j2ca.extension.eventmanagement.external package provides four public methods.
CallbackEventSender in com.ibm.j2ca.extension.eventmanagement.external package provides following four public methods.
- public void sendEventWithNoReturn(Record, InteractionSpec) throws WBISendFailedException
- public Record sendEventWithReturn(Record, InteractionSpec) throws WBISendFailedException
- public void sendEventWithNoReturn(GenericEvent, Record, InteractionSpec) throws WBISendFailedException
- public Record sendEventWithReturn(GenericEvent, Record, InteractionSpec) throws WBISendFailedException
These methods end up invoking different methods in the message-driven bean (MDB). The MDB will implement several interfaces, including InboundListener, and MessageListener.
The sendWithReturn methods invoke onMessage on the InboundListener. This method delivers the Record it received from the listener thread. Here the difference is the onMessage method will be invoked on the InboundListener to deliver the Record to the endpoint. The method would return "Record" as returned by onMessage method.
The sendWithNoReturn method invokes onNotification on the InboundListener. The sendEventWithReturn() method is not supported in case of multiple endpoint factories configured, hence will throw an appropriate exception. Also, if there are failures during the sending event when multiple endpoint factories configured, a consolidated exception stack trace will be thrown with details like which endpointfactory failed and for what reason.
Callback event sender constructors
CallbackEventSender provides four different constructors to facilitate different types of client invocation.
The following information describes the usage of the four constructors:
- CallbackEventSender(ArrayList, EventPersistence, XAResource, ActivationSpecWithXid, LogUtils)
The complete constructor which takes an array of endpoint factories and supports XA transaction with event persistence updates. If the input ActivationSpecWithXid is valid and not null, event would be delivered by calling target method on the inbound listener with ActivationSpecWithXid as additional argument.
- CallbackEventSender(ArrayList, ActivationSpecWithXid, LogUtils)
Constructor used for event delivery without XA transaction and event persistence support.
- CallbackEventSender(MessageEndpointFactory, EventPersistence, XAResource, ActivationSpecWithXid, LogUtils)
This constructor does take the same arguments as (1) except that it takes one MessageEndpointFactory instead of an array.
- CallbackEventSender(MessageEndpointFactory, ActivationSpecWithXid, LogUtils)
A slight variation for constructor (2) with just one MessageEndpointFactory argument instead of an array.
Callback event processing for basic delivery
When the event is created at the EIS end, configured adapterListener gets notified and it in turn instantiates CallbackEventSender. Here adapterListener decides which method to invoke out of the four defined.
To implement callback mechanism, adapter must have an EndPointManager class. The class needs to maintain the relationship between the activationSpec and MessageEndpointFactory arguments. Here is a snippet of EndPointManager class showing how the callback mechanism is implemented.
public class EndpointManager { /** * inner class which maintains pairs of mef and activationspec */ public static class EndpointPair { public MessageEndpointFactory mef; public ActivationSpec activationSpec; public EndpointPair(MessageEndpointFactory mef, ActivationSpec activationSpec) { this.mef = mef; this.activationSpec = activationSpec; } public boolean equals(Object o) { if (!(o instanceof EndpointPair)) { return false; } EndpointPair other = (EndpointPair) o; return other.mef.equals(this.mef) && other.activationSpec.equals (this.activationSpec); } } // adds new endpointPair to the list public void addEndpoint(MessageEndpointFactory mef, ActivationSpec activationSpec) throws ResourceException {…}}The adapter listener gets all MessageEndpointFactories for the current activationSpec and registers that with the CallbackEventSender instance.
EndpointManager epManager = ((ResourceAdapter)aSpec.getResourceAdapter()) .getEndpointManager(); EndpointPair[] endpoints = epManager.getEndpoints(this.aSpec); if (!isSynchronous && aSpec.getAssuredOnceDelivery().booleanValue()) {// XA Delivery callbackEventSender = new CallbackEventSender(endPointList, eventRecMngr.getEventPersistance(), XAres, aSpec, logger.getLogUtils()); } else {// Non XA delivery callbackEventSender = new CallbackEventSender(endPointList, aSpec, logger.getLogUtils());Refer to the section on Callback event sender constructors for more information. The adapter listener creates the worker threads to take care of calling and getting responses from the callBackEventSender method.
Once the program control gets into CallbackEventSender, it checks how many EndpointFactories are configured for the current instance of adapter. If there is more than one, then it delivers the event by creating endpoints for each of them and invoking either onNotification or onMessage method on the endpoint with out any XA transaction. Finally, it would call the release() method on the end point to free the endpoint hence the application server can add it to endpoint pool.
Also it invokes beforeDelivery() and afterDelivery() methods on the endpoint as defined by the JCA functional specification.
XA transaction will come into picture only when the adapter is configured with ONE EndpointFactory. The following sequence diagram depicts the callback event processing for basic delivery.
![]()
Callback event processing for event delivery with XA transaction
To provide data integrity and to make sure events are not delivered more than once, which would cause errors in the downstream system in the integration scenario, the invention provides a mechanism to achieve once-and-only delivery and the same is accomplished using XA transaction.
When assured delivery is required, the basic flow described in Callback event processing for basic delivery becomes more complex. For more complex scenarios, CallbackEventSender creates an instance of XA to bring the delivery under a new transaction. The beforeDevliery() call to endpoint is the starting point of XA transaction and it will last till afterDelivery(). If problems occur within this transaction scope, a proper rollback mechanism will ensure that data integrity is maintained.
XA transaction will be active and supported only when the adapter is configured with one EndpointFactory.
When the adapter signals that it has completed delivery, the transaction manager will then call "end", "prepare", and "commit" to complete the requirements outlined in the XA transaction protocol. When the "prepare" call is made, the XA implementation will call "setTransactionID" on the eventPersistance implementation; the eventPersistance implementation will store the transaction XID in the event table. When the "commit" call is made, the XA implementation will call "updateEventStatus" on the eventPersistance implementation to set the status in the event table to "COMMITED". This is done for every event that was retrieved. After all the events have been delivered to the end point successfully, they are marked "COMMITTED".
When the event is created at the EIS end, configured adapterListener gets notified and it in turn instantiates CallbackEventSender. Here adapterListener decides which method to invoke out of the four defined. Lets consider the adapter calls sendEventWithNoReturn() as shown in the sequence diagram.
Once the program control gets into CallbackEventSender, it checks how many EndpointFactories are configured for the current instance of adapter. If there is more than one, then it delivers the event by creating endpoints for each of them and invoking either onNotification or onMessage method on the endpoint without any XA transaction. Finally it would call release() method on the end point to free the endpoint hence the application server can add it to endpoint pool.
Also it invokes beforeDelivery() and afterDelivery() methods on the endpoint as defined by the JCA functional specification.
XA transaction will come into picture only when the adapter is configured with ONE EndpointFactory. The following sequence diagram depicts the callback event processing for event delivery with XA transaction.
![]()
Callback event processing for event recovery
When there is a failure in the event processing as part of system recovery, the adapter is able to recover the unprocessed events by implementing the once-one-only delivery mechanism.
During real-time event processing if any component of the business integration system fails then the adapter must process the events that are not completed, and not process the events that are completed. This ensures that once-one-only delivery mechanism is implemented when the system recovers from a failure.
When the container starts, it calls the getXAResources() method on the adapter to get all the associated XA resources. The adapter then instantiates the appropriate XA resource and returns it back to the container.
The JCA container now calls the recover() method on the returned XAResourceImpl to get all the pending transactions from the configured event persistence using the getPendingTransanctions() method. Depending on the transaction state, the container calls either the rollback() or the commit() method on the XAResourceImpl to update the status of the event to NEWEVENT or PROCESSED on event persistence.
After connecting to the EIS, the adapter starts the adapterListener. The EIS then triggers the adapterListener for any new event(s) and the adapterListener in turn calls the CallbackEventSender with the same flow explained in the basic delivery and delivery with XA transaction sequence diagrams. The following sequence diagram depicts the callback event processing for event recovery.
![]()
Outbound support
Outbound support enables application components to process operations on an EIS and retrieve the results. Input data passed by the application component is processed by the adapter to make changes or call functions on the underlying EIS.
Issuing outbound requests to a WebSphere adapter is no different than interacting with any other JCA adapter as described in the JCA specification. The basic idea is as follows:
- A CCI client ( an EJB or other business process) looks up a connection factory for the adapter using a JNDI service provided by the application server.
- The CCI client requests a resource adapter connection from that factory.
- The CCI client then uses that connection to pass data to, and receive data from, the underlying EIS.
The parts of this process that vary among adapters involve the data structures exchanged and the operation-specific parameters passed.
The data structure for all WebSphere resource adapters for outbound requests is a WebSphere business object wrapped in a WBIRecord implementation.
The parameters of the operation for any JCA adapter are defined through an adapter-specific InteractionSpec instance; this class can contain 0..n properties that specify details about the operation to perform. For WebSphere resource adapters, a default WBIInteractionSpec class has one property: FunctionName. Invoking components set the operation to perform in the FunctionName property. (This is different from the verb defined in the actual business object). You are strongly encouraged to use this InteractionSpec class. For example:
WBIConnection conn; WBIRecord input; WBIRecord output; ... Interaction ix=conn.createInteraction(); WBIInteractionSpec ixSpec=new WBIInteractionSpec(); ixSpec.setFunctionName(WBIInteractionSpec.CREATE); output = ix.doExecute(ixSpec, input);
Application sign-on
The Adapter Foundation Classes can use either container-managed or component-managed authentication or sign-on.
The process of connecting to a back-end application, such an EIS, typically requires some type of authentication. In a JCA environment, application authentication is known as sign-on. It can be performed in one of two ways:
- When using container-managed sign-on, the JCA container is responsible for providing sign-on credentials. Sign-on credentials are passed from the JCA container to the resource adapter as an instance of javax.security.auth.Subject.
- When using component-Managed sign-on, the adapter client performs a programmatic sign-on by passing explicit security information, such as username and password, to the resource adapter using the CCI ConnectionSpec implementation.
The res-auth element in the application component deployment descriptor specifies the sign-on method. The only valid values for this element are Container or Application.
Certain back-end systems support reauthentication. Reauthentication is the process of changing the security context of an existing physical connection. If reauthentication is supported by the back-end application, you can set the reauthentication-support element of the resource adapter deployment descriptor to true. Otherwise it must be set to false.
Although it does not define a specific authentication mechanism, the JCA architecture supports two commonly used mechanisms: BasePassword authentication and Kerberos authentication. Use the authentication-mechanism-type element of the resource adapter deployment descriptor to specify which type is supported.
To support authentication, resource adapters extend WBIManagedConnection as follows:
- Implement method WBIConnection(PasswordCredential pc, boolean reauthenticate).
- Extract and use the credentials provided in the PasswordCredential instance that is passed; the Foundation Classes provide values from either the subject for container-managed sign-on or a WBIConnectionSpec instance for component-managed sign-on as appropriate.
- (If you don't support reauthentication, skip this step.) Check if the reauthentication flag is true and reset the connection authentication appropriately; this flag should be set to true only if the developer updates the deployment descriptor.
- Return a WBIConnection instance.
- (Optionally) override isConnectionInfoOverwriteable(). This value is used to determine whether the WBIConnectionRequestInfo already associated with the ManagedConnection can be overwritten by another parameter that satisfies the match condition. By default, this method returns false. If you can support changing some connection parameters without destroying the connection (for example, language), override and return true.
- If you override isConnectionInfoOverwritable, consider overriding the boolean matchConnectionRequestInfo (WBIConnectionRequestInfo)
- The ConnectionManager may call getConnection(Subject, ConnectionRequestInfo) on a ManagedConnection where the passed ConnectionRequestInfo does not match the ConnectionRequestInfo already associated with the ManagedConnection. The default implementation of this method performs a property-for-property comparison between the two ConnectionRequestInfo instances. It returns true if an exact match is found, otherwise false. If the match criteria is something different, the resource adapter developer may override this method with a suitable implementation.
- Return true if the WBIConnectionRequestInfo is deemed a match with the WBIConnectionRequestInfo already associated with this ManagedConnection; otherwise return false.
Implementing outbound support
You enable outbound support by providing an EIS-specific implementation of a resource adapter. This requires extending the Adapter Foundation Class implementations of common client interfaces (Connection, Interaction, and Metadata) and the ManagedConnection and ManagedConnectionFactory interfaces.
- WBIManagedConnectionFactory A javax.resource.spi.ManagedConnectionFactory instance manages the creation and configuration of physical connections to the underlying EIS. Specifically, WBIManagedConnectionFactory implements theManagedConnectionFactory and javax.resource.spi.ResourceAdapterAssiociation interfaces.
- WBIManagedConnection WBIManagedconnection is an abstract class which implements javax.resource.spi.ManagedConnection. A javax.resource.spi.ManagedConnection instance represents a physical connection to the underlying EIS. The WBIManagedConnection instance implements methods that enable the JCA container to monitor its status and manage its lifecycle.
- WBIConnectionFactory WBIConnectionFactory implements the ConnectionFactory interface. Subclasses should implement the constructor only. As javax.resource.cci.ConnectionFactory, this interface enables clients to request connections to an EIS.
- WBIConnection WBIConnection implements the Connection interface. An instance of this interface, such as javax.resource.cci.Connection, represents a client connection handle to the underlying EIS connection. A client obtains this connection by calling the getConnection method of the ConnectionFactory instance.
- javax.resource.cci.ConnectionSpec Clients use a javax.resource.cci.ConnectionSpec instance to pass request-specific connection properties to the getConnection method of the ConnectionFactory.
- WBIInteraction A javax.resource.cci.Interaction instance enables client components to process the EIS-specific operations. WBIInteraction implements an interaction interface to provide implementations for noncritical methods. Subclasses implement the execution interfaces.
- WBIInteractionSpec A javax.resource.cci.InteractionSpec instance contains properties that identify the operation to perform on the EIS.
- WBIConnectionRequestInfo A javax.resource.spi.ConnectionRequestInfo instance enables a resource adapter to pass request-specific EIS data structure on a connection request (ConnectionManager.allocateConnection). Client components can set these using connection request properties. WBIConnectionRequestInfo implements ConnectionRequestInfo. See the Adapter Foundation Classes Javadoc for more information about this implementation.
- javax.resource.cci.ConnectionMetadata A javax.resource.cci.ConnectionMetadata instance provides information to the client components about the underlying EIS of a resource adapter. Client components can use the javax.resource.cci.Connection.getMetadata() interface to retrieve connection-specific EIS metadata.
WBIManagedConnectionFactory
A javax.resource.spi.ManagedConnectionFactory instance manages the creation and configuration of physical connections to the underlying EIS. Specifically, WBIManagedConnectionFactory implements theManagedConnectionFactory and javax.resource.spi.ResourceAdapterAssiociation interfaces.
Configuration Properties
EIS-specific subclasses should specify boxed JavaBeans-compliant accessor pairs ( setValue(Integer i) rather than setValue(int i)). The accessor pairs get and set EIS-specific outbound configuration properties and logic. This is the means by which property change events reach property change listeners with corresponding updates to the ResourceAdapter (RA) deployment descriptor, thereby making the JCA container aware of available properties. Properties defined in this class are generally intended for use by the WBIManagedConnection implementation when connecting to the EIS.
Support for the ResourceAdapterAssociation interface, which cannot be used in unmanaged environments, is optional for the JCA container. Accordingly, when defining properties, assume that ManagedConnectionFactory will not have access to the ResourceAdapter bean or any properties defined at the ResourceAdapter level. While the ManagedConnectionFactory can check for and use properties at the ResourceAdapter level as defaults when available, any properties defined at the ResourceAdapter level and used by the ManagedConnectionFactory should be optional, contain default values embedded in the ManagedConnectionFactory, or exposed in the ManagedConnectionFactory so that users can specify values if the ResourceAdapter bean is not available.
Subclass methods to implement
- Object createConnectionFactory(ConnectionManager)
This method is called by the JCA container to enable the CCI clients to generate handles to the physical EIS connection. EIS-specific subclasses should implement this method to return an EIS-specific factory instance which is a subclass of WBIManagedConnectionFactory.
public Object createConnectionFactory(ConnectionManager cm) throws ResourceException { return new EISSAConnectionFactory(cm, this); }- ManagedConnection createManagedConnection(Subject, ConnectionRequestInfo)
This method is used by the JCA container to acquire a physical connection to the EIS instance. Subclass implementation should return a EIS-specific ManagedConnection instance which is a subclass of WBIManagedConnection.
public ManagedConnection createManagedConnection(Subject subject, ConnectionRequestInfo connRequestInfo) throws ResourceException { EISSAManagedConnection conn = new EISSAManagedConnection(this,subject, (WBIConnectionRequestInfo)connRequestInfo); return conn; }
WBIManagedConnection
WBIManagedconnection is an abstract class which implements javax.resource.spi.ManagedConnection. A javax.resource.spi.ManagedConnection instance represents a physical connection to the underlying EIS. The WBIManagedConnection instance implements methods that enable the JCA container to monitor its status and manage its lifecycle.
Subclass methods to implement
- public ManagedConnection(WBIManagedConnectionFactory mcf, Subject subject, WBIConnectionRequestInfo)
This constructor should connect to the EIS instance and maintain a handle to the connection as a property in the ManagedConnection. This method also must call "super" to ensure the credentials are present for later matching.
- ManagedConnectionMetaData getMetaData()
Create and return a new instance of WBIManagedConnectionMetadata by passing the EIS-specific details such as product name, product version, maximum connections, and user name.
To:public ManagedConnectionMetaData getMetaData() throws ResourceException { return new WBIManagedConnectionMetaData("VTA", "VTA", 1,"VTA"); }- Object getWBIConnection(PasswordCredential, boolean)
If reauthentication is supported, implementation should perform an EIS-specific sign-on based on the credentials passed. Otherwise, it should return a CCI handle to this managed connection.
public Object getWBIConnection(PasswordCredential arg0, boolean arg1) throws ResourceException { if (logUtils.isTraceEnabled(Level.FINE)) logUtils.traceMethodEntrance(EISSAConstants.VTAMANAGEDCONN, "getWBIConnection"); if(rmiSession == null){ String host = factory.getHostname(); String port = factory.getPortnumber(); if (logUtils.isTraceEnabled(Level.FINE)) { logUtils.trace(Level.FINEST, EISSAConstants.VTAEVENTSTOREXID, "EISSAEventStoreWithXid", "The host name is " + host); logUtils.trace(Level.FINEST, EISSAConstants.VTAEVENTSTOREXID, "EISSAEventStoreWithXid", "The port is " + port); } if(host!=null && host.length()>0 && port != null && port.length()>0){ try{ rmiSession = new RMIObjectClient(host, Integer.parseInt(port)); }catch(Exception e){//fail to establish the connection. logUtils.log(LogLevel.FATAL, LogUtilConstants.ADAPTER_RBUNDLE, EISSAConstants.VTAMANAGEDCONN," getWBIConnection", "6011"); throw new CommException("The adapter failed to establish the connection with EIS Mocker.",e); } }else{ } } if (logUtils.isTraceEnabled(Level.FINE)) logUtils.traceMethodExit(EISSAConstants.VTAMANAGEDCONN, "getWBIConnection"); return new EISSAConnection(this); }- destroy()
This method should close this connection to the EIS and release any resources.
Best practices
- Each ManagedConnection instance should encapsulate at most one connection to the EIS.
- Since there may be more than one Connection instance for each ManagedConnection instance, resource adapter developers should implement private contracts between their WBIManagedConnection subclass and their WBIConnection/WBIInteractionsubclasses to ensure that access to the underlying EIS connection or API is performed in a thread-safe manner.
If the EIS API does not support concurrent access by multiple connection handles, concurrent access should not be denied. Instead, the implementation should ensure that one and only one handle can access the EIS at a time (through synchronization blocks, wait/notify patterns, and so on).
- At the start of any EIS-specific method implementation, developers should always invoke super.checkValidity(); this method checks the state of the ManagedConnection instance to ensure that it has not been closed, encountered an error, and so on.
- If possible, always employ eager class initialization of the physical connection to the EIS; do not assume that getConnection is the first method invoked. The JCA container may need to access the XAResource, LocalTransaction, or other features of the managed connection for recovery, and so on, before any client even issues a first request.
WBIConnectionFactory
WBIConnectionFactory implements the ConnectionFactory interface. Subclasses should implement the constructor only. As javax.resource.cci.ConnectionFactory, this interface enables clients to request connections to an EIS.
Subclass methods to implement
public EISSAConnectionFactory(ConnectionManager arg0, WBIManagedConnectionFactory arg1) { super(arg0, arg1); }
WBIConnection
WBIConnection implements the Connection interface. An instance of this interface, such as javax.resource.cci.Connection, represents a client connection handle to the underlying EIS connection. A client obtains this connection by calling the getConnection method of the ConnectionFactory instance.
Subclass methods to implement
- Implement the constructor that takes a ManagedConnection and call the Super class constructor that associates this connection handle with the ManagedConnection.
public EISSAConnection(WBIManagedConnection arg0) throws ResourceException { super(arg0); }- Create an EIS-specific interaction instance that enables clients to invoke functions on the underlying EIS.
public Interaction createInteraction() throws ResourceException { return new EISSAInteraction(this); }
To provide your own implementation of ConnectionMetadata, you must override method WBIConnection#getMetadata.
javax.resource.cci.ConnectionSpec
Clients use a javax.resource.cci.ConnectionSpec instance to pass request-specific connection properties to the getConnection method of the ConnectionFactory.
To add EIS request-specific properties, the resource adapter should implement the ConnectionSpec interface directly. The sample below extends WBIConnectionRequestInfo to inherit the properties userName and password, and then adds its own EIS-specific properties.
public class <AdapterPrefixName>ConnectionSpec extends WBIConnectionRequestInfo implements ConnectionSpec { private boolean xa; public <AdapterPrefixName>ConnectionSpec(String userid, String password, boolean xa) { setUserid(userid); setPassword(password); this.xa = xa;}}
WBIInteraction
A javax.resource.cci.Interaction instance enables client components to process the EIS-specific operations. WBIInteraction implements an interaction interface to provide implementations for noncritical methods. Subclasses implement the execution interfaces.
Subclass methods to implement
Record doExecute(InteractionSpec ispec, Record inputRecord)
doExecute(InteractionSpec ispec, Record inRecord, Record outRecord)
The inRecord is the input record, and outRecord is the output record. The difference between the two is the output record is passed in, so the code in interaction.doExecute updates that output record instead of creating a new record to return.
Processes an EIS operation represented by the InteractionSpec and returns an output Record. The following example makes use of the command patterns to simplify processing.
public class EISSAInteraction extends WBIInteraction { static String copyright() { return com.ibm.j2ca.eissa.common.Copyright.IBM_COPYRIGHT_SHORT; } private EISSACommandFactory commandFactory = null; private CommandManagerForCursor commandMgr = null; private EISSAInterpreter interpreter = null; private EISSAManagedConnection mconn = null; public EISSAInteraction(WBIConnection connection) throws ResourceException{ super(connection); mconn = (EISSAManagedConnection)connection.getManagedConnection(); logUtils = mconn.getLogUtils(); interpreter = new EISSAInterpreter(logUtils); commandFactory = new EISSACommandFactory(); commandMgr = new CommandManagerForCursor(commandFactory, mconn.getEISConnection(), logUtils); commandMgr.setNamespace(""); } public Record doExecute(InteractionSpec ispec, Record inputRecord) throws ResourceException { Record output = null; try { WBIInteractionSpec wbiSpec = (WBIInteractionSpec) ispec; EISSAStructuredRecord recordInput = null; if(inputRecord instanceof EISSAStructuredRecord){ recordInput = (EISSAStructuredRecord)inputRecord; }else if(inputRecord instanceof DataObjectRecord){// is SDO1 DataObjectRecord record = (DataObjectRecord) inputRecord; recordInput = new EISSAStructuredRecord(); DEFactorySDO binding = new DEFactorySDO(); DataObject object = record.getDataObject(); //Since it would be a BG get the root property commonj.sdo.Property prop = WPSServiceHelper.getRootBusinessObjectProperty (object.getType()); //get the corresponding dataObject from BG DataObject inputObject = object.getDataObject(prop); binding.setBoundObject(inputObject); //initialize the record Object[] array = {inputObject}; recordInput.initializeInput(binding, array); recordInput.setNamespace(object.getType().getURI()); recordInput.setRecordName(object.getType().getName()); //set the verb as operationName for backward compatability recordInput.setIsBG(true); recordInput.setBGVerb(object.getString(EISSAConstants.VERB)); }else{//is JavaBean recordInput = new EISSAStructuredRecord(); DEFactoryJavaBean binding = new DEFactoryJavaBean(); binding.setBoundObject(inputRecord); Object[] array = {inputRecord}; recordInput.initializeInput(binding, array); } CommandForCursor command = commandMgr.produceCommands(recordInput, wbiSpec.getFunctionName()); EISSABaseCommand vtaCmd = (EISSABaseCommand)command; vtaCmd.setFuncName(wbiSpec.getFunctionName()); if(recordInput.getIsBG()){ vtaCmd.setIsBG(true); vtaCmd.setBGVerb(recordInput.getBGVerb()); } interpreter.execute(command); EISSAStructuredRecord outputRecord = new EISSAStructuredRecord(); outputRecord.setEISRepresentation(command.getEisRepresentation()); outputRecord.setMetadata(recordInput.getMetadata()); outputRecord.setOperationName(wbiSpec.getFunctionName()); outputRecord.setLogUtils(logUtils); output = outputRecord; if (logUtils.isTraceEnabled(Level.FINE)) logUtils.traceMethodExit(EISSAConstants.VTAINTERACTION, "execute"); } catch (CommException ce) { throw ce; } catch (ResourceException re) { throw re; } catch (Exception e) { throw new ResourceException("The execute call on the EISSAInteraction instance has failed.", e); } return output; }
WBIInteractionSpec
A javax.resource.cci.InteractionSpec instance contains properties that identify the operation to perform on the EIS.
WBIInterationSpec implements InteractionSpec and provides functionName and maxRecords properties. Client components set these properties to provide information to the resource adapter about the EIS operation to perform. See the Javadoc for the Adapter Foundation Classes.
EIS-specific resource adapter implementations need not extend this class unless they have more EIS operation-specific properties to be added to the InteractionSpec.
WBIConnectionRequestInfo
A javax.resource.spi.ConnectionRequestInfo instance enables a resource adapter to pass request-specific EIS data structure on a connection request (ConnectionManager.allocateConnection). Client components can set these using connection request properties. WBIConnectionRequestInfo implements ConnectionRequestInfo. See the Adapter Foundation Classes Javadoc for more information about this implementation.
Configuration properties
WBIConnectionRequestInfo provides userName and password properties. Using connection properties, subclasses can add their own EIS-specific properties. These properties should not change the configuration of the EIS.
Implementing transaction support
A transaction is an isolated interaction with the EIS. Transaction support allows users to ensure that multiple operations on the EIS are performed as atomic units and are not impacted by other simultaneously occurring operations from other EIS clients.
Transactions can be supported in an adapter only if the underlying EIS supports transactions.
EIS application transactions typically rely on one of two commit protocols: the one-phase or two phase commit protocols. The one-phase commit protocol allows a client to demarcate the beginning and end of transactional operations with a single EIS application. The two-phase commit protocol, which is a superset of the one-phase protocol, enables transactions to span multiple, heterogeneous EIS systems. So, applications that support the one-phase commit protocol are often said to support local transactions while those that support the two-phase commit protocol are said to support global, or XA, transactions.
While an adapter can expose support for either or both protocols, the underlying EIS must ultimately provide the support. By this token, you would not attempt to implement XA support in your adapter if your underlying EIS application inherently lacked transaction support.
Once you have determined that your EIS supports transactions, you must make several modifications to your adapter to implement the support.
- Update Your Adapter Deployment Descriptor Property TransactionSupport, as described in the JCA 1.5 specification, supports three values: NoTransaction, LocalTransaction, and XATransaction. Set the appropriate value for the level of support you intend to provide. If your adapter supports XA, specify XATransaction support but also implement the local transaction features described below. (The JCA specification prescribes that any adapter supporting XA should also support local transactions.)
- Update your adapter-specific construction of WBIResourceAdapterMetadata to reflect support for local transactions. ResourceAdapterMetadata#supportsLocalTransactionDemarcation should return true.
- Override method WBIManagedConnection.getLocalTransaction() and, if XA support is provided, method WBIManagedConnection.getXAResource().
Wrap either or both of the LocalTransaction or XAResource instances returned by these methods with a WBILocalTransactionWrapper or WBIXATransacxtionWrapper instance. These wrappers provide extended diagnostics for troubleshooting and also help adapters determine whether or not to autocommit requests. According to the JCA 1.5 specification, a resource adapter must autocommit transactions when being used outside the context of a transaction. To help the managed connection determine if it is involved in a transaction, these wrappers act as thin delegation layers, monitoring the sequence of calls to determine whether a transaction is active. At the beginning of a transaction, the wrappers call method setEnlistedInATransaction(true) on the WBIManagedConnection instance; upon commit or rollback, the wrappers set this same property to false. By then checking the status of the transaction via method isEnlistedInTransaction on the super class, a WBIResourceAdapter subclass can quickly determine whether it should be automatically committing transactions or not when modifying the EIS.
When overriding methods, do not invoke the super implementations of these methods since the Adapter Foundation Classes simply throw exceptions for these methods.
Example of an XA-enabled adapter implementation of WBIManagedConnection
public class <AdapterPrefixName>ManagedConnection extends WBIManagedConnection { // just get the XAResource from your EIS and return the wrapper public XAResource getXAResource() { XAResource eisXAResource = this.eisXAConnection.getXAResource(); XAResource wrapper = new WBIXATransactionWrapper(eisXAResource,this); return wrapper; } // here's an example of a potentially transacted call on the EIS. Point // is that adapter should always check whether it's enlisted in a // container-managed transaction or whether it should handle transaction // on its own private void updateRecord(int id,int value) { if(!this.isEnlistedInTransaction()) this.eisConnection.beginTransaction(); eisConnection.updateRecord(id,value); if(!this.isEnlistedInTransaction()) this.eisConnection.commitTransaction(); }}
Use command patterns
Command patterns simplify adapter development by providing generic logic for dealing with hierarchical data structures.
Command patterns
To enhance uniformity across adapters for outbound processing, support for command patterns is provided by the CommandManager API in the Adapter Foundation Classes.
Adapters are responsible for creating, updating, retrieving, and deleting records in the EIS system based on the structure described by the incoming metadata and the content in the incoming cursor. The command pattern approach is recommended for handling the generic processing of create, retrieve, update, and delete operations for After-Image as well as Delta scenarios.
For example, if an incoming cursor represents an after-image update, the adapter must take steps to update the EIS such the corresponding object in the EIS matches the structure and contents of the cursor request. To accomplish this, the adapter retrieves the structure in the EIS system, then compares it to the incoming cursor. The adapter then performs the operations necessary to make the EIS system match the input. These operations are typically performed as the comparisons occur. This makes adapter processing potentially quite complex. A command pattern capability abstract this functionality into generic logic, thereby saving adapter developers time and effort.
The command pattern breaks down a hierarchical update into a hierarchy of small sub-commands. These sub-commands are passed to an interpreter, which retrieves and executes the code necessary to perform the sub-command on that particular EIS system. This makes it possible for the adapter developer to deal with operations on single-tier entities without having to walk the structure and compare. This has the potential to simplify adapter construction greatly because the comparison routines can be generic.
Advantages of the command pattern include:
- Code Reuse: The only code the adapter developer would need to write would be the EIS-specific operations: the comparator and interpreter code would be common components.
- Performance consistency: Because adapters make use of common components, developers can rigorously define the after-image update process, making various adapters work more consistently.
- Adapter "phantom" mode capability: If operations must be performed, the interpreter can easily be turned off, with the contents of the command hierarchy dumped to a file instead.
Command Manager
The Command Manager is a utility designed to reduce complexity when dealing with delta and snapshot hierarchical objects. You use the Command Manager to consolidate the code necessary to deal with these objects, breaking down the structure into nodes, then creating commands that can deal with each node.
Snapshot objects
Consider the simple case of a snapshot Create operation involving a structure to create inside the EIS. The Command Manager creates a command structure composed of Create commands that is based on the incoming structure.
This command structure will then be processed by the interpreter. As the interpreter processes each individual command, the assigned objects are created.
With a snapshot Update, the Command Manager must retrieve the object from the EIS, compare it to the incoming structure and create a command structure that can change the data in the EIS to match the incoming structure.
Consider the following scenario: Child B1 is in the EIS, but is not in the incoming structure. Child B1, then, must be deleted. The Command Manager will process a Retrieve command to build the structure as it appears in the EIS, then compare this structure to the incoming object tree. The comparison finds that child B1 is deleted. Accordingly, the resulting command structure has a Delete command in that position.
![]()
Command Manager Retrieve scenario
This behavior is dependant on the ability of the Command Manager to determine child keys. Be sure to mark the child key fields in the business object definition using the appropriate Application Specific Information.
![]()
Command Manager Delete
Delta objects
Delta processing is only relevant for service data objects (SDO).
The Command Manager functions in a similar way when processing delta objects. Instead of retrieving and comparing, the command manager reads the change summary for the intended changes. Note that since a child object might be changed without any change to the parent object, and since many EIS systems require a parent pointer in order to process children, the command manager generates NO_OPERATION commands for the untouched parents of changed child objects.
Suppose, as in the example below, that child B1 is created and is part of the change summary. The resulting command structure will contain a Create command for child B1, and will have NO-OPERATION parents linking it back to the top level parent.
![]()
Command Manager Create
When it processes this structure, the interpreter will process the No-op commands as well as the Create command. In general, the no-op commands should not modify data in the EIS system.
After-image processing
The Command Manager, based on the CommandManager API, implements the command pattern capability. This utility simplifies the work of comparing before- and after-image data.
The Command Manager is based on the CommandManager API of the Adapter Foundation Classes. For after-image processing, the Command Manager compares the cursor record structure inside the EIS (the before-image) with that of the incoming after-image cursor. Based on the comparison, the Command Manager constructs a hierarchical representation of commands that must be executed to make the before-image object match that of the after-image. The command hierarchy is passed to an interpreter, which executes each command in the order of execution required for the declared operation. The order of execution for Create and Update is top-to-bottom; for Delete the order is bottom-to-top.
As shown in the following figure, the Command Manager relieves you of the task of developing and testing comparison routines.
![]()
Command Manager simplifies before and after comparisons
As shown in the upper portion of the figure, the input to the Command Manager is a before image and an after image. The Command Manager creates a top-level command representing the operation for the top-level incoming cursor. As processing continues, sub-commands are added at the child object level, and so on, to the top-level incoming cursor, as shown in the lower portion of the figure.
The Command Manager provides a first class support for create, retrieve, update, and delete operations using static variables defined in the WBIInteractionSpec class:
WBIInteractionSpec.CREATE WBIInteractionSpec.UPDATE WBIInteractionSpec.DELETE WBIInteractionSpec.RETRIEVE
You can use the Command Manager for other supported operations, too. It creates a command pattern hierarchy with the same operation at all the levels in the cursor hierarchy. Specifically, you would configure the CommandFactory for Object type operations with isOOType() returning true. If isOOType() returns false, the Command Manager would create only one command in the command hierarchy for the top-level cursor.
For other non-CRUD operations, it may not make sense to use the command pattern capability. For example, if the operation supported is XXX, and if XXX simply executes a function call at the top-level cursor only, there is no need to apply the XXX operation to all child cursors.
As it begins to process children of the root object, the Command Manager iterates through the properties for the top-level cursor. For each property which is of type containment, the Command Manager attempts to construct a hashset of the key values for each child. Every entity, root or child, must have a primary key, which is how the Command Manager distinguishes records.
The Command Manager constructs two sets, A and B. Set A will be the set of primary keys in the before-image child container. Set B is the set of primary keys in the after-image container.
- The set A-B contains extra children. These will be Deleted.
- The set B-A contains missing children. These will be Created.
- The set A intersect B contains children to be updated. These will be updated.
For each record in each set for "extra" and "missing" children, the Command Manager will recursively follow the child record and all its children, for each entity adding to the top-level command the child command representing the child cursor and its corresponding operation.
For children to be updated, the before- and after-image data are passed back to the Command Manager. This allows the Command Manager to recursively process any children that those children might contain. When the Command Manager reaches the bottom level of both structures, the command structure is complete, and the Command Manager returns the top-level command.
Delta processing
The Command Manager processes delta structures in a manner analogous to that of after-image data. The difference is that, for delta objects, comparative data is extracted from service data object change summaries.
When the input service data object (SDO) represents an Update operation with a delta structure, the Command Manager will look up the BOChangeSummary to find the respective operations on each child SDO. For example, the following figure shows a delta SDO input with underlined text representing the operation derived from the change summary.
![]()
Command Manager extracts change summaries
Command Manager interpreter logic
An order attribute establishes the sequence by which the interpreter executes commands.
The interpreter is given a top-level command to execute. Each command has an order associated with it that is set when the command is created. The order attribute of each command may be BEFORE_PARENT or AFTER_PARENT. If the order attribute of a child command is BEFORE_PARENT, that command will execute before the parent; if the order attribute of a child is AFTER_PARENT, that command will execute after the parent.
- If an object is marked as created and then as deleted in the ChangeSummary, the adapter will not take any action.
- If an object is marked as created and then updated in the ChangeSummary, the adapter will perform a Create.
- If an object is marked as updated and then deleted in the ChangeSummary, the adapter will perform an Update.
Implementing Command Manager
You implement commands for each type of operation supported by the adapter, a command factory to support instances of each operation, and calls to the Command Manager.
You will need to implement the following:
- Command implementations for each command type ("Retrieve", "RetrieveAll", "Create", "Update", "Delete", and "NoOperation").
- A command factory implementation that will create instances of these EIS-specific commands.
- An implementation of Interaction.doExecute() that calls the Command Manager.
Command implementations
You use an doExecute() method to implement commands. Extend an abstract base command with operation-specific commands supports the coding benefits of command patterns.
doExecute() is the method that implements each command. This method should perform the appropriate operation for the associated node. If a Create command is associated with child B1, for example, doExecute() is the method that calls the EIS API to create that child.
public void doExecute(InputCursor obj, Type metadata) throws ResourceException {EisRepresentation eis = EisAPI.insert(toEisFormat(obj, metadata));}Be careful with deleted children. The SDO getContainer() does not return the original parent in a delta operation. Use the getParentDataObject() method, available in the command object, to alleviate this problem.
The Retrieve and RetrieveAll commands must create the entire object structure and return it because the input object is unaware of child objects present in the EIS.
It is a common pattern to have an abstract base command for your EIS, and then have the operation-specific commands extend that. This way, if all your commands need similar data, you can reduce your coding effort.
The WebSphere Adapter Toolkit will not generate the doExecute() methods for individual commands. You will want to override the base command execute method to put in the logic you want.
Command factory implementations
The command factory creates operation-specific command instances and establishes when the instance is processed.
Given an operation name and metadata, the command factory is responsible for creating command instances. The command factory must also set the execution order that specifies when a command should be processed in relation to its parent. This value can be either BEFORE_PARENT, or AFTER_PARENT.
The interface you must implement is as follows:
public CommandForCursor createCommand(String nodeLevelOperation) throws ResourceException;The code to implement a command factory will resemble the following, where EIS Simulator (EISS) is the name of the Enterprise Information System.
public CommandForCursor createCommand(String functionName, Type metadata) throws ResourceException { <AdapterPrefixName>BaseCommand command = null; Adapter Toolkit 99 try { if (functionName.equals(NodeLevelOperations.CREATE_NODE)) { command = new <AdapterPrefixName>CreateCommand();} else if (functionName.equals(NodeLevelOperations.DELETE_NODE)) { command = new <AdapterPrefixName>DeleteCommand();} else if (functionName.equals(NodeLevelOperations.UPDATE_NODE)) { command = new <AdapterPrefixName>UpdateCommand();} else if (functionName.equals(NodeLevelOperations.RETRIEVE_STRUCTURE)) { command = new <AdapterPrefixName>RetrieveCommand();} else if (functionName.equals(NodeLevelOperations.RETRIEVE_ALL)) { command = new <AdapterPrefixName>RetrieveAllCommand();} else { command = new <AdapterPrefixName>BaseCommand();} command.setObjectSerializer(objectSerializer); command.setObjectNaming(objectNaming); command.setMaxRecords(maxRecords); command.setMetadata(metadata); if (functionName == NodeLevelOperations.DELETE_NODE) { command.setExecutionOrder(CommandForCursor.BEFORE_PARENT);} else { command.setExecutionOrder(CommandForCursor.AFTER_PARENT);}}catch (Exception e) { throw new ResourceException(e);} return command;}
Implementing Interaction.doExecute()
To enable the command pattern capability, you implement a class from the InteractionSpec with a call to the Command Manager. The InteractionSpec is part of the JCA CCI interface.
The interaction class is part of the JCA CCI interface and processes records as input and output. This is the API that is exposed for manipulating data in outbound operations:
public Record doExecute(InteractionSpec ispec, Record inRecord) throws ResourceException;You may want to call the Command Manager to produce the command structure, then the interpreter to process each command in the structure. A simplified version of the resulting interaction code will resemble the following:
public Record doExecute(InteractionSpec ispec, Record inRecord) throws ResourceException { WBIStructuredRecord wbiRecord = (WBIStructuredRecord) inRecord; String functionName = ((WBIInteractionSpec) ispec).getFunctionName(); CommandForCursor topLevelCommand = commandManagerForCursor.produceCommands(wbiRecord, functionName); interpreter.doExecute(topLevelCommand); WBIStructuredRecord outRecord = new WBIStructuredRecord(); outRecord.setOperationName(functionName); outRecord.setFooConnection(connection.getEISConnection()); outRecord.setEISRepresentation(topLevelCommand.getEisRepresentation()); return outRecord;}Notice that you need not "walk" the incoming object structure, or the command structure– the command manager and interpreter perform this function.
Manage stale connections
Connection-related problems can be resolved in your adapter using the two properties, connectionRetryLimit and connectionRetryInterval defined in the Managed connection factory of your adapter.
These two properties are used to provide the following features during outbound communication of the adapter and are optional by default.
- Retry mechanism as part of establishing the physical connection to the enterprise information system (EIS)
The adapter retries to establish physical connection (when physical connection is not established) for the connectionRetryLimit times with a time delay of connectionRetryInterval.
- Validating the EIS connection for each request based on the property connectionRetryLimit
- If the property connectionRetryLimit is set to 0 (zero), then adapter does not perform any EIS connection validation and executes the outbound operation. If the EIS connection is invalid, the outbound operation fails. Though the subsequent requests get executed provided the associated EIS system is functional, but the current request fails.
- If the property connectionRetryLimit is set to greater than 0 (zero), then during each request the adapter validates if the EIS connection is active or alive. If connection is valid then operation is completed as usual. If connection is invalid, adapter invalidates the current managed connection so that a new managed connection is created (new physical connection). If connection creation is successful then the outbound operation is completed otherwise an error ResourceException is displayed.
This feature has performance effects as adapter checks for validity of the connection for each request.
These features take care of connections which are timed out or became stale after EIS restarts. Even though this option solves most of connection-related problems, the adapter is not guaranteed to work 100 percent error free for connection problems.
Examples of connectionRetryLimit and connectionRetryInterval
Method for retry connection to EIS (<AdapterPrefixName>ManagedConnection.java)
private void getEISConnection(PasswordCredential pc, boolean reauthenticate) { // TODO int retryLimit = test_mcf.getConnectionRetryLimit(); if(retryLimit< 0){ retryLimit =0; } int retryInterval = test_mcf.getConnectionRetryInterval(); //TODO for(int i =0; i<=retryLimit;i++){ if(i>0){If the property connectionRetryLimit is > 0, during each such request, the adapter validates if the EIS connection is active or alive. If the connection is valid, the operation is completed as usual. If the connection is invalid, the adapter invalidates the current managed connection, so that a new managed connection is created (new physical connection). If the connection is created successfully, the outbound operation is completed. Otherwise, an error ResourceException is thrownMethod for validating the connection to EIS (<AdapterPrefixName>ManagedConnectionFactory.java)
public boolean validateManagedConnection(WBIManagedConnection mngConn){ //TODO return true; }
Data and metadata
Adapter Foundation Classes (AFC) implement DESPI APIs and support two data formats, service data objects (SDO) and JavaBeans.
The data format-specific implementations are provided in the AFC and are abstracted from the adapters which use the DESPI APIs to process data in a format-independent way.
XSD and JavaBeans structure relationship to DESPI
SDO Structure:
JavaBeanRecord Structure:
The JavaBeanRecord data structure is derived from the XML schema defining the SDO. Adapter foundation classes provide an implementation of RecordGenerator which generates JavaBeanRecords for a given SDO/XML schema.
The RecordGenerator class is used by the adapter enterprise metadata to generate the required artifacts for JavaBeans Record data format. See Enterprise metadata implementation details on how to update the adapter enterprise metadata (EMD) implementation to use the RecordGenerator class.
Type mappings: Bean properties map to the attributes of a given complex type. The types of the simple attributes are derived from the XML built-in data types defined in the input schema for each subelement of the complex type. The subelements containing n-cardinality child objects are always defined as an array of the child type while single cardinality subelements are represented as a JavaBeans property with the type of the subelement.
The table below details the mapping between the built-in XML Schema Definition (XSD) types and bean properties generated by the RecordGenerator implementation in the AFC.
Mapping between built-in XSD schema and JavaBeans properties
Header Header Boolean boolean String String Int int Integer Integer Decimal BigDecimal Double double Float float Long long Short short hexBinary byte[] (byte array) Byte byte dateTime Calendar Date Calendar Time Calendar anySimpleType String Any String
There are cases in which a simple XML data type must be mapped to the corresponding Java™ wrapper class for the Java primitive type:
- an element declaration with the nillable attribute set to True
- an element declaration with the minOccurs attribute set to 0 (zero) and the maxOccurs attribute set to 1 (one) or absent
- an attribute declaration with the use attribute set to optional or absent and carrying either the default or the fixed attribute
The examples of each is as follows:
<xsd:element name="code" type="xsd:int" nillable="true"/>
<xsd:element name="code2" type="xsd:int" minOccurs=""></xsd:element>
<xsd:element name=""> <xsd:complexType> <xsd:sequence/> <xsd:attribute name=""> </xsd:attribute></xsd:complexType> </xsd:element>The element/attribute declarations for code, code2, code3 are all mapped to the java.lang.Integer type.
JavaBeans Metadata ASI format: The metadata is derived mostly from the structure of the bean. Other metadata, such as containedType and maxLength are not normal parts of a JavaBeans structure, so they must be part of the annotation maps.
Annotation maps:
Annotations are not normally part of a JavaBeans structure, so JavaBeanRecords must contain annotations in a specific format to be usable by the metadata API.
The JavaBeanRecord must implement the BeanMetadata interface.
public interface BeanMetadata { public Map getObjectAnnotations(); public Map getPropertyAnnotations(); public Set getSetAttributes();}Each property (if it needs metadata) can have its own Map, which is stored in the propertyAnnotations map, using the property name as key.
Reserved keys in the propertyAnnotations map:
- ContainedType
The class of the object that this property contains
- PrimaryKey:
Whether this property is key
- DefaultValue:
The default value
- MaxLength:
The maximum length of this property.
The notion of whether a property is set is critical to processing null values or values that have not been set in the adapter. If a property has been explicitly set to null, the adapter must be able to detect this and set the associated property to null in the EIS.
If the property has not been set, it might still have a null value, but the adapter ignores the value and not set it in the EIS system.
A list of bean properties for which the setter is called is returned when getSetAttributes() is called. This enables the DESPI implementation to determine if a particular attribute has been set.
Property order:
The notion of property order is critical, because the adapter may need to iterate over the properties in the same order they appear in the EIS system.
Since JavaBeans APIs cannot detect the order present in the class file, there must be a string array called "propertyOrder" in the bean, containing the names of all properties in the preferred order.
public static final String[] propertyOrder = {"property1","property2"};
SDO to JavaBeanRecord ASI Mappings: Annotations from the SDO/XML schema are read and stored in a Map structure in the bean. Here is a description of how the RecordGenerator would populate annotation maps. For each element in the metadata annotation, the generator would create an entry in the Map with the name of the element as the key.
- If the element is a simple type with single cardinality then the value of this element is added to the Map.
- If the element is a simple type with n-cardinality, then a List is generated containing one or more values of this element.
The List is then added to the annotation Map.
- If the element is a complex type with single cardinality then a Map is created containing the mappings for elements of this child complex type.
The Map is then added to the annotation Map.
- If the element is a complex type of multiple cardinality then a List is created.
The List would contain one or more Map entries where each Map contains the mapping for the elements of the child complex type.
Here is an example of how the object level metadata annotation would look like in an SDO schema:
<annotation> <appinfo source= "http://www.ibm.com/xmlns/prod/websphere/j2ca/sap/metadata"> <sapasi:sapBAPIBusinessObjectTypeMetadata xmlns:sapasi= "http://www.ibm.com/xmlns/prod/websphere/j2ca/sap/metadata"> <sapasi:Type>BAPI</sapasi:Type> <sapasi:Operation> <sapasi:MethodName>BAPI_CUSTOMER_CREATEFROMDATA1</sapasi:MethodName> <sapasi:Name>Create</sapasi:Name> </sapasi:Operation> <sapasi:Operation> <sapasi:MethodName>BAPI_CUSTOMER_CHANGEFROMDATA1</sapasi:MethodName> <sapasi:Name>Updatewithdelete</sapasi:Name> </sapasi:Operation> </sapasi:sapBAPIBusinessObjectTypeMetadata> </appinfo> </annotation>As defined in the sapBAPIBusinessObjectTypeMetadata schema "Operation" is an n-cardinality complex type. The "MethodName" element of the operation type is a simple type with multiple cardinality:
<complexType name="sapBAPIBusinessObjectTypeMetadata"> <sequence> <element name="Type" type="string"/> <element name="Operation" type="sapasi:sapBAPIOperationTypeMetadata" minOccurs="0" maxOccurs="unbounded"/> <element name="ErrorConfiguration" type= "sapasi:sapRFCErrorConfigurationMetadata" minOccurs="0" maxOccurs="1"/> </sequence> </complexType> <complexType name="sapBAPIOperationTypeMetadata"> <sequence maxOccurs="1" minOccurs="0"> <element name="Name" type="string" minOccurs="0" maxOccurs="1"/> <element name="MethodName" minOccurs="0" maxOccurs="unbounded" type="string"/> </sequence> </complexType> <complexType name="sapRFCErrorConfigurationMetadata"> <sequence maxOccurs="1" minOccurs="0"> <element name="ErrorParameter" type="string" minOccurs="0" maxOccurs="1"/> <element name="ErrorCode" minOccurs="0" maxOccurs="1" type="string"/> <element name="ErrorDetail" minOccurs="0" maxOccurs="1" type="string"/> </sequence> </complexType>For the above metadata, the object level annotations map generated for the JavaBeanRecord would look like the following:
public static LinkedHashMap objectAnnotations = new LinkedHashMap(); static { objectAnnotations.put("Type","BAPI"); LinkedList operationAnnotation = new LinkedList(); LinkedList methodnameList; LinkedHashMap createOperationMap = new LinkedHashMap(); createOperationMap.put("Name", "Create"); methodnameList = new LinkedList(); methodnameList.add("wbiCustomerCreate)"; createOperationMap.put("MethodName", methodnameList); operationAnnotation.add(createOperationMap); LinkedHashMap updateOperationMap = new LinkedHashMap(); updateOperationMap.put("Name", "Update"); methodnameList = new LinkedList(); methodnameList.add("wbiCustomerUpdate)"; updateOperationMap.put("MethodName", methodnameList); operationAnnotation.add(updateOperationMap); objectAnnotations.put("Operation",operationAnnotation);}ObjectAnnotations:Object level metadata in the annotations is read and stored in the 'objectAnnotations' Map. Following diagram shows the structure of objectAnnotations.
![]()
The Metadata API
Advanced implementations of adapters are metadata-driven. This implies the adapter is not hard-coded for each object type in the system, but rather has a form of discovery in which a representation of the object (the metadata) in the EIS is constructed at build time, then at runtime the adapter uses this metadata, along with the data, to process the object. Metadata can be in a preexisting format, such as a standardized schema. Standard metadata includes such information as property name, property type, maximum length, cardinality, and anything else that can be described in a standard schema. Metadata may also be in a format decided by the adapter. This form of metadata is called "Application Specific Information", or ASI. ASI can occur in three places.
- Object level metadata
This includes the information about what type is being processed
- Operation level metadata
This is context-specific object metadata, that is valid for the operation being processed at this time.
- Property level metadata
This is information about the one property in the EIS schema. It may contain such information as the column name as it occurs in the EIS, which may be different than the property name in the object.
In order for the adapters to handle multiple representations of metadata; specifically SDO and JavaBeans, the Foundation classes provide an API for the adapters and abstracts the metadata representation. The intention of this Metadata API is to present both structural and application-specific metadata to the adapter, so the adapter is insulated from the metadata format. For example, a JavaBeans or an SDO may be used as metadata, but the adapter can use the same metadata APIs to walk over the structure and to extract the required information from it.
Adapter implementations should use the following interfaces when retrieving metadata. Adapters should never cast to an implementation of these interfaces. These interfaces may contain more helper methods than are listed here, see the Javadoc for the additional helpers.
Factory classes
Class TypeFactory:
TypeFactory creates an instance of an implementation of Type. The TypeFactory is also capable of detecting whether SDO version 2, SDO version 1, or neither is present in the class path, allowing it to make decisions about what implementation to use.
- Type getType(Object object)
Gets a Type object from existing metadata.
- Type getType(String namespace, String name)
Gets a Type object from a namespace, name combination. For a JavaBeans metadata implementation, the namespace is the package and the name is the class name.
Class SDOFactory:
SDOFactory creates an SDO instance, the implementation of which will depend on what version of SDO is in the class path.
- DataObject createDataObject(String namespace, String name)
Creates the data object based on the namespace and name.
- DataObject createDataObject(Type type)
Creates the data object based on an instance of Type
Interfaces
Interface Type:
The interface type allows access to object-level metadata, including properties, object-level annotations and key properties.
String getName()retuns the name of the type. Iterator getPropertyIterator() Returns an iterator to allow iteraton over the properties in this type. List getProperties() Returns a list of properties for this type. Property getProperty(String propertyName) Returns the property object for this property name. Map getAnnotations(String source) Returns the object-level annotations for this type. You must pass in the "source" of the annotations, which corresponds to the "source" attribute of the "appinfo" tag of the XML Schema representing this object. Annotations will be returned as a Map, and this Map may contain other maps if the annotation structure is nested. Map getAnnotationsForOperation(String source, String operation) Often operation-specific object metadata is needed. For example, for Create operation there is a specific sequence of APIs that have to be executed, this set could be different for Update and Delete operations. This method returns the metadata for a given operation name as a Map of name - value pairs. List getKeyProperties(String source) Returns the list of key properties in this type.
Interface Type:
Type getContainingType() Returns the type containing this property. Object getDefault() Returns the default value for this property. String getName() Returns the name of this property. Class getPropertyClass() Returns the Class represented by this property.For example, if the property is of String type, this method will return String.class. boolean isContainment() Returns whether or not the property contains a Type (complex object). boolean isMany() Returns whether or not the property contains a List or Array. int getMaxLength() Returns the max length of the property. Map getAnnotations(String source) Returns the annotations for this property. boolean isKey(String source) Returns true if this property is a key, and false if not. Type getType() If the property is containment, this method will return the contained type.
Enterprise metadata implementation
Selection of artifact types
WebSphere adapters can run against multiple brokers (server run times).
Each broker might require different types of artifacts. The adapter foundation classes can generate artifacts in support of multiple brokers.
The following artifact types are supported by adapter foundation classes:
- Data Bindings
Data Binding classes generated by enterprise metadata discovery to support IBM Business Process Manager runtime.
- Generated Records
JavaBeans records generated from SDO to support clients that work with JavaBeans.
- Generic Records
Other DESPI implementations.
The table below provides a matrix for artifact type and their supported server run times.
Artifact types and supported run times
Run times Artifact types IBM Business Process Manager WebSphere Application Server Other DESPI implementations DataBindings X GeneratedRecords X GenericRecords X
While running the external service discovery wizard, adapter users can choose which artifact to generate depending on their runtime environment. Users can select more than one artifact.
Support for GeneratedRecords artifact type: WebSphere adapters may support JavaBeanRecord data representation along with SDO 1.0 and SDO 2.0 data objects. As part of the support for JavaBeans data representation, the adapter foundation classes provides a JavaBeans record generator class that can generate DataBindingDescriptions for the object types discovered and selected through the enterprise metadata discovery (EMD) process.
Each adapter enterprise metadata discovery provides a list of artifact types it supports, allowing the user to select an artifact type that is appropriate for their environment. For example, to enable the adapters on run times where SDO implementations are not available, users will run the ESD wizards to generate the adapter artifacts for GeneratedRecords type. When the user selects a Generated Records artifact type in the enterprise metadata discovery process, the external service discovery wizard will look for a databinding generator class name on the EMD DataDescription and invokes that class to generate the JavaBeans records.
All adapter enterprise metadata discovery that support the generated records artifact type would need to set the data binding generator class name (on the DataDescription) to the generator implementation provided in the AFC. Here is a code snippet showing how the record generator is set in the service description implementation of an adapter EMD.
WBISingleValuedPropertyImpl property = (WBISingleValuedPropertyImpl) selectionProperties.getProperty (EMDConstants.ARTIFACTS_SUPPORTED); WBIMetadataConnectionImpl.getToolContext().getProgressMonitor() .setNote("Business object definitions created"); String namespace = getNameSpace(); //Change made for making BG Optional if (property.getValue().equals(EMDConstants.DATA_BINDINGS)) { dataDescription.setName(WBIDataDescriptionImpl.convertNamespaceToUri(namespace + "/" + metadataObj.getBOName().toLowerCase() + "bg" ), metadataObj.getBOName() + "BG"); dataDescription.setDataBindingGeneratorClassName ("com.ibm.j2ca.sample.<AdapterPrefixName>emd.runtime. <AdapterPrefixName>DataBindingGenerator"); dataDescription.setGenericDataBindingClassName(null);} else if (property.getValue().equals(EMDConstants.GENERATED_RECORDS)) { dataDescription.setName(WBIDataDescriptionImpl.convertNamespaceToUri(namespace + "/" + metadataObj.getBOName().toLowerCase()), metadataObj.getBOName()); dataDescription.setDataBindingGeneratorClassName ("com.ibm.j2ca.extension.dataexchange.bean.generator.RecordGenerator"); dataDescription.setGenericDataBindingClassName(null);} else { //Generic Record Scenario dataDescription.setName(WBIDataDescriptionImpl.convertNamespaceToUri(namespace + "/" + metadataObj.getBOName().toLowerCase()), metadataObj.getBOName()); dataDescription.setGenericDataBindingClassName ("com.ibm.j2ca.sample.<AdapterPrefixName>StructuredRecord");New property types supported from WebSphere Adapter Toolkit V6.1:
TableProperty: A property representing a table with rows and columns. Each column is represented by the PropertyDescriptor instance and each cell corresponding to a given row and column is represented by a SingleValuedProperty implementation.
TreeProperty: A property representing a tree of selectable nodes. Each node is represented by a NodeProperty implementation which can be selected, highlighted and can have configuration properties represented by a PropertyGroup instance.
Enterprise Metadata Discovery general interfaces and implementation for application adapters
Enterprise metadata discovery is a discovery service, or a component within an adapter that enables the generation of business object definitions and other artifacts required by service component architecture.
The enterprise metadata discovery component is analogous to the Object Discovery Agent of WebSphere Business Integration Adapters. In addition to generating business object definitions, however, the enterprise metadata discovery also generates service component architecture artifacts such as an Import/Export file and WSDL. An explicit goal of enterprise metadata discovery is to enable existing JCA resource adapter extensions to provide metadata discovery and import in a simple, straightforward way.
Use adapters that allow for metadata discovery and import, you can create and edit services with the following capabilities, where the operation style is supported by the underlying adapter:
- Integration-framework-initiated operations to retrieve data from or modify data in the EIS.
- EIS-initiated operations, where the request originates within the EIS.
This type of operation is used for retrieving data from, or modifying data in, the integration framework.
EIS metadata
EIS metadata describes the system capabilities and business object structures employed by the EIS. The enterprise metadata discovery service acquires EIS metadata from the communication configuration information that characterizes system function and object interactions.
System Capabilities
At the system level the metadata describes the types of information managed by the EIS system. This is represented as a collection of functions on the EIS client interface or as a set of business objects that are accessed from the EIS client interface. In addition to function and object descriptions, EIS metadata includes a description of the styles of interaction that can occur with functions and objects in the EIS metadata model. There are two interaction styles:
- Inbound - EIS-initiated
- Outbound - Client-initiated
There can be two kinds of interaction for each interactionstyle.
- Request-Response - This kind of interaction takes a request and returns a response. Outbound interactions are of this type.
- One-way - A one-way interaction takes a request, but does not return a response. Inbound interaction style is one-way
The discovery service defines whether an interaction style is inbound versus outbound. The distinction between one-way and request-response is made by the method descriptions generated for the service. The request-response mode would have both input and output specified for a method description whereas input arguments only would be specified for one-way. The metadata generated by the discovery service must comply with the restrictions on interaction mode mentioned above: for Outbound the metadata must support Request/Response and for Inbound, one-way.
Business Object Structures
These are the business objects used by JCA adapters. They describe the structure and content of arguments to functions on the EIS client interface or the business objects accessed through the EIS client interface.
Communication Configuration
The communications configuration is represented by a collection of properties also referred to as PropertyGroup. The properties include properties required for both inbound and outbound communication. In some cases, there may be more than one set of properties required. These might be required to describe different types of outbound connections that for design time and runtime or for inbound connection configuration.
The discovery service is not limited to accessing metadata from the EIS. If the metadata is stored in a separate repository, the discovery service can mine the metadata from there. This allows the discovery service to combine all metadata at its disposal to provide a meaningful user experience to the tool user.
Service metadata
Service metadata is generated by the adapter as business objects are imported into a service description.
Service metadata includes the service name and the adapter and managed connection factory properties that describe the configuration for an outbound connection to the EIS (outbound case). For an inbound connection to the EIS (inbound case), service metadata might include resource adapter and Activation Specification configuration properties. Service metadata also includes method-level metadata such as the method name, data description for the input and output, and either InteractionSpec properties (outbound case) or the EIS function name (inbound case).
For most cases, service metadata representing outbound and inbound connections is the same as the EIS metadata for communication configuration. For other cases, depending on specific implementation, the service metadata might be distinctly different. For example, the discovery service might find objects from a different interface, such as a separate repository, or might use a different type of a connection for discovery.
![]()
Enterprise metadata discovery architecture
The enterprise metadata discovery tooling includes runtime, discovery, and service generation interfaces and metadata edit capabilities.
![]()
Enterprise metadata discovery architecture
The solid arrows represent the enterprise metadata discovery implementation in the above diagram.
The components of the enterprise metadata discovery implementation, described below, are:
- Runtime
These interfaces extend the CCI interfaces defined in the JCA specification to support invocation of services discovered with enterprise metadata discovery. These interface implementations are provided by the resource adapter provider or a third party discovery service provider. These are the data binding interfaces that are used to integrate with service data objects.
- Discovery
These interfaces constitute the bulk of the contracts defined in this specification. They define the following contracts:
- Discovery - These interfaces allow the tool to browse EIS metadata.
- Connections - These interfaces allow the tool to discover all the available connections, create connections, edit connections and persist the connections for future use.
- Mutable metadata - These interfaces allow the tool to edit the EIS metadata that is being browsed.
- Service Generation
These interfaces allow the tool to create or edit service descriptions that define the service a user has selected. These service descriptions are used to generate service implementations that are deployable in application servers and used as part of a service oriented architecture. These interfaces also provide support for editing application-specific information schemas.
These interface implementations are provided by the resource adapter provider or a third party discovery service provider.
- Metadata edit
This interface allows the EAI tool to edit the configuration of a resource adapter or a service. This interface implementation is provided by the resource adapter provider or a third party discovery service provider.
Metadata discovery
This primary interface to the enterprise metadata discovery plug-in holds a reference to the ToolContext. ToolContext is used for logging and tracing and to provide information that helps perform discovery.
The discovery service must specify the following for this interface.
- List of AdapterType - For JCA adapters only one AdapterType comprises this list.
- MetadataTree - Represents the object tree structure that would be displayed by the tool. Each node in the tree is represented by an instance of a MetadataObject. The nodes can have their own properties. The tool can also apply filter properties when fetching children for the node.
- Service Description - Created on request by the user for an inbound or outbound service. Includes all of the objects selected before a request.
Metadata discovery adapter type
Adapter type metadata identify aspects of the adapter that are supported by the enterprise metadata discovery implementation. The Adapter Foundation Classes provide an interface for adapter type information.
The Adapter Foundation Classes provide an implementation for this interface: WBIAdapterTypeImpl. Individual discovery service implementations can use this base class and not implement their own.
Multiple adapterTypes can be supported by a single enterprise metadata discovery implementation. A use case might involve a single adapter instance as a channel for multiple back-end EIS assets. IBM WebSphere recommends a single adapterType for each enterprise metadata discovery implementation.
The following information must be provided for this class by a discovery service implementation.
- ID ( PeopleSoft)
- Description ( PeopleSoft JCA Adapter)
- Display name ( PeopleSoft Adapter)
- Vendor ( IBM)
- Version ( 7.5)
- List of OutboundConnectionTypes - Lists the outbound connection types an adapter can support. A single adapter might support multiple connection types. The mapping of connection type to adapter is driven by the number of managed connection factories that are supported by the adapter. If the adapter uses a different connection than one provided by a managed connection factory, this list must include the additional connection types. The connection types displayed in the tool for selection are only the ones that can be used to perform metadata discovery. Such connections are marked as true for isSupportedInMetadataService. For all connection types that cannot be used to perform discovery, set isSupportedInMetadataService to false.
- List of InboundConnectionTypes - List of inbound connection types supported by an adapter. The inbound connections map to the Activation Specifications supported by an adapter.
Metadata discovery connection type
Specify connection type values for the enterprise metadata discovery service. The connection type includes connection configuration instance information for outbound and inbound directions.
ConnectionType is a factory for ConnectionConfiguration instances. The enterprise metadata discovery tool uses the instances to create actual and persistent connections. The connection can be inbound or outbound and is unique within the AdapterType.
OutboundConnectionType
The enterprise metadata discovery service uses the OutboundConnectionType property to create an outbound service description. The mapping of connection type to adapter is driven by the number of managed connection factories that are supported by the adapter. If the adapter uses a different connection than one provided by a managed connection factory, this list must include the additional connection types. The connection types displayed in the tool for selection are only the ones that can be used to perform metadata discovery. Such connections are marked as true for isSupportedInMetadataDiscovery. For all connection types that cannot be used to perform discovery, set isSupportedInMetadataDiscovery to false.
IBM WebSphere recommends implementing a connectionType for metadata that is separate from that for run time. The metadata connectionType must contain properties needed to perform the metadata discovery only. The run time connection type should have properties for the resource adapter and the managed connection factory. The discovery service should attempt to reuse the properties from the metadata connectionType wherever possible. Candidates for reuse include the username and password properties. A utility class, EMDUtil, provides methods to copy matching properties from metadata connection to run time connection. See in theWBIOutboundConnectionTypeImpl Javadoc.
The following information must be provided for this class by a discovery service implementation:
- ID ( PeopleSoft)
- Display name ( PeopleSoft)
- Description ( PeopleSoft Component Interface)
- ResourceAdapterBean class ( "com.ibm.j2ca.peoplesoft.PeopleSoftResourceAdapter")
- ManagedConnectionFactory bean class ( "com.ibm.j2ca.peoplesoft.PeopleSoftManagedConnectionFactory" )
- OutboundConnectionConfiguration - Represents properties needed to connect to the EIS for discovery and to create service descriptions. For connection types that are used only at run time this represents managed connection factor and resource adapter properties.
- isSupportedForMetadataDiscovery - is set to true if the connectionType can be used for metadata discovery. Only valid, specified connection types are displayed for connectionType selection.
InboundConnectionType
InboundConnectionType is used to create Inbound service description. An adapter can support multiple Inbound connection types, the mapping of inbound connection is to Activation Specs, as many activation specs an adapter supports than many inbound connection types would have to be supported.
The following information has to be provided by discovery service implementation for this component.
- ID ( PeopleSoft)
- Display name ( PeopleSoft)
- Description ( PeopleSoft Component Interface)
- ResourceAdapterBean class ( "com.ibm.j2ca.peoplesoft.PeopleSoftResourceAdapter")
- ActivationSpecBean class ( "com.ibm.j2ca.peoplesoft.PeopleSoftActivationSpec")
- InboundConnectionConfiguration - Represents resource adapter and Activation Specification bean properties.
Discovering System Capabilities
After selecting the ConnectionType, enter the properties for connection configuration. This typically includes those properties needed to connect to the EIS or EIS repository and also properties required to define the artifacts that will be generated by enterprise metadata discovery. Once you enter the properties the tool requests, the enterprise metadata discovery service attempts to establish a connection to the EIS repository. The service extracts values for configuration properties and opens a connection to the EIS repository. This is represented by MetadataConnection object.
MetadataConnection
The MetadataConnection object represents the connection to EIS or EIS repository. This interface is implemented by the Adapter Foundation Classes only and does not require any implementation from discovery service instances.
MetadataConnection uses the managed connection factory to create the connection to the EIS. The configuration properties specified by the user are mapped to the managed connection factory. AgetConnection() call is placed to obtain an EIS connection.
Besides the physical connection it represents, MetadataConnection also has a handle to the ConnectionType and OutboundConnectionConfiguration.
Once the connection is established, enterprise metadata discovery makes the request to get the MetadataTree from the MetadataDiscovery implementation. If there is a filter PropertyGroup specified at the MetadataTree you are prompted enter those properties.
MetadataTree model
The enterprise metadata discovery tool displays a MetadataTree model that represents an object structure in the EIS. The display also reflects your enterprise metadata discovery service implementation and filters that you can apply to the MetadataTree model to improve usability.
The structure of the MetadataTree reflects not only the EIS business data but also your enterprise metadata discovery implementation. For example, one implementation might display the properties of the nodes or MetadataObject in the MetadataTree model. Another implementation might display function parameters as nodes in the MetadataTree model.
IBM WebSphere recommends displaying the leaf-level properties in the model only if there is an advantage to doing so. In most cases, simple properties or function parameters should not be added as nodes in the tree. The description of the node representing the object or the function should provide information about the node. For example, in an EIS where function overloading is possible, the function description for the node should show enough parameter information to make the right import selection.
To improve usability, provide filters on MetadataTree models as applicable. For example, if the EIS contains many objects and is difficult to search, a filter might help. A best practice recommendation is to provide an option of inbound or outbound as a filter property for the MetadataTree. Doing so restricts the objects selected to one type for each discovery service pass. Where the same objects are used for inbound and outbound, skip this property and define it after choosing objects for MetadataSelection.
See the WBIMetadataTreeImpl in Javadoc.
MetadataSelection
MetadataSelection is a container that holds objects and properties that you select to guide or filter enterprise metadata discovery.
In addition to object selection, MetadataSelection also holds properties that are applicable for the selected objects. Such properties include the following:
- Specification of service type: inbound or outbound
- Namespace for use by business object definitions
- ConnectionType that for use at run time.
This step is required if the ConnectionType at run time differs from that for metadata discovery. Regardless, IBM WebSphere recommends a different connectionType for metadata than for run time. The metadata connectionType should contain properties needed to perform the discovery only. The runtime connectionType should contain resource adapter, managed connection factory, or ActivationSpecWithXid properties.
Implement the discovery service to reuse properties ( username, password) from the MetadataSelection connectionType wherever possible. You can specify other properties after the service description is created, when the tool checks whether artifact properties have been specified.
MetadataObject
The MetadataObject represents the node of the MetadataTree. You define properties and filters in this object that help guide enterprise metadata discovery.
IBM WebSphere recommends specified objectProperties that suggest the EIS objects you are defining. You should also define filter properties in MetadataObject that might make fetching of child objects more efficient and usable. For example, for JDBC, if the node represents a schema, you might define a filter to fetch tables by name rather than fetching all tables.
Enterprise metadata discovery description APIs
The enterprise metadata discovery description APIs comprise the objects that correspond to the artifacts generated by the discovery process. The artifacts include business object XSDs, the SCA import, and export files and WSDL files.
The description APIs embody the service metadata generated by the discovery service in response to import requests. The high-level model for this information includes the following:
- ServiceDescription
- FunctionDescription
- DataDescription
- ConnectionDescription
Service, function, and data descriptions are present for both inbound and outbound services. The models for the connection and function descriptions differ slightly for inbound and outbound (for consistency with the JCA 1.5 specification). The data description is identical for both inbound and outbound.
Service descriptions
You extend abstract service description classes and implement methods to define a service description for an inbound or outbound object.
You can specify a service description for inbound or outbound connections. The objects you select are maintained by the MetadataSelection object. The MetadataSelection is passed to the discovery service implementation to complete the import. The Adapter Foundation Classes provide an implementation for ServiceDescription as abstract classes. Discovery service implementations should extend these classes and implement the abstract methods
Inbound service descriptions
Enterprise metadata discovery service implementations should provide the following information for an inbound service description.
- Service name - The implementation must provide a default service name, ( PeopleSoftInboundService), but you can specify this property.
- Inbound connection description - This is the connection description for inbound, typically resource adapter and Activation Spec beans
- Function list - These represent the methods and functions that can be invoked through the inbound connection. An inbound function description describes the interface for each of these methods.
- EIS function selector - A function selector is a class provided by the adapter developer or the Integration Designer that takes as input the message received from the adapter and returns the name of the EIS function the message represents. This is used by the SCA run time to determine which method to invoke on the next SCA component. The JCA adapters would use the base class implementation of FunctionSelector. The default value for this property is the name of Generic Function selector provided by the Adapter Foundation Classes. The discovery service can override the default value.
Function selector
The function selector provides a unique name for the EIS function name. Due to SCA restrictions, method overloading cannot be used in interface definitions. Accordingly, you cannot have two methods with same name but which accept different arguments. For most inbound descriptions, the method name and the EIS function name are identical.
The base class FunctionSelector creates the EIS function name based on whether the input object is an AfterImage or a Delta. If a delta, then the name returned is emitDelta_business_object_name; if an AfterImage, then name returned is emit_TopLevelVerb_AfterImage_busineess_object_name.
See Business object names for more information about naming business objects.
Outbound service descriptions
Discovery service implementations must provide the following information for outbound service descriptions.
- Service name - The implementation must provide a default service name.
- Outbound connection description - This is the connection description for outbound, typically resource adapter and Activation Spec beans
- Function list - These represent the methods and functions that can be called by the client. An Outbound Function Description describes the interface for each of these methods.
Connection descriptions
You must provide EIS connection descriptions for the enterprise metadata discovery service. Adapter Foundation Classes contain interface implementations to help you get started.
Like ServiceDescription, ConnectionDescription can be either inbound or outbound service. Adapter Foundation Classes provide implementation for ConnectionDescription interfaces. Discovery service implementations need not implement these interfaces.
Inbound Connection Description
The following information must supplied by the discovery service implementations:
- ResourceAdapter - This is an instance of the ResourceAdapter JavaBeans that will be used to configure a resource adapter instance.
- ActivationSpecWithXid - This is an ActivationSpecWithXid instance that will be passed to ResourceAdapter.endpointActivation() at run time to support the methods defined on the inbound service.
Outbound Connection Description
The following information must supplied by the discovery service implementations
- ResourceAdapter - This is an instance of the ResourceAdapter JavaBeans that will be used to configure a resource adapter instance.
- ManagedConnectionFactory - This is an instance of the ManagedConnectionFactory JavaBeans that will be used to configure an instance of the ManagedConnectionFactory at run time for creating outbound connections.
Function descriptions
Function descriptions apply to either inbound or outbound service. The Adapter Foundation Classes provide implementations for the FunctionDescription interfaces. Discovery service implementations need not implement these interfaces.
Inbound Function Description
The following information has to be filled in by the discovery service implementations:
- Name - for example, emitDeltaCustomer or emitCreateAfterImageCustomer
- EIS Function Name - the name of the function that would be returned by function selector. For example, emitDeltaCustomer or emitCreateAfterImageCustomer
- Input - input data description representing the object that is input to the method
- Output - output data description representing the object that is returned by the method. This would be null for JCA adapters as they support only One-way interaction style.
- MetadataImportConfiguration - Handle to the metadata import configuration or the object that was selected by the user which lead to creation of this method description.
See "Inbound Operation Signatures" in Standard operations for descriptions of the inbound operation signatures and scenarios for their use.
Outbound Function Description
The following information has to be filled in by the discovery service implementations:
- Name - for example, createCustomer, applyChangesCustomer
- InteractionSpec - Instance of interaction spec which has function name specified that represents this method description. For example, for createCustomer the function name would be 'Create'.
- Input - input data description representing the object that is input to the method
- Output - output data description representing the object that is returned by the method.
- MetadataImportConfiguration - Handle to the metadata import configuration or the object that was selected by the user which lead to creation of this method description.
See "Outbound Operation Signatures" in Standard operations for descriptions of the outbound operation signature and scenarios for their use.
Data descriptions
The data description implementation enables the adapter to create valid data objects for EIS requests and to interpret the objects returned as responses. You must implement DataDescription, InboundServiceDescription, and OutboundServiceDescription.
DataDescription
The data description is common to inbound and outbound service. It includes a definition of the structure and content of adapter business objects that will be passed between the client and adapter at run time. Each DataDescription instance should have a unique namespace. The convention followed by IBM is to use a base namespace concatenated by the name of the corresponding object.
InboundServiceDescription
The InboundServiceDescription must have a default name and associated function descriptions. The standard top-level operations are described in Inbound Operation Signatures. InboundFunctionDescription should use the same functionName and EISFunctionName.
If needed, the default FunctionSelector can be overridden.
OutboundServiceDescription
The OutboundServiceDescription must have a default name, along with associated function descriptions. The supported, standard top-level operations are described in the Outbound operation signatures table in Standard operations.
Adapters that can provide functionality above and beyond these standard operations can opt to expose unique, EIS-specific operations, giving customers access to more functionality of the EIS. Define names and behavior on a case-by-cases basis to most accurately reflect the functionality of the underlying EIS.
To limit confusion, custom operation names should not conflict with the standard operation names mentioned above.
In cases where the mapping of EIS operations to Create, Retrieve, Update and Delete is equivalent except for naming conventions–for example, PeopleSoft has a Find operation that is functionally equivalent to a Retrieve–the EIS-specific operation should not be exposed since it adds no value.
Function-based adapters occasionally may be required to perform multiple individual EIS operations to achieve the equivalent of a single Create, Retrieve, Update, or Delete operation. IBM WebSphere recommends these low-level EIS operations also be exposed so that users are free to compose equivalent operations.
Business object structures for enterprise metadata discovery
In the Adapter Foundation Classes, BusinessObject and its BusinessObjectAttribute and Metadata structures facilitate the generation of XML schema definitions.
The Adapter Foundation Classes allow discovery service implementations to use Java™ APIs to prepare the BusinessObject structure. This BusinessObject structure can then be serialized to create an XML schema document string. This will reduce the effort for individual discovery service implementations, as they do not use XML parsers or general string concatenation functions to prepare the XML schema definitions.
BusinessObject
BusinessObject contains properties and methods that help the discovery service generate object definitions.
The discovery service must provide the following for BusinessObject:
- Name – For example, PURCHASEORDER
- BusinessObjectAttributes
- Namespaces – These name spaces are added to the XSD definition.
- TargetNameSpace – For example, http://www.ibm.com/xmlns/prod/websphere/j2ca/peoplesoft/purchaseorder.
- ImportedNameSpaces – These name spaces would be added as <import.. in XSD.
- IncludeNameSpaces – These name spaces would be added as <include.. in XSD.
- TopLevel – Boolean if business object is TopLevel and needs a business graph definition
- Metadata – Metadata object representing the business object level application-specific information.
BusinessObject provides two methods:
- Serialize – To obtain the XSD string for the object.
- getGraphDefinition – To obtain the business graph definition for a top-level business object.
BusinessObjectAttribute
BusinessObjectAttribute provides information that further defines the business object for the discovery service.
The discovery service must provide the following for BusinessObjectAttribute:
- Name – For example, VENDORID
- Type – For example, string
- Cardinality – 1 or N
- Required – Boolean
- ObjectTypeName – For cases where an attribute maps to an object for example, porecord:PORECORD.
- Max Length
- Metadata – the MetadataObject representing attribute-level application-specific information.
ImportedNamespace
ImportedNamespace describes the names that must be imported into the business object definition.
This class represents the import statement in the XML schema definition. There are two properties that discovery service must provide:
- NameSpace – The name that must be imported
- Location – The location of the file that must be imported
Metadata
The metadata component describes information about a business object definition and its attributes.
The business object and attribute level metadata should be modeled using this component. The discovery service must provide the following information for this object:
- Source – Added in the application-specific information statement. For example, WBI.
- NameSpace – Added to application-specific information clause.
- Name-value pairs for application-specific information properties (HashMap). – For example,pasi:Getter value getObjectName
Namespace definition
The namespace http://www.ibm.com/xmlns/prod/websphere/j2ca is reserved for XML artifacts produced by or employed by WebSphere Adapters.
Adapters should use http://www.ibm.com/xmlns/prod/websphere/j2ca/<adapter_name> for any adapter-specific artifacts generated during the metadata import process; for example, http://www.ibm.com/xmlns/prod/websphere/j2ca/peoplesoft.
For Business Objects the name of the business object should be appended to the base name space; for example,http://www.ibm.com/xmlns/prod/websphere/j2ca/peoplesoft/purchaseorder.
For ASI schema the target namespace used must be http://www.ibm.com/xmlns/prod/websphere/j2ca/peoplesoft/metadata.
Implementing enterprise metadata discovery classes
The following subsections describe the steps and constructs required for implementing an enterprise metadata discovery instance.
BootStrap
IBM Integration Designer performs a bootstrap step to identify a resource adapter that has been enabled for enterprise metadata discovery service.
To identify a resource adapter that is enabled for metadata discovery service, IBM Integration Designer launches a bootstrap step to find a discovery-service.xml file. This file should be in the META-INF folder for the resource adapter. An example of this file is found in the sample delivered with the WebSphere Adapter Toolkit.
Resource bundles
Resource bundle files capture properties and logging and tracing messages that are germane to an enterprise metadata discovery implementation.
Each enterprise metadata discovery implementation must have two resource bundle files. One captures the property group and property names and descriptions for properties displayed by IBM Integration Designer tooling. The other is for messages written to the log file for tracing. The bundle names must follow the convention of including the EMD.properties file in the enterprise metadata discovery package as shown in the following examples:
- com.<company name>.j2c.<app name>.emd.EMD.properties to capture resource bundles for property groups
- com.<company name>.j2c.<app name>.emd.LogMessages.properties to capture logging and tracing resource bundles.
The property groups representing resource adapter, managed connection factory, and the Activation Specification must have property names matching their bean properties.
Property groups
All the properties used in the discovery service are represented by the PropertyGroup set of interfaces.
A property group is a collection of properties. A property group can be associated with the Inbound- and OutboundConnectionConfiguration, MetadataTree, nodes of the MetadataTree (MetadataObject and MetadataSelection). PropertyGroup supports nesting and can therefore include child PropertyGroups. It also provides a listener and an event interface to trickle changes from one property into another property or property group.
The Adapter Foundation Classes provide a complete implementation of the PropertyGroupAPIs. Individual discovery service implementations should not implement these APIs.
The key properties of this API set are as follows:
- SingleValuedProperty – Allows a single property of any Java™ type. It includes attributes such as required, sensitive, hidden, primitive, default value, and valid values.
- MultiValuedProperty – Allows a property to be represented as a list of values. For example, you can represent the operations for a BusinessObject using this type of property and then make multiple selections.
- PropertyGroup – A collection of properties including single and multi types and PropertyGroup itself. For example, OutboundConnectionConfiguration allows three property groups in one Main property group: UserConfiguration that includes Username and Password; MachineConfiguration that includes Hostname and PortNo; and Miscellaneous that includes other properties such as Prefix and DirectoryName.
- PropertyChangeListener – Used when a property change affects some other property or property group. This can be associated to any property or a property group. Each property can, in turn, have associated listeners that it can notify when a change happens. For example, Property A default value must change when Property B's value changes. Accordingly, the PropertyChangeListener that references Property A will be added to the listener list for Property B. When property B is changed in the set method, propertyChange can be fired on all listeners in the list. This will lead to changes in Property A.
- PropertyChangeEvent – An event that would be passed when propertyChange is fired on PropertyChangeListener. It includes the type of change, such as PROPERTY_VALUE_CHANGE, PROPERTY_ENABLED, PROPERTY_DISABLED, PROPERTY_VALID_VALUES_CHANGE, OLD_VALUE, NEW_VALUE, and SOURCE_OF_CHANGE.
- TableProperty A property representing a table with rows and columns. Each column is represented by the PropertyDescriptor instance and each cell corresponding to a given row and column is represented by a SingleValuedProperty implementation.
- TreeProperty A property representing a tree of selectable nodes. Each node is represented by a NodeProperty implementation which can be selected, highlighted and can have configuration properties represented by a PropertyGroup instance.
8.7.10. Enterprise metadata discovery implementation samples
The following section explains a few EIS Simulator Adapter code samples, to implement an enterprise metadata discovery.
For more detailed information, refer to the EIS Simulator Adapter code samples that are delivered with WebSphere Adapter Toolkit, to implement an enterprise metadata discovery.
8.7.10.1. Logging and Tracing
This describes the logging and tracing implementation for enterprise metadata discovery.
Use the WBIMetadataDiscoveryImpl.getLogUtils() call to acquire an LogUtils instance. Then use the appropriate method to perform logging and tracing.
8.7.10.2. Property group sample
Use the property group APIs to create property groups required for an enterprise metadata discovery implementation.
To enable validation of specific properties, extend the WBISingleValuedPropertyImpl or WBIMultiValuedPropertyImpl and then implement the vetableChange() method. Any validation can be performed in this code. In case of failures, PropertyVetoException must be thrown.
You must implement a propertyChange() method, if one property needs to support another property type. For more details, check the EIS Simulator Adapter code samples for the ServiceTypeSingleProperty.
To enable the function of both vetoableChange and propertyChange, the instance of the property should be added to thepropertyChangeListener list. In the EISSConnectionFactoryMetadataSelection class in the EIS Simulator Adapter code sample, the operations property supports theserviceType property.
WBIMultiValuedPropertyImpl operationProp = new WBIMultiValuedPropertyImpl ("Operations", String.class); operationProp.setDisplayName("Operations"); operationProp.setDescription("Operations"); operationProp.setRequired(true); String[] operations=null; if(serviceType.equals(MetadataConfigurationType.INBOUND_SERVICE.toString())){ operations = new String[3]; operations[0] ="Create"; operations[1] ="Update"; operations[2] ="Delete"; }else{ if(artifactType.equals(MetadataConfigurationType.GENERATED_DATA_BINDING.toString ())){// is WPS operations = operationsWPS; }else{ operations = operationsNonWPS; } } operationProp.setValidValues(operations); for(int idx=0;idx.operations.length;idx++){ operationProp.addValue(operations[idx]); } pg.addProperty(operationProp); //Copy the applied properties to the new instance if (getAppliedSelectionProperties() != null) EMDUtil.copyValues(getAppliedSelectionProperties(), pg); } catch (MetadataException e) { throw new RuntimeException(e.getMessage()); } return pg;}
8.7.10.3. Progress monitor sample
For enterprise metadata discovery processes that are time-consuming–such as retrieving information from an EIS and building MetadataObject instances–you can use the progress monitor.
While you are running the discovery service, the progress monitor can capture information about current processes and allow you to cancel operations. You can locate a handle to ProgressMonitor using the following:WBIMetadataDiscovery.getLogUtils().getProgressMonitor(). As a process elapses, you can use the setProgress() method to set progress levels that approach a specified maximum as shown below:
WBIMetadataConnectionImpl.getToolContext().getProgressMonitor().setMaximum(100); WBIMetadataConnectionImpl.getToolContext().getProgressMonitor().setMinimum(0); WBIMetadataConnectionImpl.getToolContext().getProgressMonitor().setProgress(50); WBIMetadataConnectionImpl.getToolContext().getProgressMonitor().setNote ("Getting namespace from Peoplesoft");
8.7.10.4. WBIMetadataDiscoveryImpl sample
WBIMetadataDiscoveryImpl is the main entry class for invoking enterprise metadata discovery.
Interaction between the enterprise metadata discovery service and an EIS originates in an implementation of the WBIMetadataDiscoveryImpl class. You must implement the methods described below.
Constructor
The constructor should call super(Bundle Name). The bundle name is the name of the resource bundle for property-group properties of the enterprise metadata discovery; for example: super("com.abc.j2c.testapp.emd"). When creating resource bundles the EMD.properties and LogMessages.properties should share the same package name.
public EISSAMetadataDiscovery() throws MetadataException { super("com.ibm.j2ca.eissa.emd"); helper = new PropertyNameHelper(null, "com.ibm.j2ca.eissa.emd", null); }The WBIAdapterTypeImpl constructor requires the following parameters:
- The name of the class representing the ResourceAdapter class.
This is used to create property groups for ResourceAdapter in enterprise metadata discovery.
- Number of outbound connections
- Number of inbound connections
getAdapterTypeSummaries
Set supportedInMetadataService to true for connections that you want IBM Integration Designer to display when performing enterprise metadata discovery. Add the connections to adapterType using the add<Inbound/Outbound>ConnectionType() method:
public AdapterTypeSummary[] getAdapterTypeSummaries() throws MetadataException { if (helper.getLogUtils().isTraceEnabled(Level.FINE)) helper.getLogUtils().traceMethodEntrance("EISSAMetadataDiscovery", "getAdapterTypeSummaries"); adapterType = new WBIAdapterTypeImpl ("com.ibm.j2ca.eissa.EISSAResourceAdapter", 2, 1); adapterType.setDescription("VTA"); adapterType.setDisplayName("VTA"); adapterType.setId("VTA"); adapterType.setVendor("IBM"); adapterType.setVersion("6.1"); EISSAOutboundConnectionType outConnTypeForMetadata = new EISSAOutboundConnectionType (adapterType, helper); outConnTypeForMetadata.setIsSupportedInMetadataService(true); outConnTypeForMetadata.setIsSupportedAtRuntime(false); outConnTypeForMetadata.setManagedConnectionFactoryJavaBean ("com.ibm.j2ca.eissa.outbound.EISSAManagedConnectionFactory"); outConnTypeForMetadata.setResourceAdapterJavaBean ("com.ibm.j2ca.eissa.EISSAResourceAdapter"); adapterType.addOutboundConnectionType(outConnTypeForMetadata); EISSAOutboundConnectionType outConnTypeForRuntime = new EISSAOutboundConnectionType(adapterType, helper); outConnTypeForRuntime.setIsSupportedInMetadataService(false); outConnTypeForRuntime.setIsSupportedAtRuntime(true); outConnTypeForRuntime.setManagedConnectionFactoryJavaBean ("com.ibm.j2ca.eissa.outbound.EISSAManagedConnectionFactory"); outConnTypeForRuntime.setResourceAdapterJavaBean ("com.ibm.j2ca.eissa.EISSAResourceAdapter"); adapterType.addOutboundConnectionType(outConnTypeForRuntime); EISSAInboundConnectionType inConnTypeForRuntime = new EISSAInboundConnectionType(adapterType, helper); inConnTypeForRuntime.setResourceAdapterJavaBean ("com.ibm.j2ca.eissa.EISSAResourceAdapter"); inConnTypeForRuntime.setActivationSpecJavaBean ("com.ibm.j2ca.eissa.inbound.EISSAActivationSpecWithXid"); adapterType.addInboundConnectionType(inConnTypeForRuntime); return new WBIAdapterTypeImpl[] { adapterType }; }
getAdapterType
This method returns the instance of adapterType for a given ID. If the enterprise metadata discovery implementation supports only one adapterType, then it returns either that ID or the input ID.
getMetadatatree
This method returns an instance of the WBIMetadataTreeImpl implementation. Each enterprise metadata discovery implementation extends the WBIMetadataTreeImpl class and an instance of that class is returned from this method.
public MetadataTree getMetadataTree(MetadataConnection conn) throws MetadataException { this.connection = (WBIMetadataConnectionImpl) conn; connType = (WBIOutboundConnectionTypeImpl) connection.getConnectionType(); EISSAMetadataTree tree = new EISSAMetadataTree(connection, helper); tree.setSelectionStyle(MetadataTree.MULTI_SELECT); return tree; }
createServiceDescription
This class returns an instance of the inbound or outbound service description, depending on which input selection is set.
You might usefully iterate through import configurations in the MetadataSelection set and then use the properties specified on MetadataSelection to complete the service description.
The instance of ServiceDescription created should be filled in with name, namespace, function description and configurations as shown below. The method copyPropertyValues(), defined on connection configurations, copies the properties that match between the connection configuration that was used to perform discovery and the one that used for run time. The copy is based on names. For example, if a property name Username exists in the configuration used for discovery and that used for run time, the Username value is copied.
public ServiceDescription createServiceDescription (MetadataSelection importSelection) throws MetadataException { ServiceDescription description = null; WBIMetadataSelectionImpl selection = (WBIMetadataSelectionImpl) importSelection; MetadataImportConfiguration[] confArray = selection.getSelection(); if (confArray.length == 0) return description; super.getLogUtils().trace(Level.FINER, CLASSNAME, "createServiceDescription()", "Number of MetadataImportConfigurations " + confArray.length); PropertyGroup serviceType = selection.getAppliedSelectionProperties(); String directionality = getDirectionality(serviceType); String nameSpace = getNameSpace(serviceType); boolean inbound = false; if (directionality.equals("Inbound")) { super.getLogUtils().trace(Level.FINER, CLASSNAME, "createServiceDescription()", "Selected Service Type is:Inbound"); inbound = true; } if (inbound) { description = createInboundServiceDescription (importSelection, selection, nameSpace); } else { description = createOutboundServiceDescription (importSelection, selection, nameSpace); } return description; }
setToolContext
To implement setToolContext(), initialize the LogUtils instance and set it on the Foundation Class WBIMetadataDiscoveryImpl.
public void setToolContext(ToolContext toolContext) { super.setToolContext(toolContext); try { AdapterType adapterType = new WBIAdapterTypeImpl("com.ibm.j2ca.eissa.EISSAResourceAdapter", 2, 1);LogUtils logUtils = new LogUtils(toolContext.getLogger(), "com.ibm.j2ca.eissa.emd", adapterType.getId(), adapterType.getVersion()); LogRecord record = new LogRecord(Level.FINEST, "Entering setToolContext"); toolContext.getLogger().log(record); helper.setLogUtils(logUtils); helper.setToolContext(toolContext); super.setLogUtils(logUtils); } catch (Exception e) { throw new RuntimeException(e.getMessage()); } }
8.7.10.5. WBIAdapterTypeImpl sample
You use this class to implement the adapter type for enterprise metadata discovery.
Extend WBIAdapterTypeImpl and implement the methods described in the sections below.
Constructor
The constructor populates the adapter type instance as shown below:
public <AdapterPrefixName>AdapterType()throws MetadataException{ super(Constants.RESOURCE_ADAPTER_BEAN_NAME, 2, 1); setId(Constants.ADAPTER_NAME); setDisplayName(Constants.ADAPTER_NAME); setDescription(WBIMetadataDiscoveryImpl.getPropertyDescription (ADAPTERTYPE_PROPERTY)); setVendor(VENDOR); setVersion(VERSION); setOutboundConnections(); setInboundConnections();}
setInboundConnections
The setInboundConnections() method sets the inbound connections on the adapter type.
private void setInboundConnections() throws MetadataException { <AdapterPrefixName>InboundConnectionType inConnTypeForRuntime = new <AdapterPrefixName>InboundConnectionType(this); addInboundConnectionType(inConnTypeForRuntime); inConnTypeForRuntime.setResourceAdapterJavaBean (Constants.RESOURCE_ADAPTER_BEAN_NAME); inConnTypeForRuntime.setActivationSpecJavaBean (Constants.ACTIVATION_SPEC);}
setOutboundConnections
This method sets the outbound connections on the adapter type. The connection type that can be used to perform discovery should be set to true for IsSupportedInMetadataService and connections that can be used for run time should be set to true for IsSupportedAtRuntime.
You might find it preferable to have separate connection types for enterprise metadata discovery and for run time. This way the property group for discovery can display properties needed to perform the discovery and not the entire set of properties describing ResourceAdapter and ManagedConnectionFactory properties.
private void setOutboundConnections() throws MetadataException { <AdapterPrefixName>OutboundConnectionType outConnTypeForRuntime = new <AdapterPrefixName>OutboundConnectionType(this); <AdapterPrefixName>OutboundConnectionType outConnTypeForMetadata = new <AdapterPrefixName>OutboundConnectionType(this); addOutboundConnectionType(outConnTypeForMetadata); addOutboundConnectionType(outConnTypeForRuntime); outConnTypeForMetadata.setManagedConnectionFactoryJavaBean (Constants.MANAGED_CONNECTION_FACTORY_NAME); outConnTypeForRuntime.setManagedConnectionFactoryJavaBean (Constants.MANAGED_CONNECTION_FACTORY_NAME); outConnTypeForMetadata.setResourceAdapterJavaBean (Constants.RESOURCE_ADAPTER_BEAN_NAME); outConnTypeForRuntime.setResourceAdapterJavaBean (Constants.RESOURCE_ADAPTER_BEAN_NAME); outConnTypeForMetadata.setIsSupportedInMetadataService(true); outConnTypeForMetadata.setIsSupportedAtRuntime(false); outConnTypeForRuntime.setIsSupportedInMetadataService(false); outConnTypeForRuntime.setIsSupportedAtRuntime(true);}
8.7.10.6. WBIOutboundConnectionTypeImpl samples
WBIOutboundConnectionTypeImpl represents the outbound connection types supported by the adapter. The mapping of these connection types corresponds to the managed connection factory types that are supported by the adapter. Each managed connection factory maps to an instance of outbound connection types.
Each enterprise metadata discovery implementation should extend WBIOutboundConnectionTypeImpl and implement the methods described below.
Constructor
The constructor takes the adapterType argument, and then sets the ID, and the description and display names. If the description and display names must be globalized, they can be retrieved from the resource bundle EMD.properties using the method WBIMetadataDiscoveryImpl.getString(<prop name>).
public EISSAOutboundConnectionType(WBIAdapterTypeImpl adapterType,PropertyNameHelper helper) throws MetadataException { super(adapterType, helper); this.helper = helper; setDescription("Connection to VTA system"); setDisplayName("VTA Connection"); setId("VTA"); }
createOutboundConnectionConfiguration
The createOutboundConnectionConfiguration() method returns an instance of OutboundConnectionConfiguration. Each enterprise metadata discovery implementation must extend WBIOutboundConnectionConfugurationImpl and an instance of that class should be returned in this method.
public OutboundConnectionConfiguration createOutboundConnectionConfiguration() { try { if (conf == null) conf = new EISSAOutboundConnectionConfiguration(this,helper); } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } }
8.7.10.7. WBIInboundConnectionTypeImpl samples
WBIInboundConnectionTypeImpl represents the inbound connection types supported by the adapter. The mapping of connection types corresponds to the activationSpec types that are supported by the adapter. Each activationSpec will map to an instance of inbound connection types.
Each enterprise metadata discovery implementation should extend WBIInboundConnectionTypeImpl and implement the methods described below.
Constructor
The constructor takes the adapterType argument, setting the ID and the description and display names. You can retrieve the description and display names from the resource bundle EMD.properties using method WBIMetadataDiscoveryImpl.getString(<prop name>) (if they must be globalized).
public EISSAInboundConnectionType(WBIAdapterTypeImpl adapterType,PropertyNameHelper helper) throws MetadataException { super(adapterType); this.helper = helper; }
createInboundConnectionConfiguration
The createInboundConnectionConfiguration() method returns an instance of InboundConnectionConfiguration. Each enterprise metadata discovery implementation extends WBIInboundConnectionConfugurationImpl and an instance of that class is returned in this method.
public InboundConnectionConfiguration createInboundConnectionConfiguration() { try { if (conf == null) conf = new EISSAInboundConnectionConfiguration(this,helper); } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } return conf; }
8.7.10.8. WBIOutboundConnectionConfigurationImpl samples
You use this class to specify outbound connection configuration properties, including those for ResourceAdapter and ManangedConnectionFactory, for your enterprise metadata discovery implementation.
Extend WBIOutboundConnectionConfigurationImpl requires that you implement the methods described below. Note that all methods that create instances of property groups should initialize them with the applied properties. You can do this with a utility method provided in the EMDUtil class as shown below after successfully constructing the property group.
if (getAppliedProperties() != null) EMDUtil.copyValues(getAppliedProperties(), adapterProp);
Constructor
The constructor accepts ConnectionType.
public EISSAOutboundConnectionConfiguration(WBIOutboundConnectionTypeImpl connType, PropertyNameHelper helper) throws MetadataException { super(connType, helper); this.helper = helper; }
createUnifiedProperties
The createUnifiedProperties() method returns an instance of property group that represents ManagedConnectionFactory and ResourceAdapter properties together in a consolidated property group. Property groups required for discovery might differ from those needed at run time. Accordingly, this method can check isSupportedInMetadataService and then create the corresponding property groups. IBM Integration Designer uses this method to display the first connection configuration screen for enterprise metadata discovery.
public PropertyGroup createUnifiedProperties() { WBIPropertyGroupImpl propGroup = null; try { if (this.getOutboundConnectionType().isSupportedInMetadataService()) { propGroup = new WBIPropertyGroupImpl("Connection Properties"); propGroup.setDisplayName(helper.getPropertyName("ConnectionProperties")); propGroup.setDescription(helper.getPropertyDescription("ConnectionProperties")); WBIFolderProperty propFolder = new WBIFolderProperty("XSDFolder", java.io.File.class); propFolder.setRequired(true); propFolder.setMustExist(true); propFolder.setDisplayName(helper.getPropertyName("XSDFolder")); propFolder.setDescription(helper.getPropertyDescription("XSDFolder")); propGroup.addProperty(propFolder); } else { propGroup = (WBIPropertyGroupImpl) createManagedConnectionFactoryProperties(); PropertyGroup adapterProp = createResourceAdapterProperties(); if(adapterProp != null){ WBISingleValuedPropertyImpl logProp = (WBISingleValuedPropertyImpl) adapterProp.getProperties()[0]; if (logProp != null) { logProp.setValue(EISSAConstants.VTA_ADAPTERID); } propGroup.addProperty(adapterProp); } } if (this.getOutboundConnectionType().isSupportedInMetadataService() && (getAppliedProperties() != null)) { EMDUtil.copyValues(getAppliedProperties(), propGroup); } } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } return propGroup; }
createResourceAdapterProperties
The createResourceAdapterProperties method returns an instance of PropertyGroup that represents properties you can configure for the ResourceAdapter bean. The getPropertyGroup() method, provided in the EMDUtil class, fetches the properties for the base class WBIResourceAdapter bean. Then the enterprise metadata discovery implementation can add its own specific properties to the ResourceAdapter bean class.
public PropertyGroup createResourceAdapterProperties() { WBIPropertyGroupImpl propGroup = null; try { EISSAResourceAdapter ra = new EISSAResourceAdapter(); EMDUtil util = new EMDUtil(); propGroup = (WBIPropertyGroupImpl) util.getPropertyGroup(ra, helper); propGroup.setExpert(true); if (getAppliedProperties() != null && propGroup != null) EMDUtil.copyValues(getAppliedProperties(), propGroup); } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } return propGroup; }
createManagedConnectionFactoryProperties
The createManagedConnectionFactoryProperties method returns an instance of PropertyGroup that represents properties that you can configure for the ManagedConnectionFactory bean. The getPropertyGroup() method, provided in the EMDUtil class, fetches the properties for the base class WBIManagedConnectionFactory bean. As with the ResourceAdapter bean, the enterprise metadata discovery implementation can add its own specific properties to the ManagedConnectionFactory bean class.
public PropertyGroup createManagedConnectionFactoryProperties() { WBIPropertyGroupImpl propGroup = null; try { propGroup = new WBIPropertyGroupImpl("Connection Properties"); propGroup.setDisplayName(helper.getPropertyName("ConnectionProperties")); propGroup.setDescription(helper.getPropertyDescription("ConnectionProperties")); WBIPropertyGroupImpl mcPG = new WBIPropertyGroupImpl("MachineCredentials", helper); mcPG.setDisplayName(helper.getPropertyName("MachineCredentials")); mcPG.setDescription(helper.getPropertyDescription("MachineCredentials")); WBISingleValuedPropertyImpl prop = new WBISingleValuedPropertyImpl ("Hostname", String.class); prop.setRequired(true); prop.setDisplayName(helper.getPropertyName("HostName")); prop.setDescription(helper.getPropertyDescription("HostName")); prop.setValue("localhost"); mcPG.addProperty(prop); prop = new WBISingleValuedPropertyImpl("Portnumber", String.class); prop.setRequired(true); prop.setDisplayName(helper.getPropertyName("Port")); prop.setDescription(helper.getPropertyDescription("Port")); prop.setValue("9000"); mcPG.addProperty(prop); propGroup.addProperty(mcPG); if (getAppliedProperties() != null) EMDUtil.copyValues(getAppliedProperties(), propGroup); } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } return propGroup; }
8.7.10.9. WBIInboundConnectionConfigurationImpl samples
You use this class to specify inbound connection configuration properties, including those for ActivationSpecWithXid, for your enterprise metadata discovery implementation.
This class is similar to WBIOutboundConnectionConfigurationImpl except instead of ManagedConnectionFactory, WBIInboundConnectionConfigurationImpl handles the ActivationSpecWithXid bean class. You must extend the methods described below.
public PropertyGroup createActivationSpecProperties() { WBIPropertyGroupImpl connProp = null; try { EMDUtil util = new EMDUtil(); connProp = (WBIPropertyGroupImpl) util.getPropertyGroup (new EISSAActivationSpecWithXid(), helper); WBISingleValuedPropertyImpl namespaceProp = (WBISingleValuedPropertyImpl) connProp.getProperty("BONamespace"); if (namespaceProp != null) connProp.remove(namespaceProp); WBIPropertyGroupImpl machineCredPG = new WBIPropertyGroupImpl("MachineCredentials", helper); machineCredPG.setDisplayName(helper.getPropertyName ("MachineCredentials")); machineCredPG.setDescription (helper.getPropertyDescription("MachineCredentials")); WBISingleValuedPropertyImpl prop = new WBISingleValuedPropertyImpl("Hostname", String.class); prop.setRequired(true); prop.setDisplayName(helper.getPropertyName("HostName")); prop.setDescription(helper.getPropertyDescription("HostName")); prop.setValue("localhost"); machineCredPG.addProperty(prop); prop = new WBISingleValuedPropertyImpl("Portnumber", String.class); prop.setRequired(true); prop.setDisplayName(helper.getPropertyName("Port")); prop.setDescription(helper.getPropertyDescription("Port")); prop.setValue("9000"); machineCredPG.addProperty(prop); connProp.addProperty(machineCredPG); if (getAppliedProperties() != null) util.copyValues(getAppliedProperties(), connProp,helper); } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } return connProp; }
8.7.10.10. WBIMetadataTreeImpl samples
WBIMetadataTreeImpl represents the object that holds the metadataObject nodes of the tree that IBM Integration Designer displays for enterprise metadata discovery.
Extend the WBIMetadataTreeImpl class and implement the methods described below.
Constructor
The constructor takes MetadataConnection as an argument. The constructor can also return properties from MetadataConnection that were used to start the discovery service; for example, prefix, directory name, and those properties that populate the MetadataObject nodes in the tree.
public EISSAMetadataTree(MetadataConnection connection,PropertyNameHelper helper) { super(connection,helper); this.helper = helper; WBIOutboundConnectionConfigurationImpl conf = (WBIOutboundConnectionConfigurationImpl) connection.getConnectionCofiguration(); PropertyGroup pg = conf.getAppliedProperties(); WBIFolderProperty xsdFilesPathProp = (WBIFolderProperty) pg.getProperty("XSDFolder"); xsdFolderPath = xsdFilesPathProp.getValue().toString(); }
createMetadataSelection
The createMetadataSelection() method returns an instance of the specific MetadataSelection class. The enterprise metadata discovery implementation extends WBIMetadataSelectionImpl and returns an instance of that class in this method.
public MetadataSelection createMetaDataSelection() { return new EISSAMetadataSelection(); }
createFilterProperties
The createFilterProperties() method returns a property group instance used to perform filtering for nodes of the tree. This filter is used for displaying top-level nodes on the tree only.
public PropertyGroup createFilterProperties() { WBIPropertyGroupImpl propertyGroup = null; try { propertyGroup = new WBIPropertyGroupImpl (Constants.SELECTION_PROPERTIES); propertyGroup.setDisplayName (WBIMetadataDiscoveryImpl.getPropertyName (Constants.SELECTIONPROPERTIES)); propertyGroup.setDescription (WBIMetadataDiscoveryImpl.getPropertyDescription (Constants.SELECTIONPROPERTIES)); WBISingleValuedPropertyImpl typeProp = new WBISingleValuedPropertyImpl (Constants.SERVICETYPE, String.class); String[] values = { Constants.INBOUND, Constants.OUTBOUND }; typeProp.setValidValues(values); typeProp.setDefaultValue(Constants.OUTBOUND); typeProp.setDisplayName (WBIMetadataDiscoveryImpl.getPropertyName (Constants.SERVICETYPE)); typeProp.setDescription (WBIMetadataDiscoveryImpl.getPropertyDescription (Constants.SERVICETYPE)); propertyGroup.addProperty(typeProp); WBISingleValuedPropertyImpl nameSpaceProp = new WBISingleValuedPropertyImpl (Constants.NAMESPACE, String.class); nameSpaceProp.setDefaultValue(Constants.TB_DEFAULT_NAMESPACE); propertyGroup.addProperty(nameSpaceProp); nameSpaceProp.setDisplayName (WBIMetadataDiscoveryImpl.getPropertyName (Constants.NAMESPACE)); nameSpaceProp.setDescription (WBIMetadataDiscoveryImpl.getPropertyDescription (Constants.NAMESPACE)); ServiceTypeSingleProperty operationProp = new ServiceTypeSingleProperty (Constants.OPERATIONS, String.class); String[] operations = <AdapterPrefixName>Operations.getOutboundOperations(); operationProp.setValidValues(operations); operationProp.setDisplayName (WBIMetadataDiscoveryImpl.getPropertyName (Constants.OPERATIONS)); operationProp.setDescription (WBIMetadataDiscoveryImpl.getPropertyDescription (Constants.OPERATIONS)); propertyGroup.addProperty(operationProp); } catch (MetadataException e) { throw new RuntimeException(e); } return propertyGroup; }
getMetadataObject
The getMetadataObject() method returns an instance of MetadataObject for a specific location. Each MetadataObject instance that is added to the MetadataTree should have a unique location such that when the tool calls this method, the enterprise metadata discovery implementation can find the corresponding MetadataObject and return it.
A sample implementation might usefully maintain a HashTable in MetadataTree and add the location and corresponding MetadataObject to it whenever a new instance of MetadataObject is added. Then this method could return an object corresponding to the key value from Hashtable .
public MetadataObject getMetadataObject(String locationId) { return (MetadataObject) treeNodes.get(locationId); }
listMetadataObjects
The listMetadataObjects() method returns an instance of WBIMetadataObjectResponseImpl. The instance should be populated with MetadataObjects using method setObjects(). The logic should use filter properties, if supported by the implementation. Any metadataObjects that can be selected for import should be set as true with the setIsSelectableForImport() method.
public MetadataObjectResponse listMetadataObjects(PropertyGroup filterParameters) throws MetadataException { WBIMetadataObjectResponseImpl response = new WBIMetadataObjectResponseImpl(); ArrayList objects = new ArrayList(); String[] fileNames = getFileNames(this.xsdFolderPath); String directory = new File(this.xsdFolderPath).getAbsolutePath(); if (!directory.endsWith(File.separator)) { directory = directory + File.separator; } String fileLocation = null; ArrayList objectsRegular = null; if (fileNames != null && fileNames.length > 0) { for (int i = 0; i < fileNames.length; i++) { try { fileLocation = directory + fileNames[i]; BOSchema schema = new BOSchema(fileLocation, WBIBiDiConstants.EMPTY_STR); Hashtable types = schema.getBOTypes(); File file = new File(fileLocation); FileInputStream fs = new FileInputStream(file); int size = fs.available(); byte[] bytes = new byte[size]; fs.read(bytes); objectsRegular = prepareSelectionObjectList(bytes, types, fileLocation); objects.addAll(objectsRegular); } catch (Exception e) { throw new MetadataException ("Unable to load objects " + e.getMessage(), e); } } } response.setObjects(objects); return response; }
8.7.10.11. WBIMetadataObjectImpl samples
WBIMetadataObjectImpl represents the nodes of the tree that IBM Integration Designerdisplays during enterprise metadata discovery. In most cases these nodes map to objects in the EIS the user selects to import a service description.
WBIMetadataObjectImpl should be extended and the following methods must be implemented.
createFilterProperties
The createFilterProperties() method returns an instance of a property group that represents properties that you can use to filter searches for child objects of a MetadataObject. For example, if the top level node is a schema for JDBC, you might fetch table names with a filter consisting of a specific alphabet sequence. Implementation should return null if such properties are not applicable. See WBIMetadataTreeImpl.createFilterProperties in the Javadoc.
createObjectProperties
The createObjectProperties() method returns a property group that provides information about the specific object in MetadataTree. This helps inform the user about the metadata object instance. Implementation should return null if such properties are not applicable.
getChildren
The getChildren() method returns an instance of WBIMetadataObjectResponseImpl. The instance should be populated with child MetadataObjects using method setObjects(). (This is comparable to the MetadataTree.listMetadataObjects call.) The logic should use filter properties, if are supported by the implementation.
public MetadataObjectResponse getChildren(PropertyGroup filterParameters) throws MetadataException { WBIMetadataObjectResponseImpl response = new WBIMetadataObjectResponseImpl(); ArrayList list = new ArrayList(); try { if (boType != null) { List children = boType.getChildren(); if (children != null) for (Iterator e = children.iterator(); e.hasNext();) { BOType child = (BOType) e.next(); String name = child.getName(); // Create the child MetadataObject EISSAMetadataObject childObject = new EISSAMetadataObject(tree,helper); childObject.setTargetNameSpace(child.getType().getNameSpace()); childObject.setDisplayName(name); childObject.setBOType(child); if (child.getChildren() != null && child.getChildren().size() > 0) { childObject.setHasChildren(true); } // Mark these as not selectable childObject.setSelectableForImport(false); childObject.setContainedChild(true); //childObject.setContentType(getContentType()); childObject.setBOName(name); // Set the parent object childObject.setParent(this); childObject.setLocation(childObject.getTargetNameSpace() + childObject.getBOName()); // Copy the content and header from the // object created for the same complexType // as a top level object. This would have happened // in the step of DTFMetadataTree.listMetadataObjects() EISSAMetadataObject topObject = (EISSAMetadataObject) tree.getMetadataObject(childObject.getLocation()); childObject.setHeader(topObject.getHeader()); childObject.setAliasTag(topObject.getAliasTag()); childObject.setContent(topObject.getContent()); childObject.setXsdName(topObject.getXsdName()); if (childObject.getXsdName().equals(this.getXsdName())) { childObject.setPartOfSameXSD(true); topObject.setPartOfSameXSD(true); } list.add(childObject); } } else { if (childList != null) list = childList; } } catch (Exception e) { throw new MetadataException(e.getMessage()); } response.setObjects(list); return response; }
8.7.10.12. WBIMetadataSelectionImpl samples
WBIMetadataSelectionImpl represents the object that holds the MetadataObjects that users can select for importing. This class also holds properties that users specify to select from the set of available MetadataObjects.
Extend WBIMetadataSelectionImpl and implement the following methods described below.
createSelectionProperties
The createSelectionProperties() method returns a property group used to capture inputs from users. These inputs include business object namespace, supported operations, and the relative path in the module project where XML schema definitions should be saved.
public PropertyGroup createSelectionProperties() { WBIPropertyGroupImpl pg = null; try { pg = new WBIPropertyGroupImpl("Selection Properties"); pg.setDisplayName("SelectionProperties"); pg.setDescription("SelectionProperties"); MetadataConfigurationType[] types = WBIMetadataDiscoveryImpl. getMetadataConfiguration(); for(int i=0;i types.length;i++){ if (types[i].equals(MetadataConfigurationType.GENERIC_RECORDS) || types[i].equals(MetadataConfigurationType.GENERATED_RECORDS) || types[i].equals (MetadataConfigurationType.GENERATED_DATA_BINDING) || types[i].equals(MetadataConfigurationType.GENERIC_DATA_BINDING)) { artifactType = types[i].toString(); } if(types[i].equals(MetadataConfigurationType.INBOUND_SERVICE) || types[i].equals(MetadataConfigurationType.OUTBOUND_SERVICE)){ serviceType = types[i].toString(); } } WBIMultiValuedPropertyImpl operationProp = new WBIMultiValuedPropertyImpl ("Operations", String.class); operationProp.setDisplayName("Operations"); operationProp.setDescription("Operations"); operationProp.setRequired(true); String[] operations=null; if(serviceType.equals(MetadataConfigurationType.INBOUND_SERVICE.toString())){ operations = new String[3]; operations[0] ="Create"; operations[1] ="Update"; operations[2] ="Delete"; }else{ if(artifactType.equals(MetadataConfigurationType.GENERATED_DATA_BINDING.toString ())){// is WPS operations = operationsWPS; }else{ operations = operationsNonWPS; } } operationProp.setValidValues(operations); for(int idx=0;idxoperationProp.addValue(operations[idx]); } pg.addProperty(operationProp); //Copy the applied properties to the new instance if (getAppliedSelectionProperties() != null) EMDUtil.copyValues(getAppliedSelectionProperties(), pg); } catch (MetadataException e) { throw new RuntimeException(e.getMessage()); } return pg; }
8.7.10.13. WBIMetadataImportConfigurationImpl samples
WBIMetadataImportConfigurationImpl represents an instance of MetadataObject and the configuration properties that users specify for it.
Extend WBIMetadataImportConfigurationImpl and implement the methods described below.
Constructor
The constructor for WBIMetadataImportConfigurationImpl accepts MetadataObject.
public EISSAMetadataImportConfiguration(WBIMetadataObjectImpl mo) { super(mo); }
createConfigurationProperties
The createConfigurationProperties() method returns a property group for the MetadataObject. The properties are specific to the instance of MetadataObject and are used to capture inputs from users. Those inputs might include operations that are supported for each MetadataObject instance, or additional information required to process the object at run time.
8.7.10.14. WBIMetadataEditImpl samples
The enterprise metadata discovery service uses WBIMetadataEditImpl to acquire connectionTypes, which contains editable properties forResourceAdapter, ManagedConnectionFactory, or ActivationSpecWithXid.
The enterprise metadata discovery tooling creates an instance of WBIMetadataEditImpl during the boot strap process. Along with the name of the MetadataDiscovery class, WBIMetadataEditImpl is specified in the discovery-service.xml file. If for any reason WBIMetadataEditImpl cannot be instantiated, then enterprise metadata discovery is not selectable in theIBM Integration Designer tooling.
getOutboundConnectionType
The getOutboundConnectionType() method returns an instance of OutboundConnectionType with an input name.
public OutboundConnectionType getOutboundConnectionType(String arg0) throws MetadataException { return adapterType.getOutboundConnectionTypes()[1]; }
getInboundConnectionType
The getInboundConnectionType() method returns an instance of InboundConnectionType with an input name.
public InboundConnectionType getInboundConnectionType(String arg0) throws MetadataException { return adapterType.getInboundConnectionTypes()[0]; }
8.7.10.15. WBIDataDescriptionImpl samples
WBIDataDescriptionImpl represents the data description interface. This interface maps business object definitions to Java™ objects.
prepareChildSchemaFiles
The prepareChildSchemaFiles() method creates child objects when a parent object cannot do so. If your adapter requires a separate and recursive creating of child objects, then implement this method. Its should call recursively as shown:
prepareChildSchemaFiles(); prepareSchemaFiles();public void prepareChildSchemaFiles() throws MetadataException { MetadataObjectResponse response = getMetadataObject().getChildren(null); EISSAMetadataObject child = null; Iterator i = response.getObjectIterator(); while (i.hasNext()) { child = (EISSAMetadataObject) i.next(); if (child.getBOType() != null) { if (child.getTargetNameSpace().equals(((EISSAMetadataObject) this.getMetadataObject()).getTargetNameSpace()) && child.isPartOfSameXSD()) { includeXSDs.append("<" + child.getAliasTag() + "include schemaLocation=\"" + child.getBOName() + ".xsd\" />\n"); } boolean found = false; for (int j = 0; j < selectedSet.length; j++) { EISSAMetadataObject selectedObj = (EISSAMetadataObject) ((EISSAMetadataImportConfiguration) selectedSet[j]).getMetadataObject(); if (selectedObj.getLocation().equals(child.getLocation())) { found = true; break; } } if (found) continue; // Generate the schemas for grand and following level children EISSADataDescription desc = new EISSADataDescription(child, selectedSet); desc.setRelativePath(this.getRelativePath()); desc.setAliasTag(child.getAliasTag()); desc.prepareChildSchemaFiles(); SchemaDefinition[] schemas = desc.getSchemaDefinitions(); for (int j = 0; j < schemas.length; j++) { SchemaDefinition defn = schemas[j]; put(defn.getNamespace(), defn.getLocation(), defn.getContent()); } // If not found continue to add the defn of the child object String complexTypeInfo = child.getContent().substring(0, child.getContent().indexOf(">") + 1) + System.getProperty("line.separator"); String header = child.getHeader(); int encoding = header.indexOf("encoding"); if (encoding != -1) { String encodingName = header.substring (encoding + 10, header.indexOf("\"", encoding + 10)); if (!encodingName.equalsIgnoreCase("UTF-8")) header = header.substring(0, encoding + 10) + "UTF-8" + header.substring(header.indexOf("\"", encoding + 10)); } String content = header + desc.getIncludeXSDs() + getSerializedImports(this.getImportNameSpaces()) + System.getProperty("line.separator") + getSerializedAnnotationForEMD(getASISchemaName()) + complexTypeInfo + getSerializedMetadata(this.getMetadataForBusinessObject()) + child.getContent().substring(child.getContent().indexOf(">") + 1); URI uri = null; try { uri = new URI(this.getRelativePath() + child.getBOName() + ".xsd"); } catch (URISyntaxException use) { throw new MetadataException(use.getMessage(),use); } put(child.getTargetNameSpace(), uri, content); } else { EISSADataDescription boDesc = new EISSADataDescription(child, selectedSet); boDesc.setRelativePath(this.getRelativePath()); boDesc.setAliasTag(child.getAliasTag()); boDesc.populateSchemaDefinitions(); SchemaDefinition[] schemas = boDesc.getSchemaDefinitions(); for (int j = 0; j < schemas.length; j++) { SchemaDefinition defn = schemas[j]; put(defn.getNamespace(), defn.getLocation(), defn.getContent()); } } }
getVerbs
The getVerbs() method returns a list of verbs when the data description represents a top-level object that supports verbs.
public List getVerbs() { ArrayList list = new ArrayList(); list.add(TopLevelVerbs.CREATE_TLV); list.add(TopLevelVerbs.UPDATE_TLV); list.add(TopLevelVerbs.DELETE_TLV); return list; }
getMetadataForAttribute
The getMetadataForAttribute() method returns an instance of the WBIMetadata object and represents application specific information for the element or field in the object definition. This corresponds to the annotation section for the element definition.
public WBIMetadata getMetadataForAttribute(String attrName) { WBIMetadata attributeMetadata = new WBIMetadata(); attributeMetadata.setSource(Constants.ASI_TARGET_NAMESPACE); attributeMetadata.setObjectNameSpace(Constants.ATTR_APPINFO_ASI_TYPE_TAG); QName asiNamespace = new QName (Constants.ASI_TARGET_NAMESPACE, Constants.ASI); attributeMetadata.setNameSpace(asiNamespace); attributeMetadata.setASI(Constants.FIELD_NAME, attrName); if (attrName.equalsIgnoreCase(Constants.PRIMARYKEY)) { attributeMetadata.setASI(Constants.PRIMARY_KEY, "true"); } return attributeMetadata; }
getMetadataForBusinessObject
The getMetadataForBusinessObject() method returns an instance of the WBIMetadata object and represents application specific information for the object definition. This corresponds to the annotation section for the complexType definition.
public WBIMetadata getMetadataForBusinessObject() { WBIMetadataDiscoveryImpl.getLogUtils().traceMethodEntrance (CLASSNAME, "getMetadataForBusinessObject"); WBIMetadata bometadata = new WBIMetadata(); bometadata.setSource(Constants.ASI_TARGET_NAMESPACE); QName namespace = new QName(Constants.ASI_TARGET_NAMESPACE, Constants.ASI); bometadata.setNameSpace(namespace); bometadata.setObjectNameSpace(Constants.BUS_OBJ_APPINFO_ASI_TYPE_TAG); bometadata.setASI(Constants.ASI_OBJECTNAME, this.getMetadataObject().getDisplayName()); WBIMetadataDiscoveryImpl.getLogUtils().traceMethodExit (CLASSNAME, "getMetadataForBusinessObject"); return bometadata; } // End of BO level metadata
isContainer
The isContainer() method returns true when the complexType definition requires a Container definition with the graph definition. The Container definition is used when the adapter supports a RetrieveAll operation.
public boolean isContainer() { WBIMetadataDiscoveryImpl.getLogUtils().traceMethodEntrance (CLASSNAME, "isContainer"); boolean retValue = false; String objName = getName().getLocalPart(); if (objName.endsWith("Container") && !objName.equals(getBOName())) retValue = true; WBIMetadataDiscoveryImpl.getLogUtils().traceMethodExit (CLASSNAME, "isContainer"); return retValue; }
getType
The getType() method returns the XML schema definition type that represents the element or field of the object definition.
public String getType(String attrName) { LinkedHashMap ht = this.getAttributeList(); EISSAAttributeType vtaAttrType = (EISSAAttributeType) ht.get(attrName); return vtaAttrType.getType(); }
getAttributeName
The getAttributeName() method returns the element name that represents the field in the object. This is the element name that would be used in the XML schema definition.
public String getAttributeName(String attrName) { return StringCaseChanger.toCamelCase(attrName); }
getImportNameSpaces
The getImportNameSpaces() method returns a list of ImportedNameSpace instances that should be imported in the business object schema.
public List getImportNameSpaces() throws MetadataException { WBIMetadataDiscoveryImpl.getLogUtils().traceMethodEntrance (CLASSNAME, "getImportNameSpaces"); ArrayList list = new ArrayList(); ImportedNameSpace namespace = new ImportedNameSpace(); namespace.setLocation(Constants.<AdapterPrefixName>ASI_XSD); namespace.setNameSpace(Constants.ASI_TARGET_NAMESPACE); list.add(namespace); 140 WebSphere Adapters: WebSphere Adapter Toolkit User Guide WBIMetadataDiscoveryImpl.getLogUtils().traceMethodExit (CLASSNAME, "getImportNameSpaces"); return list;}
getNameSpaces
The getNameSpaces() method returns the NameSpaces listed in the XML schema definition. Typically these are application specific information schema definition namespaces. Note that this list is for outside namespaces only; child object namespaces are included by the Adapter Foundation Classes.
public List getNameSpaces() { WBIMetadataDiscoveryImpl.getLogUtils().traceMethodEntrance (CLASSNAME, "getNameSpaces"); ArrayList list = new ArrayList(); list.add(new QName(Constants.ASI_TARGET_NAMESPACE, Constants.ASI)); WBIMetadataDiscoveryImpl.getLogUtils().traceMethodExit (CLASSNAME, "getNameSpaces"); return list; }
getASISchemaName
The getASISchemaName() method returns the target namespace that represents the application specific information schema.
public String getASISchemaName() { return Constants.ASI_TARGET_NAMESPACE; }
getCardinality
The getCardinality() method returns the cardinality for an elements in the business object definition. This value is used to formulate the maxOccurs and minOccurs tag.
public String getCardinality(String name) { LinkedHashMap ht = this.getAttributeList(); EISSAAttributeType vtaAttrType = (EISSAAttributeType) ht.get(name); return vtaAttrType.getCardinality(); }
getMaxLength
The getMaxLength() method returns the maxLength for the elements in the business object definition. This is used to fill in the maxLength tag for the XML schema definition.
public int getMaxLength(String name) { return 0; }
getRequired
The getRequired() method returns true if the element is marked as required in the XML schema definition. Otherwise, this method returns false.
public boolean getRequired(String attrName) { return false; }
getChildList
The getChildList() method returns the Iterator for the child objects of the DataDescription.
public Iterator getChildList() throws MetadataException { return (this.getMetadataObject().getChildren(null)).getObjectIterator(); }
8.7.10.16. WBIInboundServiceDescriptionImpl samples
WBIInboundServiceDescriptionImpl represents the object that populates function descriptions for inbound service descriptions.
Implement the method shown in the section below.
setFunctionDescriptions
The setFunctionDescriptions() method populates function descriptions based on objects and properties selected in MetadataSelection .
public void setFunctionDescriptions(MetadataSelection selection) throws MetadataException { try{ ArrayList functionDescriptions = new ArrayList(); MetadataImportConfiguration[] confArray = selection.getSelection(); PropertyGroup selectionProps = WBIMetadataSelectionImpl.getAppliedSelectionProperties(); WBIMultiValuedPropertyImpl prop = (WBIMultiValuedPropertyImpl) selectionProps.getProperty("Operations"); String[] values = prop.getValuesAsStrings(); helper.getToolContext().getProgressMonitor().setMaximum(confArray.length * values.length * 10); helper.getToolContext().getProgressMonitor().setMinimum(0); helper.getToolContext().getProgressMonitor().setNote ("Creating Service Description"); for (int i = 0; i < confArray.length; i++) { if (helper.getToolContext().getProgressMonitor().isCanceled()) { return; } WBIMetadataImportConfigurationImpl spec = (WBIMetadataImportConfigurationImpl) confArray[i]; WBIInboundFunctionDescriptionImpl funcDesc; EISSAMetadataObject metadataObj = (EISSAMetadataObject) spec.getMetadataObject(); helper.getToolContext().getProgressMonitor().setNote ("Creating Service for " + metadataObj.getDisplayName()); this.setNameSpace(metadataObj.getTargetNameSpace()); EISSADataDescription dataDesc = EISSAOutboundServiceDescription.setupMetadataObject (spec, selection, getNameSpace()); for (int j = 0; j < values.length; j++) { String operation = values[j]; helper.getToolContext().getProgressMonitor ().setProgress(i + j * 10); funcDesc = new WBIInboundFunctionDescriptionImpl(); char firstCharacter = operation.charAt(0); funcDesc.setName("emit" + Character.toUpperCase(firstCharacter) + operation.substring(1).toLowerCase() + "AfterImage" + metadataObj.getBOName()); funcDesc.setEISFunctionName("emit" + Character.toUpperCase(firstCharacter) + operation.substring(1).toLowerCase() + "AfterImage" + dataDesc.getName().getLocalPart()); funcDesc.setImportConfiguration(spec); funcDesc.setInputDataDescription(dataDesc); functionDescriptions.add(funcDesc); } } FunctionDescription[] funcArray = new FunctionDescription[functionDescriptions.size()]; functionDescriptions.toArray(funcArray); super.setFunctionDescriptions(funcArray); }catch(Exception e){ throw new MetadataException(e.getMessage(),e); } } FunctionDescription[] funcArray = new FunctionDescription[functionDescriptions.size()]; functionDescriptions.toArray(funcArray); super.setFunctionDescriptions(funcArray); }
8.7.10.17. WBIOutboundServiceDescriptionImpl samples
WBIOutboundServiceDescriptionImpl represents the object that populates function descriptions for outbound service descriptions.
Implement the method shown in the section below.
setFunctionDescriptions
The setFunctionDescriptions() method populates the function descriptions based on objects and properties selected in MetadataSelection.
public void setFunctionDescriptions(MetadataSelection selection) throws MetadataException { ArrayList functionDescriptions = new ArrayList(); MetadataImportConfiguration[] confArray = selection.getSelection(); PropertyGroup selectionProps = WBIMetadataSelectionImpl.getAppliedSelectionProperties(); WBIMultiValuedPropertyImpl prop = (WBIMultiValuedPropertyImpl) selectionProps.getProperty("Operations"); String[] values = prop.getValuesAsStrings(); helper.getToolContext().getProgressMonitor() .setMaximum(confArray.length * values.length * 10); helper.getToolContext().getProgressMonitor().setMinimum(0); helper.getToolContext().getProgressMonitor().setNote ("Creating Service Description"); for (int i = 0; i < confArray.length; i++) { WBIMetadataImportConfigurationImpl spec = (WBIMetadataImportConfigurationImpl) confArray[i]; WBIOutboundFunctionDescriptionImpl funcDesc; EISSAInteractionSpec iSpec; EISSAMetadataObject metadataObj = (EISSAMetadataObject) spec.getMetadataObject(); helper.getToolContext().getProgressMonitor().setNote ("Creating Service for " + metadataObj.getDisplayName()); this.setNameSpace(metadataObj.getTargetNameSpace()); EISSADataDescription dataDesc = setupMetadataObject(spec, selection, getNameSpace()); for (int j = 0; j < values.length; j++) { String operation = (String) values[j]; if(operation.equalsIgnoreCase(WBIInteractionSpec.APPLY_CHANGES_OP) && (!metadataObj.getBOName().endsWith("BG"))){ continue; } helper.getToolContext().getProgressMonitor().setProgress(i + j * 10); funcDesc = new WBIOutboundFunctionDescriptionImpl(); funcDesc.setName(operation.toLowerCase() + metadataObj.getBOName()); funcDesc.setInputDataDescription(dataDesc); funcDesc.setOutputDataDescription(dataDesc); iSpec = new EISSAInteractionSpec(); iSpec.setFunctionName(operation); funcDesc.setInteractionSpec(iSpec); funcDesc.setImportConfiguration(spec); functionDescriptions.add(funcDesc); } } FunctionDescription[] funcArray = new FunctionDescription [functionDescriptions.size()]; functionDescriptions.toArray(funcArray); super.setFunctionDescriptions(funcArray); }
Enterprise Metadata Discovery interfaces and implementation for technology adapters
Version 1.2 of Enterprise Metadata Discovery includes enhancements for configurable data handlers, function selectors, and data bindings, and a way to build service descriptions using these configured artifacts and existing schemas.
The enhancements to Enterprise Metadata Discovery are useful when building technology-style adapters that transform unstructured data to structured data and use the existing schemas instead of generating them from an EIS system.
Enterprise Metadata Discovery and technology-style adapters use data handlers, function selectors, and data bindings in the following ways:
- A data handler, which is a Java™ class or library of classes, is used by a process to transform data into and from specific formats. In the WebSphere Business Integration environment, data handlers transform text data of specified formats into business objects, and transform business objects into text data of specified formats.
- A function selector is used by adapters performing inbound processing. The function selector directs the data to the appropriate function in the message-driven bean (MDB) or EIS export. A function selector can inspect data or metadata to determine how and where to direct the data.
- A data binding, which is a Java class, converts a stream of native data to a business object during inbound processing, and converts a business object to a stream of native data during outbound processing.
Creating services that use technology-style adapters relies on being able to implement the interfaces in the commonj.connector.metadata.build.* package or by extending the adapter foundation classes in com.ibm.j2ca.extension.emd.build.* package, or a combination thereof.
Building configurable artifacts (data bindings, data handlers, and function selectors)
Building services using Enterprise Metadata Discovery involves building configurable artifacts that include data bindings, data handlers, and function selectors.
Implementing a data handler
To implement a data handler, implement the common.connector.runtime.DataHandler interface.
This interface contains two methods as follows:
- Object transform(Object input, Class targetClass, Object options)
- void transformInto(Object input, Object target, Object options)
The transform method takes an InputStream and produces a data object from it or takes a data object and produces an InputStream (depending on the processing mode). The target class indicates the processing to be performed by the data handler. The options parameter is a map that can include an encoding parameter. When implementing a data handler, code it to handle both byte array and string formats, if possible.
Existing WebSphere adapters, as of versions 6.2x, 7.0 and 7.5.x use InputStream for accessing raw data and data object for the transformed version exclusively.
Implement the TransformInto method in a data handler to transform a data object by writing to an output stream, so the input would be a data object, and the target would be an output stream.
A data handler should only transform from the raw payload to a data object and vice versa; it should not put the data in a record, or an envelope or other adapter-specific format, as this is the processing responsibility of a data binding.
Implementing a function selector
When provided with data and metadata from an adapter, the function selector generates the native function name. A function selector implements the interface commonj.connector.runtime.FunctionSelector. This interface contains the method String generateEISFunctionName(Object[] args);.
The argument array you get depends on which listener interface you are using. If you are using InboundListener (passing data only), the first object in the array is the record. If you are using ExtendedMessageListener (passing data and metadata), the first object in the array is an InboundNativeDataRecord that contains an InboundInteraction spec (for metadata) and the record (for data).
For services using adapters to exchange data with a local file system (like flat files) and services using adapters to access files on an FTP server, the InboundInteractionSpec contains the file name and path to the files being processed. A custom function selector can use the information in the InboundInteractionSpec to generate a native function.
For a custom adapter, you can create either a smart function selector that uses the data or metadata to perform function selection, with or without configuration; or you can implement a simple function selector that always returns a static function name. Implementing a simple function selector restricts your inbound service to a single function. This, in turn, restricts the service to dealing with a single data type; unless anyType is used in the WSDL, which is discouraged because a WSDL that contains an anyType schema is difficult to use in BPM or WebSphere ESB (due to the fact that it does not indicate the actual type emitted).
Implementing a data binding
A data binding implements the interface commonj.connector.runtime.RecordHolderDataBinding. This interface contains four methods as follows:
- Record getRecord();
- void setRecord(Record record);
- DataObject getDataObject();
- void setDataObject(DataObject object);
These methods perform the mediation between the record the adapter needs (for example an InputStreamRecord), and the data object specified in the service (WSDL).
The data binding can call a data handler to perform low-level transformation on an input stream. The adapter foundation classes provide a base class, named BaseDataBinding that adapters can extend to handle the low-level details of calling a data handler. The BaseDataBinding data handler has three methods as follows:
- InputStream transformToInputStream(DataObject object);
- DataObject transformToDataObject(InputStream stream, QName expectedType);
- void setChildDataHandler(Qname bindingConfiguration);
To use these methods, call setChildDataHandler first with a data handler configuration, then call one of the transform methods. The expectedType parameter on transformToDataObject should match the type of the DataObject you want the transformation to produce. You can derive this from the expected type the data binding is passed in the BindingContext interface described in the Binding context and configuration.
Binding context and configuration
Data handlers, data bindings and function selectors can be context-enabled and may be configurable.
BindingContext is a mix-in interface that provides access to contextual information, such as the configuration of this binding, the expected type for data handlers and data bindings and the type of service being used.
The BindingContext interface has several constants and one method as follows:
- void setBindingContext(Map context);
To access the binding configuration, do context.get(BindingContext.BINDING_CONFIGURATION)
To access the expected type, do context.get (BindingContext.EXPECTED_TYPE)
Function selectors, data handlers, and data bindings are all configurable. This configuration can be quite rich, providing single and multi-valued properties, drop-downs, and user-editable tables and trees.
Every configurable artifact needs to have a Properties bean. The class name for this bean must follow the naming convention [Artifact]Properties, where [Artifact] is the class name of the function selector, data binding, or data handler being configured. The properties bean contains all the artifact's properties as JavaBeans properties. Getters and setters must be provided for every attribute. Arrays are allowed for complex properties.
To enable the type of configuration that provides single and multi-valued properties, drop-downs, and user-editable tables and trees, you need a Configuration class and an EditableType class; each one using the same naming convention as the Properties class: [Artifact]Configuration, and [Artifact]EditableType. The Configuration class must implement the interface commonj.connector.metadata.BindingConfigurationEdit, which has one method of note, which is public EditableType getEditableType();.
The method public EditableType getEditableType(); return the EditableType implementation for this artifact. The EditableType class implements the commonj.connector.metadata.discovery.EditableType interface, which contains the following methods:
- PropertyGroup createProperties()
- void synchronizeFromBeanToPropertyGroup(Object bean, PropertyGroup pg)
- void synchronizeFromPropertyGroupToBean(PropertyGroup pg, Object bean)
The createProperties method creates an enterprise metadata discovery (EMD) property group that can contain several properties, or even nested property groups.
The synchronization methods provide the capability to keep the property group synchronized with the property bean. To specify a data handler property in a data binding, use a BindingTypeBeanProperty in the Property bean and a WBIBindingProperty in the property group.
Implementing Enterprise Metadata Discovery to build an interface
The com.ibm.j2ca.extension.emd.build.* package allows a simpler way to build services with an adapter from existing types. Instead of the EMD process generating types, it will import them and use them in a service.
Extend the adapter foundation classes to build services
Creating services that use technology-style adapters relies on being able to implement the interfaces in the commonj.connector.metadata.build.* package or by extending the AFC classes in com.ibm.j2ca.extension.emd.build.* package, or a combination thereof.
To implement the interfaces that allow you to build services, you need to extend the following adapter foundation classes:
- WBIMetadataBuild
- WBIFunctionBuilder
- WBIMetadataType (optional)
When you extend WBIMetadataBuild, implement the following methods:
- FunctionBuilder createFunctionBuilder(String functionSelector)
CreateFunctionBuilder returns your FunctionBuilder instance.
- String[] getConnectionSpecClassName();
getConnectionSpecClassName returns the class name of your J2CA connection spec.
- InteractionSpec getDefaultInteractionSpec();
getDefaultInteractionSpec returns the class name of the J2CA interaction spec that is most commonly used for your adapter.
- QName[] getAdapterSchemaTypes();
getAdapterSchemaTypes returns any common schemas; for example, schemas that are used independently of the operation.
- SchemaDefinition[] getSchemasForQName(QName type);
getSchemasForQName returns the SchemaDefinition[s] for any Qnames that you provide for schemas in the build process.
When you extend WBIFunctionBuilder, implement the following methods:
- FunctionType[] getFunctionTypes();
This method returns the function type(s) for the selected operation. This is particularly useful for determining whether this is input/output, the input or output are the same or different.
- String getDefaultDataBindingClassName();
This method returns the default data binding class for this adapter.
- updateInputDataDescription(DataDescription dataDescription, FunctionDescription functionDescription);
This method gives your adapter a chance to update the data description for input.
- String[] getSupportedOperationNames();
This method returns the list of operations the adapter foundation classes display to the user. The user can select one of these per added function.
- String[] getRecordInterfaces();
This method returns the record interfaces that your adapter can deal with, for instance InputStreamRecord.
- InteractionSpec getInteractionSpec(String methodName, QName inputData, QName outputData)
This method returns a populated the interaction spec, containing the necessary information about the function to be run. This is used in building the service description.
WBIMetadataType
If your adapter requires the ability to generate its own types (or wrappers), you should either extend WBIMetadataType or implement the MetadataType interface directly.
Extend WBIMetadataType if your adapter needs a simple wrapper object around a payload object, similar to the IBM WebSphere Adapter for Flat Files and the IBM WebSphere Adapter for FTP. The WBIMetadataType interface allows you to select a payload type, and optionally generate a business graph structure in addition to a plain wrapper. Implement MetadataType interface directly to deal with a more complex object structure.
To extend WBIMetadataType, implement the following methods:
- public abstract String getDefaultNamespace();
This method returns a default namespace for your adapter.
- public abstract SchemaDefinition[] getSchemaDefinitions();
This method returns the generated schema definitions, based on the payload. The following helper methods enable you to do this:
- getImportedSchemaLocationString();
This helper method returns the relative location of the selected schema.
- getImportedSchema()
This helper method returns the Qname of the selected schema.
- getNamespace()
This helper method returns the namespace the user has entered.
Discovery-service.xml
For the tool to detect and use your adapter, you need a discovery-service.xml file in your “meta-in” folder.
Here is an example of the discovery-service.xml file:
<?xml version="1.0" encoding="UTF-8"?> <emd:discoveryService xmlns:emd="commonj.connector" xmlns:j2ee="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/j2ee_1_4.xsd"> <j2ee:description>WebSphere Sample Adapter for Enterprise Information System Simulator <j2ee:description> <j2ee:display-name>WebSphere Sample Adapter for Enterprise Information System Simulator </j2ee:display-name> <emd:vendor-name xsi:type ="j2ee:xsdStringType>IBM</emd:vendor-name> <emd:version xsi:type="j2ee:xsdStringType"> @adapter-version@@adapter-version@> <emd:spec-version>1.1/emd:spec-version> <emd:discoveryService-class xsi:type= "j2ee:fully-qualified-classType"> com.ibm.j2ca.eissa.emd.discovery.EISSAMetadataDiscovery </emd:discoveryService-class> <emd:metadataEdit-class xsi:type= "j2ee:fully-qualified-classType"> com.ibm.j2ca.eissa.emd.discovery.EISSAMetadataEdit </emd:metadataEdit-class> <emd:application-specific-schema> <j2ee:description> PeopleSoft ASI schema</j2ee:description> <j2ee:displayname>PeopleSoft ASI schema</j2ee:display-name> <emd:asiNSURI>http://www.ibm.com/xmlns/prod /websphere/j2ca/peoplesoft/metadata </emd:asiNSURI><emd:asiSchemaLocation> PeopleSoftASI.xsdemd:asiSchemaLocation> PeopleSoftASI.xsd> </emd:application-specific-schema> </emd:discoveryService>
Structured record implementation
StructuredRecord class needs to be implemented by adapters when the data exchanged with backend application can be well-defined. Extend foundation class com.ibm.j2ca.base.WBIStructuredRecord and implement the associated methods.
Initialize input method
This method resolves the type of the metadata if it is a JavaBeans or SDO type and initializes the metadata interfaces appropriately. public void initializeInput(DataExchangeFactory dataBinding, Object metadata) throws DESPIException .
Purpose of the initialize input method
Implement the initializeInput method only if the metadata contains information to be used to initialize the back-end connection for processing the request. For example, if an application requires you to instantiate a corresponding component on the back-end application to process the request.
This method should first invoke super.initializeInput() to initialize the cursors, accessors and metadata.
Sample code
Here is a coding sample on how to implement the intitializeInput method:public void initializeInput(DataExchangeFactory factory, Object[] metadata) throws DESPIException { super.initializeInput(factory, metadata); objectNaming = new ObjectNaming(); objectSerializer = new ObjectSerializer(objectNaming); try{ objectAnnotations = super.getMetadata() .getAnnotations( <AdapterPrefixName>Constants.METADATA_NAMESPACE);} catch(Exception e){ throw new DESPIException(e);}}
Initialize output method
public void initializeOutput(DataExchangeFactory dataBinding,Object metadata)throws DESPIException.
Purpose of the initialize output method
Implement this method if there is some initialization needed to support record retrieval from getNext().
This method should first invoke super.initializeInput() to initialize the cursors, accessor, and metadata.
Sample code
Here is a coding sample on how to implement the intitializeOutput method:public void initializeOutput(DataExchangeFactory factory, Object[] metadata) throws DESPIException { super.initializeOutput(factory, metadata); objectNaming = new ObjectNaming(); objectSerializer = new ObjectSerializer(objectNaming); try{ objectAnnotations = super.getMetadata().getAnnotations (FooConstants.METADATA_NAMESPACE);}catch(Exception e){ throw new DESPIException(e);}}
Set managed connection method
This method passes the ManagedConnection handle to the record implementation, allowing the record to get access to the physical connection to the backend application to perform processing.public void setManagedConnection( ManagedConnection managedConnection) throws ResourceException
Purpose of the set managed connection method
This method is called after initializeInput().
Implement this only if there is a need for to build a component on the backend EIS to perform an adapter function. For example, if the backend application needs to initialize a corresponding component on the backend EIS, use this method to initialize that component.
Sample code
Here is a coding sample on how to implement the setManagedConnection method:public void setManagedConnection( ManagedConnection managedConnection) throws ResourceException { try { this.managedConnection = managedConnection; if (this.getEISRepresentation() == null) { //get the handle to physical connection BackEndConnection conn = managedConnection.getBackEndHandle(); Object object = conn.create(name); if (object == null) { throw new ResourceException("Invalid metadata defined for the input Data."); } //set the instantiated object, would be accessed later this.setEISRepresentation(object); } } catch (Exception e) { throw new ResourceException("Failed in creating object " + name); } }
Get next method
The client application invokes this method to retrieve data through the adapter. For outbound processing, this method is used to get the response data back from the adapter. For inbound processing, this method is called to get the inbound data from the adapter.public boolean getNext(boolean copyValues) throws DESPIException
Purpose of the getNext method
Use the argument copyValues to fill in values as part of getNext.
When the value for copyValues is set to True, the getNext() method should fill in data in output cursors as part of the call.
When the value for copyValues is set to False, the getNext() method should just keep the instance of cursors ready, but not fill in the data. The data would be filled in using the pushValue() call, which passes an Xpath expression.
This method can be called multiple times by the client application if the operation can return multiple records from the backend application. For example, if the retriveAll operation could return "N" records from the backend application, for each call to the getNext() method the implementation should fill in data of one record from the backend application into OutputCursors/Accessors. It should keep track of which record it needs to do next so in subsequent call to getNext() it can fill in next record.
This method would be using the eisRepresentation being held on to the Record instance, this is the backend representation of data which is used in this method to read fields and set those in Output Cursors and Accessors.
Sample code
For a sample of how to implement the getNext() method, refer to the EIS Simulator Adapter code sample.
Clone method
Use this method to copy property values from the record instance to a newly created instance.public Object clone ()
Sample
Here is a coding sample on how to implement the Clone method:
public Object clone() { //Build a new record <AdapterPrefixName>StructuredRecord record = new <AdapterPrefixName>StructuredRecord(); try{ //Copying property values record.<AdapterPrefixName>BallConnection = <AdapterPrefixName>BallConnection; record.objectNaming = objectNaming; record.objectSerializer = objectSerializer; record.setEISRepresentation(this.getEISRepresentation());}catch(Exception e){ throw new RuntimeException(e);} return record;}
Close method
This method provides cleanup for the getNext method.public void close().
Purpose of the close method
Implement this method to release resources/objects after the getNext() method has been run.
Extract method
Use the public void extract(String xpath) throws DESPIException to retrieve individual field values from backend object representation.
Purpose
This method needs implementation only if an Xpath expression can be used to retrieve individual field values from backend object representation. This method is invoked after getNext() is called with boolean value as false.
The method should first extract the value from backend object representation defined through Xpath and use OutputCursor and OutputAccessor interfaces to populate values in runtime data structure.
Data binding implementation
Adapters must provide implementations for DataBinding interface in order to work with BPM. The marshalling of data from SDO to CCI record and from CCI record to SDO occurs through DataBinding implementation.
Interfaces
Adapters should implement the following interfaces:
- commonj.connector.runtime
- RecordHolderDataBinding
The following sections describe the methods that need implementation.
setDataObject
public void setDataObject(DataObject arg0) throws DataBindingException
This method builds an instance of adapter record instance and initializes with the metadata that represents input SDO.
public void setDataObject(DataObject arg0) throws DataBindingException { try { record = new EISSAStructuredRecord(); inputBG = arg0; DEFactorySDO binding = new DEFactorySDO(); boolean isBG = WPSServiceHelper.isBusinessGraph(arg0); DataObject dataObject = null; if (isBG) { dataObject = WPSServiceHelper.getRootBusinessObjectInstance(arg0); String verb = arg0.getString(EISSAConstants.VERB); if(verb != null){ record.setOperationName(verb); record.setBGVerb(verb); } record.setIsBG(true); } else dataObject = arg0; binding.setBoundObject(dataObject); Object[] array = new Object[1]; array[0] = dataObject; record.initializeInput(binding, array); record.setNamespace(inputBG.getType().getURI()); record.setRecordName(inputBG.getType().getName()); } catch (Exception e) { throw new DataBindingException("Failed to initialize cursor", e); } }
getDataObject
public DataObject getDataObject() throws DataBindingException
This method builds an instance of SDO with the data that is returned from the backend application. For example, when an adapter executes a Retrieve operation, the data returned from the backend application is held in the adapter structured record implementation. In this method the adapter reads data from the backend application and builds and SDO instance.
To perform this task the adapter should use DESPI APIs. Initialize the record with initializeOutput(), then call getNext() to build data in SDO.
This method should take care of building an instance of BG is the methods getNamespaceURI()and getBusinessObjectName() return a type BG.
For operations where getNext() should be invoked multiple times like RetrieveAll, the databinding should call getNext() multiple times add the built BusinessObject to the list of BusinessObjects within the Container BO.
getRecord
public Record getRecord() throws DataBindingException
This method should return the instance of record being build in setDataObject() call or passed through setRecord() call.
setRecord
public void setRecord(Record arg0) throws DataBindingException
This method should hold the instance of the record passed to this method as a record instance for the binding implementation. This record instance is used in method getDataObject().
Abstract methods (getNamespaceURI and getBusinessObjectName)
public abstract String getNamespaceURI();
public abstract String getBusinessObjectName();
DataBinding implementation uses these two methods in getDataObject() call to determine the SDO type the binding should instantiate.
The generated databinding classes described the section DataBinding generator provide the implementation for the abstract methods.
DataBinding generator
To enable the right business object type being made available to DataBinding implementations adapters should implement DataBindingGenerator interface.
Adapters should implement com.ibm.j2ca.extension.databinding, WBIDataBindingGenerator and implement provide a default constructor implementation.
Call the super class constructor and pass in the name of the adapter and the absolute classname of the base DataBinding implementation.
Sample code:
public EISSADataBindingGenerator() { super(null, "com.ibm.j2ca.eissa.emd.runtime.EISSADataBinding"); }EMD implementations should set the absolute name of the class for DataBindingGenerator as the generator classname in DataDescription instance. Set the DataBinding Classname to null.
Bidirectional language support
Specifying bidirectional properties allows your adapter to exchange data in various bidirectional formats. Bidi normalization is supported the following fashion:
Problem determination
You can implement messages to accompany a range events.
Fault handling support
Through enhancements to the Service Component Architecture (SCA) and the Adapter Foundation Classes (AFC), the WebSphere Adapter Toolkit provides fault handling support. Fault handling allows the developer to differentiate information technology (IT) exceptions from business processing exceptions during outbound processing.
A fault is an exception condition that alters the normal flow of a business process. Typically, a fault represents a predictable error that has a well-defined action. Presenting errors as faults instead of exceptions makes it easier for you to configure recovery processing, because fault handling does not require you to write Java™ code to catch and handle an exception. Adapters created with the WebSphere Adapter Toolkit generate several faults.
Fault handling support adheres to the DataBinding model, in that when an exception is thrown by an adapter, a fault selector determines that it is a fault and the fault (data) binding converts the exception to a fault business object and returns it to the server run time.
Fault artifacts
To facilitate fault handling support, WebSphere Adapter Toolkit provides artifacts that include fault classes, fault business objects, a fault selector, and a fault binding class.
The following table shows AFC fault classes, corresponding fault business names, and fault type names. The configured fault binding and a descriptive example of each fault can be found in the section about configuration for fault handling.
Fault Exception in AFC Corresponding Fault Name Corresponding Fault Type Name DuplicateRecordException DUPLICATE_RECORD DuplicateRecordFault InvalidRequestException INVALID_REQUEST InvalidRequestFault MatchesExceededLimitException MATCHES_EXCEEDED_LIMIT MatchesExceededLimitFault MissingDataException MISSING_DATA MissingDataFault MultipleMatchingRecordsException MULTIPLE_MATCHING_RECORDS MultipleMatchingRecordsFault RecordNotFoundException RECORD_NOT_FOUND RecordNotFoundFault
In addition to the fault classes, the following fault selector class and base fault binding class are provided:
- WBIFaultSelectorImpl
- WBIFaultDataBindingImpl
A utility class named FaultBOUtil can help you define simple custom fault business objects.
How to support fault handling
Understand the following concepts for implementing fault handling into your adapter.
Before you define faults, review adapter processing to determine which error conditions can be categorized as faults, rather than as exceptions. You will likely be able to apply at least one of the faults provided in the Adapter Foundation Classes. Some unique conditions might be categorized as faults, but fault classes in the Adapter Foundation Classes might not be provided for the conditions. Error conditions from which you can recover might be candidates for fault handling. IT exceptions, such as one time configuration issues (wrong password, incorrect directory permissions, etc.) are not candidates for fault handling.
When naming a fault, ensure the name describes the condition and is independent of the technology or adapter you are using. For example, the fault class name for an SAP IDoc record not found condition should be RecordNotFoundFault, not SAPIDOCRecordNotfoundFault. Additionally, you might not need to define new faults if the same semantic meaning can apply to multiple conditions ( RecordNotFoundFault, FileNotFoundFault, and ObjectNotfoundFault).
Implementing faults
As part of the external service discovery process, you generate fault business objects and create the method that copies them to your outbound module.
The following examples show these fault exceptions:
- DuplicateRecord
- MatchesExceedLimit
To implement fault handling in the adapter, add getXMLListFunctions method and getBFFunctions method in the extension to WBIOutboundFunctionDescriptionImpl.
Modify getXMLListFunctions method
Modify getXMLListFunctions involves the following changes:
- Add a line to invoke a new method.
- Creating the new method or add some lines to an existing method to specify the faults
- Completing the stub to implement the FaultDataDescription class
The following example shows the first two changes:
private void getXMLListFunctions(ArrayList functionDescriptions, PropertyGroup pg, String relativePath, JDEXMLListMetadataObject metadataObj, WBIMetadataImportConfigurationImpl spec) throws MetadataException{ ... while(iterator.hasNext()) { String operation = JDEESDConstants.RETRIEVEALL; /* this is only operation supported for XML Lists */ WBIOutboundFunctionDescriptionImpl funcDesc = new WBIOutboundFunctionDescriptionImpl(); JDEXMLListQueryDataDescription queryDataDesc = (JDEXMLListQueryDataDescription)iterator.next(); //Added for Faults addFaultsToXMLListDataDescriptionBasedOnOperationName (funcDesc,operation); //Added for Faults funcDesc.setName(operation.toLowerCase() + queryDataDesc.getBOName()); getLogUtils().trace(LogLevel.FINEST, CLASSNAME, "getXMLListFunctions", "Setting input data description to: " + queryDataDesc.getName().toString() + " for function: " + funcDesc.getName()); //$NON-NLS-1$ funcDesc.setInputDataDescription(queryDataDesc); funcDesc.setOutputDataDescription(containerDataDesc); JDEInteractionSpec iSpec = new JDEInteractionSpec(); WBISingleValuedPropertyImpl maxCount = (WBISingleValuedPropertyImpl)pg.getProperty (JDEESDProperties.MAXRECORDS); if (maxCount.getValue() == null) iSpec.setMaxRecords(((Integer) maxCount.getPropertyType() .getDefaultValue ()).intValue()); else iSpec.setMaxRecords(((Integer) maxCount.getValue()).intValue()); WBISingleValuedPropertyImpl timeoutProp = (WBISingleValuedPropertyImpl) pg.getProperty(JDEESDProperties.ISPECTIMEOUT); if (timeoutProp.getValue() != null && ((Integer) timeoutProp.getValue ()).intValue()>0){ iSpec.setTimeout(((Integer) timeoutProp.getValue()).intValue()); } iSpec.setFunctionName(operation); funcDesc.setInteractionSpec(iSpec); functionDescriptions.add(funcDesc); } ...} private void addFaultsToXMLListDataDescriptionBasedOnOperationName( WBIOutboundFunctionDescriptionImpl funcDesc, String operationName) throws MetadataException { // Define XSDs for faults supported by this adapter. try { // During implementation - add faults based on the operationName // parameter. For ex an operation may have more than one fault. // And so the below logic will have to be using conditions // if(operationName.equals("CREATE")) {} then do this etc. JDEXMLListFaultDataDescription fdesc1 = new JDEXMLListFaultDataDescription(); JDEXMLListFaultDataDescription fdesc2 = new JDEXMLListFaultDataDescription(); BusinessObjectDefinition bo = FaultBOUtil.createDuplicateRecordBO(); URI uri = new URI("./" + FaultBOUtil.DUPLICATE_RECORD_NAME //$NON-NLS-1$ + EMDConstants.XSD); fdesc1.put(FaultBOUtil.FAULT_TARGET_NS, uri, bo.serialize()); fdesc1.setGenericDataBindingClassName ("com.ibm.j2ca.extension.emd.runtime.WBIFaultDataBindingImpl"); fdesc1.setFaultName(FaultBOUtil.DUPLICATE_RECORD_NAME); bo = FaultBOUtil.createMatchesExceededLimitBO(); uri = new URI("./" + FaultBOUtil.MATCHES_EXCEEDED_LIMIT_NAME //$NON-NLS-1$ + EMDConstants.XSD); fdesc2.put(FaultBOUtil.FAULT_TARGET_NS, uri, bo.serialize()); fdesc2.setGenericDataBindingClassName ("com.ibm.j2ca.extension.emd.runtime.WBIFaultDataBindingImpl"); fdesc2.setFaultName(FaultBOUtil.MATCHES_EXCEEDED_LIMIT_NAME); FaultDataDescription desc[] = new FaultDataDescription[] { fdesc1, fdesc2 }; funcDesc.setFaultSelectorClassname ("com.ibm.j2ca.extension.emd.runtime.WBIFaultSelectorImpl"); funcDesc.setFaultDataDescriptions(desc); } catch (Exception e) { throw new MetadataException( "Unable to create fault BO definitions " + e.getMessage(), e); //$NON-NLS-1$ } }The following example shows code for implementing FaultDataDescription in the JDEXMLListFaultDataDescription class:
public class JDEXMLListFaultDataDescription implements FaultDataDescription { public JDEXMLListFaultDataDescription() { super(); // TODO Auto-generated constructor stub } private String faultName = null; public String getFaultName() { // TODO Auto-generated method stub return faultName; } public void setFaultName(String faultName) { this.faultName = faultName; }}
Modify getBFFunctions method
Modify getBFFunctions involves the following changes:
- Add a line to invoke a new method
- Creating the new method or add some lines to an existing method to specify the faults
- Completing the stub to implement the FaultDataDescription class
The following example shows the first two changes:
private void getBFFunctions(ArrayList functionDescriptions, PropertyGroup pg, String relativePath, ArrayList dataDescriptions) throws MetadataException { Iterator iterator = dataDescriptions.iterator(); while(iterator.hasNext()){ JDEBFContainerDataDescription dataDesc = (JDEBFContainerDataDescription)iterator.next(); JDEBFOperationASI[] ops = dataDesc.getOperationASI(); ArrayList operations = new ArrayList(); for(int i=0; i<ops.length; i++) { if(ops[i].getBsfnNames().length>0){ operations.add(ops[i].getName()); } } Iterator opIterator = operations.iterator(); while (opIterator.hasNext()) { String operation = (String)opIterator.next(); WBIOutboundFunctionDescriptionImpl funcDesc = new WBIOutboundFunctionDescriptionImpl(); //Added for Faults addFaultsToBFDataDescriptionBasedOnOperationName (funcDesc,operation); //Added for Faults funcDesc.setName(operation.toLowerCase() + dataDesc.getBOName()); funcDesc.setInputDataDescription(dataDesc); funcDesc.setOutputDataDescription(dataDesc); JDEInteractionSpec iSpec = new JDEInteractionSpec(); iSpec.setFunctionName(operation); funcDesc.setInteractionSpec(iSpec); functionDescriptions.add(funcDesc); } } } private void addFaultsToBFDataDescriptionBasedOnOperationName (WBIOutboundFunctionDescriptionImpl funcDesc, String operationName) throws MetadataException { // Define XSDs for faults supported by this adapter. try { //During implementation - add faults based on the operationName parameter. For example,an operation may have more than one fault. //And so the below logic will have to be using conditions if(operationName.equals("CREATE")) {} then do this etc. JDEBFFaultDataDescription fdesc1 = new JDEBFFaultDataDescription(); JDEBFFaultDataDescription fdesc2 = new JDEBFFaultDataDescription(); BusinessObjectDefinition bo = FaultBOUtil.createDuplicateRecordBO(); URI uri = new URI("./" + FaultBOUtil.DUPLICATE_RECORD_NAME //$NON-NLS-1$ + EMDConstants.XSD); fdesc1.put(FaultBOUtil.FAULT_TARGET_NS, uri, bo.serialize()); fdesc1.setGenericDataBindingClassName ("com.ibm.j2ca.extension.emd.runtime.WBIFaultDataBindingImpl"); fdesc1.setFaultName(FaultBOUtil.DUPLICATE_RECORD_NAME); bo = FaultBOUtil.createMatchesExceededLimitBO(); uri = new URI("./" + FaultBOUtil.MATCHES_EXCEEDED_LIMIT_NAME //$NON-NLS-1$ + EMDConstants.XSD); fdesc2.put(FaultBOUtil.FAULT_TARGET_NS, uri, bo.serialize()); fdesc2.setGenericDataBindingClassName ("com.ibm.j2ca.extension.emd.runtime.WBIFaultDataBindingImpl"); fdesc2.setFaultName(FaultBOUtil.MATCHES_EXCEEDED_LIMIT_NAME); FaultDataDescription desc[] = new FaultDataDescription[] {fdesc1, fdesc2}; funcDesc.setFaultSelectorClassname ("com.ibm.j2ca.extension.emd.runtime.WBIFaultSelectorImpl"); funcDesc.setFaultDataDescriptions(desc); } catch (Exception e) { throw new MetadataException( "Unable to create fault BO definitions " + e.getMessage(), e); //$NON-NLS-1$ } }The following example shows code for implementing FaultDataDescription in the JDEBFFaultDataDescription class:
public class JDEBFFaultDataDescription implements FaultDataDescription { public JDEBFFaultDataDescription() { super(); // TODO Auto-generated constructor stub } private String faultName = null; public String getFaultName() { // TODO Auto-generated method stub return faultName; } public void setFaultName(String faultName) { this.faultName = faultName; }}
Configuration for fault handling
Adapter Foundation Classes fault names and the corresponding fault binding names are used in the fault configuration.
A fault name is defined within each fault class. The base fault binding is configured unless attributes are unique.
The following table includes examples of situations when an adapter might throw each type of fault. These are examples only.
Fault name and configured fault binding
Fault Name Configured Fault Binding DUPLICATE_RECORD
com.ibm.j2ca.extension.emd.runtime.WBIFaultDataBindingImpl The adapter throws this fault when processing an outbound Create operation when an error occurs because the specified file already exists in the specified directory path.
INVALID_REQUEST
com.ibm.j2ca.extension.emd.runtime.WBIFaultDataBindingImpl When input to the operation does not have the required characteristics, the adapter throws this fault. Specific errors that can result include the following:
- For a Create operation:
- A ChangeSummary is provided but the required child business objects are not marked as created (per strict conventions)
- A business object is marked as deleted in the ChangeSummary (assertion optional)
- The input business object specifies key values, but the server supports only auto-creation
- The input business object does not contain key values, but the server requires them
- For a Delete operation:
- A ChangeSummary is provided but the required child business objects are not marked as deleted (per strict conventions)
- A business object is marked as created in the ChangeSummary (assertion optional)
MATCHES_EXCEEDED_LIMIT
com.ibm.j2ca.extension.emd.runtime.MatchingFaultDataBinding When processing a RetrieveAll operation, the adapter throws this fault if the number of records returned from a database query exceed the maximum number of records property in the interaction specification.
MISSING_DATA
com.ibm.j2ca.extension.emd.runtime.WBIFaultDataBindingImpl If the business object that is passed to the outbound operation does not have all the required attributes, the adapter throws this fault.
MULTIPLE_MATCHING_RECORDS
com.ibm.j2ca.extension.emd.runtime.MatchingFaultDataBinding When processing a Retrieve operation, the adapter throws this fault if the query returns more than one record for the specified keys.
RECORD_NOT_FOUND
com.ibm.j2ca.extension.emd.runtime.WBIFaultDataBindingImpl When processing a data retrieval operation, the adapter throws this fault if the record is not found in the database for the keys specified. This fault can occur for the Delete, Update, Retrieve, and RetrieveAll operations.
Defining custom faults
You can define custom faults for fault handling.
- Define the fault class
Implement BaseFaultException and define additional attributes if necessary. In defining the BaseFaultException class, you can see the convention for specifying the fault name. For example, the RecordNotFoundException fault name is RECORD_NOT_FOUND.
- Define a fault binding
Only required if you have defined additional attributes for your fault.
- Define the fault business object
You can use the FaultBOUtil to define the fault business object, as long as either no attributes or only simple attributes are added. This should amount to a few lines of code, see Implementing Faults for an example.
The model for fault classes and fault business objects is a 1-to-1 relationship, the base fault business object cannot be used even if no additional attributes are needed. This is because SCA does not pass back the fault name to the client / server runtime. Instead, the fault name is resolved to the fault (BO) type. So if you reuse fault BOs, you cannot definitively determine which fault occurred.
Logging and tracing messages
Providing information about the runtime state of the adapter is a critical aspect of adapter development. The Adapter Foundation Classes include the LogUtils class. When implemented, this functionality enables developers to target information to various user roles, enabling them to filter information by levels of importance and to generate informational events that can be monitored by and acted upon by IBM Business Process Manager.
Information about the runtime state of the adapter is invaluable not only to support teams trying to resolve problems but also to users looking to monitor the adapter and track its operations. For these reasons, you should focus early in your adapter development process on what information to provide, which users to target, and how to most efficiently and clearly communicate the information.
The JCA 1.5 specification provides minimal support for communicating information to users. It defines a single stream to which the adapter writes any information. As a result, without additional tools or support, users cannot filter information, analyze information or, in general, easily determine what information is of interest to them.
The New Adapter wizard generates code skeleton using Adapter Foundation Classes to provide you with a consistent method to get the LogUtils object in your own implementation. This is very useful when an adapter wants to record business information or needs to track execution flow. The LogUtils class allows you to direct information usefully to various users by generating three types of "messages": trace, log, and event messages. Each has a distinct purpose and conveys different information.
- The following guidelines apply to trace messages:
- They do not contain information needed by general users to resolve problems
- They encapsulate information intended for support and other development teams
- They need not be translated
- They can be hard-coded in the adapter itself
- They feature three levels of detail: fine, finer, and finest
- The following guidelines apply to log messages:
- They encapsulate information such as warnings and errors that are targeted at general users of the adapter
- Rather than hard-code log messages in the adapter, place them in a separate log message file to facilitate translation in to localized languages
- They feature multiple levels that users can employ to filter log messages
- The following guidelines apply to event messages:
- They provide information about the state of the adapter for use by monitor tooling
- Represented as common base event data at run time, event messages can be included in the extended LogUtils.log method signatures
Support for protecting sensitive user data in log and trace files
WebSphere Adapter Toolkit provides support for confidential tracing of properties. This means that when you decide whether a property might contain potentially sensitive data then use a special interface to record that information in a log or trace message. Data recorded with the special interface is displayed in the logs by a "XXXX". This functionality is most useful to customers who mainly deal with numerous confidential information such as banks, healthcare companies and defense. This property is a part of the Adapter Foundation Classes, and so it can be used by any adapters.
When a property is marked as confidential and if it needs to be logged or traced, then you record the information using a special confidential log and trace method provided in the logUtils will be invoked.
The following types of information are considered potentially sensitive data and will be hidden:
- The contents of a business object
- The contents of the object key of the event record
- User names, Password, Environment, and Role
- The URL used to connect to the Enterprise Information System (EIS)
The following types of information are not considered potentially sensitive data and will not be hidden:
- The contents of the event record that are not part of the event record object key. For example, the transactionID ( XID), event ID, business object name, and event status
- Business object schemas
- Call sequences
Inserting log and trace messages
The WebSphere Adapter Toolkit automatically provides entry and exit tracing statements to the generated code, excluding constructors and accessor methods. The WebSphere Adapter Toolkit does not add logging and tracing statements to the generated code for a JCA resource adapter. You will not be able to manually add logging and tracing to the generated JCA adapter code.
You can insert log or trace statements into your generated IBM WebSphere adapter code using a dialog box that collects information about the log or trace statement to be generated and insert the appropriate code at the cursor position.
Trace messages
Trace messages convey information that is intended for support teams and developers. Such information includes stack dumps for exceptions and operation logic for debugging purposes. Because trace messages are directed at the teams that wrote or support the adapter rather than customers, trace messages need not be translated and can, in fact, be hard-coded in the adapter.
Writing a trace message
You use the trace method of the LogUtils class to generate a trace message. This method has two signatures. One of them is informational. The other is associated with an exception.
void trace (Level l, String classname, String method, String msg) void trace (Level l, String classname, String method, String msg, Exception ex)In an outbound or inbound scenario, to get the LogUtils object instance, in IBM Integration Designer, Right click the method and select the following option:
- Source > Insert Trace Statement
In an outbound scenario, you can use the logger property as a consistent way to get a log object to write log or trace messages into log or trace files.
Trace messages might contain data from the customer's EIS. Because a customer might be unwilling to send a trace file that contains sensitive data to a support specialist for analysis, you can optionally use the traceConfidential method of the LogUtils class to write confidential trace messages whose EIS-specific content is replaced by a string of XXX's when the customer enables the HideConfidentialTrace property. Like the trace method, the traceConfidential method has two signatures. One of them is informational. The other is associated with an exception.
void traceConfidential (Level l, String classname, String method, String msg, Object[] confidentialData) void traceConfidential (Level l, String classname, String method, String msg, Object[] confidentialData, Exception e)Example of informational trace message
getLogUtils().trace (Level.Fine, "EISSAResourceAdapter", "openConnect", "Successfully connected to EIS Simulator");Example of exception trace message
getLogUtils().trace(Level.Finer, "EISSAResourceAdapter", "closeConnection", "While attempting to close the connection to EIS Simulator, EISS API reported the server had already closed the connection previously due to inactivity. Ignoring because connection was closed all the same", EISSAPIException);Example of trace message for the outbound scenario
public<AdapterPrefixName>ConnectionFactory(ConnectionManager connMgr, WBIManagedConnectionFactory mcf) { super(connMgr, mcf); getLogUtils().trace(Level.FINE,"com.ibm.(AdapterPrefixName).outbound. <AdapterPrefixName>ConnectionFactory", "<AdapterPrefixName>ConnectionFactory()", "test");}Example of trace message for the inbound scenario
public javax.resource.cci.Record getRecordForEvent (com.ibm.j2ca.extension.eventmanagement.Event event) throws javax.resource.ResourceException, javax.resource.spi.CommException { logger.trace(Level.FINE, "com.ibm.<AdapterPrefixName>inbound.<AdapterPrefixName>EventStoreWithXid", "getRecordForEvent()", "test"); return null;}}Example of trace message for the outbound scenario with confidential tracing property enabled
public<AdapterPrefixName>ConnectionFactory(ConnectionManager connMgr, WBIManagedConnectionFactory mcf) { super(connMgr, mcf); getLogUtils().traceConfidential(Level.FINE, "com.ibm.<AdapterPrefixName>.outbound.<AdapterPrefixName>ConnectionFactory", "<AdapterPrefixName>ConnectionFactory()", "test", new Object[] { "str" });}Example of trace message for the inbound scenario with confidential tracing property enabled
public javax.resource.cci.Record getRecordForEvent (com.ibm.j2ca.extension.eventmanagement.Event event) throws javax.resource.ResourceException, javax.resource.spi.CommException { logger.traceConfidential(Level.FINE, "com.ibm.<AdapterPrefixName>.inbound.<AdapterPrefixName>EventStoreWithXid", "getRecordForEvent()", "test", new Object[] { "str" }); return null;}In the previous code snippets, getLogUtils() and logger are instances of the LogUtils class.
Trace levels
Three trace levels allow users to adjust the level of detail. Consult the guidelines shown in the following table to determine which trace level to assign to a trace message.
Trace level indicators
Level Indicator Significance Fine 1 This trace features the lowest level of detail. It includes broad actions taken by the adapter such as establishing a connection to the EIS, converting an event in the EIS to a business object (key values only), processing a business object (key values only). Finer 2 This trace provides more detailed information about adapter logic, including API calls to the EIS and any parameters or return values. Finest 3 This is the most detailed level and includes method entry, exit, and return values. Include complete business object dumps and all detail needed to debug problems.
Configure log and trace detail level
Set the trace level on the package to trace to all in the Change Log Detail Levels field: For example, if the adapter package name is com.ibm.myadapter, modify the Change Log Detail Levels pane and add com.ibm.myadapter.* = all."
Performance considerations
Tracing assists developers and troubleshooters. Due to the significant performance cost incurred by tracing, however, many customers disable it in production environments. When developing or troubleshooting, it is good practice to check whether tracing is enabled before building to generate trace messages. You can do this by checking method LogUtils.isTraceEnabled(java.util.logging.Level) before building the adapter. The following is an example:
if(logUtils.isTraceEnabled(Level.Fine) { getLogUtils().trace(...);
Log messages
Log messages convey timely information intended for consumption by customers: warnings about potential problems, errors that have occurred and suggested fixes for those errors, and information that is necessary or helpful to understanding how the adapter operates.
Message files
To facilitate translation of log messages for different user groups, place all log messages in a resource bundle file rather than hard-code them in the adapter itself. The convention for packaging this bundle file is to embed it in the adapter RAR as <adapter package>.emd/logMessages.properties.
The message file can contain one or more messages. Each message should consists these three parts:
- Message Identifier – The message ID follows the format NNNNNmmmmS, where NNNNN is a five-letter component prefix, mmmm is the message number, and S identifies the message type. For example, a message identifier such as ABCDE0001E has a component identifier of ABCDE and a message number of 0001. The message type E tells you this is an error message. The component identifier must be registered with IBM to avoid conflicts between products. The type identifier should conform to one of the values specified in the Log Level table shown below. The message number is left to you.
- Explanation – The explanation provides an in-depth description of the message. Assume the customer is unfamiliar with the meaning of the base message. The explanation is the first level of help documentation for users, not a crutch for a poorly written base message.
- User Action – For every explanation of what went wrong, typically there are actions that customers can take to rectify the situation or to ensure that it doesn't happen again. The User Action field provides detailed information about what customers can do and is very much like first-level help documentation.
The following is an example of a message file:
0001=CWYBS0001I: Adapter {1} started. 0001.explanation=The adapter has successfully initialized and is now ready to service requests. 0001.useraction= 0004=CWYBS9999E: Failed to establish connection link to server on host {1}. 0004.explanation=The adapter is unable to contact the backend application. Business data cannot be exchanged with the backend until this issue is resolved. 0004.useraction= Check your adapter configuration and ensure the specified host and port match the machine and port on which the backend is listening. If correct, check that your backend application is on-line and accepting requests.
Message types
There are two message types for adapters, ADAPTER_RBUNDLE and BASE_RBUNDLE. The BASE_RBUNDLE is reserved for the Adapter Foundation Classes. The message types are used to distinguish between the adapter and the base classes message file. The default value of Message Type field is ADAPTER_RBUNDLE. You use only the ADAPTER_RBUNDLE message type because you should only access adapter message file.
Log levels
Log Levels and indicators
Level Indicator Significance Fatal F Task cannot continue. Component cannot function Severe E Task cannot continue. Component can still function. This can also indicate an impending unrecoverable error, including situations that strongly suggest that resources are on the verge of being depleted. Warning W Potential error or impending error. This includes conditions that indicate a progressive failure - for example, the potential leaking of resources. Audit A Significant event affecting server state or resources Info I General information outlining overall task progress.
Writing a log message
Use the log method of the LogUtils class to generate log messages. This method accepts parameters similar to that of the trace file. Instead of providing a hard-coded message, however, provide a key to the message from the log message file. This log method can also take optional parameters if there are values to be substituted in the message.
void log (Level l, int bundleType, String classname, String method, String msgKey) void log (Level l, int bundleType , String classname, String method, String msgKey, Object[] params)For example, if you have defined parameters in your log message such as "Successfully processed business object {1} with id {2}", you would provide values for those parameters using the argument params[].
Since parameters are not translated, avoid passing hard-coded phrases as parameters because the resulting message will be a combination of English and translated text. Values that are language-independent, such as key values or object names, are appropriate as log message parameters.
Similarly to trace messages, parameters in a log message can contain data from the customer's EIS. Because a customer might be unwilling to send a log file that contains sensitive data to a support specialist for analysis, you can optionally use the logConfidential method of the LogUtils class to generate confidential log messages whose EIS-specific content is replaced by a string of XXX's when the customer enables the HideConfidentialTrace property. Like the log method, the logConfidential method accepts parameters similar to that of the trace file. Instead of providing a hard-coded message, however, provide a key to the message from the log message file. The logConfidential method can also take optional parameters if there are values to be substituted in the message.
void logConfidential (Level l, int bundleType, String classname, String method, String msgKey, Object[] params) void logConfidential (Level l, String classname, String method, String msgKey, CBEEngineData engine) void logConfidential (Level l, String classname, String method, String msgKey, Object[] params) void logConfidential (Level l, String classname, String method,String msgKey, Object[] params,CBEEngineData engineData)In an outbound or inbound scenario, to get the LogUtils object instance, in IBM Integration Designer. Right click the method and select the Source Insert Log Statement option:.
Example of log message for the outbound scenario
public HelloWorldConnectionFactory(ConnectionManager connMgr, WBIManagedConnectionFactory mcf) { super(connMgr, mcf); getLogUtils().log(Level.INFO, LogUtilConstants.ADAPTER_RBUNDLE, "com.ibm.helloworld.outbound.HelloWorldConnectionFactory", "HelloWorldConnectionFactory()", "10"); }Example of log message for the inbound scenario
public javax.resource.cci.Record getRecordForEvent (com.ibm.j2ca.extension.eventmanagement.Event event) throws javax.resource.ResourceException, javax.resource.spi.CommException { logger.log(Level.INFO, LogUtilConstants.ADAPTER_RBUNDLE, "com.ibm.helloworld.inbound.HelloWorldEventStoreWithXid", "getRecordForEvent()", "10"); return null; }Example of log message for the outbound scenario with confidential tracing property enabled
public HelloWorldConnectionFactory(ConnectionManager connMgr, WBIManagedConnectionFactory mcf) { super(connMgr, mcf); getLogUtils().logConfidential(Level.INFO, LogUtilConstants.ADAPTER_RBUNDLE, "com.ibm.helloworld.outbound.HelloWorldConnectionFactory", "HelloWorldConnectionFactory()", "10", new Object[] { "str" }); }Example of log message for the inbound scenario with confidential tracing property enabled
public javax.resource.cci.Record getRecordForEvent com.ibm.j2ca.extension.eventmanagement.Event event) throws javax.resource.ResourceException, javax.resource.spi.CommException { logger.logConfidential(Level.INFO, LogUtilConstants.ADAPTER_RBUNDLE, "com.ibm.helloworld.inbound.HelloWorldEventStoreWithXid", "getRecordForEvent()", "10", new Object[] { "test" }); return null; }In the previous code snippets, getLogUtils() and logger are instances of the LogUtils class.
Monitor and measuring performance
The purpose of monitoring is to observe the progress of execution of WebSphere Business Integration applications, and the WebSphere Business Integration system itself, and publish the results of this observation.
Monitor can be accomplished by:
- Use the Common Event Infrastructure (CEI), a set of modular event processing components that provide functions to capture information about significant system or business occurrences.
- Use the Performance monitoring infrastructure (PMI) to collect data, such as average response time and total number of requests, from various components in a server runtime environment, and organizes the data into a tree structure.
- Use Application response measurement (ARM) to monitor the availability and performance of applications.
Common Event Infrastructure (CEI)
The Common Event Infrastructure (CEI) is a set of modular event processing components that provide functions to capture information about significant system or business occurrences.
IBM Business Process Manager includes the Common Event Infrastructure technology, which adapters use to create, transmit, persist, and distribute events.
If an adapter is running on a broker that does not use the IBM CEI technology but instead uses its own event monitoring technology; that broker can also plug-in its monitoring infrastructure with the adapters by implementing the interfaces described in the sections that follow and by optionally using schema definitions (.xsd and .mes files).
EventSourceContext
The EventSourceContext interface provides the context for a monitored component and is the starting point for the adapters. The EventSourceContext interface provides APIs to obtain event source, which is an application or component that submits an event creation request to CEI. Each event source defines a set of event points, which represent the points where CEI events are triggered.
/** * Provides the context for a monitored component. */ package com.ibm.j2ca.extension.monitoring.CEI; public interface EventSourceContext { /** * Returns an event source for a monitored element. * @param elementKind an artifact kind that can be monitored e.g ResourceAdapter. * @param elementName the name of the monitored element * @return the event source object that encapsulates the element to be monitored */ EventSource getEventSource(String elementKind, String elementName); /** * Creates an event source for a monitored element. The usage is similar to * java.util.logging.Logger. * @param componentTypeQName : The element type can be specified using the element * type from * a schema which defines the structure/syntax of the artifact itself * e.g.http://www.ibm.com/xmlns/prod/websphere/scdl/ eis/6.0.0:JCAAdapter" * @param componentQName the name of the component , * e.g http://www.ibm.com/j2ca/ResourceAdapter:Customer" * @return the event source factory for the component to be monitored */ public interface Factory{ EventSourceContext create(String componentTypeQName, String componentQName); }}
EventSource
Event Sources are applications or components that submit event creation requests to CEI. Each monitorable element defines an event source. An example of event source is an adapter. An event source is used to retrieve event points in order to send monitoring events to a CEI logger.
package com.ibm.j2ca.extension.monitoring.CEI; /** * An event source represents a monitoarable element kind such as an adapter.... * Each monitorable element defines an event source. Each event source defines a set of component-element specific event points. An event source object is used * to retrieve event points to fire monitoring events */ public interface EventSource { /** * returns an EventPoint for the monitored element * @param eventPointName a valid event nature for this event */ public EventPoint getEventPoint(String eventPointName);}
EventPoint
Every monitorable component needs to define the event points. Each event point defines an event and the data or payload associated with that event. The EventPoint is used to fire monitoring events. The client of an event point needs to know the payload of the fired events. Where the payload of an event can be specified in an event catalog for each component.
package com.ibm.j2ca.extension.monitoring.CEI; /** * Every monitorable component needs to defines the event points. Each event point defines an event and the data/payload associated with that event. The EventPoint is used to fire monitoring events. * The client of an event point needs to know the payload of the fired events. */ public interface EventPoint { /** *return the name of the event point */ String getName(); /** * Checks if an event needs to be fired for this event point. This method minimizes the overhead of inactive monitoring * points. Returns: true if this event point fires monitoring events. */ boolean isEnabled(); /** * Fires a monitoring event. * @param name the name of the payload data element. * @param value the value of the payload data element */ void fire(String name, Object value); /** * Fires a monitoring event, * it is a convenient method for payloads with two data elements. */ void fire(String firstName, String secondName, Object firstValue, Object secondValue); /** * Fires a monitoring event * It is a convenient method for payloads with list of data elements. */ void fire(String[] names, Object[] values);}
Unique Id
The Unique Id interface can be used to uniquely identify event points:
/** * Every monitorable component needs to defines the event points. * Each event point defines * an event and the data/payload associated with that event. The EventPoint is * used to fire monitoring events. * The client of an event point needs to know the payload of the events.h */ public interface AdapterContext { public String getUniqueId(); }
Example of the schema definition files
- Monitorable element schema (.mes file):
Monitorable element schema can be used to define element types that can be logged into the CEI database (Polling, InboundEventDelivery, Outbound etc) and it can also define natures that are available for each element type (entry, exit, failed, polling etc).
<?xml version="1.0" encoding="UTF-8"?> <EventNaturesSpec name="EventNatures" targetNamespace= "http://www.ibm.com/xmlns/prod/websphere/scdl/eis/6.0.0:JCAAdapter" xmlns="http://www.ibm.com/xmlns/prod/websphere/monitoring/6.1/mes" xmlns:eis="http://www.ibm.com/xmlns/prod/websphere/scdl/eis/ 6.0.0:JCAAdapter" shortName="ResourceAdapter"> <Property>CEI</Property> <ElementKind name="Polling"> <EventNature name="STARTED" eventName= "eis:WBI.JCAAdapter.Polling.STARTED" /> <EventNature name="STOPPED" eventName= "eis:WBI.JCAAdapter.Polling.STOPPED" /> </ElementKind> </EventNaturesSpec>- Xsd schema (.xsd):
Xsd schema can be used to provide CEI specific to each data elements and it also defines the event types that can be emitted for the data elements.
<?xml version="1.0" encoding="UTF-8"?> <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace= "http://www.ibm.com/xmlns/prod/websphere/scdl/eis/6.0.0:JCAAdapter" xmlns:eis= "http://www.ibm.com/xmlns/prod/websphere/scdl/eis/6.0.0:JCAAdapter" xmlns:wbi= "http://www.ibm.com/xmlns/prod/websphere/monitoring/6.1"> <import namespace="http://www.ibm.com/xmlns/prod/websphere/monitoring/ 6.1" schemaLocation="WBIEvent.xsd" /> <complexType name="WBI.JCAAdapter.Polling.STARTED"> <complexContent> <extension base="wbi:WBIMonitoringEvent"> <sequence> <element name="PollFrequency" type="int" minOccurs="1" maxOccurs="1" /> <element name="PollQuantity" type="int" minOccurs="1" maxOccurs="1" /> </sequence> </extension> </complexContent> </complexType> <complexType name="WBI.JCAAdapter.Polling.STOPPED"> <complexContent> <extension base="wbi:WBIMonitoringEvent"></extension> </complexContent> </complexType> </schema>
Extend Common Event Infrastructure logging on IBM Business Process Manager
You can extend CEI logging to WebSphere Process Server by adding custom events.
Example of how to log an event
The following example describes how to log an event named Polling, when the event action is Started and you want to log two integers values for this event in the CEI database.
- Monitorable Element Schema “.mes” file changes
Defines element types to monitor (Polling for example) and it also defines natures that are available for each element type (STARTED).
<?xml version="1.0" encoding="UTF-8"?> <EventNaturesSpec name="EventNatures" targetNamespace= "http://www.ibm.com/xmlns/prod/websphere/scdl/eis/6.0.0:JCAAdapter" xmlns= "http://www.ibm.com/xmlns/prod/websphere/monitoring/6.1/mes" xmlns:eis= "http://www.ibm.com/xmlns/prod/websphere/scdl/eis/6.0.0:JCAAdapter" shortName="ResourceAdapter"> <Property>CEI</Property> <ElementKind name="Polling"> <EventNature name="STARTED" eventName ="eis:WBI.JCAAdapter.Polling.STARTED" /> </ElementKind> </EventNaturesSpec>- “.xsd” file changes
The .xsd event schema file provides monitoring that is specific to each data element, and it also defines the types of events that can be emitted for the data elements. The following is an example of xsd event schema content::
<?xml version="1.0" encoding="UTF-8"?>" <EventSpec xmlns= "http://www.ibm.com/xmlns/prod/websphere/monitoring/6.0.0/es" name="Events" targetNamespace= "http://www.ibm.com/xmlns/prod/websphere/scdl/eis/6.0.0:JCAAdapter" xmlns:er= "http://www.ibm.com/xmlns/prod/websphere/recovery/6.0.0/es/eventpayloads" > <Event name= "ResourceAdapter.Polling.STARTED" situationType= "STATUS" situationCategory="ReportSituation" reasoningScope= "EXTERNAL" parent="WBI.MonitoringEvent"> <Payload> <Data name= "PollFrequency" type="int" minOccurs="0" maxOccurs="1"/> <Data name= "PollQuantity" type="int" minOccurs="0" maxOccurs="1"/> </Payload> </Event>- Invoke Events
import com.ibm.j2ca.extension.logging.internal.cbe.EngineData; ... CBEEngineData engineData = CBEEngineDataFactory.getEngineDataForEventType("Polling"); //This will instantiate the EngineData class for user defined event e.g "Polling". engineData.setValue("EventAction","STARTED"); //This will set the user defined action e.g. "Started" engineData.setValue("PollFrequency", activationSpec.getPollPeriod()); //This will set the user defined arg engineData.setValue("PollQuantity", activationSpec.getPollQuantity()); //This will set the user defined arg
Performance monitoring infrastructure (PMI) for resource adapters
The Performance Monitoring Infrastructure (PMI) is the underlying framework in WebSphere Application Server that gathers performance data from various runtime resources such as adapters.
The purpose of monitoring is to observe the progress of execution of WebSphere Business Integration applications, and the WebSphere Business Integration system itself, and publish the results of this observation. By using Performance Monitoring Infrastructure (PMI), you can observe the progress of adapters running in the server runtime environment and other business integration applications, and publish the results. PMI collects data, such as average response time and total number of requests, from various components in the server and organizes the data into a tree structure. You can observe data through the Tivoli Performance Viewer, a graphical monitoring tool that is included with WAS..
You can monitor the performance of the adapters by having PMI collect data at the following points:
- InboundEventRetrieval:
Will monitor performance of retrieving events from the EIS. It enables monitoring of entering, exiting, failing of the EventManager.getEvents() method.
- InboundEventDelivery:
Will monitor the performance when resource adapter deliver data to the endpoint, which conveys changes in or general information from the EIS. It enables monitoring of entering, exiting, failing of the EventSender.doSendEvent() method.
- Outbound:
Will monitor the performance of outbound processing of a resource adapter. It enables monitoring of entering, exiting, failing of the WBIInteraction.execute() method.
- Extend PMI on IBM Business Process Manager To add a user-defined element or method into the list of monitorable components you need to modify code and schema files.
- Extend PMI on WAS Extend PMI on WAS does not require you to add content into schema files (.xsd and.mes files).
Extend PMI on IBM Business Process Manager
To add a user-defined element or method into the list of monitorable components you need to modify code and schema files.
Purpose
- Monitorable Element Schema (.mes) file changes
Defines the element type within an adapter where monitoring can be attached.
The element type is specified using the Qname of the element type from the schema, which defines the structure of the artifact itself. It also defines the natures (ENTRY, EXIT, FAILURE) that are available for that type of element. The sample below declares how the monitors can be attached to myOutbound. For example myOutbound method can emit event at ENTRY, EXIT or FAILURE event points.
<?xml version="1.0" encoding="UTF-8"?> <EventNaturesSpec name="EventNatures" targetNamespace= "http://www.ibm.com/xmlns/prod/websphere/scdl/eis/6.0.0:JCAAdapter" xmlns= "http://www.ibm.com/xmlns/prod/websphere/monitoring/6.0.0/mes" shortName="JCAAdapter"> <Property>CEI</Property> <ElementKind name="myOutbound"> <EventNature name="ENTRY" eventName="eis:WBI.JCAAdapter.myOutbound.ENTRY" /> <EventNature name="EXIT" eventName="eis:WBI.JCAAdapter.myOutbound.EXIT" /> <EventNature name="FAILURE" eventName="eis:WBI.JCAAdapter.myOutbound.FAILURE" /> </ElementKind>- “.xsd” file changes
The xsd event schema file provides monitoring specific of each data elements and it defines the types of events, payload or extended element for each event type that can be emitted for the data elements. Content of schema looks like following:
<?xml version="1.0" encoding="UTF-8"?> <EventSpec xmlns= "http://www.ibm.com/xmlns/prod/websphere/monitoring/6.0.0/es" name="Events" targetNamespace= "http://www.ibm.com/xmlns/prod/websphere/scdl/eis/6.0.0:JCAAdapter" xmlns:er= "http://www.ibm.com/xmlns/prod/websphere/recovery/6.0.0/es/eventpayloads" > <complexType name="WBI.JCAAdapter.myOutbound.ENTRY"> <complexContent> <extension base="wbi:WBIMonitoringEvent" /> </complexContent> </complexType> <complexType name="WBI.JCAAdapter.myOutbound.EXIT"> <complexContent> <extension base="wbi:WBIMonitoringEvent" /> </complexContent> </complexType> <complexType name="WBI.JCAAdapter.myOutbound.FAILURE"> <complexContent> <extension base="wbi:WBIMonitoringEvent"> <sequence> <element name="FailureReason" type="string" /> </sequence> </extension> </complexContent> </complexType> </schema>- Invoke PMI:
To invoke PMI statistics around a method named myOutbound, you would do the following:
- Import com.ibm.j2ca.extension.monitoring.CEI.EventPoint;
- Define a unique PMI event point name.
For example String eventName = uniqueAdapterID + “##” + "myOutbound";
- Get an instance of EventPoint:
for each eventAction ENTRY, EXIT, FAILURE. EventPoint ep = (EventPoint)(EventPoints.INSTANCE.getEventPoints(eventName,eventAction))
- If eventPoint is enabled, then fire event for Entry, Exit and Failure is invoked.
Entry event is fired in the beginning of the method call, exit event is fired in the end of the method call and failure event is fired in case of exception. For example we can invoke failure event by following API call.
if(ep.isEnabled()) { ep.fire(new String[]{"FailureReason"}, new Object[]{ex.toString()});}
Extend PMI on WebSphere Application Server
Extend PMI on WebSphere Application Server does not require you to add content into schema files (.xsd and.mes files).
Invoke PMI
Invoke PMI statistics on WebSphere Application Server can be done by following the steps listed below.
The steps below describe how to invoke PMI statistics around a method named myOutbound.
- Import com.ibm.j2ca.extension.monitoring.CEI.EventPoint;
- Define a unique PMI event point name.
For example String eventName = uniqueAdapterID + "##" + "myOutbound";
- 3. Get an instance of EventPoint: for each eventAction ENTRY, EXIT, FAILURE.
EventPoint ep = (EventPoint)(EventPoints.INSTANCE.getEventPoints(eventName,eventAction))
- 4. If eventPoint is enabled fire event for Entry, Exit and Failure.
Entry event is fired in the beginning of the method call, exit event is fired in the end of the method call and failure event is fired in case of exception. For example we can invoke failure event by following API call:
if(ep.isEnabled()) { ep.fire(new String[]{"FailureReason"}, new Object[]{ex.toString()});}
Application response measurement (ARM)
Application response measurement (ARM), an API jointly developed by an industry partnership, monitors the availability and performance of applications. ARM is an approved standard of The Open Group.
To ensure that requests are performing as expected in a multi-tiered heterogeneous server environment, you must be able to identify requests based on business importance. In addition, you must be able to track the performance of those requests across server and subsystem boundaries, and manage the underlying physical and network resources used to achieve specified performance goals.
You can collect this performance data by using versions of middleware that have been instrumented with the Application Response Measurement (ARM) standard.
Combining ARM calls within your application with an ARM agent, users of your application can answer questions like:
- Is a transaction (and the application) hung, or are transactions failing?
- What is the response time?
- Are service level commitments being met?
- Who uses the application and how many of each transaction are used?
The resource adapters are instrumented with the Application Response Measurement API, an API that allows adapters to collect and manage transaction end-to-end response time and volumetric information.
The adapters can participate in IBM Tivoli Monitoring for Transaction Performance, by allowing collection and review of data concerning transaction metrics.
The resource adapters uses ARM defined transactions at following three points:
- InboundEventRetrieval:
Will measure response time of retrieving events from the EIS. It measures response time of the EventManager.getEvents() method.
- InboundEventDelivery:
Will measure response time when the resource adapter delivers data to the endpoint, which conveys changes in or general information from the EIS. It measures the response time of the EventSender.doSendEvent() method.
- Outbound:
Will measure the response time of outbound processing of a resource adapter. It measures the response time of the WBIInteraction.execute() method.
An ARM agent, such as Tivoli Composite Application Manager for Response Time Tracking, can perform response time collection and analysis.
To enable/extend ARM, different brokers need to implement: armTransactionFactoryName() method found in com.ibm.j2c.monitoring.ARM AdapterArmTransactionFactory class. This transaction factory creates all objects that defined in the org.opengroup.arm40.transaction package.
ARM interface
/** * ArmTransactionFactory provides methods to create instances of the classes in the org.opengroup.arm40.transaction package. **/ package com.ibm.j2ca.extension.monitoring.ARM; public interface AdapterARMTransactionFactory { public String armTransactionFactoryName();}
Extend application response measurement (ARM) events using the InteractionMetrics
The WebSphere container provides InteractionMetrics interface that introduces the capability for any resource adapter to participate in reporting its usage time in a request and have that time reported by the various request metrics reporting tools available for WebSphere.
Tracking interaction metrics
The WebSphere ConnectionEventListener has implemented this class.
WebSphere keeps an EventListener associated with each ManagedConnection to track the interaction time on a per ManagedConnection basis to gather usage time statistics and data for each ManagedConnection, which can be used to assess and troubleshoot performance-related problems.
In order for resource adapters to participate in various WebSphere RequestMetric tools for outbound, diagnostic tools, etc, follow these steps:
- Import com.ibm.websphere.j2c.*;
- Get interaction metrics listener by using WBIManagedConnection classes' getInteractionListener() method or by calling WBIInteraction classes' getInteractionListener() method.
- At the beginning of each method to report statics for, call isInteractionMetricsEnabled, check whether the listener is enabled. listener.isInteractionMetricsEnabled(); If it returns false, do nothing for the rest of this request.
- If isInteractionMetricsEnabled returns true, call preInteraction in the beginning of a method where you want to start ARM Object ctx = listener.preInteraction();
- Before sending the request to the downstream EIS process, call getCorrelator and attach the correlator with the request so the downstream EIS process can get the correlator. Obtain correlation byte[] armCorBytes = listener.getCorrelator();
- In the end of method you need to collect the ARM statistics by calling postInteraction(ctx, InteractionMetrics.RM_ARM_GOOD, ispec);
- In case of exception call postInteraction(ctx, InteractionMetrics.RM_ARM_FAILED, ispec);
For details about interactionMetrics API, see: l
Extend ARM events using the Open Group API
Use following reference information to make you component ARM-enabled using the Open Group API.
Application response measurement (ARM) documentation
Use following links to access the information about how to make you component ARM enabled using the Open Group API.:
First failure data capture (FFDC)
First failure data capture (FFDC) provides the instrumentation for exception handlers (catch blocks) to record exceptions that are thrown by a component.
To provide FFDC for your component, exception handlers can be instrumented by defining an aspect, which determines the packages, classes, methods, and exceptions types that will be supported by FFDC.
Users extend the abstract FFDCSupport aspect that captures the required context, such as method name and exception object, automatically. No additional configuration is required because the data provided by the aspect is the same data that would be provided from a hand-coded invocation.
FFDC processing overview
Instead of explicitly instrumenting catch blocks by calling FFDC directly, either manually or by using a tool, you can write a simple aspect using the AspectJ language, which encapsulates the FFDC policy for your code.
The FFDCSupport aspect is abstract. Like an abstract class, FFDCSupport cannot be instantiated and defers some of its implementation to a sub-aspect. It follows the standard library aspect pattern of declaring an abstract pointcut for which you must declare a concrete implementation. This concrete implementation of the pointcut can use the simple AspectJ scoping pointcut designators (PCD) such as within() and withincode() to determine the packages, classes, and methods to be included in the FFDC policy.
FFDC programming examples
The following examples assume a certain familiarity with the AspectJ language (see http://eclipse.org/aspectj/). In most cases a user of the FFDCSupport aspect will require knowledge of only a small subset of the AspectJ syntax. In particular they should know how to define a concrete aspect by extending an abstract one and how to declare a concrete pointcut typically using simple scoping primitive pointcuts.
Figure 1. Add FFDC to the sample package
import com.ibm.websphere.ffdc.FFDCSupport; public aspect Example_1 extends FFDCSupport { protected pointcut ffdcScope () : within(com.<AdapterPrefixName>.*); }Figure 1 illustrates the simple aspect Example_1 that adds FFDC to all classes in the com.<AdapterPrefixName> package. The example illustrates the following processing:
- On line 1, the FFDCSupport aspect is imported
- On line 3, the FFDCSupport aspect is extended and made concrete in a similar way to a Java™ class.
- On line 5, the inherited abstract pointcut ffdcScope()\ is made concrete.
This is done using the within() pointcut designator (PCD) and “*” wildcard that results in FFDC for all classes in the com.<AdapterPrefixName> package. For example, com.<AdapterPrefixName>.Bar.
Figure 2. Add FFDC to com.<AdapterPrefixName> package and all sub-packages
import com.ibm.websphere.ffdc.FFDCSupport; public aspect Example_2 extends FFDCSupport { protected pointcut ffdcScope () : within(com.<AdapterPrefixName>..*); }Figure 2 illustrates aspect Example_2, which differs from Example_1 . Notice line 13, where the wildcard includes "double dots" (..) in the within() PCD, which means the includes all classes in the com.<AdapterPrefixName> package and sub-packages. For example, com.<AdapterPrefixName>.impl.Bar.
Figure 3. Add FFDC to all classes in the com.<AdapterPrefixName> package excluding com.<AdapterPrefixName>.
import com.ibm.websphere.ffdc.FFDCSupport; public aspect Example_3 extends FFDCSupport { protected pointcut ffdcScope () : within(com.<AdapterPrefixName>.*) && !within(com.<AdapterPrefixName>); }In Figure 3 aspect Example_3 has the same effect as Example_1 except it excludes FFDC for class com.<AdapterPrefixName> by using the && and ! operators to form a pointcut expression.
Figure 4. Add FFDC to the com.<AdapterPrefixName> package but exclude aMethod
import com.ibm.websphere.ffdc.FFDCSupport; public aspect Example_3 extends FFDCSupport { protected pointcut ffdcScope () : within(com.<AdapterPrefixName>.*) && !withincode(* com.<AdapterPrefixName>.aMethod(..)); }In Figure 4, aspect Example_4 is also similar to Example_1, however FFDC is excluded from a particular method on line 30 using the withincode() PCD.
Figure 5. Add FFDC to the com.<AdapterPrefixName> package but exclude catch blocks for ClassNotFoundException handling
import com.ibm.websphere.ffdc.FFDCSupport; public aspect Example_4 extends FFDCSupport { protected pointcut ffdcScope () : within(com.<AdapterPrefixName>.*) && !args(ClassNotFoundException); }In Figure 5 aspect Example_5 illustrates how to account for a programming by exception, where certain exceptions are not considered to be a failure and should not be reported. In the example, the handling of ClassNotFoundException will not be reported to FFDC. The args() PCD on line 39 selects a join points based on contextual information in this case the exception passed to the handler join point.
If using the FFDCSupport aspect, you can ensure a consistent FFDC policy for your application by adding declare warning or error advice to your aspects While this capability is not explicitly provided by the FFDCSupport aspect, you can leverage the use of AspectJ and follow a standard pattern of enforcing a policy implemented using an aspect with compiler warnings or errors.
In Figure 6, aspect Example_6 illustrates how to prevent direct use of the FFDC API or undesired dumping of exception messages and stack traces to the console. The declare warning statements on lines 51 and 57 instruct the AspectJ compiler to issue warnings during weaving if join points are matched by the accompanying pointcuts on lines 48 and 54.
The statements are only evaluated during compilation and have no impact on the runtime.
Figure 6. Warn user about calling FFDC directly or dumping stack traces
import com.ibm.websphere.ffdc.FFDCSupport; public aspect Example_6 extends FFDCSupport { protected pointcut ffdcScope () : within(com.<AdapterPrefixName>.*); public pointcut ffdcCall () : call(* com.ibm.websphere.ffdc..*(..)); declare warning : ffdcCall() && ffdcScope() : "Don't call FFDC directly. Use FFDCSupport aspect."; public pointcut dumpException () : call(void Throwable.printStackTrace(..)); declare warning : dumpException() && ffdcScope() : "Don't dump exceptions to console. Use FFDCSupport aspect."; }When using FFDCSupport aspect you can control the data gathered. Two template methods getSourceId and getProbeId are provided to you for this purpose. For example, you may want to limit the length of the source ID strings. In Figure 7, aspect Example_7 illustrates how to override the getSourceId method and return a short name.
Figure 7. Override default source ID generation to create short name
import com.ibm.websphere.ffdc.FFDCSupport; import org.aspectj.lang.JoinPoint; public aspect Example_7 extends FFDCSupport { protected pointcut ffdcScope () : within(com.<AdapterPrefixName>.*); protected String getSourceId (JoinPoint.StaticPart ejp) { String name = ejp.getSignature().getName(); return name; } }You can use FFDC to control how your classes are introspected by implementing the introspectSelf method. Class Person in Figure 8 illustrates how you can hide a sensitive field (in this example a password is hidden).
Figure 8. How to hide a sensitive field in this case a password
private class Person { private String userid = "USER"; private String password = "PASSW0RD"; public String[] introspectSelf () { String[] self = { "userid=" + userid, "password=XXXXXXXX" }; return self; }} Hide password field of Person class from introspection.
First failure data capture (FFDC) support
The adapter supports first failure data capture (FFDC), which provides persistent records of failures and significant software incidents that occur during run time in BPM or WebSphere Enterprise Service Bus.
The FFDC feature runs in the background and collects events and errors that occur at run time. The feature provides a means for associating failures to one another, allowing software to link the effects of a failure to their causes, and thereby facilitate the quick location of the root cause of a failure. The data that is captured can be used to identify exception processing that occurred during the adapter run time.
When a problem occurs, the adapter writes exception messages and context data to a log file, which is in the install_root/profiles/profile/logs/ffdc directory.
For more information about first-failure data capture (FFDC), see the BPM or WebSphere Enterprise Service Bus documentation.
To get the FFDC (First Failure Data Capture) specific diagnostic data for the adapter that needs to implement following logutils.logffdc method (example given below) in the catch block of the exception handling.
import com.ibm.j2ca.extension.logging.LogUtils; try{ ---- ----}catch (Exception e){ LogUtils.logFfdc(e, ManagedConnection.class, "ManagedConnection", "getWBIConnection", null);}AFC plays as the upper classes in the call chain so it can cover inbound and cursor portion, but the following components in AFC are just interface or abstract, so custom adapters have to invoke logFfdc themselves:
- outbound relevant, including the connection, interaction, and so on
- record implementation
- data binding
- command implementation
- event store implementation
- other component which call chain will not go into AFC
logFfdc is considered to be used in runtime rather than EMD tooling time.
Monitor Inbound Events
The adapter supports monitoring inbound events from the EIS server, in addition to the other events you are monitoring using IBM Business Monitor or WebSphere Business Events.
- Monitor inbound events using IBM Business Monitor
- Monitor inbound events using WebSphere Business Events
Foundation Classes Requirements
Adapters that employ the Foundation Classes for event monitoring must meet the following requirements:
- WBIMetadataDiscoveryImpl - Implementation for MetatdataDiscovery Interface
- RecordGeneratorForMonitor.java - Record generator for monitor enablement
Foundation Classes provides two different generators with or without the jaxb annotation:
- RecordGenerator
- RecordGeneratorWithAnnotation
Adapter Requirements
To enable inbound event monitoring, do the following changes:
- In the HelloWorldMetadataDiscovery class, add the below bold lines (array[5] and array[6]) to notify the monitoring inbound events support.
public MetadataConfigurationType[] getSupportedConfiguration() { return getMetadataConfiguration(); } public static MetadataConfigurationType[] getMetadataConfiguration() { MetadataConfigurationType[] array = new MetadataConfigurationType[7]; array[0] = MetadataConfigurationType.GENERATED_DATA_BINDING; array[1] = MetadataConfigurationType.GENERIC_RECORDS; array[2] = MetadataConfigurationType.GENERATED_RECORDS; array[3] = MetadataConfigurationType.INBOUND_SERVICE; array[4] = MetadataConfigurationType.OUTBOUND_SERVICE; array[5] = MetadataConfigurationType_WEBSPHEREBUSINESSMONITOR; array[6] = MetadataConfigurationType_WEBSPHERE_BUSINESS_EVENTS;- In the EMD HelloWorldInboundServiceDescription class, if the WBIMetadataDiscoveryImpl.MetadataConfigurationType_MonitorService/WebSphereBusinessEvent is interlocked by both adapter and tooling, individual adapter should return the class for the DataBindingGenerator:
//Monitor support if(WBIMetadataDiscoveryImpl.isSupportMonitor()){ dataDescription.setDataBindingGeneratorClassName ("com.ibm.j2ca.extension.dataexchange.bean.generator.RecordGeneratorForMonitor"); }else{ dataDescription.setDataBindingGeneratorClassName ("com.ibm.j2ca.extension.dataexchange.bean.generator.RecordGenerator");} dataDescription.setGenericDataBindingClassName(null);}
Exception messages
Exception messages, like trace messages, convey information about problems. The difference is that exception messages are tailored more directly to support teams familiar with adapter source code, and therefore need not be translated.
Treat text included in exception messages as you would text for trace messages. In general, exception messages are not directed at general users but rather at support teams who have the ability to investigate adapter source code. For that reason, exception messages need not be translated and can be hard-coded. If an exception is thrown and the customer must be informed of the problem, use an appropriate log message, which can be translated, to inform the customer; refrain from simply printing out the contents of the exception.
When implementing an adapter exception message, do the following:
- Define subclasses of ResourceException where appropriate and include relevant properties on these implementations
- Raise the exception with a message that can be hard-coded in English.
- Print the stack trace of the exception using the trace API. This allows support teams to see all exception details.
- When appropriate, the exception messages raised should have a corresponding high-level message in the LogMessages.properties file. The developer should log this high-level message after raising the exception so that general users can see an explanation of the error in their native language.
Change the Java logging API settings
To change the Java™ logging API settings, you modify a permission in the adapter deployment descriptor.
The following permission must be added to the adapter deployment descriptor, represented as the file ra.xml in the RAR package:
permission java.util.logging.LoggingPermission "control";
In the ra.xml file, this permission is as follows:
<security-permission> <security-permission-spec> grant { permission java.util.logging.LoggingPermission "control"; }; <security-permission-spec> <security-permission>
Validating the code
Validate your adapter implementation by unit testing it outside of a JCA container (unmanaged testing mode). You can then deploy to the target runtime server and test instances of the adapter (managed testing mode).
Unmanaged and managed testing modes are not mutually exclusive. A thorough testing regime typically involves unit testing to debug and refine adapter components before managed testing in the target environment.
Testing Enterprise Metadata Discovery for an adapter
Testing the EMD implementation means testing if the adapter can connect to EIS and discover services from an existing metadata repository or is able to build the appropriate interactions with the EIS by generating the required artifacts.
To test the enterprise metadata discovery (EMD) implementation for the developed resource adapter, copy the following three dependent JAR files into the connectorModule connector project from the IBM WebSphere Adapters Foundation Classes library.
- commonj.connector.jar
- CWYBS_AdapterFoundation.jar
- DESPI.jar
- Right-click connectorModule > import > File System and browse <WID>\eclipse\plugins\com.ibm.j2ca.wat.afc_7.5.0\runtime and select the required JAR files and click Finish.
![]()
Displaying the dependent JAR import
- Right-click on connector project (for example: HelloWorld) > properties > Java™ Build Path add the three JAR files to the build path by clicking Add JARs in the Libraries tab and click OK.
![]()
Displaying the dependent JAR selection
- On importing the dependent JAR files, the files are added to the connector project as below:
![]()
Displaying the dependent JAR files
- In theIBM Integration Designer window, click Go to the Business Integration perspective.
- Right-click inside the Business Integration section of theIBM Integration Designer window.
- Type in a new Module Name in the New Module window. Click Finish.
- Open the external service by clicking the File > New > External Service.
- In the External service window, expand Adapters and select Unlisted Adapters and click Next. Select the adapter name entered in the ra.xml file.
You can enter the adapter name in the ra.xml file using the Resource Adapter Deployment Descriptor editor.
- Click through Next to open the last External service window. Click Browse and select the module created in Step 4 to generate the required artifacts.
If you do not add the dependency JAR files to the connectorModule, the following error might display during the deployment: java.lang.NoClassDefFoundError: com.ibm.j2ca.base.WBIResourceAdapter
Testing the adapter in unmanaged mode
Testing in unmanaged mode means unit testing the adapter implementation in the development environment. You can unit test your adapter with JUnit, a widely used and reliable open source framework for regression testing.
JUnit: an open source framework for unit testing
JUnit is becoming the standard tool for unit testing in Java™ development environments. JUnit allows you to quickly and easily integrate automated regression testing into your coding and build processes.
With JUnit, an open source unit test framework, you can write and run tests for your adapter implementation. You use a simple setup() method to prepare each component for testing. Each test method can contain one or more assertions. The assertions test actual results against expected results. Using JUnit assertions, you can achieve a high degree of code quality and responsiveness to requirements outside of the adapter runtime environment.
A simple JUnit test case resembles the following:
public class MyTest extends TestCase { protected void setUp() throws Exception { super.setUp(); } public testSomething() throws Exception{ String result = classUnderTest.executeSomething(); assertEquals(result,"Something"); }}The setUp() method is called once before each test method. The purpose of the setUp() method is to prepare the component for the test. You can create several test methods; each must begin with the word test and contain at least one assertion.
The next section shows how to use the setUp() method to prepare your adapter for testing, and how to use the test methods to run functions. Because the goal is to test the adapter in unmanaged mode, you run the adapter outside of a JCA container.
Validating the adapter in unmanaged mode–testing the adapter as part of development, gradually building the test case suite to address requirements–is a first step. This prepares the adapter for managed testing in a runtime environment. It also yields useful artifacts: the test case suite remains useful after unit testing because changes in code that break the functionality are tracked, alerting you when testing future iterations inside the development environment.
For more information about JUnit, see http://junit.org.
Developing JUnit tests
You can unit test outbound and inbound processing by creating and specifying JCA contracts and operations. You then test and compare data before and after applying the tests. The EIS Simulator Adapter code sample illustrates these steps.
Outbound
The Java EE Connector Architecture (JCA) specification defines an unmanaged mode for running adapters. This means running the adapter outside of a JCA container and in process with the caller. This is the environment for developing JUnit tests.
Through a series of common client interface (CCI) and service provider interface (SPI) calls, you can force the adapter to perform an operation you want to test. First create instances of ManagedConnectionFactory and ResourceAdapter then set the appropriate properties in the client code.
Your adapter cannot be dependent on "live" data inside the EIS. If so, either return the data to a known state after every test, or create a mock implementation of the EIS API so that EIS data remains untouched.
setUp()
In the setup method for outbound, perform the following step:
- Load any schemas (if necessary)
Test
When you have completed the steps for setting up the test, you are ready to call the CCI interaction and validate the result. The following procedure creates an object, retrieves it, and validates its content.
In the test method, you need to do the following things:
These tasks can be delegated to helper methods
- Create the data and metadata you can work with (JavaBeans, SDO, or other format).
- Create a DataExchangeFactory for this data type, set the data as the bound object
- Create a StructuredRecord and initialize it, with the Data Exchange Factory and the metadata
- Invoke the adapter interaction.execute() using JCA CCI semantics
- Inspect the result of the output, by getting the bound object of the data exchange factory of the output record.
- Create a WBIRecord.
- Create a business object, populate it with data, and place it in WBIRecord.
- Set the appropriate verb in the business object.
- Call the interaction, capturing the output.
- Perform the assertion, which includes:
- Retrieve the object
- Validating the retrieved object against the original data
Inbound
In contrast to the outbound direction, inbound communication is not defined for unmanaged operation. To test the inbound capability of the adapter outside of a JCA container, you must implement some of the JCA container contracts. The following includes:
- BootstrapContext – To obtain a reference to a work manager and a timer
- InboundListener and MessageEndpoint – For the listener client
- MessageEndpointFactory – To create endpoints
- WorkManager – To create work instances
- Work – To map to threads
For more details on these contracts, study the EIS Simulator Adapter samples that are shipped with WebSphere Adapter Toolkit.
setUp()
The setUp() method for inbound is like that for outbound. You can, however, not need an outbound connection through the adapter. Accordingly, you only need to perform the following tasks:
- Create an adapter instance and set its properties
- Start the resource adapter.
Test
The test methods for inbound must do the following:
- Prepare the data inside the EIS. In a polling adapter, this would cause the triggers to fire, populating the event table.
- Create a MockEndpointFactory, and an ActivationSpecWithXid.
- Call endpointActivation() on the adapter.
- Wait for the event to arrive.
- Assert the correctness of the data after it is sent to the endpoint.
You can group your inbound and outbound tests into a single suite, and run them at once, getting instant feedback in the development environment.
For more details on the procedures described in this topic, study the EIS Simulator Adapter samples that are shipped with WebSphere Adapter Toolkit.
Testing the adapter in managed mode
Testing the adapter in managed mode means testing adapter instances on IBM Business Process Manager. This type of testing, in contrast to testing in unmanaged mode, more closely reflects the production environment that customers encounter.
Before testing your adapter implementation in managed mode, you must Packaging and exporting a resource adapter. Running tests in managed mode help uncover problems your adapter might have with the following services provided by IBM Business Process Manager and the Adapter Foundation Classes:
- Connection management
- Transaction management
- Event management
For information about testing the adapter in managed mode in WebSphere Application Server, see Validating code with Rational Application Developer / WebSphere Application Server.
Testing outbound functionality
You test outbound processing by configuring an adapter instance, selecting test parameters, and optionally executing the test in debug mode to pause at breakpoints.
After you have created and exported your adapter to IBM Business Process Manager, you can test outbound functionality by following the procedure:
- Open the test module in the Assembly Editor. Right-click the test module in the Navigation pane and select Test > Test Module.
- Configure the adapter instance. The Test Client displays a panel in which you select the Configuration, Module, Component, Interface and Operation you want to test. Make these selections, including the verb and the values you want sent to the adapter and click Continue.
![]()
Test module configuration
- Select the testing mode and click Finish to start the test. On the Deployment Location screen, select IBM Business Process Manager to test in managed mode (optionally you can select Eclipse to test in unmanaged mode). In addition, you select Run or Debug mode. If you select Debug mode, you can set breakpoints in your code; when the test reaches a breakpoint, IBM Integration Designer displays the Debug perspective.
A screen informs you the test is running. Then, if the adapter is successful, the business object you specified is populated with the return data.
To run another test, click Invoke in the top corner of the Assembly Editor.
Saving business object data
You can use Data pool to save business object data during testing to eliminate the need to reenter business data with each test iteration.
After entering the same data numerous times, you will be thankful for Data pool, an Integration Designer utility. Data pool allows you to save business object data for subsequent tests. To use Data pool, perform the steps in the following procedure:
- Open the Test module in the Assembly Editor. Right-click the adapter module in the Navigation pane and select Test > Test Module.
Save the business data. After entering values for Detailed Properties, right-click the topmost entry in the Initial request parameters pane. Select Add Value to Pool from the menu.
![]()
Add a value to the Data pool
This adds the data to Data pool.
When you want to use this keyed data again, select Use Value from Pool.
Use an execution trace
The test client you installed provides you with a trace of the execution and the data path of the test. You can optionally load any previously saved execution trace into the test client. This enables you to renew a test session at the point where you saved the execution.
The following procedure describes how to load and save an execution trace file.
- Select the module from the Navigation window, right-click, and select Test > Load Execution Trace.
- In the Choose a file list box, expand the folder that contains the execution trace file to load and select the execution trace file. (By default, execution trace files have a file extension of .wbiexetrace.)
- Click Finish. The selected execution trace opens in a new instance of the test client.
Save the execution trace.
- In the test client, enter Ctrl-S.
- In the Save dialog, under the Enter or select the parent folder field, select the folder where you want to save your execution trace file.
- Enter the name to assign to the execution trace file in the File name field.
- Click Finish. The execution trace file is saved to the folder that you selected and the test client page tab changes to the name of the execution trace file.
- Enter Ctrl-S in the test client to save the file.
Testing inbound functionality
To test inbound functionality, you configure an inbound instance of your adapter with an export monitor. You then run an outbound adapter instance to generate an event of interest for your inbound adapter.
After you have created and exported an adapter EAR file with the service type set to Inbound, you can test inbound functionality.
- Edit your module using the Assembly Editor, connecting the export to a Java™ component.
- Double-click on the module to start the Assembly Editor.
- Create a new Component by selecting the Component with no implementation from the first option.
- Add a wire by clicking the export and dragging it to the component.
![]()
Wiring a component
- Click OK in the next window.
- Right-click the component and select Generate Implementation > Java . This creates a Java component that simulates an end point.
- Select the package where the Java code should be created. Once the package is selected, the Java file should display as shown in the following figure. This can be edited to insert print or process statements for testing.
![]()
Selecting the Java package
Save the module.
- Publish the application to IBM Business Process Manager.
- Open the administration console for BPM and configure the application's activation specifications so that it can process inbound requests.
- Restart the inbound application and ensure that it is polling.
- To start testing, select the module from the Navigation window, right-click, and select Test > Attach. The test client displays the Events window.
- Examine the window for an export monitor.
- Return to the Events tab and click Continue. The Deployment Location displays.
- Select the server on which you want to test and click Finish. The Starting The Integration test client window displays.
- Create an event in your application's event table. You can do this by running the test client on the Outbound application. When an event is received on the monitored component, an entry will appear in the Events window.
Validating code with Rational Application Developer and WebSphere Application Server
To test the adapter in the WebSphere Application Server environment, use the JavaBeans generation capability of EMD to generate records and a Java™ proxy interface to the adapter. Then generate a session bean that will call this interface, and use the WebSphere universal test client (UTC) to send data to the adapter.
- Run EMD In Rational Application Developer, EMD can be accessed via New > Other > J2C Java Bean
The output of EMD will be JavaBeans for your schema definition, as well as a “J2C JavaBeans” that proxies the adapter.
Once the J2C JavaBeans are generated you need to generate EJBs to Test them.
- Select the J2C JavaBeans that you just created.
![]()
- In the EJB Creation window, select theStateless Session type and container as the transaction type and click Next
![]()
- In the Resource Adapter deployment panel, choose how to deploy the adapter. You can deploy the adapter with the EAR or you can deploy the adapter as a stand-alone component.
![]()
- Click Finish to generate the code. Once the EJB is generated you can send data to the adapter and examine the return values using the UTC.
- Use the UTC to validate the adapter can process data Publish your EAR project to the server using the Add and Remove projects option.
![]()
- Start UTC using the Run universal test client option.
![]()
- Once the UTC comes up, use the JNDI explorer to find your EJB. Look for your session EJB under EJB Beans.
![]()
Now, you can test your adapter via the EJB interface.
You can create a session bean using the home interface (create), then invoke business methods on the remote interface, providing the appropriate data. This works the same way as testing any session bean.
10. Packaging and exporting a resource adapter
You can create a Resource Adapter Archive (RAR) file, with the help of JAR files. You must first add the required JAR files to your project workspace. A Resource Adapter Archive (RAR) is an archive file format defined in the Java™ EE Connector Architecture (JCA) specification. A RAR file is the approved format to deploy resource adapters on application servers. A Java EE driven RAR represents the connector module of a connector project. The following example shows how to create a RAR file for a sample WebSphere adapter for Enterprise Information System Simulator. You use the RAR file to deploy the adapter on a different environment, after you import it. Add the required JAR files to your project workspace
- Open the IBM Integration Designer workspace.
- Go to the sample WebSphere Adapter for Enterprise Information System Simulator project.
- Click File >Import.
- Choose the File System option, and click Next.
- Click Browse and choose the folder where the JAR files, for example,DESPI.jar, commonj.connector.jar, CWYBS_AdapterFoundation.jar are located. In the development environment, a probable path can be \plugins\com.ibm.j2ca.wat.afc_7.5.0.2\runtime.
- Enable all the options for the JAR files that are to be packaged with the RAR file.
- Choose the connector module as the destination folder.
- Click Finish. All the JAR files will be added to the project workspace, and the files will be packaged with the RAR file.
Create a RAR file
The following section explains how to create a RAR file.
- Open the Integration Designer workspace where the Enterprise Information System Simulator Project is located. This will typically be in the Java EE perspective.
- Click File > Export.
- Choose the RAR file option in the screen that appears, and click Next.
- Choose the folder where you want to create the RAR file.
- Name the RAR file.
- Run the other default options in the Connector Export screen.
- Click Finish.
11. Import a resource adapter
The External Service wizard also gives you an option to import a RAR. You can import your Resource adapter directly. You can also add it as an existing or new EAR, as described in the following steps:
- Select File > New > External Service.
- Select the Unlisted Adapter option.
- Click Import a resource adapter from the file system option, in the screen that appears.
- Select the RAR file to import. The wizard prompts you for the project name and the target run time.
- ClickFinish. The RAR file is imported to your workspace, as a connector project.
- Complete the steps in the External Service wizard, to configure your service.
12. Troubleshooting and support
Common troubleshooting techniques and self-help information help you identify and solve problems quickly. For information about configuring logging properties and changing the log and trace file names, see Configure logging and tracing.
Techniques for troubleshooting problems
Certain common techniques can help with the task of troubleshooting.
The first step in the troubleshooting process is to describe the problem completely. Without a problem description, neither you or IBM can know where to start to find the cause of the problem. This step includes asking yourself basic questions, such as:
- What are the symptoms of the problem?
- Where does the problem occur?
- When does the problem occur?
- Under which conditions does the problem occur?
- Can the problem be reproduced?
The answers to these questions typically lead to a good description of the problem, and that is the best way to start down the path of problem resolution.
What are the symptoms of the problem?
When starting to describe a problem, the most obvious question is "What is the problem?" Which might seem like a straightforward question; however, you can break it down into several more-focused questions that create a more descriptive picture of the problem. These questions can include:
- Who, or what, is reporting the problem?
- What are the error codes and messages?
- How does the system fail? For example, is it a loop, hang, lock up, performance degradation, or incorrect result?
- What is the business impact of the problem?
Where does the problem occur?
Determining where the problem originates is not always simple, but it is one of the most important steps in resolving a problem. Many layers of technology can exist between the reporting and failing components. Networks, disks, and drivers are only a few components to be considered when you are investigating problems.
The following questions can help you to focus on where the problem occurs in order to isolate the problem layer.
- Is the problem specific to one platform or operating system, or is it common for multiple platforms or operating systems?
- Is the current environment and configuration supported?
Remember that if one layer reports the problem, the problem does not necessarily originate in that layer. Part of identifying where a problem originates is understanding the environment in which it exists. Take some time to completely describe the problem environment, including the operating system and version, all corresponding software and versions, and hardware information. Confirm that you are running within an environment that is a supported configuration; many problems can be traced back to incompatible levels of software not intended to run together or have not been fully tested together.
When does the problem occur?
Develop a detailed timeline of events leading up to a failure, especially for those cases that are one-time occurrences. You can most simply do this by working backward: Start at the time an error was reported (as precisely as possible, even down to the millisecond), and work backward through the available logs and information. Typically, you need to look only as far as the first suspicious event that you find in a diagnostic log; however, this is not always simple to do and takes practice. Knowing when to stop looking is especially difficult when multiple layers of technology are involved, and when each has its own diagnostic information.
To develop a detailed timeline of events, answer the following questions:
- Does the problem happen only at a certain time of day or night?
- How often does the problem happen?
- What sequence of events leads up to the time the problem is reported?
- Does the problem happen after an environment change, such as upgrading or installing software or hardware?
Responding to these types of questions can provide you with a frame of reference in which to investigate the problem.
Under which conditions does the problem occur?
Knowing what other systems and applications are running at the time that a problem occurs is an important part of troubleshooting. These and other questions about the environment can help you to identify the root cause of the problem:
- Does the problem always occur when the same task is being performed?
- Does a certain sequence of events need to occur for the problem to surface?
- Do any other applications fail at the same time?
Answering these types of questions can help you explain the environment in which the problem occurs and correlate any dependencies. Remember that just because multiple problems might have occurred around the same time, the problems are not necessarily related.
Can the problem be reproduced?
From a troubleshooting standpoint, the "ideal" problem is one that can be reproduced. Typically with problems that can be reproduced, you have a larger set of tools or procedures at your disposal to help you investigate. Consequently, problems that you can reproduce are often simpler to debug and solve. However, problems that you can reproduce can have a disadvantage: If the problem is of significant business impact, you do not want it to recur! If possible, re-create the problem in a test or development environment, which typically offers you more flexibility and control during your investigation.
Tip: Simplify the scenario to isolate the problem to a suspected component.
The following questions can help you with reproducing the problem:
- Can the problem be re-created on a test machine?
- Are multiple users or applications encountering the same type of problem?
- Can the problem be re-created by running a single command, a set of commands, a particular application, or a stand-alone application?
Preventing BG generation in the EMD invocation
To prevent the BG generation in the EMD invocation, perform these code changes:
- In the HelloWorldOutboundServiceDescription.setFunctionDescriptions(), you must have the dataDescription.setTopLevel(false); entry set.
- In the HelloWorldDataDescription.prepareChildSchemaFiles(), add the dataDescription.setTopLevel(false); code before the dataDescription.prepareSchemaFiles() invocation, for example,
dataDescription.setTopLevel(false); dataDescription.prepareSchemaFiles();- Modify the code in HelloWorldOutboundServiceDescription and remove bg and BG from the code.
dataDescription.setName(WBIDataDescriptionImpl.convertNamespaceToUri(namespace + "/" + metadataObj.getBOName().toLowerCase()), metadataObj .getBOName());
Failing to get expected results after enhancing the code
When you develop a custom adapter, you may not get the results that you expect.
When you develop a custom adapter, you may not get the results that you expect after you enhance the code. You must then make sure that no old instance of the Inbound/Outbound project is running in your application or process server. To get successful results:
- Log on to the server administrative console.
- Uninstall the Inbound or Outbound project.
- Add the project name you newly created, to the server instance.
- Publish your project.
Failing to find Integration Designer User Interfaces
On occasions, you may not be able to find user interface options in Integration Designer.
If you do not find any of the described user interface options in Integration Designer, make sure that you are in the right perspective. Most of the options explained in this guide work only in the Business Integration perspective.
Encountering a Java™NullPointerException during discovery
Make sure that you add CWYBS_AdapterFoundation.jar and DESPI.jar files to the build path of the connector module, and then export these two JAR files.
Defining properties of the attributes other than String
To define properties of the attributes other than Strings, for example Integers, perform these code changes:
- In the MTDSataDescription.java, change the getType() method as:
public String getType(String attrName) { BusinessObjectAttributeDefinition info = (BusinessObjectAttributeDefinition) ((MTSMetadataObject) getMetadataObject()) .getAttributes().get(attrName); return info.getType(); }- In MTSMetadataObject.java, add the following method:
private BusinessObjectAttributeDefinition createBODAttributeInfo (String type, String cardinality, boolean required) { BusinessObjectAttributeDefinition info = new BusinessObjectAttributeDefinition(); info.setType(type); info.setCardinality(cardinality); info.setRequired(required); return info; }- In MTSMetadataObject.java, change the getChildren() method for adding properties as:
attribs.put("Hello", createBODAttributeInfo("string", "1", false)); attribs.put("amount", createBODAttributeInfo("int", "1", false));
List of the other data types
The following section provides information about how to define other data types, for example double byte, which can be used with the attribute generation in EMD.
The BusinessObjectAttribute represents a Business Object Attribute definition, in terms of XSD maps to an element definition within a complexType. It holds information like name, type, cardinality, metadata, maxlength. So the setType() method actually set the type of the xsd element, so the type used here can be element type supported by XSD definition. Basically, you can refer to the SDO specification (9.4 Mapping of XSD Build-in data types) or the set methods in com.ibm.despi.OutputAccessor (we use DESPI to access the SDO, so actually the types supported in DESPI are the current types we can map from the XSD) for the details.
Regarding the array type, the SDO support property has many values (Collection or List, refer the SDO specification for details), and in terms of XSD maps to an element which has maxOccurs attribute set to unbound. In the BusinessObjectAttribute, you can use setCadinality("N") to specify it. And with DESPI, you can use the OutputAccessor.set["TYPE"](value, index) instead of the set["Type"](value) method to write value for the property with many values. However, you cannot directly setType("byte[]").
For example,
For byte[], because XSD has hexBinary and base64Binary can map to Java™ type byte[], and also in DESPI, we have setBytes(byte[] value), so you can declare a BusinessObjectAttribute as:
attribs.put("Name", createBODAttributeInfo("hexBinary", "1", false));
But for String[] or int[], there is no XSD type can map to (there is xsd:ENTITIES can map to Java List<String>, but the DESPI does not have setStrings(List<String>)). So you have to declare a BusinessObjectAttribute as:
attribs.put("Name", createBODAttributeInfo("String", "N", false));
It declares an element in your BO schema as:
<xsd:element name="Name" type="xsd:String" maxOccurs="unbound"/>
Support
This section provides information about how to troubleshoot a problem with your IBM software, including instructions for searching knowledge bases, downloading fixes, and obtaining support.
Searching knowledge bases (Web search)
You can often find solutions to problems by searching IBM knowledge bases. You can optimize your results by using available resources, support tools, and search methods.
You can find useful information by searching the information center for Product X. However, sometimes you need to look beyond the information center to answer your questions or resolve problems.
To search knowledge bases for information that you need, use one or more of the following approaches:
- Search for content by using the IBM Support Assistant (ISA).
ISA is a no-charge software serviceability workbench that helps you answer questions and resolve problems with IBM software products. You can find instructions for downloading and installing ISA on the ISA website.
- Find the content that you need by using the IBM Support Portal.
The IBM Support Portal is a unified, centralized view of all technical support tools and information for all IBM systems, software, and services. The IBM Support Portal lets you access the IBM electronic support portfolio from one place. You can tailor the pages to focus on the information and resources that you need for problem prevention and faster problem resolution. Familiarize yourself with the IBM Support Portal by viewing the demo videos (https://www.ibm.com/blogs/SPNA/entry/the_ibm_support_portal_videos) about this tool. These videos introduce you to the IBM Support Portal, explore troubleshooting and other resources, and demonstrate how you can tailor the page by moving, adding, and deleting portlets.
- Search for content by using the IBM masthead search. You can use the IBM masthead search by typing your search string into the Search field at the top of any ibm.com page.
- Search for content by using any external search engine, such as Google, Yahoo, or Bing. If you use an external search engine, your results are more likely to include information that is outside the ibm.com domain. However, sometimes you can find useful problem-solving information about IBM products in newsgroups, forums, and blogs that are not on ibm.com.
Tip: Include "IBM" and the name of the product in your search if you are looking for information about an IBM product.
Getting Fixes
A product fix might be available to resolve your problem.
To get product fixes.
- Determine which fix you need. Check the list of IBM WebSphere Adapter Toolkit recommended fixes to confirm that your software is at the latest maintenance level. Check the list of problems fixed in the IBM WebSphere Adapter Toolkit fix readme documentation that is available for each listed fix pack to see if IBM has already published an individual fix to resolve your problem. To determine what fixes are available using IBM Support Assistant, run a query on fix from the search page.
Individual fixes are published as often as necessary to resolve defects in BPM or WebSphere Enterprise Service Bus IBM WebSphere Adapter Toolkit. In addition, two kinds of cumulative collections of fixes, called fix packs and refresh packs, are published periodically for IBM WebSphere Adapter Toolkit, in order to bring users up to the latest maintenance level. You should install these update packages as early as possible in order to prevent problems.
A list of recommended, generally available (GA) fixes for the WebSphere Java™ Connector Architecture (JCA) and WebSphere Business Integration adapters are available here. If a Fix Pack is not available for an adapter, it implies the GA version is the recommended version and details about that version of the adapter can be found in the Release notes.
- Download the fix. Open the download document and follow the link in the Download package section. When downloading the file, ensure the name of the maintenance file is not changed. This includes both intentional changes and inadvertent changes caused by certain web browsers or download utilities.
- Apply the fix. Follow the instructions in the Installation Instructions section of the download document.
- To receive weekly notification of fixes and updates, subscribe to My Support e-mail updates.
Self-help resources
Use the resources of IBM software support to get the most current support information, obtain technical documentation, download support tools and fixes, and avoid problems with WebSphere Adapters. The self-help resources also help you diagnose problems with the adapter and provide information about how to contact IBM software support.
Support website
The WebSphere Adapters software support website at http://www.ibm.com/support/docview.wss?uid=swg27006249 provides links to many resources to help you learn about, use, and troubleshoot WebSphere Adapters, including:
- Flashes (alerts about the product)
- Technical information including the product information center, manuals, IBM Redbooks , and whitepapers
- Educational offerings
- Technotes
Recommended fixes
A list of recommended fixes apply is available at the following location: http://www.ibm.com/support/docview.wss?fdoc=aimadp&rs=695&uid=swg27010397.
Technotes
Technotes provide the most current documentation about WebSphere Adapter Toolkit, including the following topics:
- Problems and their currently available solutions
- Answers to frequently asked questions
- How to information about installing, configuring, using, and troubleshooting the adapter
- IBM Software Support Handbook
For a list of technotes for WebSphere Adapter Toolkit, see http://www-01.ibm.com/support/docview.wss?uid=swg27020139.
For a list of technotes for all adapters, see http://www.ibm.com/support/search.wss?tc=SSMKUK&rs=695&rank=8&dc=DB520+D800+D900+DA900+DA800+DB560&dtm.
Terminology
The terminology presented are of terms that are used frequently in the documentation.
- Adapter foundation classes (AFC)
- Sometimes referred to as base classes, the adapter foundation classes are a common set of services for all IBM WebSphere resource adapters. The Adapter Foundation Classes conform to, and extend, the Java™ 2 Connector Architecture JCA 1.5 specification. The foundation classes include generic contracts and methods to develop a working resource adapter and are included as a component to the WebSphere Adapter Toolkit.
- Application response measurement (ARM)
- An application programming interface (API), developed by a group of technology vendors, that can be used to monitor the availability and performance of business transactions within and across diverse applications and systems.
- Application-specific information (ASI)
- The portion of business object metadata that enables the adapter to interact with its application or a data source.
- Common Client Interface (CCI)
- The Common Client Interface (CCI) of the Java EE Connector Architecture provides a standard interface that allows developers to communicate with any number of Enterprise Information Systems (EISs) through their specific resource adapters, using a generic programming style. The CCI is closely modeled on the client interface used by Java Database Connectivity (JDBC), and is similar in its idea of Connections and Interactions. The generic CCI classes define the environment in which a Java EE component can send and receive data from an EIS.
- Common event infrastructure (CEI)
- The implementation of a set of APIs and infrastructure for the creation, transmission, persistence, and distribution of business, system, and network Common Base Events.
- Data exchange service provider interface (DESPI)
- The interface by which resource adapters and run time components exchange business object data. It is based on the concept of cursors and accessors, abstracting the data type so that an adapter can be written once and work on runtimes supporting different data types, such as data objects and JavaBeans. DESPI is an architecture that provides the capability of using JCA adapters on multiple brokers (run time environments).
- Deployment descriptor
- An XML file that describes how to deploy a module or application by specifying configuration and container options. For example, an EJB deployment descriptor passes information to an EJB container about how to manage and control an enterprise bean. Typically deployed in a run time environment to discover the configuration attributes of the component being described.
- Eclipse
- An open source infrastructure for building tools such as an Integrated Development Environment (IDE). The toolkit wizard and editor are Eclipse plug-ins.
- Eclipse plug-in
- A module that extends the functionality of the Eclipse Platform
- Editor
- A component in Eclipse that allows data to be edited. Editors can perform syntax validation.
- Enterprise information system (EIS)
- The applications that comprise an existing system of an enterprise for handling company-wide information. An enterprise information system offers a well-defined set of services that are exposed as local or remote interfaces or both.
- Event
- An occurrence of significance to a task or system. Events can include completion or failure of an operation, a user action, or the change in state of a process. Events generally result from user-defined triggers set on objects in the EIS
- IBM Rational Application Developer
- An IBM application that provides a set of extensions to the base Eclipse platform.
- IBM WebSphere Adapters
- A JCA Resource Adapter that is based on the Adapter Foundation Classes.
- IBM Business Process Manager
- Enables deployment of standards-based integration applications in a service-oriented architecture (SOA).
- IBM Integration Designer
- An IBM IDE.
- Inbound
- Inbound is a description of the direction in which data and messages pass from the EIS to a Java EE client application. Adapters support both inbound and outbound data flow.
- JCA contract
- A contract is a collaborative agreement between an application server and an EIS on how to keep all system-level mechanisms, such as transactions, security, and connection management, transparent from the application components.
- Java EE JCA Resource Adapter
- A system-level software driver used by an EJB container or an application client to connect to an enterprise information system (EIS). A resource adapter can plug-in to a container; the application components deployed on the container then use the client API (exposed by adapter) or tool-generated, high-level abstractions to access the underlying EIS.
- managed mode
- An environment in which connections are obtained from connection factories the Java EE server has set up. Such connections are owned by the Java EE server.
- Outbound
- Outbound is a description of the direction in which data and messages pass from a Java EE client application to the EIS. Adapters support both inbound and outbound data flow.
- Performance monitoring infrastructure (PMI)
- A set of packages and libraries assigned to gather, deliver, process, and display performance data. PMI is the underlying framework in WAS that gathers performance data from various run time resources such as adapters. The purpose of monitoring is to observe the progress of execution of WebSphere Business Integration applications, and the WebSphere Business Integration system itself, and publish the results of this observation.
- Request
- In a request and response interaction, the role performed by a business object that instructs an adapter to interact with an application or other programmatic entity.
- Subclass
- In programming, to add custom processing to an existing function or subroutine by hooking into the routine at a predefined point and adding additional lines of code.
- Wizard
- A sequence of dialogue pages which collect user inputs to perform a task such as creating a New Java Project in the workspace or creating a New Java Class within a selected project.
Adapter Foundation Classes Javadoc Information
The WebSphere Adapter Foundation Classes establish a WebSphere standard for building resource adapters that conform to the JCA 1.5 specification. The Javadoc information links give you instant access to the Foundation Classes that are referenced throughout the WebSphere Adapter Toolkit Guide.
- com.ibm.j2ca.base
- com.ibm.j2ca.base.exceptions
- com.ibm.j2ca.extension.commandpattern
- com.ibm.j2ca.extension.databinding
- com.ibm.j2ca.extension.databinding.exception
- com.ibm.j2ca.extension.databinding.utils
- com.ibm.j2ca.extension.dataexchange.bean
- com.ibm.j2ca.extension.dataexchange.map
- com.ibm.j2ca.extension.dataexchange.sdo
- com.ibm.j2ca.extension.emd
- com.ibm.j2ca.extension.eventmanagement
- com.ibm.j2ca.extension.logging
- com.ibm.j2ca.extension.metadata
- com.ibm.j2ca.extension.monitoring
Video samples
To help you use WebSphere Adapters, sample videos are available to detail some of the scenarios.
You can find several WebSphere Adapters video demonstrations at this FTP location ftp://ftp.software.ibm.com/software/websphere/integration/wsa/library/videos/.
To view these video samples:
- Download the zip file of the required sample from the FTP location.
- Extract the downloaded zip file to your system.
- From the extracted folder, double-click the HTML file.
- The video sample opens in your default Web browser.
The video has a built-in audio narration. If you do not want to listen to the audio, you can lower its tab to the minimum, and slide the tab to an audio level, whenever you want the audio back.
The following sample videos are currently available at this location: ftp://ftp.software.ibm.com/software/websphere/integration/wsa/library/videos/
- AFC: Scheduling Calendar based polling
- AFC: Overcoming an AFC version conflict situation
- WAT: Creating a custom adapter using WebSphere Adapter Toolkit
- WAT: Creating a custom adapter outbound interface in WebSphere Adapter Toolkit
- WAT: Testing a module in WebSphere Adapter Toolkit
14. Adapter documentation in PDF format
Documentation in PDF format for WebSphere Adapter Toolkit is available at the following location.
Adapter documentation in PDF format: ftp://ftp.software.ibm.com/software/websphere/integration/wsa/library/pdf7503/