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 com.metamatrix.data.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. Teiid provides a base implementation of this class called BasicConnectorCapabilities. You can either extend this basic implementation or implement your own implementation.
Execution (and sub-interfaces) - These interfaces represent a command execution with your Connector. There is a sub-interface for executing each kinds of command: query, update, and procedure. Your connector can specify via the ConnectorCapabilities which of these command types it can handle.
Batch - This interface represents a batch of results being sent to the Teiid Server from the custom connector. Teiid provides a default implementation of this class called BasicBatch.
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.
SecurityContext / ExecutionContext – interfaces defining the security information and execution context available to the connector when executing a command.
A Connector will be initialized one time via the initialize() 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.
Runtime metadata – access to the runtime metadata of the model deployed in the Teiid Server for your physical source
Large object replacement – ability to stream the results of large values (such as blobs and clobs) through the Teiid system
Type facility – an interface defining runtime datatypes and type conversion facility.
Other methods on the connector allow the Connector Manager to start() or stop() the connector. Typically the connector is started or stopped in response to system startup, system shutdown, or an administrator changing these states on connector bindings in the Teiid Console or through Admin API. A connector should perform whatever actions are necessary in these methods to create or destroy all connector states, including connections to the actual physical source.
The connector must implement the getConnection() method to allow the Connector Manager to obtain a connection. The getConnection() method is passed a SecurityContext, which contains information about the context in which this query is being executed.
The SecurityContext contains the following information:
User name
Virtual database name
Virtual database version
Trusted token
The trusted token is used to pass security information specific to your application through the Teiid Server. 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 a custom Membership Service, contact Teiid technical support.
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 release() 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. Connectors may support any subset of the available execution modes. The execution modes are defined by constants in the ConnectorCapabilities.EXECUTION_MODE class. The following execution modes are available:
Table 3.1. Types of Execution Modes
Execution Mode | Execution Interface | Command interface(s) | Description |
---|---|---|---|
Synchronous Query |
SynchQueryExecution
|
IQuery
| A query, corresponding to a SQL SELECT statement |
Update |
UpdateExecution
|
IInsert, IUpdate, IDelete
| An insert, update, or delete, corresponding to a SQL INSERT, UPDATE, or DELETE command |
Procedure Execution |
ProcedureExecution
|
IProcedure
| A procedure execution that may return a result set and/or output values. |
Asynchronous Query |
AsynchQueryExecution
|
IQuery
| Polled asynchronous execution of a SQL SELECT statement |
Batched Update |
BatchedUpdatesExecution
|
ICommand[]
| Execute multiple commands in a batch |
Bulk Insert |
BatchedUpdatesExecution
|
IInsert
| Insert a large set of data using the same INSERT command |
Following is a class diagram further defining the relationships between the execution interfaces:
All of the execution interfaces extend the base execution interface that defines how executions are cancelled and closed. SynchQueryExecution, AsynchQueryExecution, and ProcedureExecution all extend the BatchedExecution interface, which defines how batched results are returned from an execution.
Most commands executed against connectors are queries. Queries correspond to the SELECT statement in SQL. The actual queries themselves are sent to connectors in the form of a set of objects, which are further described in Chapter Command Language.
The following diagram represents the typical sequence of events when executing a query:
While the command is being executed, the connector retrieves results in batches via the BatchedExecution interface. Each time nextBatch() is called, the SynchQueryExecution implementation should return a batch of no more than maxBatchSize records. The final batch of records should set the isLast flag to true.
The maxBatchSize parameter passed to the nextBatch method corresponds to the Connector Batch Size that can be set on a system-wide bases in the Teiid Console (under System Properties in the buffer section..) The Connector Batch Size should typically be set in conjunction with the Processor Batch Size from the same category. For more information on these parameters, see the Teiid Console User Guide.
In some scenarios, a connector needs to execute queries asynchronously and poll for results. In this case, your connector should use the asynchronous query execution mode instead of the synchronous query execution mode. The connector capabilities specify which will be used (only one can be supported at the same time).
The following diagram represents the typical sequence of events when executing a query asynchronously:
While the command is being executed, the connector retrieves results in batches via the BatchedExecution interface. The AsynchQueryExecution interface works similarly to the SynchQueryExecution interface with one important difference. If the nextBatch method returns an empty batch with the isLast flag set to false, then the Connector Manager interprets this as no data being available. In this case, the Connector Manager will wait for the poll interval before asking again for a batch.
The nextBatch() is not expected to sleep or otherwise block for results as this would tie up a Connector Manager thread which could be doing other work. Instead, the Connector Manager is designed to avoid tying up worker threads while waiting for the poll interval, so the connector is expected to return from the nextBatch() method as quickly as possible.
Insert, update, and delete commands correspond to the INSERT, UPDATE, and DELETE commands in SQL. They are used to insert a single row into a data source, update one or more rows in a data source, or delete one or more rows in a data source. Each of these commands returns a count specifying the number of rows updated in the physical source in response to the command.
The following diagram represents the typical sequence of events when executing an insert, update, or delete:
With an update execution, the execute method is the only call in the execution. No subsequent interaction will take place.
Batched update and bulk insert execution are very similar to update execution except multiple commands are passed to the connector in a single method call. In the case of a bulk insert, a single template INSERT command is passed with a set of data rows that need to be inserted with the command. In the case of batched update, a series of arbitrary commands is sent and the batch must be executed together for efficiency.
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.
The following diagram represents the typical sequence of events when executing a procedure:
If a result set is expected when a procedure is executed, all rows from it will be retrieved via the BatchedExecution interface first. Then, if any output values are expected, they will be retrieved via the getOutputValue() method, which will be called once for each expected output value.
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 via the Teiid Console or Admin API
Clean-up during session termination
Clean-up if a query fails during processing
In these cases, if the command being executed on the connector has not yet finished, Teiid will call the cancel() method on the execution interface in a separate thread from the thread that may be blocked calling the execute() method.
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 synchronous 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.