CDI Extension

MicroStream comes with a CDI extension which allows accessing the functionality of MicroStream through the usage of a few annotations.

It is available within this artifact:

pom.xml
<dependencies>
   <dependency>
      <groupId>one.microstream</groupId>
      <artifactId>microstream-integrations-cdi</artifactId>
      <version>08.01.02-MS-GA</version>
   </dependency>
</dependencies>

The integration requires the javax namespace and requires a CDI 2.0 implementation and an Eclipse MicroProfile Config 2.0 implementation.

When you like to use in a Jakarta EE 9+ runtie, you can make use of the following artifact

pom.xml
<dependencies>
   <dependency>
      <groupId>one.microstream</groupId>
      <artifactId>microstream-integrations-cdi3</artifactId>
      <version>08.01.02-MS-GA</version>
   </dependency>
</dependencies>

This version requires the jakarta namespace and requires a CDI 3.0 implementation or higher and an Eclipse MicroProfile Config 3.0 implementation or higher.

This CDI extension makes use of the Extension interface and the BeanManager functionality, so it might not work in a strict Jakarta EE 10 Core Profile product that only supports the CDI Lite functionality.

Configuration

The configuration of the StorageManager can be done using key/value pairs that are provided by MicroProfile Config. The configuration keys must be prefixed by one.microstream

one.microstream.storage-directory=/opt/data/microstream
one.microstream.channel-count=2

Since the - character is not supported in some sources (like the environment variables), you can also define the configuration keys using the . character.

one.microstream.storage.directory=/opt/data/microstream
one.microstream.channel.count=2

Besides that, the regular MicroProfile Config rules about keys are applied (since we are using MicroProfile Config directly, see specification).

The configured and started StorageManager is a CDI bean and thus can be injected or retrieved programmatically.

@Inject
private StorageManager storageManager;

public void someMethod() {
    StorageManager storageManager = CDI.current().select(StorageManager.class).get();
}

The StorageManager configuration can be customized by CDI beans that implement the interface one.microstream.integrations.cdi.types.config.EmbeddedStorageFoundationCustomizer. The customize method is called with an EmbeddedStorageFoundation which allows you to fully customize the StorageManager that will be created. You can for example, add the specific Type Handlers for JDK 8 as described on the documentation.

After the StorageManager is created, the CDI beans that implement one.microstream.integrations.cdi.types.config.StorageManagerInitializer are called. You have the opportunity to perform actions on the StorageManager or root object. Following rules apply to the StorageManager that is passed to the initialize method of the interface.

  • The StorageManager is already started unless you specified the configuration value one.microstream.autoStart=false.

  • If you have used the @Storage annotation on a class, the StorageManager is already associated with an instance of that class as the Root object.

There is a second option to configure and retrieve the StorageManager, and it makes use of the MicroStream functionality to read the configuration from any file.

@Inject
@ConfigProperty(name = "one.microstream.ini")
private StorageManager storageManager;

The above construct makes use of the MicroProfile Config functionality that you convert the value of the key one.microstream.ini and convert it into a StorageManager. The value of the key is expected to point to an existing file. The formats XML, INI, and properties are supported.

The StorageManager is also fully configured and started just as you would use it when using the first option of configuration.

If you define it multiple times, within different beans for example, you always receive the same instance of the StorageManager when you specify the same value for the name member of the @ConfigProperty annotation.

This way, you can define and use multiple _StorageManager_s within your application.

The customizer and initializer features described earlier as CDI beans implementing a specific interface,are also available when you use the MicroProfile Config annotation (@ConfigProperty). Since you can define multiple StorageManager_s this way, you can distinguish between them based on the _database name.

The database name can be set by using the following property within the configuration file (example makes use of the properties format, but it is also supported in the other formats)

database-name=theName

If this property is not specified, the value of the MicroProfile config key (used within the name member of @ConfigProperty) is used.

Within the customizer and initializer you can use this to perform the required actions based on the instance you receive.

EmbeddedStorageFoundation.getDataBaseName();

StorageManager.databaseName();

Root object

The root object can be indicated by using the @Storage annotation on the class. This annotation converts the POJO into a CDI bean (there is no need to use any scope-defining annotation) with Application Scope.

This is only supported when you inject the StorageManager without making use of the MicroProfile Config @ConfigProperty annotation.

Besides converting it into a CDI bean, any field injection within this class is also resolved.

The integration also defines the instance of the class that is created as the root object (StorageManager.setRoot()) and stores the initial value (StorageManager.storeRoot()) when storageManager does not have a root object assigned yet (this happens only the very first time when you start up your application and the storage doesn’t contain any data yet)

The POJO must have a (default) no-argument constructor so that the integration can create an instance of it.

You can only annotate 1 class with the @Storage annotation, if you have marked multiple, the deployment of your application will fail at the CDI validation phase.