JBoss.orgCommunity Documentation
A component called the Connector Manager is controlling access to your connector. This chapter reviews the basics of how the Connector Manager interacts with your connector while leaving reference details and advanced topics to be covered in later chapters.
A custom connector must implement the following interfaces to connect and query an enterprise Data Source. These interfaces are in package called org.teiid.connector.api:
Connector - This interface is the starting point for all interaction with your connector. It allows the Connector Manager to obtain a connection and perform lifecycle events.
Connection - This interface represents a connection to your data source. It is used as a starting point for actual command executions. Connections provided to the Connector Manager will be obtained and released for each command execution. Teiid provides for extensible automatic connection pooling, as discussed in the Connection Pooling chapter.
ConnectorCapabilities - This interface allows a connector to describe the execution capabilities of the connector.
Execution (and sub-interfaces) - These interfaces represent a command execution with your Connector. There is a sub-interface for executing each kinds of command: ResultSetExecution, UpdateExecution, and ProcedureExecution.
Note that many of the interfaces above have base implementations in the org.teiid.connector.basic package. Consider extending the corresponding BasicXXX class rather than fully implementing the interface.
The most important interfaces provided by Teiid to the connector are the following:
ConnectorEnvironment – an interface describing access to external resources for your connector.
ConnectorLogger – an interface for writing logging information to Teiid logs.
ExecutionContext – interface defining the execution context available to the connector when executing a command.
A Connector instance will be initialized one time via the start method, which passes in a ConnectorEnvironment object provided by the Connector Manager . The ConnectorEnvironment provides the following resources to the connector:
Configuration properties – name / value pairs as provided by the connector binding in the Teiid Console
Logging – ConnectorLogger interface allows a Connector to log messages and errors to Teiid’s log files.
Type facility – an interface defining runtime datatypes and type conversion facility.
Scheduling facility – repeating tasks can be scheduled and managed by Teiid.
Caching facility – easy methods for caching based upon relevant contexts, such as session or query scope.
While the connector is running it is expected to return provide connections and capabilities information in response to system requests. If the source system is not available ConnectorExceptions or RuntimeExceptions may be thrown at any time to indicate failure. The connector should handle failure internally in a graceful manner, since the system will not automatically perform a stop/start.
The connector must implement the getConnection() method to allow the Connector Manager to obtain a connection. The getConnection() method is passed a ExecutionContext, which contains information about the context in which this query is being executed.
The ExecutionContext provides the following:
User name
Virtual database name
Virtual database version
The ability to add execution warnings.
Trusted token
The trusted token is used to pass security information specific to your application through the Teiid. The client can pass the trusted token when they connect via JDBC. This token is then passed to the Membership Service and may be created, replaced, or modified at that time. In some cases, you may wish to provide a customer Membership Service implementation to handle security needs specific to your organization. For more information on implementing see the Server Extension Guide
Once the Connector Manager has obtained a connection, it will use that connection only for the lifetime of the request. When the request has completed, the close() method will be called on the connection.
In cases (such as when a connection is stateful and expensive to create), connections should be pooled. Teiid provides an extensible connection pool for this purpose, as described in chapter Connection Pooling.
The Connector API uses a Connection to obtain an execution interface for the command it is executing. The actual queries themselves are sent to connectors in the form of a set of objects, which are further described in Chapter Command Language. Connectors are allowed to support any subset of the available execution modes.
Table 2.1. Types of Execution Modes
Execution Interface | Command interface(s) | Description |
---|---|---|
ResultSetExecution
|
IQueryCommand
| A query corresponding to a SQL SELECT or set query statement. |
UpdateExecution
|
IInsert, IUpdate, IDelete, IBatchedUpdates
| An insert, update, or delete, corresponding to a SQL INSERT, UPDATE, or DELETE command |
ProcedureExecution
|
IProcedure
| A procedure execution that may return a result set and/or output values. |
All of the execution interfaces extend the base Execution
interface that defines how executions are
cancelled and closed. ProcedureExecution also extends ResultSetExecution, since procedures may also return resultsets.
Typically most commands executed against connectors are IQueryCommands. While the command is being executed, the connector provides results via the ResultSetExecution next method. The next method should return null to indicate the end of results. Note: the expected batch size can be obtained from the ExecutionContext and used as a hint in fetching results from the EIS.
Each execution returns the update count(s) expected by the update command. If possible IBatchedUpdates should be executed atomically. The ExecutionContext can be used to determine if the execution is already under a transaction.
Procedure commands correspond to the execution of a stored procedure or some other functional construct. A procedure takes zero or more input values and can return a result set and zero or more output values. Examples of procedure execution would be a stored procedure in a relational database or a call to a web service.
If a result set is expected when a procedure is executed, all rows from it will be retrieved via the ResultSetExecution interface first. Then, if any output values are expected, they will be retrieved via the getOutputParameterValues() method.
In some scenarios, a connector needs to execute asynchronously and allow the executing thread to perform other work. To allow this, you should:
Set either the SynchronousWorkers annotation or the connector binding property SynchWorkers to false - this overrides the default behavior in which connector threads stay associated with their Execution until the Execution is closed.
Throw a DataNotAvailableExecption during a retrival method, rather than explicitly waiting or sleeping for the results. The DataNotAvailableException may take a delay parameter in its constructor to indicate how long the system should wait befor polling for results. Any non-negative value is allowed.
Be aware that a connector with asynchronous workers cannot be transactional.
Non batched
IInsert, IUpdate, IDelete
commands may have Iliteral values marked as multiValued if the
ConnectorCapabilities shows support for BulkUpdate. Commands with
multiValued Iliterals represent multiple executions of the same
command with different values. As with IBatchedUpdates, bulk operations should be executed atomically if possible.
All normal command executions end with the calling of close() on the Execution object. Your implementation of this method should do the appropriate clean-up work for all state in the Execution object.
Commands submitted to Teiid may be aborted in several scenarios:
Client cancellation via the JDBC API (or other client APIs)
Administrative cancellation
Clean-up during session termination
Clean-up if a query fails during processing
Unlike the other execution methods, which are handled in a single-threaded manner, calls to cancel happen asynchronously with respect to the execution thread.
Your connector implementation may choose to do nothing in response to this cancellation message. In this instance, Teiid will call close() on the execution object after current processing has completed. Implementing the cancel() method allows for faster termination of queries being processed and may allow the underlying data source to terminate its operations faster as well.
Teiid can automatically monitor connectors, which will update a status flag on the connector. This status can be checked via the AdminApi and is exposed in the console. To use connector monitoring effectively:
Set a positive test interval value on on the connector binding (default is 600) indicating the number of seconds between status checks. These checks are useful in idle periods.
Implement a meaningful isAlive method on your Connector Connections.
Use either a pooled Connector or a Connector that supports single identity.
Possible status results include:
Not initialized - to indicate not yet started.
Init failed - to indicate start failed.
Open - to indicate the running state and that connections can be obtained form the source.
Unable to check - to indicate the running state but connections cannot be obtained administratively.
Data Source Unavailable - to indicate the running state.
Closed - to indicate that the Connector has been stopped.