<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.teiid</groupId>
<artifactId>teiid-parent</artifactId>
<version>${version.teiid}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
Embedded Guide
Embedded is a light-weight version of Teiid for use in any Java 8+ JRE. WildFly nor any application server is not required. This feature/kit are still evolving. Please consult the source examples and even unit tests utilizing the EmbeddedServer for a more complete guide as to its use.
Configuration
The primary way to configure Teiid Embedded is with the EmbeddedConfiguration
class. It is provided to the EmbeddedServer
at start-up and dictates much of the behavior of the embedded instance. From there the running server instance may have translators and VDBs deployed as needed. Additional modifications to the EmbeddedConfiguration
after the server is started will not have an effect.
In many cases an EmbeddedConfiguration
instance can just be instantiated and passed to the EmbeddedServer
without the need to set additional properties. Many properties, including those used to configure the BufferManager, will be given a similar name to their server side counter part - for example setProcessorBatchSize.
Important
|
Most of the default configuration values for memory and threads assume that there is only one Teiid instance in the vm. If you are using multiple Teiid Embedded instances in the same vm, then memory and thread resources should be configured manually. |
The Classpath
Embedded Using Maven
Your application is responsible for having the appropriate classpath to utilize Teiid embedded. Typically you will want all transitive dependencies from referenced Teiid artifacts to be included. Optional dependencies, such as Hibernate core, will be needed for specific features - such as utilizing the JDBC translator support for dependent joins using temp tables.
Note
|
With Teiid 10+ the maven coordinate group for most Teiid artifacts changed from org.jboss.teiid to just org.teiid. Please update your pom files accordingly. |
Some of the Teiid transitive dependencies have known vulnerabilities. WildFly/Teiid addresses this by introducing managed dependency overrides. It is recommended that you include these overrides in your usage of Teiid Embedded by importing the Teiid parent pom in your dependency management section:
Dependencies
If you are trying run Teiid Embedded as a Maven based project, the runtime
, admin
, connector
, translator
dependencies necessary are
<dependency>
<groupId>org.teiid</groupId>
<artifactId>teiid-runtime</artifactId>
</dependency>
<dependency>
<groupId>org.teiid</groupId>
<artifactId>teiid-admin</artifactId>
</dependency>
<dependency>
<groupId>org.teiid.connectors</groupId>
<artifactId>translator-SOURCE</artifactId>
</dependency>
<dependency>
<groupId>org.teiid.wildfly.connectors</groupId>
<artifactId>connector-SOURCE</artifactId>
</dependency>
You would include all translator/connectors needed by your project.
Optional Libraries
If you include a dependency to org.teiid:teiid-data-quality, the osdq data quality functions will be available for use with Embedded.
If you include a dependency to org.teiid:cache-infinispan, Infinispan will be used for caching.
If you do not need XML type support including XPath and SQL/XML functions like XMLTABLE, then you may also choose to exclude saxon, xom, and nux from usage by the runtime by using excludes:
<dependency>
<groupId>org.teiid</groupId>
<artifactId>teiid-runtime</artifactId>
<exclusions>
<exclusion>
<groupId>org.teiid</groupId>
<artifactId>teiid-optional-xml</artifactId>
</exclusion>
</exclusions>
</dependency>
Some geospatial support requires additional dependencies. If you need no or minimal support (no geojson nor projection), then you may also choose to exclude this from the runtime by using excludes:
<dependency>
<groupId>org.teiid</groupId>
<artifactId>teiid-runtime</artifactId>
<exclusions>
<exclusion>
<groupId>org.teiid</groupId>
<artifactId>teiid-optional-geo</artifactId>
</exclusion>
</exclusions>
</dependency>
Some json support requires additional dependencies. If you need no or minimal support (no jsonpath support), then you may also choose to exclude this from the runtime by using excludes:
<dependency>
<groupId>org.teiid</groupId>
<artifactId>teiid-runtime</artifactId>
<exclusions>
<exclusion>
<groupId>org.teiid</groupId>
<artifactId>teiid-optional-json</artifactId>
</exclusion>
</exclusions>
</dependency>
VDB Deployment
VDBs may be deployed in several ways in Embedded.
VDB Metadata API
VDB deployment can be done directly through VDB metadata objects that are the underpinning of vdb.xml deployment. Models (schemas) are deployed as a set to form a named vdb - see the EmbeddedServer.deployVDB
method.
XML Deployment
Similar to a server based -vdb.xml deployment an InputStream
may be given to a vdb.xml file - see the EmbeddedServer.deployVDB(InputStream)
method.
Zip Deployment
Similar to a server based .vdb deployment a URL
may be given to a zip file - see the EmbeddedServer.deployVDBZip
method. The use of the zip lib for dependency loading is not enabled in Embedded.
See VDB Guide and Metadata Repositories for more on a typical vdb file and zip structures.
Support Teiid Designer 7 and later VDBs is deprecated and are subject to all of the limitations/differences highlighted in this guide. To use a Teiid Designer VDB requires including the teiid-metadata dependency:
<dependency> <groupId>org.teiid</groupId> <artifactId>teiid-metadata</artifactId> </dependency>
Translators
Translators instances can be scoped to a VDB in AS using declarations in a vdb.xml file, however named instances in embedded are scoped to the entire EmbeddedServer
and must be registered via the EmbeddedServer.addTranslator
methods. Note that there are three addTranslator
methods:
-
addTranslator(Class<? extends ExecutionFactory> clazz)
- Adds a default instance of the ExecutionFactory, using the default name either from the Translator annotation or the class name. -
addTranslator(String name, ExecutionFactory<?, ?> ef)
- Adds a pre-initialized (ExecutionFactory.start() must have already been called) instance of the ExecutionFactory, using the given translator name. The instance will be shared for all usage. -
addTranslator(String name, String type, Map<String, String> properties)
- Adds a definition of an override translator - this is functionally equivalent to using a vdb.xml translator override.
A new server instance does not assume any translators are deployed and does not perform any sort of library scanning to find translators.
Sources
The Embedded Server will still attempt to lookup the given JNDI connection factory names via JNDI. In most non-container environments it is likely that no such bindings exist. In this case the Embedded Server instance must have ConnectionFactoryProvider
instances manually registered, either using the EmbeddedServer.addConnectionFactory
method, or the EmbeddedServer.addConnectionFactoryProvider
method to implement ConnectionFactoryProvider
registering. Note that the Embedded Server does not have built-in pooling logic, so to make better use of a standard java.sql.DataSource
or to enable proper use of javax.sql.XADataSource
you must first configure the instance via a third-party connection pool.
EmbeddedServer es = new EmbeddedServer();
EmbeddedConfiguration ec = new EmbeddedConfiguration();
//set any configuration properties
ec.setUseDisk(false);
es.start(ec);
//example of adding a translator by pre-initialized ExecutionFactory and given translator name
H2ExecutionFactory ef = new H2ExecutionFactory()
ef.setSupportsDirectQueryProcedure(true);
ef.start();
es.addTranslator("translator-h2", ef);
//add a Connection Factory with a third-party connection pool
DataSource ds = EmbeddedHelper.newDataSource("org.h2.Driver", "jdbc:h2:mem://localhost/~/account", "sa", "sa");
es.addConnectionFactory("java:/accounts-ds", ds);
//add a vdb
//physical model
ModelMetaData mmd = new ModelMetaData();
mmd.setName("my-schema");
mmd.addSourceMapping("my-schema", "translator-h2", "java:/accounts-ds");
//virtual model
ModelMetaData mmd1 = new ModelMetaData();
mmd1.setName("virt");
mmd1.setModelType(Type.VIRTUAL);
mmd1.setSchemaSourceType("ddl");
mmd1.setSchemaText("create view \"my-view\" OPTIONS (UPDATABLE 'true') as select * from \"my-table\"");
es.deployVDB("test", mmd, mmd1);
Secured Data Sources
If Source related security authentication, for example, if you want connect/federate/integrate Twitter supplied rest source, a security authentication is a necessary, the following steps can use to execute security authentication:
-
refer to Secure Embedded with PicketBox start section to develop a SubjectFactory,
-
initialize a ConnectionManager with ironjacamar libaries, set SubjectFactory to ConnectionManager
-
use the following method to create ConnectionFactory
WSManagedConnectionFactory mcf = new WSManagedConnectionFactory();
NoTxConnectionManagerImpl cm = new NoTxConnectionManagerImpl();
cm.setSecurityDomain(securityDomain);
cm.setSubjectFactory(new EmbeddedSecuritySubjectFactory(authConf))
Object connectionFactory = mcf.createConnectionFactory(cm);
server.addConnectionFactory("java:/twitterDS", connectionFactory);
twitter-as-a-datasource is a completed example.
Access from client applications
Typically when Teiid is deployed as Embedded Server, and if your end user application is also deployed in the same virtual machine as the Teiid Embedded, you can use Local JDBC Connection, to access to your virtual database. For example:
EmbeddedServer es = ...
Driver driver = es.getDriver();
Connection conn = driver.connect("jdbc:teiid:<vdb-name>", null);
// do work with conn; create statement and execute it
conn.close();
This is the most efficient method as it does not impose any serialization of objects.
If your client application is deployed in remote VM, or your client application is not a JAVA based application then accesses to the Teiid Embedded is not possible through above mechanism. In those situations, you need to open a socket based connection from remote client application to the Embedded Teiid Server. By default, when you start the Embedded Teiid Sever it does not add any capabilities to accept remote JDBC/ODBC based connections. If you would like to expose the functionality to accept remote JDBC/ODBC connection requests, then configure necessary transports during the initialization of the Teiid Embedded Server. The example below shows a sample code to enable a ODBC transport
EmbeddedServer es = new EmbeddedServer()
SocketConfiguration s = new SocketConfiguration();
s.setBindAddress("<host-name>");
s.setPortNumber(35432);
s.setProtocol(WireProtocol.pg);
EmbeddedConfiguration config = new EmbeddedConfiguration();
config.addTransport(s);
es.start(config);
EmbeddedServer server = new EmbeddedServer();
...
EmbeddedConfiguration config = new EmbeddedConfiguration();
SocketConfiguration socketConfiguration = new SocketConfiguration();
SSLConfiguration sslConfiguration = new SSLConfiguration();
//Settings shown with their default values
//sslConfiguration.setMode(SSLConfiguration.ENABLED);
//sslConfiguration.setAuthenticationMode(SSLConfiguration.ONEWAY);
//sslConfiguration.setSslProtocol(SocketUtil.DEFAULT_PROTOCOL);
//sslConfiguration.setKeymanagementAlgorithm(KeyManagerFactory.getDefaultAlgorithm());
//optionally restrict the cipher suites
//sslConfiguration.setEnabledCipherSuites("SSL_RSA_WITH_RC4_128_MD5,SSL_RSA_WITH_RC4_128_SHA");
//for the server key
sslConfiguration.setKeystoreFilename("ssl-example.keystore");
sslConfiguration.setKeystorePassword("redhat");
sslConfiguration.setKeystoreType("JKS");
sslConfiguration.setKeystoreKeyAlias("teiid");
sslConfiguration.setKeystoreKeyPassword("redhat");
//for two way ssl set a truststore for client certs
//sslConfiguration.setTruststoreFilename("ssl-example.truststore");
//sslConfiguration.setTruststorePassword("redhat");
socketConfiguration.setSSLConfiguration(sslConfiguration);
config.addTransport(socketConfiguration);
server.start(config);
if you want to add a JDBC transport, follow the instructions above, however set the protocol to WireProtocol.teiid
and choose a different port number. Once the above server is running, you can use same instructions as Teiid Server to access Embedded Teiid Server from remote client application. Note that you can add multiple transports to single Embedded Server instance, to expose different transports.
Security
The primary interface for Teiid embedded’s security is the org.teiid.security.SecurityHelper
in the engine jar. The SecurityHelper instance is associated with with the EmbeddedServer via EmbeddedConfiguration.setSecurityHelper
. If no SecurityHelper is set, then no authentication will be performed. A SecurityHelper controls authentication and associates a security context with a thread. How a security context is obtained can depend upon the security domain name. The default security domain name is teiid-security
and can be changed via EmbeddedConfiguration.setSecurityDomain
. The effective security domain may also be configured via a transport of the VDB.
See the JBoss Security Helper source for an example of expected mechanics.
You can just return null from negotiateGssLogin unless you want to all GSS authentications from JDBC/ODBC.
Example
embedded-portfolio-security demonstrates how to implement security authentication in Teiid Embedded:
-
EmbeddedSecurityHelper is the implementation of
org.teiid.security.SecurityHelper
-
users.properties and roles.properties in class path user to pre define users and roles
-
application-policy’s name in authentication.conf should match to security domain(
EmbeddedConfiguration.setSecurityDomain
)
Transactions
Transaction processing requires setting the TransactionManager
in the EmbeddedConfiguration
used to start the EmbeddedServer
. A client facing javax.sql.DataSource
is not provided for embedded. However the usage of provided java.sql.Driver
should be sufficient as the embedded server is by default able to detect thread bound transactions and appropriately propagate the transaction to threads launched as part of request processing. The usage of local connections is also permitted.
AdminApi
Embedded provides a the Admin
interface via the EmbeddedServer.getAdmin
method. Not all methods are implemented for embedded - for example those that deal with data sources. Also the deploy method may only deploy VDB xml artifacts.
Logging
Teiid by default use JBoss Logging, which will utilize JUL (Java Util Logging) or other common logging frameworks depending upon their presence in the classpath. Refer to Logging in Teiid Embedded for details.
The internal interface for Teiid embedded’s logging is org.teiid.logging.Logger
in teiid-api jar. The Logger instance is associated with the org.teiid.logging.LogManager
via static method LogManager.setLogListener()
. You may alternatively choose to directly set a Logger
of your choice.
Other Differences Between Teiid Embedded and an AS Deployment
-
There is no default JDBC/ODBC socket transport in embedded. You are expected to obtain a
Driver
connection via theEmbeddedServer.getDriver
method. If you want remote JDBC/ODBC transport see above on how to add a transport. -
A
MetadataRepository
is scoped to a VDB in AS, but is scoped to the entireEmbeddedServer
instance and must be registered via theEmbeddedServer.addMetadataRepository
method. -
MDC logging values are not available as Java logging lacks the concept of a mapped diagnostic context.
-
Translator overrides in vdb.xml files is not supported, but you may add overridden translators using the addTranslator methods that accept an ExecutionFactory instance or a property set.
-
The default for the maximum disk space used by the buffer manager is 5 GB, rather than 50 GB.
-
VDB imports are processed only at deployment time. A missing vdb import results in a failed deployment. If the imported vdb is redployed after the importing vdb is deployed, the importing vdb is not redeployed.