Fabric3 provides support for accessing data sources in a portable way accross different host environments. This is particularly useful as an application moves through the development lifecycle from integration testing to production. Specific data sources can be configured for integration testing using the Fabric3 Maven runtime that work against a transient database, such as H2 . When an application is placed in production, those data sources can be reconfigured to use a live database without having to change application code. This is done using @Resource injection.
Accessing a Data Source
Data sources may be accessed directly from application code using resource injection. Resource injection follows SCA injection rules except instead of setting a property or reference, a container-supplied resource is provided. Properties declare the set of configuration elements for a component. References declare the dependencies a component implmentation has on other services. Resources declare the dependencies a component implementation has on its hosting container.
Accessing a resource is done using the Fabric3 or JSR-250 @Resource annotations:
public class MyComponent implements Component { // ... public MyComponent(@Resource(name="myDatasource", mappedName="mainDB", optional=false) DataSource dataSource) { //... } }
The above code uses @Resource to inject the data source as a constructor parameter when a component instance is created. The name attribute is used to specify the resource name for the component (similar to a reference or property name). The mappedName is used to specify the name of the resource as it is provided by the host runtime environment. The optional attribute is itself optional and used to declare whether the resource must be provided by the host runtime.
The definition of the @Resource annotation is provided below:
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface Resource {
/**
* Denotes the name of the resource declared by the implementation.
*/
String name() default "";
/**
* Denotes if the resource is optional
*/
boolean optional() default false;
/**
* Denotes the default name of the resource provided by the runtime environment.
*/
String mappedName() default "";
}
Configuring a Data Source
Datasource configuration will vary by host environment. Below are instructions on how to configure data sources on various runtimes.
Data sources in managed JEE environments
TODO Write up
Data sources in the Maven runtime
There are several options for configuring data sources in the Maven runtime. The simplest is to use the Fabric3 H2 database extension. This extension allows an in-memory (or durable) database with data sources to be configured for integration testing. To use this option, the Maven runtime must be configured with the database extension, similar to the following:
<plugin> <groupId>org.codehaus.fabric3</groupId> <artifactId>fabric3-itest-plugin</artifactId> <version>0.5ALPHA3-SNAPSHOT</version> <configuration> <runtimeVersion>0.5ALPHA3-SNAPSHOT</runtimeVersion> <extensions> <dependency> <groupId>org.codehaus.fabric3</groupId> <artifactId>fabric3-db-h2</artifactId> <version>(extension version)</version> </dependency> <!-- .... ---> </extensions> </configuration>
The above configuration adds the extension to the runtime. The next step is to configure the data source, which is done via a user extension. A user extension is an SCA composite that configures one or more components. Since Fabric3 itself is built using SCA - that is, it is an assembly of SCA components - the runtime can be extended by simply adding components. A data source is added to the runtime by creating a data source component and contributing it as a user extension. Typically in SCA, components are added using a composite file that is packaged in a JAR known as a "contribution". Having to to create an archive to configure a data source is tedious, so Fabric3 also supports contributions that are just XML documents. The data source contribution from the BigBank tutorial is listed below as an example:
<?xml version="1.0" encoding="UTF-8"?> <f3:xmlContribution xmlns:f3="http://fabric3.org/xmlns/sca/2.0-alpha" xmlns="http://www.osoa.org/xmlns/sca/1.0" xmlns:maven="http://fabric3.org/xmlns/sca/2.0-alpha/maven"> <contribution> <maven:import artifactId="fabric3-db-h2" groupId="org.codehaus.fabric3"/> </contribution> <composite xmlns:sample="org.codehaus.fabric3" name="DatabaseConfiguration" targetNamespace="org.codehaus.fabric3"> <component name="xaPoolDataSource"> <implementation.composite name="sample:H2DataSource"/> <property name="url">jdbc:h2:mem:loanapplication;DB_CLOSE_DELAY=-1</property> <property name="dataSourceKeys">LoanApplicationDS</property> </component> </composite> </f3:xmlContribution>
The datasource contribution can be added to the Maven runtime by configuring the Maven Fabric3 plugin with <userExtensionsArchives> elements:
<plugin> <groupId>org.codehaus.fabric3</groupId> <artifactId>fabric3-itest-plugin</artifactId> <version>0.5ALPHA3-SNAPSHOT</version> <configuration> <runtimeVersion>0.5ALPHA3-SNAPSHOT</runtimeVersion> <extensions> <dependency> <groupId>org.codehaus.fabric3</groupId> <artifactId>fabric3-db-h2</artifactId> <version>(extension version)</version> </dependency> </extensions> </userExtensionArchives> <userExtensionArchive>mydatasource.xml</userExtensionArchive> </userExtensionArchives> </configuration>
The <userExtensionArchive> element takes an absolute or relative path to the XML contribution file. For a full example, consult the BigBank tutorial.
Data sources in the Standalone runtime
Data source contributions can be created as XML files as described above. To configure the standalone runtime to use them, simply place the XML contribution in the /user directory (the place where user extensions are installed) and boot the runtime.
The H2 database extension may also be used in the standalone runtime. To do so, simply place it in the /user directory. Alternatively, you may want to use custom JDBC drivers for connecting to a separate production database such as Oracle, DB2, Postgress, or MySQL. See below for how to do this.
Data sources in the WebApp runtime
Using the Contribution Plugin to create data source extensions
TODO complete
Connecting to production databases
TODO complete
