-
Language:
English
-
Language:
English
Red Hat Training
A Red Hat training course is available for Red Hat JBoss Data Virtualization
Development Guide Volume 4: Server Development
This guide is intended for developers
Red Hat Customer Content Services
Abstract
Chapter 1. Developing for Red Hat JBoss Data Virtualization
1.1. Developing for Red Hat JBoss Data Virtualization
1.2. Red Hat JBoss Data Virtualization Connector Architecture
- a translator (mandatory) and
- a resource adapter (optional), also known as a connector. Most of the time, this will be a Java EE Connector Architecture (JCA) Adapter.
- translate Red Hat JBoss Data Virtualization commands into commands understood by the datasource for which the translator is being used,
- execute those commands,
- return batches of results from the datasource, translated into the formats that Red Hat JBoss Data Virtualization is expecting.
- handles all communications with individual enterprise information systems, (which can include databases, data feeds, flat files and so forth),
- can be a JCA Adapter or any other custom connection provider (the JCA specification ensures the writing, packaging and configuration are undertaken in a consistent manner),
Note
Many software vendors provide JCA Adapters to access different systems. Red Hat recommends using vendor-supplied JCA Adapters when using JMS with JCA. See http://docs.oracle.com/cd/E21764_01/integration.1111/e10231/adptr_jms.htm - removes concerns such as connection information, resource pooling, and authentication for translators.
1.3. Other Red Hat JBoss Data Virtualization Development
- You can add user defined functions.
- You can adapt logging to your requirements, which is especially useful for custom audit or command logging.
- A delegating translator can be used to add custom code to all methods for a given translator.
- You can also customize authentication and authorization modules. See the Red Hat JBoss Data Virtualization Security Guide.
1.4. Setting the Development Environment
<dependencies> <dependency> <groupId>org.jboss.teiid</groupId> <artifactId>teiid-api</artifactId> <version>${teiid-version}</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.jboss.teiid</groupId> <artifactId>teiid-common-core</artifactId> <version>${teiid-version}</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.resource</groupId> <artifactId>connector-api</artifactId> <version>${connector-api-version}</version> <scope>provided</scope> </dependency> </dependencies>
teiid-version
property must be set to the expected version. You must also add the new declared property connector-api-version. You can find relevant artifacts in the Maven repository.
1.5. Maven Repository Location
- File System
- Red Hat JBoss Data Virtualization -
file:///path/to/repo/jboss-dv-6.4.0-maven-repository
- Online Maven Repository
http://maven.repository.redhat.com/techpreview/all/
Chapter 2. Resource Adapter Development
2.1. Developing Custom Adapters
Note
- Define a Managed Connection Factory by extending the
BasicManagedConnectionFactory
class - Define a Connection Factory by extending the
BasicConnectionFactory
class - Define a Connection by extending the
BasicConnection
class - Specify configuration properties in an
ra.xml
file
Note
teiid/connectors
directory of the Red Hat JBoss Data Virtualization 6.4 Source Code ZIP file. This ZIP file can be downloaded from the Red Hat Customer Portal at https://access.redhat.com.
2.2. Define a Managed Connection Factory
- Extend the
org.teiid.resource.spi.BasicManagedConnectionFactory
class, providing an implementation for thecreateConnectionFactory()
method. This method will create and return an instance of a Connection Factory. - Define an attribute for each configuration variable, and then provide both "getter" and "setter" methods for them. This class will define various configuration variables (such as user, password, and URL) used to connect to the datasource.
public class MyManagedConnectionFactory extends BasicManagedConnectionFactory { @Override public BasicConnectionFactory createConnectionFactory() throws ResourceException { return new MyConnectionFactory(); } // config property name (metadata for these are defined inside the ra.xml) String userName; public String getUserName() { return this.userName; } public void setUserName(String name){ this.userName = name; } // config property count (metadata for these are defined inside the ra.xml) Integer count; public Integer getCount() { return this.count; } public void setCount(Integer value) { this.count = value; } }
Important
java.lang
objects as the attributes. DO NOT use Java primitives for defining and accessing the properties.
2.3. Define a Connection Factory
org.teiid.resourse.spi.BasicConnectionFactory
class, and provide an implementation for the getConnection()
method. This method will create and return an instance of a connection.
public class MyConnectionFactory extends BasicConnectionFactory { @Override public MyConnection getConnection() throws ResourceException { return new MyConnection(); } }
getConnection()
method can pass credentials to the requesting application. Therefore, the Connection Factory can reference the calling user's javax.security.auth.Subject
from within the getConnection()
method.
Subject subject = ConnectionContext.getSubject();
Subject
can give access to logged-in user's credentials and roles that are defined. This may be null
.
Note
2.4. Define a Connection
org.teiid.resource.spi.BasicConnection
class, and provide an implementation based on your access of the Connection object in your translator. If your connection is stateful, override the isAlive()
and cleanup()
methods with suitable implementations. These methods are called to check if a connection is stale and needs flushing from the connection pool by the application server.
public class MyConnection extends BasicConnection { public void doSomeOperation(Command command) { // do some operation with requesting application.. // This is method you use in the Translator, you should know // what need to be done here for your source.. } @Override public boolean isAlive() { return true; } @Override public void cleanUp() { } public void close() throws ResourceException { } }
2.5. XA Transactions
Connection
object must override the getXAResource()
method and provide the XAResource
object for the application. To participate in crash recovery you must also extend the BasicResourceAdapter
class and implement the public XAResource[] getXAResources(ActivationSpec[] specs)
method.
2.6. Specify Configuration Properties in an ra.xml File
ra.xml
file. These properties are used to configure each instance of the connector.
<config-property> <description> {$display:"display-name",$description:"description", $allowed:"allowed", $required:"true|false", $defaultValue:"default-value"} </description> <config-property-name>property-name</config-property-name> <config-property-type>property-type</config-property-type> <config-property-value>optional-property-value</config-property-value> </config-property>
<config-property> <description> {$display:"User Name",$description:"The name of the user.", $required="true"} </description> <config-property-name>UserName</config-property-name> <config-property-type>java.lang.String</config-property-type> </config-property>
<description>
element may be used as extended metadata for tooling. This use of the special format and all properties is optional and must follow these rules:
- The special format must begin and end with curly braces e.g.
{ }
. - Property names begin with
$
. - Property names and the associated value are separated with a colon (
:
). - Double quotes (
"
) identifies a single value. - A pair of square brackets (
[ ]
), containing comma separated double quoted entries indicates a list value.
$display
: Display name of the property.$description
: Description about the property.$required
: The property is a required property; or optional and a default is supplied.$allowed
: If property value must be in certain set of legal values, this defines all the allowed values.$masked
: The tools need to mask the property; Do not show in plain text; used for passwords.$advanced
: Notes this as Advanced property.$readOnly
: Property is set to read-only.
Note
Note
maven archetype
.
2.7. Packaging the Adapter
Note
- JBoss Developer Studio
- If you create a Java Connector project in JBoss Developer Studio, it will include a build target that produces a RAR file.
- Apache Ant
- When using Apache Ant, you can use the standard
rar
build task. - Apache Maven
- When using Apache Maven, set the value of the
<packaging>
element torar
. Since Red Hat JBoss Data Virtualization uses Maven, you can refer to any of the Connector projects; for example,pom.xml
shown below.<project> <modelVersion>4.0.0</modelVersion> <artifactId>connector-{name}</artifactId> <groupId>org.company.project</groupId> <name>Name Connector</name> <packaging>rar</packaging> <description>This connector is a sample</description> <dependencies> <dependency> <groupId>org.jboss.teiid</groupId> <artifactId>teiid-api</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>org.jboss.teiid</groupId> <artifactId>teiid-common-core</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>javax.resource</groupId> <artifactId>connector-api</artifactId> <scope>provided</scope> </dependency> </dependencies>
META-INF
directory must contain the ra.xml
file. If you are using Apache Maven, see http://maven.apache.org/plugins/maven-rar-plugin/. In the root of the RAR file, you can embed the JAR file containing your connector code and any dependent library JAR files.
2.8. Adding Dependent Libraries
MANIFEST.MF
file into the META-INF
directory, and the following line to add the core Red Hat JBoss Data Virtualization API dependencies for the resource adapter.
Dependencies: org.jboss.teiid.common-core,org.jboss.teiid.api,javax.api
MANIFEST.MF
file to specify them as dependencies.
2.9. Deploying the Adapter
- Edit the server configuration file and add the following XML in the "resource-adapters" subsystem.
<!-- If susbsytem is already defined, only copy the contents under it and edit to suit your needs --> <subsystem xmlns="urn:jboss:domain:resource-adapters:1.0"> <resource-adapters> <resource-adapter> <archive>teiid-connector-sample.rar</archive> <transaction-support>NoTransaction</transaction-support> <connection-definitions> <connection-definition class-name="org.teiid.resource.adapter.MyManagedConnectionFactory" jndi-name="${jndi-name}" enabled="true" use-java-context="true" pool-name="sample-ds"> <config-property name="UserName">jdoe</config-property> <config-property name="Count">12</config-property> </connection-definition> </connection-definitions> </resource-adapter> </resource-adapters> </subsystem>
There are more properties that you can define in this file; for example, for pooling, transactions, and security. Refer to the Red Hat JBoss Enterprise Application Platform documentation for all the available properties. See https://access.redhat.com/site/documentation/JBoss_Enterprise_Application_Platform/. - You can use the web-based Management Console to create a new
ConnectionFactory
.
Chapter 3. Translator Development
3.1. Environment Set-Up
- Create a new (or reuse an existing) resource adapter for the data source, to be used with this translator.
- Decide whether to use the Teiid archetype template to create your initial custom translator project and classes or manually create your environment.
- Create an
ExecutionFactory
by:- extending the
org.teiid.translator.ExecutionFactory
class or - extending the
org.teiid.translator.jdbc.JDBCExecutionFactory
class .
- Package the translator.
- Deploy your translator.
- Deploy a Virtual Database (VDB) that uses your translator.
- Execute queries via the Teiid engine.
teiid/connectors
directory of the Red Hat JBoss Data Virtualization 6.4 Source Code ZIP file which can be downloaded from the Red Hat Customer Portal at https://access.redhat.com.
<dependencies> <dependency> <groupId>org.jboss.teiid</groupId> <artifactId>teiid-api</artifactId> <version>${teiid-version}</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.jboss.teiid</groupId> <artifactId>teiid-common-core</artifactId> <version>${teiid-version}</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.resource</groupId> <artifactId>connector-api</artifactId> <version>${version.connector.api}</version> <scope>provided</scope> </dependency> </dependencies>
Procedure 3.1. Create a Project in JBDS
- Open the Java perspective.
- From the menu select File - New - Other.
- In the tree, expand Maven and select Maven Project.
- Click Next.
- On the "Select project name and Location" window, you can accept the defaults, so click Next
- On the "Select an Archetype" window, click the Configure button
- Add the remote catalog found at https://repository.jboss.org/nexus/content/repositories/releases/ then click OK to return.
- Uncheck Show the last version of Archetype only and enter "teiid" in the filter to see the Teiid archetypes.
- Select the translator-archetype 8.12.x and then click Next.
- Enter all the information (such as Group ID and, Artifact ID) needed to generate the project.
- Click Finish.
Procedure 3.2. Create a Project Using the Command Line
- Issue the following template command:
mvn archetype:generate \ -DarchetypeGroupId=org.jboss.teiid.arche-types \ -DarchetypeArtifactId=translator-archetype \ -DarchetypeVersion=8.12.0 \ -DgroupId=${groupId} \ -DartifactId=translator-${translator-name} \ -Dpackage=org.teiid.translator.${translator-name} \ -Dversion=${version} \ -Dtranslator-name=${translator-name} \ -Dtranslator-type=${translator-type} \ -Dteiid-version=${teiid-version}
This is what the instructions mean:- -DarchetypeGroupId - this is the group ID for the archetype to use to generate
- -DarchetypeArtifactId - this is the artifact ID for the archetype to use to generate.
- -DarchetypeVersion - this is the version for the archetype to use to generate.
- -DgroupId - this is a (user defined) group ID for the new translator project pom.xml.
- -DartifactId - this is a (user defined) artifact ID for the new translator project pom.xml.
- -Dpackage - this is a (user defined) the package structure where the java and resource files will be created.
- -Dversion - this is a (user defined) the version that the new connector project pom.xml will be.
- -Dtranslator-name - this is a (user defined) the name (type) of the new translator project, used to create the java class names.
- -Dteiid-version - the Teiid version upon which the connector will depend.
- -Dtranslator-type - This specifies the identifier used for the translator in EAP configuration files.
Here is a sample command:mvn archetype:generate \ -DarchetypeGroupId=org.jboss.teiid.arche-types \ -DarchetypeArtifactId=translator-archetype \ -DarchetypeVersion=8.12.0 \ -DgroupId=org.jboss.teiid.connector \ -DartifactId=translator-myType \ -Dpackage=org.teiid.translator.myType \ -Dversion=0.0.1-SNAPSHOT \ -Dtranslator-name=MyType \ -Dtranslator-type=MyType \ -Dteiid-version=8.12.0.Final
- After you execute it, you will be asked to confirm the properties:
Confirm properties configuration: groupId: org.jboss.teiid.connector artifactId: translator-myType version: 0.0.1-SNAPSHOT package: org.teiid.translator.myType teiid-version: 8.12.0.Final translator-name: MyType Y: :
Type Y (for Yes) and press enter. - Upon creation, a directory based on the artifactId will be created, that will contain the project. Navigate to that directory.
- Execute a test build to confirm the project was created correctly:
mvn clean package
It should build successfully. If so, you are now ready to start adding your custom code.
3.2. Implementing the Framework
3.2.1. Caching API
CacheDirective
object. Translators wishing to participate in caching should return a CacheDirective
from the ExecutionFactory.getCacheDirective
method, which is called prior to execution. The commands passed to getCacheDirective
will have already been vetted to ensure that the results are eligible for caching. For example update commands or commands with pushed dependent sets will not be eligible for caching.
CacheDirective
, which is the default implementation, the engine will not cache the translator results beyond the current command. It is up to your custom translator or custom delegating translator to implement your desired caching policy.
Note
Scope
to Scope.NONE
.
CacheDirective
will be set on the ExecutionContext
and is available via the ExecutionContext.getCacheDirective()
method. Having ExecutionFactory.getCacheDirective
called prior to execution allows the translator to potentially be selective about which results to even attempt to cache. Since there is a resource overhead with creating and storing the cached results it may not be desirable to attempt to cache all results if it is possible to return large results that have a low usage factor. If you are unsure about whether to cache a particular command result you may return an initial CacheDirective
then change the Scope
to Scope.NONE
at any time prior to the final cache entry being created and the engine will give up creating the entry and release its resources.
Note
CacheDirective
during execution, return a new instance from the ExecutionFactory.getCacheDirective
call, rather than returning a shared instance.
CacheDirective
readAll Boolean field is used to control whether the entire result should be read if not all of the results were consumed by the engine. If readAll is false then any partial usage of the result will not result in it being added as a cache entry. Partial use is determined after any implicit or explicit limit has been applied. The other fields on the CacheDirective
object map to the cache hint options . See the table below for the default values for all options.
option
|
default
|
---|---|
scope
|
Session
|
ttl
|
rs cache ttl
|
readAll
|
true
|
updatable
|
true
|
prefersMemory
|
false
|
3.2.2. Command Language
3.2.2.1. Language
ExecutionFactory
class. Refer to the section on translator capabilities for more information.
LanguageObject
interface. Language objects should be thought of as a tree where each node is a language object that has zero or more child language objects of types that are dependent on the current node.
Command
. Command has several sub-interfaces, namely:
QueryExpression
Insert
Update
Delete
BatchedUpdates
Call
3.2.2.2. Expressions
Expression
- base expression interfaceColumnReference
- represents an column in the data sourceLiteral
- represents a literal scalar value, but may also be multi-valued in the case of bulk updates.Function
- represents a scalar function with parameters that are also ExpressionsAggregateFunction
- represents an aggregate function which holds a single expressionWindowFunction
- represents a window function which holds an AggregateFunction (which is also used to represent analytical functions) and a WindowSpecificationScalarSubquery
- represents a subquery that returns a single valueSearchedCase, SearchedWhenClause
- represents a searched CASE expression. The searched CASE expression evaluates the criteria in WHEN clauses until one of them evaluates to TRUE, then evaluates the associated THEN clause.Array
- represents an array of expressions, currently only used by the engine in multi-attribute dependent joins - see the supportsArrayType capability.
3.2.2.3. Condition
Condition
- the base criteria interfaceNot
- used to NOT another criteriaAndOr
- used to combine other criteria via AND or ORSubqueryComparison
- represents a comparison criteria with a subquery including a quantifier such as SOME or ALLComparison
- represents a comparison criteria with =, >, <, etc.BaseInCondition
- base class for an IN criteriaIn
- represents an IN criteria that has a set of expressions for valuesSubqueryIn
- represents an IN criteria that uses a subquery to produce the value setIsNull
- represents an IS NULL criteriaExists
represents an EXISTS criteria that determines whether a subquery will return any valuesLike
- represents a LIKE/SIMILAR TO/LIKE_REGEX criteria that compares string values
3.2.2.4. The FROM Clause
TableReference
's.
NamedTable
- represents a single TableJoin
- has a left and rightTableReference
and information on the join between the itemsDerivedTable
- represents a table defined by an inlineQueryExpression
TableReference
are used by default, in the pushdown query when no outer joins are used. If an outer join is used anywhere in the join tree, there will be a tree of Join
s with a single root. This latter form is the ANSI-preferred style. If you wish all pushdown queries containing joins to be in ANSI style have the capability "useAnsiJoin" return true. Refer to the section on command form for more information.
3.2.2.5. QueryExpression Structure
QueryExpression
is the base for both SELECT queries and set queries. It may optionally take an OrderBy
(representing a SQL ORDER BY clause) and a Limit
(represent a SQL LIMIT clause) or a With
(represents a SQL WITH clause).
3.2.2.6. Select Structure
QueryExpression
can be a Select
describing the expressions (typically elements) being selected and a TableReference
specifying the table or tables being selected from, along with any join information. The Select
may optionally also supply a Condition
(representing a SQL WHERE clause), a GroupBy
(representing a SQL GROUP BY clause), a Condition
(representing a SQL HAVING clause).
3.2.2.7. SetQuery Structure
QueryExpression
can also be a SetQuery
that represents the SQL set operations (UNION, INTERSECT, EXCEPT) on two QueryExpression
s. The all flag may be set to indicate UNION ALL (currently INTERSECT and EXCEPT ALL are not supported).
3.2.2.8. With Structure
With
clause contains named QueryExpressions
held by WithItem
s that can be referenced as tables in the main QueryExpression
.
3.2.2.9. Insert Structure
Insert
will have a single NamedTable
specifying the table being inserted into. It will also has a list of ColumnReference
specifying the columns of the NamedTable
that are being inserted into. It also has InsertValueSource
, which will be a list of Expressions (ExpressionValueSource
), or a QueryExpression
.
3.2.2.10. Update Structure
Update
will have a single NamedTable
specifying the table being updated and list of SetClause
entries that specify ColumnReference
and Expression
pairs for the update. The Update may optionally provide a criteria Condition
specifying which rows should be updated.
3.2.2.11. Delete Structure
Delete
will have a single NamedTable
specifying the table being deleted from. It may also optionally have a criteria specifying which rows should be deleted.
3.2.2.12. Call Structure
Call
has zero or more Argument
objects. The Argument
objects describe the input parameters, the output result set, and the output parameters.
3.2.2.13. BatchedUpdates Structure
BatchedUpdates
has a list of Command
objects (which must be either Insert
, Update
or Delete
) that compose the batch.
3.2.2.14. The Type Facility
TypeFacility
that defines data types and provides value translation facilities. This interface can be obtained from calling the ExecutionFactory.getTypeFacility()
method.
Expression
instances define a data type based on this set of types. These constants are often needed in understanding or creating language interfaces.
3.2.2.15. Language Manipulation
getLanguageFactory()
method on the ExecutionFactory
to get a reference to the LanguageFactory
instance for your translator. This interface is a factory that can be used to create new instances of all the concrete language interface objects.
Condition
objects are provided in the LanguageUtil
class. This class has methods to combine Condition
with AND
or to break a Condition
apart based on AND
operators. These utilities are helpful for breaking apart a criteria into individual filters that your translator can implement.
3.2.2.16. Runtime Metadata
RuntimeMetadata
interface at the time of Excecution
creation. Translators can access runtime metadata by using the interfaces defined in org.teiid.metadata
package. This package defines API representing a Schema, Table, Columns and Procedures, and ways to navigate these objects.
3.2.2.17. Metadata Objects
AbstractMetadataRecord
class
- Column - returns Column metadata record
- Table - returns a Table metadata record
- Procedure - returns a Procedure metadata record
- ProcedureParameter - returns a Procedure Parameter metadata record
3.2.2.18. Access to Runtime Metadata
Example 3.1. Obtaining Metadata Properties
//getting the Table metadata from an Table is straight-forward Table table = runtimeMetadata.getTable("table-name"); String contextName = table.getNameInSource(); //The props will contain extension properties Map<String, String> props = table.getProperties();
3.2.2.19. Visitor Framework
org.teiid.language.visitor
package. The framework provides utilities useful in navigating and extracting information from trees of language objects.
AbstractLanguageVisitor
class defines the visit methods for all leaf language interfaces that can exist in the tree. The LanguageObject interface defines an acceptVisitor() method. This method will call back on the visit method of the visitor to complete the contract. A base class with empty visit methods is provided as AbstractLanguageVisitor. The AbstractLanguageVisitor is a visitor shell - it performs no actions when visiting nodes and does not provide any iteration.
HierarchyVisitor
provides the basic code for walking a language object tree. The HierarchyVisitor
performs no action as it walks the tree - it encapsulates the knowledge of how to walk it. If your translator wants to provide a custom iteration that walks the objects in a special order (to exclude nodes, include nodes multiple times, conditionally include nodes, and so forth) then you must either extend HierarchyVisitor or build your own iteration visitor. In general, that is not necessary.
DelegatingHierarchyVisitor
is a special subclass of the HierarchyVisitor that provides the ability to perform a different visitor's processing before and after iteration. This allows users of this class to implement either pre- or post-order processing based on the HierarchyVisitor. Two helper methods are provided on DelegatingHierarchyVisitor
to aid in executing pre- and post-order visitors.
3.2.2.20. Provided Visitors
SQLStringVisitor
is a special visitor that can traverse a tree of language interfaces and output the equivalent Red Hat JBoss Data Virtualization SQL. This visitor can be used to print language objects for debugging and logging. The SQLStringVisitor
does not use the HierarchyVisitor
described in the last section; it provides both iteration and processing type functionality in a single custom visitor.
CollectorVisitor
is a handy utility to collect all language objects of a certain type in a tree. Some additional helper methods exist to do common tasks such as retrieving all elements in a tree, retrieving all groups in a tree, and so on.
3.2.2.21. Writing a Visitor
visit(ColumnReference)
method. Collect any state in local variables and provide accessor methods for that state.
// Get object tree LanguageObject objectTree = ... // Create your visitor initialize as necessary MyVisitor visitor = new MyVisitor(); // Call the visitor using pre-order visitation DelegatingHierarchyVisitor.preOrderVisit(visitor, objectTree); // Retrieve state collected while visiting int count = visitor.getCount();
3.2.3. Connections to Source
3.2.4. Dependent Join Pushdown
Comparison
with a Parameter
, may be ignored in part or in total. Pushdown dependent join queries will be instances of Select
with the relevant dependent sets available via Select.getDependentSets()
. The dependent set is associated to Parameters by id via the Parameter.getDepenentValueId()
identifier. The dependent set tuple iterators provide rows that are referenced by the column positions (available via Parameter.getValueIndex()
) on the dependent join Comparison criteria right expression. Care should be taken with the tuple values as they may guaranteed to be unique or ordered.
Note
3.2.5. Executing Commands
3.2.5.1. Execution Modes
ExecutionFactory
class to obtain the Execution
interface for the command it is executing. The query is sent to the translator as a set of objects. Refer to Section 3.2.2.1, “Language” for more information.
Table 3.1. Types of Execution Modes
Execution Interface | Command interface(s) | Description |
---|---|---|
ResultSetExecution | QueryExpression | A query corresponding to a SQL SELECT or set query statement. |
UpdateExecution | Insert, Update, Delete, BatchedUpdates | An insert, update, or delete, corresponding to a SQL INSERT, UPDATE, or DELETE command |
ProcedureExecution | Call | A procedure execution that may return a result set and/or output values. |
Execution
interface that defines how executions are canceled and closed. ProcedureExecution also extends ResultSetExecution, since procedures may also return resultsets.
3.2.5.2. ExecutionContext
org.teiid.translator.ExecutionContext
class provides information related to the current execution. An instance of ExecutionContext
is available for each Execution
. Various 'get' methods are provided; for example, ExecutionContext.getRequestIdentifier()
and ExecutionContext.getSession()
are provided for logging purposes. Specific usage is highlighted in this guide where applicable.
3.2.5.3. Generated Keys
CommandContext.isReturnAutoGeneratedKeys()
method. If you wish to return generated keys, you must first create a GeneratedKeys
instance to hold the keys with the returnGeneratedKeys
method passing the column names and types of the key columns. Only one GeneratedKeys
may be associated with the CommandContext
at any given time.
3.2.5.4. Source Hints
getGeneralHint
and getSourceHint
. See the source for the OracleExecutionFactory
for an example of how this source hint information can be utilized.
3.2.5.5. ResultSetExecution
ResultSetExecution.next()
method. This method returns null to indicate the end of results. Note: the expected batch size can be obtained using the ExecutionContext.getBatchSize()
method and used as a hint in fetching results from the EIS.
3.2.5.6. Update Execution
ExecutionContext.isTransactional()
method can be used to determine if the execution is already under a transaction.
3.2.5.7. Procedure Execution
getOutputParameterValues()
method.
3.2.5.8. Asynchronous Executions
DataNotAvailableException
is thrown during a retrieval method, rather than explicitly waiting or sleeping for the results.
Note
DataNotAvailableException
should not be thrown by the execute method, as that can result in the execute method being called multiple times. The DataNotAvailableException
may take a delay parameter or a Date
in its constructor to indicate when to poll next for results. Any non-negative delay value indicates the time in milliseconds until the next polling should be performed.
DataNotAvailableException.NO_POLLING
exception (or any DataNotAvailableException with a negative delay) can be thrown so that processing will resume (via ExecutionContext.dataAvailable()
).
DataNotAvailableException
is consumed while the engine thinks more work can be performed or there are other shorter delays issued from other translators, then the plan may be queued again earlier than expected. You should throw a DataNotAvailableException
again if your execution is not yet ready. Alternatively the DataNotAvailableException
may be marked as strict, which does provide a guarantee that the Execution
will not be called until the delay has expired or the given Date
has been reached. Using the Date
constructor makes the DataNotAvailableException
automatically strict. Due to engine thread pool contention, platform time resolution, etc. a strict DataNotAvailableException
is not a real-time guarantee of when the next poll for results will occur, only that it will not occur before then.
Note
ExecutionFactory
returns only asynch executions that perform minimal work, then consider having ExecutionFactory.isForkable
return false so that the engine knows not to spawn a separate thread for accessing your Execution
.
3.2.5.9. Reusable Executions
ReusableExecutions
for the expected Execution objects. There can be one ReusableExecution
per query executing node in the processing plan. The lifecycle of a ReusableExecution
is different that a normal Execution
. After a normal creation/execute/close cycle the ReusableExecution.reset
is called for the next execution cycle. This may occur indefinitely depending on how many times a processing node executes its query. The behavior of the close
method is no different from a regular Execution
, it may not be called until the end of the statement if lobs are detected and any connection associated with the Execution
will also be closed. When the user command is finished, the ReusableExecution.dispose()
method will be called.
ReusableExecutions
are most useful for continuous query execution and will also make use of the ExecutionCotext.dataAvailable()
method for Asynchronous Executions. See Red Hat JBoss Data Virtualization Development Guide: Client Development for more information about executing continuous statements. In continuous mode the user query will be continuously re-executed. A ReusableExecution
allows the same Execution
object to be associated with the processing plan for a given processing node for the lifetime of the user query. This can simplify asynch resource management, such as establishing queue listeners. Returning a null result from the next()
method ReusableExecution
as with normal Executions
indicates that the current pushdown command results have ended. Once the reset()
method has been called, the next set of results should be returned again terminated with a null result.
3.2.5.10. Bulk Execution
Insert, Update, Delete
commands may have multi-valued Parameter
objects if the capabilities shows support for BulkUpdate. Commands with multi-valued Parameters represent multiple executions of the same command with different values. As with BatchedUpdates, bulk operations should be executed atomically if possible.
3.2.5.11. Command Completion
close()
on the Execution object. Your implementation of this method should do the appropriate clean-up work for all state created in the Execution object.
3.2.5.12. Command Cancellation
- 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
3.2.6. Extending the Execution Factory Class
3.2.6.1. Extending the ExecutionFactory Class
org.teiid.translator.ExecutionFactory
class to connect and query a data source. This extended class must provide a constructor with no arguments that can be constructed using Java reflection libraries.
package org.teiid.translator.custom; @Translator(name="custom", description="Connect to My EIS") public class CustomExecutionFactory extends ExecutionFactory<MyConnectionFactory, MyConnection> { public CustomExecutionFactory() { } }
@Translator
on the extended "ExecutionFactory" class. This annotation defines the name and description of your translator, and is also used as an identifier during deployment. This is the name you would be using in the VDB and elsewhere in the configuration to refer to this translator.
MyConnectionFactory
specifies the type of ConnectionFactory interface that is expected from the associated resource adapter. This is required as part of the class definition when extending the ExecutionFactory
class.
MyConnection
specifies the type of Connection interface that is expected from the associated resource adapter. This is required as part of class definition when extending the ExecutionFactory
class.
3.2.6.2. Configuration Properties
- define a variable for every property as an attribute in the extended
ExecutionFactory
class, - define "get" and "set" methods for each attribute,
- and annotate each "get" method with
@TranslatorProperty
annotation and provide the metadata about the property.
foo
, by providing the annotation on these properties, Red Hat JBoss Data Virtualization will automatically interrogate and provide a graphical way to configure your Translator while designing your VDB.
private String foo = "blah"; @TranslatorProperty(display="Foo property", description="description about Foo") public String getFoo() { return foo; } public void setFoo(String value) { this.foo = value; }
int
, boolean
), primitive object wrapper (java.lang.Integer
), or Enum
types are supported as Translator properties. The default value will be derived from calling the getter, if available, on a newly constructed instance. All properties should have a default value. If there is no applicable default, then the property should be marked in the annotation as required. Initialization will fail if a required property value is not provided.
@TranslatorProperty
defines the following metadata that you can define about your property.
- display - the display name of the property.
- description - a description about the property.
- required - specifies that the property is required.
- advanced - an advanced property (a default value must be provided).
- masked - tools need to mask the property, that is, do not show it in plain text. Used for passwords.
Note
3.2.6.3. Initializing the Translator
start()
method if your translator needs to do any initialization before it is used by the Red Hat JBoss Data Virtualization engine. This method must also call super.start()
to perform any initialization required by the superclass. This method is called by Red Hat JBoss Data Virtualization once all the configuration properties are injected into the class.
3.2.6.4. Extended Translator Capabilities
supports
, that specify translator capabilities. These methods need to be overridden to describe the execution capabilities of the Translator. See Section 3.2.8.1, “Introduction to Translator Capabilities” for more information about these methods.
3.2.6.5. Execution (and sub-interfaces)
createResultSetExecution
- Override if you are doing read based operation that is returning rows of results. For example, select.createUpdateExecution
- Override if you are doing write based operations. For example, insert, update, delete.createProcedureExecution
- Override if you are doing procedure based operations. For example, stored procedures. This works well for non-relational sources.
3.2.6.6. Metadata
getMetadataProcessor()
, in order to expose the metadata about the source for use in Dynamic VDBs. This defines the tables, column names, procedures, parameters, and so forth. for use in the query engine. This method is used by Designer tooling when the Teiid Connection importer is used. Here is a sample MetadataProcessor
:
public class MyMetadataProcessor implements MetadataProcessor<Connection> { public void process(MetadataFactory mf, Connection conn) { Object somedata = connection.getSomeMetadata(); Table table = mf.addTable(tableName); Column col1 = mf.addColumn("col1", TypeFacility.RUNTIME_NAMES.STRING, table); Column col2 = mf.addColumn("col2", TypeFacility.RUNTIME_NAMES.STRING, table); //add a pushdown function that can also be evaluated in the engine Method method = ... FunctionMethod f = mf.addFunction("func", method); //add a pushdown aggregate function that can also be evaluated in the engine Method aggMethod = ... FunctionMethod af = mf.addFunction("agg", aggMethod); af.setAggregateAttributes(new AggregateAttributes()); ... } }
MetadataProcessor
needs external properties that are needed during the import process, you can define them on the MetadataProcessor
. For example, to define a import property called "Column Name Pattern", which can be used to filter which columns are defined on the table, you can add it like this:
@TranslatorProperty(display="Column Name Pattern", category=PropertyType.IMPORT, description="Pattern to derive column names") public String getColumnNamePattern() { return columnNamePattern; } public void setColumnNamePattern(String columnNamePattern) { this.columnNamePattern = columnNamePattern; }
<vdb name="myvdb" version="1"> <model name="legacydata" type="PHYSICAL"> <property name="importer.ColumnNamePattern" value="col*"/> .... <source name = .../> </model> </vdb>
public class MyMetadataProcessor implements MetadataProcessor<Connection> { public static final String NAMESPACE = "{http://my.company.corp}"; @ExtensionMetadataProperty(applicable={Table.class}, datatype=String.class, display="File name", description="File Name", required=true) public static final String FILE_PROP = NAMESPACE+"FILE"; public void process(MetadataFactory mf, Connection conn) { Object somedata = connection.getSomeMetadata(); Table table = mf.addTable(tableName); table.setProperty(FILE_PROP, somedata.getFileName()); Column col1 = mf.addColumn("col1", TypeFacility.RUNTIME_NAMES.STRING, table); Column col2 = mf.addColumn("col2", TypeFacility.RUNTIME_NAMES.STRING, table); } }
@ExtensionMetadataProperty
defines the following metadata that you can define about your property:
applicable
: Metadata object this is applicable on. This is array of metadata classes like Table.class and Column.class.datatype
: The java class indicating the data typedisplay
: Display name of the propertydescription
: Description about the propertyrequired
: Indicates if the property is a required property
'SELECT * FROM MyTable'
, MyTable will be represented by an object called NamedTable
.
for (TableReference tr:query.getFrom()) { NamedTable t = (NamedTable) tr; Table table = t.getMetadataObject(); String file = table.getProperty(FILE_PROP); .. }
3.2.6.7. Logging
org.teiid.logging.LogManager
class for logging purposes, based on the Apache Log4j logging services.
3.2.6.8. Exceptions
org.teiid.translator.TranslatorException
class.
3.2.6.9. Default Name
@Translator
on the ExecutionFactory
. After deployment, a default instance of this Translator can be used by any VDB by referencing it by this name in its vdb.xml
configuration file.
Note
3.2.6.10. Obtaining Connections
ExecutionFactory
must implement the getConnection()
method to allow the Connector Manager to obtain a connection.
3.2.6.11. Releasing Connections
closeConnection()
method is called on the ExecutionFactory
. You must override this method to close the connection properly.
Note
3.2.7. Large Objects
3.2.7.1. Data Types
3.2.7.2. Why Use Large Object Support?
- Reduces memory usage when returning the result set to the user.
- Improves performance by passing less data in the result set.
- Allows access to large objects when needed rather than assuming that users will always use the large object data.
- Allows the passing of arbitrarily large data values.However, these benefits can only truly be gained if the Translator itself does not materialize an entire large object all at once. For example, the Java JDBC API supports a streaming interface for BLOB and CLOB data.
3.2.7.3. Handling Large Objects
ExecutionContext.keepAlive()
method.
executionContext.keepExecutionAlive(true);
3.2.7.4. Inserting or Updating Large Objects
3.2.8. Translator Capabilities
3.2.8.1. Introduction to Translator Capabilities
ExecutionFactory
class defines all the methods that describe the capabilities of a Translator. These are used by the Connector Manager to determine what kinds of commands the translator is capable of executing. A base ExecutionFactory
class implements all the basic capabilities methods, which says your translator does not support any capabilities. Your extended ExecutionFactory
class must override the necessary methods to specify which capabilities your translator supports. You should consult the debug log of query planning (set showplan debug) to see if desired pushdown requires additional capabilities.
Note
3.2.8.2. Translator Development
@TranslatorProperty(display="Copy LOBs",description="If true, returned LOBs will be copied, rather than streamed from the source",advanced=true) public boolean isCopyLobs() { return copyLobs; } public void setCopyLobs(boolean copyLobs) { this.copyLobs = copyLobs; }
vdb.xml
file like this:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <vdb name="vdb" version="1"> <model name="PM1"> <source name="connector" translator-name="my-translator-override" /> </model> <translator name="my-translator-override" type="my-translator"> <property name="CopyLobs" value="true" /> </translator> </vdb>
@Translator(name = "my-translator", description = "My Translator") public class MyExecutionFactory extends ExecutionFactory<ConnectionFactory, MyConnection> { ... public MetadataProcessor<C> getMetadataProcessor() { return MyMetadataProcessor(); } } public MyMetadataProcessor implements MetadataProcessor<MyConnection> { public void process(MetadataFactory metadataFactory, MyConnection connection) throws TranslatorException{ // schema generation code here } @TranslatorProperty(display="Header Row Number", category=PropertyType.IMPORT, description="Row number that contains the header information") public int getHeaderRowNumber() { return headerRowNumber; } public void setHeaderRowNumber(int headerRowNumber) { this.headerRowNumber = headerRowNumber; } }
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <vdb name="vdb" version="1"> <model name="PM1"> <property name="importer.HeaderRowNumber" value="12"/> <source name="connector" translator-name="my-translator" /> </model> </vdb>
Note
public class MyMetadataProcessor implements MetadataProcessor<MyConnection> { public static final String URI = "{http://www.teiid.org/translator/mytranslator/2014}"; @ExtensionMetadataProperty(applicable=Table.class, datatype=String.class, display="Encoding", description="Encoding", required=true) public static final String ENCODING = URI+"encode"; public void process(MetadataFactory mf, FileConnection conn) throws TranslatorException { .. Table t = mf.addTable(tableName); t.setProperty(ENCODING, "UTF-16"); // add columns etc. .. } }
Select select = (Select)command; NamedTable tableReferece = select.getFrom().get(0); Table t = tableReference.getMetadataObject(); String encoding = t.getProperty(MyMetadataProcessor.ENCODING, false); // use the encoding value as needed to marshal or unmarshal data
Note
3.2.8.3. ExecutionFactory Class Capabilities
Table 3.2. Available Capabilities
Capability
|
Requires
|
Description
|
---|---|---|
SelectDistinct
| |
The translator supports SELECT DISTINCT in queries.
|
SelectExpression
| |
The translator supports SELECT of more than column references.
|
AliasedTable
| |
The translator supports Tables in the FROM clause that have an alias.
|
InnerJoins
| |
The translator supports inner and cross joins.
|
SelfJoins
|
AliasedGroups and at least on of the join type supports.
|
The translator supports a self join between two aliased versions of the same Table.
|
OuterJoins
| |
The translator supports LEFT and RIGHT OUTER JOIN.
|
FullOuterJoins
| |
The translator supports FULL OUTER JOIN.
|
DependentJoins
|
Base join and criteria support
|
The translator supports key set dependent join pushdown (see Section 3.2.4, “Dependent Join Pushdown”). When set, the MaxDependentInPredicates and MaxInCriteriaSize values are not used by the engine, rather all independent values are made available to the pushdown command.
|
SubqueryInOn
|
Join and base subquery support, such as ExistsCriteria
|
The translator supports subqueries in the ON clause. It defaults to true.
|
InlineViews
|
AliasedTable
|
The translator supports a named subquery in the FROM clause.
|
BetweenCriteria
| |
This is not currently used - between criteria are rewritten as compound comparisons.
|
CompareCriteriaEquals
| |
The translator supports comparison criteria with the operator "=".
|
CompareCriteriaOrdered
| |
The translator supports comparison criteria with the operator ">" or "<".
|
LikeCriteria
| |
The translator supports LIKE criteria.
|
LikeCriteriaEscapeCharacter
|
LikeCriteria
|
The translator supports LIKE criteria with an ESCAPE character clause.
|
SimilarTo
| |
The translator supports SIMILAR TO criteria.
|
LikeRegexCriteria
| |
The translator supports LIKE_REGEX criteria.
|
InCriteria
|
MaxInCriteria
|
The translator supports IN predicate criteria.
|
InCriteriaSubquery
| |
The translator supports IN predicate criteria where values are supplied by a subquery.
|
IsNullCriteria
| |
The translator supports IS NULL predicate criteria.
|
OrCriteria
| |
The translator supports the OR logical criteria.
|
NotCriteria
| |
The translator supports the NOT logical criteria. IMPORTANT: This capability also applies to negation of predicates, such as specifying IS NOT NULL, "<=" (not ">"), ">=" (not "<"), etc.
|
ExistsCriteria
| |
The translator supports EXISTS predicate criteria.
|
QuantifiedCompareCriteriaAll
| |
The translator supports a quantified comparison criteria using the ALL quantifier.
|
QuantifiedCompareCriteriaSome
| |
The translator supports a quantified comparison criteria using the SOME or ANY quantifier.
|
OnlyLiteralComparison
| |
If only Literal comparisons (equality, ordered, like, and so on) are supported for non-join conditions.
|
Convert(int fromType, int toType)
| |
This is used for fine-grained control of the convert/cast pushdown. The
ExecutionFactory.getSupportedFunctions() must contain SourceSystemFunctions.CONVERT . This method can then return false to indicate a lack of specific support. (See TypeFacility.RUNTIME_CODES for the possible type codes.) The engine does not care about unnecessary conversions where fromType == toType . By default lob conversion is disabled.
|
OrderBy
| |
The translator supports the ORDER BY clause in queries.
|
OrderByUnrelated
|
OrderBy
|
The translator supports ORDER BY items that are not directly specified in the select clause.
|
OrderByNullOrdering
|
OrderBy
|
The translator supports ORDER BY items with NULLS FIRST/LAST.
|
GroupBy
| |
The translator supports an explicit GROUP BY clause.
|
Having
|
GroupBy
|
The translator supports the HAVING clause.
|
AggregatesAvg
| |
The translator supports the AVG aggregate function.
|
AggregatesCount
| |
The translator supports the COUNT aggregate function.
|
AggregatesCountStar
| |
The translator supports the COUNT(*) aggregate function.
|
AggregatesDistinct
|
At least one of the aggregate functions.
|
The translator supports the keyword DISTINCT inside an aggregate function. This keyword indicates that duplicate values within a group of rows will be ignored.
|
AggregatesMax
| |
The translator supports the MAX aggregate function.
|
AggregatesMin
| |
The translator supports the MIN aggregate function.
|
AggregatesSum
| |
The translator supports the SUM aggregate function.
|
AggregatesEnhancedNumeric
| |
The translator supports the VAR_SAMP, VAR_POP, STDDEV_SAMP, STDDEV_POP aggregate functions.
|
ScalarSubqueries
| |
The translator supports the use of a subquery in a scalar context (wherever an expression is valid).
|
CorrelatedSubqueries
|
At least one of the subquery pushdown capabilities.
|
The translator supports a correlated subquery that refers to an element in the outer query.
|
CaseExpressions
| |
This is not currently used - simple case is rewritten as searched case.
|
SearchedCaseExpressions
| |
The translator supports "searched" CASE expressions anywhere that expressions are accepted.
|
Unions
| |
The translator supports UNION and UNION ALL.
|
Intersect
| |
The translator supports INTERSECT.
|
Except
| |
The translator supports EXCEPT.
|
SetQueryOrderBy
|
Unions, Intersect, or Except
|
The translator supports set queries with an ORDER BY.
|
RowLimit
| |
The translator supports the limit portion of the limit clause.
|
RowOffset
| |
The translator supports the offset portion of the limit clause.
|
FunctionsInGroupBy
|
GroupBy
|
The translator supports non-column reference grouping expressions.
|
InsertWithQueryExpression
| |
Translator supports INSERT statements with values specified by a QueryExpression.
|
BatchedUpdates
| |
The translator supports a batch of INSERT, UPDATE and DELETE commands to be executed together.
|
BulkUpdate
| |
Translator supports updates with multiple value sets
|
CommonTableExpressions
| |
The translator supports the WITH clause.
|
ElementaryOlapOperations
| |
The translator supports window functions and analytic functions RANK, DENSE_RANK, and ROW_NUMBER.
|
WindowOrderByWithAggregates
|
ElementaryOlapOperations
|
The translator supports windowed aggregates with a window order by clause.
|
WindowDistinctAggregates
|
ElementaryOlapOperations, AggregatesDistinct
|
The translator supports windowed distinct aggregates.
|
AdvancedOlapOperations
|
ElementaryOlapOperations
|
The translator supports aggregate conditions.
|
OnlyFormatLiterals
|
This provides function support for a parse/format function and an implementation of the supportsFormatLiteral method.
|
The translator supports only literal format patterns that are validated by the supportsFormatLiteral method.
|
FormatLiteral(String literal, Format type)
|
OnlyFormatLiterals
|
The translator supports the given literal format string.
|
ArrayType
| |
The translator supports the push down of array values.
|
OnlyCorrelatedSubqueries
|
CorrelatedSubqueries
|
The translator ONLY supports correlated subqueries. Uncorrelated scalar and exists subqueries will be pre-evaluated prior to push-down.
|
SelectWithoutFrom
|
SelectExpressions
|
The translator supports selecting values without a FROM clause, such as SELECT 1.
|
Note
3.2.8.4. Command Form
ExecutionFactory.useAnsiJoin()
should return true if the Translator prefers the use of ANSI style join structure for join trees that contain only INNER and CROSS joins.
ExecutionFactory.requiresCriteria()
should return true if the Translator requires criteria for any Query, Update, or Delete. This is a replacement for the model support property "Where All".
3.2.8.5. Scalar Functions
ExecutionFactory.getSupportedFunctions()
can be used to specify which scalar and aggregate functions the Translator supports. The set of possible functions is based on the set of functions supported by Red Hat JBoss Data Virtualization. This set can be found in the Red Hat JBoss Data Virtualization Reference Guide. If the Translator states that it supports a function, it must support all type combinations and overloaded forms of that function.
ExecutionFactory.getPushDownFunctions()
list as FunctionMethod
metadata objects. The FuncitonMethod
representation allow the translator to control all of the metadata related to the function, including type signature, determinism, varargs, etc. The simplest way to add a pushdown function is with a call to ExecutionFactory.addPushDownFunction
:
FunctionMethod addPushDownFunction(String qualifier, String name, String returnType, String...paramTypes)
FunctionMethod
object may be further manipulated depending upon the needs of the source. An example of adding a custom concat vararg function in an ExecutionFactory
subclass:
public void start() throws TranslatorException { super.start(); FunctionMethod func = addPushDownFunciton("oracle", "concat", "string", "string", "string"); func.setVarArgs(true); ... }
3.2.8.6. Physical Limits
ExecutionFactory.getMaxInCriteriaSize()
can be used to specify the maximum number of values that can be passed in an IN criteria. This is an important constraint as an IN criteria is frequently used to pass criteria between one source and another using a dependent join.
ExecutionFactory.getMaxDependentInPredicates()
is used to specify the maximum number of IN predicates (of at most MaxInCriteriaSize) that can be passed as part of a dependent join. For example if there are 10000 values to pass as part of the dependent join and a MaxInCriteriaSize of 1000 and a MaxDependentInPredicates setting of 5, then the dependent join logic will form two source queries each with 5 IN predicates of 1000 values each combined by OR.
ExecutionFactory.getMaxFromGroups()
can be used to specify the maximum number of FROM Clause groups that can used in a join. -1 indicates there is no limit.
3.2.8.7. Update Execution Modes
ExecutionFactory.supportsBatchedUpdates()
can be used to indicate that the Translator supports executing the BatchedUpdates
command.
ExecutionFactory.supportsBulkUpdate()
can be used to indicate that the Translator accepts update commands containg multi valued Literals.
Note
3.2.8.8. Null Ordering
ExecutionFactory.getDefaultNullOrder()
specifies the default null order. It can be one of UNKNOWN, LOW, HIGH, FIRST, LAST. This is only used if ORDER BY is supported, but null ordering is not.
ExecutionFactory.getCollation()
specifies the default collation. If you set it to a value that does not match the collation locale defined by org.teiid.collationLocale, then some ordering may not be pushed down.
Chapter 4. Extending the JDBC Translator
4.1. Extensions
org.teiid.translator.jdbc.JDBCExecutionFactory
class in the translator-jdbc
module. There are three types of methods that you can override from the base class to define the behavior of the Translator.
Table 4.1. Extensions
Extension
|
Purpose
|
---|---|
Capabilities
|
Specify the SQL syntax and functions the source supports.
|
SQL Translation
|
Customize what SQL syntax is used, how source-specific functions are supported, how procedures are executed.
|
Results Translation
|
Customize how results are retrieved from JDBC and translated.
|
4.2. Capabilities Extension
4.3. SQL Translation Extension
- Change basic SQL syntax options. See the useXXX methods, e.g. useSelectLimit returns true for SQLServer to indicate that limits are applied in the SELECT clause.
- Register one or more FunctionModifiers that define how a scalar function is to be modified or transformed.
- Modify a LanguageObject (see the
translate
,translateXXX
, andFunctionModifier.translate
methods). Modify the passed in object and return null to indicate that the standard syntax output will be used. - Change the way SQL strings are formed for a LanguageObject (see the
translate
,translateXXX
, andFunctionModifier.translate
methods). This returns a list of parts which can contain strings and LanguageObjects. These are appended to the SQL string in order. If the incoming LanguageObject appears in the returned list it is not translated again.
4.4. Results Translation Extension
- Overriding the createXXXExecution to subclass the corresponding JDBCXXXExecution. The JDBCBaseExecution has protected methods to get the appropriate statement (getStatement, getPreparedStatement, getCallableStatement) and to bind prepared statement values bindPreparedStatementValues.
- Retrieve values from the JDBC ResultSet or CallableStatement - see the retrieveValue methods.
4.5. Adding Function Support
- Override the capabilities method to declare support for the function (REQUIRED)
- Implement a FunctionModifier to change how a function is translated and register it for use (OPTIONAL)
package my.connector; import java.util.ArrayList; import java.util.List; public class ExtendedJDBCExecutionFactory extends JDBCExecutionFactory { @Override public List getSupportedFunctions() { List supportedFunctions = new ArrayList(); supportedFunctions.addAll(super.getSupportedFunctions()); supportedFunctions.add("ABS"); return supportedFunctions; } }
4.6. Using Function Modifiers
FunctionModifier
for this purpose.
JDBCExecutionFactory.registerFunctionModifier
.
translate
. Use the translate method to change the way the function is represented.
public class ModFunctionModifier extends FunctionModifier { public List translate(Function function) { List parts = new ArrayList(); parts.add("("); Expression[] args = function.getParameters().toArray(new Expression[0]); parts.add(args[0]); parts.add(" % "); parts.add(args[1]); parts.add(")"); return parts; } }
Table 4.2. Common Modifiers
Modifier
|
Description
|
---|---|
AliasModifier
|
Handles renaming a function ("ucase" to "upper" for example)
|
EscapeSyntaxModifier
|
Wraps a function in the standard JDBC escape syntax for functions: {fn xxxx()}
|
ExecutionFactory.registerFunctionModifier(String name, FunctionModifier modifier)
method.
public class ExtendedJDBCExecutionFactory extends JDBCExecutionFactory { @Override public void start() { super.start(); // register functions. registerFunctionModifier("abs", new MyAbsModifier()); registerFunctionModifier("concat", new AliasModifier("concat2")); } }
4.7. Installing Extensions
Chapter 5. Delegating
5.1. Delegating Translator
BaseDelegatingExecutionFactory
. Within this subclass, delegation methods can be overridden to perform the common functionality.
@Translator(name="custom-delegator") public class MyTranslator extends BaseDelegatingExecutionFactory<Object, Object> { @Override public Execution createExecution(Command command, ExecutionContext executionContext, RuntimeMetadata metadata, Object connection) throws TranslatorException { if (command instanceof Select) { //modify the command or return a different execution ... } //the super call will be to the delegate instance return super.createExecution(command, executionContext, metadata, connection); } ... }
<translator type="custom-delegator" name="my-translator"> <property value="delegateName" name="name of the delegate instance"/> <!-- any custom properties you may have on your custom translator --> </translator>
Note
BaseDelegatingExecutionFactory
by default means that standard override translator property settings on your instance will have no effect, since the underlying delegate is called instead.
DelegatingExecutionFactory
instead.
5.2. Adding Dependent Modules
Dependencies: org.jboss.teiid.common-core,org.jboss.teiid.api,javax.api
Chapter 6. Packaging and Deploying the Translator
6.1. Packaging
org.teiid.translator.custom.CustomExecutionFactory
6.2. Translator Deployment Overview
6.3. Module Deployment
standalone.xml
file or domain.xml
file and restart the server. The dependent Red Hat JBoss Data Virtualization or any other Java class libraries must be defined in module.xml file of the module. For production profiles this is recommended.
Example 6.1. Example module.xml
file
module.xml
file provided for the Salesforce translator. This file is located in the EAP_HOME/docs/teiid/datasources/salesforce/modules/org/springframework/spring/main
directory.
<module xmlns="urn:jboss:module:1.0" name="org.springframework.spring"> <resources> <resource-root path="spring-beans.jar"/> <resource-root path="spring-context.jar"/> <resource-root path="spring-core.jar"/> </resources> <dependencies> <module name="javax.api"/> </dependencies> </module>
6.4. JAR Deployment
Example 6.2. Example MANIFEST.mf
file
/META-INF/MANIFEST.mf
file provided in the Loopback translator JAR file, EAP_HOME/modules/system/layers/dv/org/jboss/teiid/translator/loopback/main/translator-loopback-[VERSION].jar
.
Manifest-Version: 1.0 Bnd-LastModified: 1516984498575 Build-Jdk: 1.7.0_85 Build-Timestamp: Fri, 26 Jan 2018 11:34:13 -0500 Built-By: mockbuild Bundle-Description: Loopback Translator Bundle-DocURL: http://www.jboss.org/ Bundle-License: http://www.gnu.org/licenses/lgpl.html Bundle-ManifestVersion: 2 Bundle-Name: Loopback Translator Bundle-SymbolicName: org.jboss.teiid.connectors.translator-loopback Bundle-Vendor: JBoss by Red Hat Bundle-Version: 8.12.11.6_4-redhat-64-12 Created-By: Apache Maven Bundle Plugin Export-Package: org.teiid.translator.loopback;uses:="org.teiid.language, org.teiid.metadata,org.teiid.translator";version="8.12.11" Implementation-Title: Loopback Translator Implementation-URL: http://www.jboss.org/teiid/connectors/translator-loo pback Implementation-Vendor: JBoss by Red Hat Implementation-Vendor-Id: org.jboss.teiid.connectors Implementation-Version: 8.12.11.6_4-redhat-64-12 Import-Package: org.teiid.core.util;version="[8.12,9)",org.teiid.languag e;version="[8.12,9)",org.teiid.logging;version="[8.12,9)",org.teiid.met adata;version="[8.12,9)",org.teiid.translator,org.teiid.translator.jdbc .teiid;version="[8.12,9)" Java-Vendor: Oracle Corporation Java-Version: 1.7.0_85 Os-Arch: amd64 Os-Name: Linux Os-Version: 2.6.32-696.18.7.el6.x86_64 Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.6))" Scm-Connection: scm:git:git://github.com/teiid/teiid.git/connectors/tran slator-loopback Scm-Revision: 01b968a220e981ee820ab1b07df148833eb8b995 Scm-Url: http://github.com/teiid/teiid/connectors/translator-loopback Specification-Title: Loopback Translator Specification-Vendor: JBoss by Red Hat Specification-Version: 8.12.11.6_4-redhat-64-12 Tool: Bnd-2.3.0.201405100607
Chapter 7. User Defined Functions
7.1. User Defined Functions
- Function Name - When you create the function name, keep these requirements in mind:
- You cannot overload existing Red Hat JBoss Data Virtualization functions.
- The function name must be unique among user-defined functions in its model for the number of arguments. You can use the same function name for different numbers of types of arguments. Hence, you can overload your user-defined functions.
- The function name cannot contain the '.' character.
- The function name cannot exceed 255 characters.
- Input Parameters - defines a type specific signature list. All arguments are considered required.
- Return Type - the expected type of the returned scalar value.
- Pushdown - can be one of REQUIRED, NEVER, ALLOWED. Indicates the expected pushdown behavior. If NEVER or ALLOWED are specified then a Java implementation of the function should be supplied. If REQUIRED is used, then user must extend the Translator for the source and add this function to its pushdown function library.
- invocationClass/invocationMethod - optional properties indicating the static method to invoke when the UDF is not pushed down.
- Deterministic - if the method will always return the same result for the same input parameters. Defaults to false. It is important to mark the function as deterministic if it returns the same value for the same inputs as this will lead to better performance. See also the Relational extension boolean metadata property "deterministic" and the DDL OPTION property "determinism".
Note
7.2. Support for Non-Pushdown User Defined Functions
7.2.1. Non-Pushdown UDF Metadata in Teiid Designer
7.2.2. Non-Pushdown UDF Metadata for Dynamic VDBs
<vdb name="{vdb-name}" version="1"> <model name="{model-name}" type="VIRTUAL"> <metadata type="DDL"><![CDATA[ CREATE VIRTUAL FUNCTION celsiusToFahrenheit(celsius decimal) RETURNS decimal OPTIONS (JAVA_CLASS 'org.something.TempConv', JAVA_METHOD 'celsiusToFahrenheit'); CREATE VIRTUAL FUNCTION sumAll(arg integer) RETURNS integer OPTIONS (JAVA_CLASS 'org.something.SumAll', JAVA_METHOD 'addInput', AGGREGATE 'true', VARARGS 'true', "NULL-ON-NULL" 'true');]]> </metadata> </model> </vdb>
7.2.3. Coding Non-Pushdown Functions
7.2.3.1. UDF Coding
- The Java class containing the function method must be defined public.
Note
You can declare multiple user defined functions for a given class. - The function method must be public and static.
Example 7.1. Sample UDF Code
package org.something; public class TempConv { /** * Converts the given Celsius temperature to Fahrenheit, and returns the * value. * @param doubleCelsiusTemp * @return Fahrenheit */ public static Double celsiusToFahrenheit(Double doubleCelsiusTemp) { if (doubleCelsiusTemp == null) { return null; } return (doubleCelsiusTemp)*9/5 + 32; } }
7.2.3.2. UDAF Coding
- The Java class containing the function method must be defined public and extend
org.teiid.UserDefinedAggregate
. - The function method must be public.
Example 7.2. Sample UDAF Code
package org.something; public class SumAll implements UserDefinedAggregate<Integer> { private boolean isNull = true; private int result; public void addInput(Integer... vals) { isNull = false; for (int i : vals) { result += i; } } @Override public Integer getResult(org.teiid.CommandContext commandContext) { if (isNull) { return null; } return result; } @Override public void reset() { isNull = true; result = 0; } }
7.2.3.3. Coding: Other Considerations
- Number of input arguments and types must match the function metadata defined in Section 7.1, “User Defined Functions”.
- Any exception can be thrown, but Red Hat JBoss Data Virtualization will throw the exception as a
FunctionExecutionException
. - You may optionally add an additional
org.teiid.CommandContext
argument as the first parameter. TheCommandContext
interface provides access to information about the current command, such as the executing user, subject, the VDB, the session id, etc. ThisCommandContext
parameter should not be declared in the function metadata.
Example 7.3. Sample CommandContext
Usage
package org.something; public class SessionInfo { /** * @param context * @return the created Timestamp */ public static Timestamp sessionCreated(CommandContext context) { return new Timestamp(context.getSession().getCreatedTime()); } }
Timestamp sessionCreated()
.
7.2.3.4. Post Coding Activities
- After coding the functions, compile the Java code into a Java Archive (JAR) file.
- Create a JBoss EAP module (
module.xml
) accompanying the JAR file in theEAP_HOME/modules/
directory. - Add the module dependency to the
DATABASE-vdb.xml
file as shown in the example below.<vdb name="{vdb-name}" version="1"> <property name ="lib" value ="{module-name}"></property> ... </vdb>
Thelib
property value may contain a space delimited list of module names if more than one dependency is needed.Note
Alternatively, when using a VDB created with Teiid Designer (DATABASE.vdb
), the JAR file may be placed in your VDB under the/lib
directory. It will be added automatically to the VDB classloader.
7.3. Source Supported Functions
SELECT score(1), ID, FREEDATA FROM Docs WHERE contains(freedata, 'nick', 1) > 0
score
and contains
functions are not part of built-in scalar function library. While you could write your own custom scalar function to mimic their behavior, it is more likely that you would want to use the actual Oracle functions that are provided by Oracle when using the Oracle Free Text functionality.
7.3.1. Defining a Source Supported Function by Extending the Translator
- Required - extend the OracleExecutionFactory and add SCORE and CONTAINS as supported pushdown functions by either overriding or adding additional functions in "getPushDownFunctions" method. For this example, we'll call the class MyOracleExecutionFactory. Add the
org.teiid.translator.Translator
annotation to the class, e.g.@Translator(name="myoracle")
- Optionally register new FunctionModifiers on the start of the ExecutionFactory to handle translation of these functions. Given that the syntax of these functions is same as other typical functions, this probably is not needed - the default translation should work.
- Create a new translator JAR containing your custom ExecutionFactory. Once this extended translator is deployed in Red Hat JBoss Data Virtualization, use "myoracle" as translator name instead of the "oracle" in your VDB's Oracle source configuration.
7.3.2. Defining a Source Supported Function via Teiid Designer
Note
7.3.3. Defining a Source Supported Function Using Dynamic VDBs
<vdb name="{vdb-name}" version="1"> <model name="{model-name}" type="PHYSICAL"> <source name="AccountsDB" translator-name="oracle" connection-jndi-name="java:/oracleDS"/> <metadata type="DDL"><![CDATA[ CREATE FOREIGN FUNCTION SCORE (val integer) RETURNS integer; .... (other tables, procedures etc) ]]> </metadata> </model> </vdb>
<vdb name="{vdb-name}" version="1"> <model name="{model-name}" type="PHYSICAL"> <source name="AccountsDB" translator-name="oracle" connection-jndi-name="java:/oracleDS"/> <metadata type="NATIVE,DDL"><![CDATA[ CREATE FOREIGN FUNCTION SCORE (val integer) RETURNS integer; ]]> </metadata> </model> </vdb>
<vdb name="{vdb-name}" version="1"> <model name="{model-name}" type="PHYSICAL"> <source name="AccountsDB" translator-name="oracle" connection-jndi-name="java:/oracleDS"/> <metadata type="{metadata-repo-module}"></metadata> </model> </vdb>
Chapter 8. Admin API
8.1. Admin API
org.teiid.adminapi
package.
8.2. Connecting
org.teiid.adminapi.Admin
interface, is obtained through the org.teiid.adminapi.AdminFactory.createAdmin
methods. AdminFactory
is a singleton, see AdminFactory.getInstance()
. The Admin
instance automatically tests its connection and reconnects to a server in the event of a failure. The close
method should be called to terminate the connection.
8.3. Administration Methods
Chapter 9. Custom Logging
9.1. Customized Logging
standalone.xml
or domain.xml
configuration file and the "logging" subsystem. Refer to the Red Hat JBoss Data Virtualization Administration and Configuration Guide for more details about the different contexts available.
9.2. Command Logging API
java.util.logging.LogRecord
s to the "COMMAND_LOG" context, the handler will receive a message that is an instance of LogRecord
. This object will contain a parameter of type org.teiid.logging.CommandLogMessage
. The relevant Red Hat JBoss Data Virtualization classes are defined in the teiid-api-[versionNumber].jar
. The CommandLogMessage includes information about VDB, session, command SQL, etc. CommandLogMessages are logged at the DEBUG level. An example follows.
package org.something; import java.util.logging.Handler; import java.util.logging.LogRecord; public class CommandHandler extends Handler { @Override public void publish(LogRecord record) { CommandLogMessage msg = (CommandLogMessage)record.getParameters()[0]; //log to a database, trigger an email, etc. } @Override public void flush() { } @Override public void close() throws SecurityException { } }
9.3. Audit Logging API
java.util.logging.LogRecord
s to the "AUDIT_LOG" context, the handler will receive a message that is an instance of LogRecord
. This object will contain a parameter of type org.teiid.logging.AuditMessage
. The relevant Red Hat JBoss Data Virtualization classes are defined in the teiid-api-[versionNumber].jar
. AuditMessages are logged at the DEBUG level. An example follows.
package org.something; import java.util.logging.Handler; import java.util.logging.LogRecord; public class AuditHandler extends Handler { @Override public void publish(LogRecord record) { AuditMessage msg = (AuditMessage)record.getParameters()[0]; //log to a database, trigger an email, etc. } @Override public void flush() { } @Override public void close() throws SecurityException { } }
9.4. Configuration
module.xml
file in the same directory and add
<resource-root path="{your-jar-name}.jar" />
standalone.xml
or domain.xml
file, locate the "logging" subsystem and add the following entries.
<custom-handler name="COMMAND" class="org.teiid.logging.CommandHandler" module="org.jboss.teiid"> </custom-handler> ..other entries <logger category="org.teiid.COMMAND_LOG"> <level name="DEBUG"/> <handlers> <handler name="COMMAND"/> </handlers> </logger>
Chapter 10. Custom Metadata Repository
10.1. Custom Metadata Repository
10.2. NATIVE
Example 10.1. Sample vdb.xml file
<vdb name="{vdb-name}" version="1"> <model name="{model-name}" type="PHYSICAL"> <source name="AccountsDB" translator-name="oracle" connection-jndi-name="java:/oracleDS"/> <metadata type="NATIVE"></metadata> </model> </vdb>
Note
getMetadata
method on the ExecutionFactory
class, NATIVE uses this method to retrieve the metadata from source.
10.3. DDL
Example 10.2. Sample vdb.xml file
<vdb name="{vdb-name}" version="1"> <model name="{model-name}" type="PHYSICAL"> <source name="AccountsDB" translator-name="oracle" connection-jndi-name="java:/oracleDS"/> <metadata type="DDL"> **DDL Here** </metadata> </model> </vdb>
10.4. FILE
Example 10.3. Sample vdb.xml file
<vdb name="{vdb-name}" version="1"> <model name="{model-name}" type="PHYSICAL"> <source name="AccountsDB" translator-name="oracle" connection-jndi-name="java:/oracleDS"/> <metadata type="DDL-FILE">/accounts.ddl</metadata> </model> </vdb>
10.5. Custom
- Users can write metadata facility that is based on reading data from database or a JCR repository or so forth. Here is an example:
package com.something; import org.teiid.metadata.MetadataRepository; ... public class CustomMetadataRepository extends MetadataRepository { @Override public void loadMetadata(MetadataFactory factory, ExecutionFactory executionFactory, Object connectionFactory) throws TranslatorException { /* Provide implementation and fill the details in factory */ ... } }
- Build a JAR archive with above implementation class and create file named org.teiid.metadata.MetadataRepository in the META-INF/services directory with these contents:
com.something.CustomMetadataRepository
- Deploy the JAR to Red Hat JBoss EAP as a module under the modules directory. Follow the below steps to create a module.
- Create a directory called modules/com/something/main.
- Under this directory create a "module.xml" file that looks like:
<?xml version="1.0" encoding="UTF-8"?> <module xmlns="urn:jboss:module:1.0" name="com.something"> <resources> <resource-root path="something.jar" /> </resources> <dependencies> <module name="javax.api"/> <module name="javax.resource.api"/> <module name="org.jboss.teiid.common-core"/> <module name="org.jboss.teiid.teiid-api" /> </dependencies> </module>
- Copy the jar file under this same directory. Make sure you add any additional dependencies if required by your implementation class under dependencies.
- Restart the server.
Example 10.4. Sample vdb.xml file
<vdb name="{vdb-name}" version="1"> <model name="{model-name}" type="PHYSICAL"> <source name="AccountsDB" translator-name="oracle" connection-jndi-name="java:/oracleDS"/> <metadata type="{metadata-repo-module}"></metadata> </model> </vdb>
Important
10.6. Using Multiple Importers
<vdb name="{vdb-name}" version="1"> <model name="{model-name}" type="PHYSICAL"> <source name="AccountsDB" translator-name="oracle" connection-jndi-name="java:/oracleDS"/> <metadata type="NATIVE,DDL"> **DDL Here** </metadata> </model> </vdb>
10.7. Development Considerations
MetadataRepository
instances are created on a per VDB basis and may be called concurrently for the load of multiple models.
- See the
MetadataFactory
and theorg.teiid.metadata
package javadocs for metadata construction methods and objects. For example if you use your own DDL, then call theMetadataFactory.parse(Reader)
method. If you need access to files in a VDB zip deployment, then use theMetadataFactory.getVDBResources
method.
- Use the
MetadataFactory.addPermission
and addMetadataFactory.addColumnPermission
method to grant permissions on the given metadata objects to the named roles. The roles should be declared in your vdb.xml, which is also where they are typically tied to container roles.
10.8. Preparser
import org.teiid.PreParser; ... package com.something; public class CustomPreParser implements PreParser { @Override public String preParse(String command, CommandContext context) { //manipulate the command } }
com.something.CustomPreParser
<?xml version="1.0" encoding="UTF-8"?> <module xmlns="urn:jboss:module:1.0" name="com.something"> <resources> <resource-root path="something.jar" /> </resources> <dependencies> <module name="javax.api"/> <module name="javax.resource.api"/> <module name="org.jboss.teiid.common-core"/> <module name="org.jboss.teiid.teiid-api" /> </dependencies> </module>
Important
Chapter 11. Runtime Updates
11.1. Data Updates
org.teiid.events.EventDistributorFactory
and org.teiid.events.EventDistributor
can be used to distribute change events. The EventDistributorFactory
can be looked up by its name "teiid/event-distributor-factory". See the example below.
InitialContext ctx = new InitialContext(); EventDistributorFactory edf = (EventDistributorFactory)ctx.lookup("teiid/event-distributor-factory"); EventDistributor ed = edf.getEventDistributor(); ed.dataModification(vdbName, vdbVersion, schema, tableName);
EventDistributor
methods to manually distribute other events is not always necessary. See System Procedures in Red Hat JBoss Development Guide: Reference Material for SQL based updates.
Note
org.teiid.events.EventDistributor
interface you can also update runtime metadata. Refer to the API.
11.2. Runtime Metadata Updates
org.teiid.metadata.MetadataRepository
.
MetadataRepository
can be installed via the VDB file.
<vdb name="{vdb-name}" version="1"> <model name="{model-name}" type="VIRTUAL"> <metadata type="{jboss-as-module-name}"></metadata> </model> </vdb>
org.teiid.metadata.MetadataRepository
interface and defines file "META-INF/services/org.teiid.metadata.MetadataRepository" with name of the implementation file.
MetadataRepository
repository instance may fully implement as many of the methods as needed and return null from any unneeded getter.
Note
org.teiid.metadata.AbstractMetadataRecord
instances. System procedures and DDL statements should be used instead since the effects will be distributed through the cluster and will not introduce inconsistencies.
org.teiid.metadata.AbstractMetadataRecord
objects passed to the MetadataRepository
have not yet been modified. If the MetadataRepository
cannot persist the update, then a RuntimeException
should be thrown to prevent the update from being applied by the runtime engine.
Note
11.3. Costing Updates
SYSADMIN.setColumnStats
and SYSADMIN.setTableStats
. To make costing updates persistent MetadataRepository
implementations should be provided for the following methods:
TableStats getTableStats(String vdbName, int vdbVersion, Table table); void setTableStats(String vdbName, int vdbVersion, Table table, TableStats tableStats); ColumnStats getColumnStats(String vdbName, int vdbVersion, Column column); void setColumnStats(String vdbName, int vdbVersion, Column column, ColumnStats columnStats);
11.4. Schema Updates
String getViewDefinition(String vdbName, int vdbVersion, Table table); void setViewDefinition(String vdbName, int vdbVersion, Table table, String viewDefinition); String getInsteadOfTriggerDefinition(String vdbName, int vdbVersion, Table table, Table.TriggerEvent triggerOperation); void setInsteadOfTriggerDefinition(String vdbName, int vdbVersion, Table table, Table.TriggerEvent triggerOperation, String triggerDefinition); boolean isInsteadOfTriggerEnabled(String vdbName, int vdbVersion, Table table, Table.TriggerEvent triggerOperation); void setInsteadOfTriggerEnabled(String vdbName, int vdbVersion, Table table, Table.TriggerEvent triggerOperation, boolean enabled); String getProcedureDefinition(String vdbName, int vdbVersion, Procedure procedure); void setProcedureDefinition(String vdbName, int vdbVersion, Procedure procedure, String procedureDefinition); LinkedHashMap<String, String> getProperties(String vdbName, int vdbVersion, AbstractMetadataRecord record); void setProperty(String vdbName, int vdbVersion, AbstractMetadataRecord record, String name, String value);
Appendix A. Appendix
A.1. Template for ra.xml
<?xml version="1.0" encoding="UTF-8"?> <connector xmlns="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/connector_1_5.xsd" version="1.5"> <vendor-name>${comapany-name}</vendor-name> <eis-type>${type-of-connector}</eis-type> <resourceadapter-version>1.0</resourceadapter-version> <license> <description>${license text}</description> <license-required>true</license-required> </license> <resourceadapter> <resourceadapter-class>org.teiid.resource.spi.BasicResourceAdapter</resourceadapter-class> <outbound-resourceadapter> <connection-definition> <managedconnectionfactory-class>${connection-factory}</managedconnectionfactory-class> <!-- repeat for every configuration property --> <config-property> <description> {$display:"${short-name}",$description:"${description}",$allowed:[${value-list}], $required:"${required-boolean}", $defaultValue:"${default-value}"} </description> <config-property-name>${property-name}</config-property-name> <config-property-type>${property-type}</config-property-type> <config-property-value>${optional-property-value}</config-property-value> </config-property> <!-- use the below as is if you used the Connection Factory interface --> <connectionfactory-interface> javax.resource.cci.ConnectionFactory </connectionfactory-interface> <connectionfactory-impl-class> org.teiid.resource.spi.WrappedConnectionFactory </connectionfactory-impl-class> <connection-interface> javax.resource.cci.Connection </connection-interface> <connection-impl-class> org.teiid.resource.spi.WrappedConnection </connection-impl-class> </connection-definition> <transaction-support>NoTransaction</transaction-support> <authentication-mechanism> <authentication-mechanism-type>BasicPassword</authentication-mechanism-type> <credential-interface> javax.resource.spi.security.PasswordCredential </credential-interface> </authentication-mechanism> <reauthentication-support>false</reauthentication-support> </outbound-resourceadapter> </resourceadapter> </connector>
A.2. Download API Documentation
Procedure A.1. Download API Documentation
- Open a web browser and navigate to https://access.redhat.com/jbossnetwork.
- From the Software Downloads page, when prompted for a Product, select Data Virtualization. This will present a table of files to download for the latest version of the product.
- Change the Version to the current release if required.
- Look for Red Hat JBoss Data Virtualization VERSION Javadocs in the table and select Download.
A.3. Red Hat JBoss Data Virtualization Functions and Order of Precedence
- System functions (effectively scoped to SYS) and are known at design time.
- Pushdown functions (also effectively scoped to SYS) and are supplied by translators.
- UDFs which are schema scoped (except for legacy function models) and are defined via metadata.
Note
Appendix B. Revision History
Revision History | |||
---|---|---|---|
Revision 6.4.0-11 | Wed Jul 5 2017 | David Le Sage | |
|