///////////////////////////////////////////////////////////////////////////////

    Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved.

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

        http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.

///////////////////////////////////////////////////////////////////////////////

= CDI extension for Jedis
:description: Helidon CDI extension for Jedis
:keywords: helidon, java, microservices, microprofile, extensions, cdi, jedis, redis
:cdi-extension-api-url: https://docs.jboss.org/cdi/spec/2.0/cdi-spec.html#spi
:cdi-applicationscoped-api-url: http://docs.jboss.org/cdi/api/2.0/javax/enterprise/context/ApplicationScoped.html
:jedis-jedispool-api-url: https://static.javadoc.io/redis.clients/jedis/2.9.0/redis/clients/jedis/JedisPool.html
:jedis-jedispool-constructor-api-url: https://static.javadoc.io/redis.clients/jedis/2.9.0/redis/clients/jedis/JedisPool.html#JedisPool-org.apache.commons.pool2.impl.GenericObjectPoolConfig-java.lang.String-int-int-java.lang.String-int-boolean-javax.net.ssl.SSLSocketFactory-javax.net.ssl.SSLParameters-javax.net.ssl.HostnameVerifier-
:jedis-jedispoolconfig-api-url: https://static.javadoc.io/redis.clients/jedis/2.9.0/redis/clients/jedis/JedisPoolConfig.html
:jedis-pool-api-url: https://static.javadoc.io/redis.clients/jedis/2.9.0/redis/clients/util/Pool.html
:jedis-project-url: https://github.com/xetorthio/jedis
:commons-pool-baseobjectpoolconfig-api-url: https://commons.apache.org/proper/commons-pool/apidocs/org/apache/commons/pool2/impl/BaseObjectPoolConfig.html
:commons-pool-genericobjectpoolconfig-api-url: https://commons.apache.org/proper/commons-pool/apidocs/org/apache/commons/pool2/impl/GenericObjectPoolConfig.html

This link:{cdi-extension-api-url}[CDI portable extension] provides support for
 injecting link:{jedis-project-url}[Jedis clients] in your Helidon
 MicroProfile applications.

== Prerequisites

Declare the following dependency in your project:

[source,xml]
----
<dependency>
    <groupId>io.helidon.integrations.cdi</groupId>
    <artifactId>helidon-integrations-cdi-jedis</artifactId>
</dependency>
----

== Injecting a Jedis client

The following examples show how to create and inject a Jedis pool named `orders`
 in your application code.

[source,java]
.Field-injection example
----
 @Inject
 @Named("orders")
 private JedisPool ordersPool;
----

[source,java]
.Constructor-injection example
----
 private final JedisPool ordersPool;
 @Inject
 public YourConstructor(@Named("orders") JedisPool pool) {
   super();
   this.ordersPool = pool;
 }
----

The extension implements this injection point by creating a
 link:{jedis-jedispool-api-url}[JedisPool] object in the
 link:{cdi-applicationscoped-api-url}[application scope].

You can configure the object using
 <<microprofile/02_server-configuration.adoc, MicroProfile config>>. For example,
 the Jedis pool created above can be configured as follows:

[source, properties]
.META-INF/microprofile-config.properties
----
redis.clients.jedis.JedisPool.orders.port=6379
----

Property names that start with
`redis.clients.jedis.JedisPoolConfig.instanceName.` are parsed, and
the remaining portion of each name is treated as a Java Bean property
of link:{jedis-jedispoolconfig-api-url}[`JedisPoolConfig`].  Because
the `JedisPoolConfig` class inherits from
link:{commons-pool-genericobjectpoolconfig-api-url}[Apache
commons-pool's `GenericObjectPoolConfig`] class and from
link:{commons-pool-baseobjectpoolconfig-api-url}[Apache commons-pool's
`BaseObjectPoolConfig`] class, those writable Java Bean properties are
available as well.

Accordingly, the `JedisPoolConfig` Java Bean properties that can be
set are as follows, where `instanceName` should be replaced with the
actual name used in application code:

[role="flex, md7"]
|===
| `redis.clients.jedis.JedisPoolConfig.instanceName.blockWhenExhausted`
| `redis.clients.jedis.JedisPoolConfig.instanceName.evictionPolicyClassName`
| `redis.clients.jedis.JedisPoolConfig.instanceName.fairness`
| `redis.clients.jedis.JedisPoolConfig.instanceName.jmxEnabled`
| `redis.clients.jedis.JedisPoolConfig.instanceName.jmxNameBase`
| `redis.clients.jedis.JedisPoolConfig.instanceName.jmxNamePrefix`
| `redis.clients.jedis.JedisPoolConfig.instanceName.lifo`
| `redis.clients.jedis.JedisPoolConfig.instanceName.maxIdle`
| `redis.clients.jedis.JedisPoolConfig.instanceName.maxTotal`
| `redis.clients.jedis.JedisPoolConfig.instanceName.maxWaitMillis`
| `redis.clients.jedis.JedisPoolConfig.instanceName.minEvictableTimeMillis`
| `redis.clients.jedis.JedisPoolConfig.instanceName.minIdle`
| `redis.clients.jedis.JedisPoolConfig.instanceName.numTestsPerEvictionRun`
| `redis.clients.jedis.JedisPoolConfig.instanceName.softMinEvictableIdleTimeMillis`
| `redis.clients.jedis.JedisPoolConfig.instanceName.testOnBorrow`
| `redis.clients.jedis.JedisPoolConfig.instanceName.testOnCreate`
| `redis.clients.jedis.JedisPoolConfig.instanceName.testOnReturn`
| `redis.clients.jedis.JedisPoolConfig.instanceName.testWhileIdle`
| `redis.clients.jedis.JedisPoolConfig.instanceName.timeBetweenEvictionRunsMillis`
|===

Any documentation for these properties that exists may be found in the
javadocs for the
link:{jedis-jedispoolconfig-api-url}[`JedisPoolConfig`],
link:{commons-pool-genericobjectpoolconfig-api-url}[`GenericObjectPoolConfig`]
and
link:{commons-pool-baseobjectpoolconfig-api-url}[`BaseObjectPoolConfig`]
classes.

Property names that start with
 `redis.clients.jedis.JedisPool.instanceName.` are parsed, and the
 remaining portion of each name is treated as a Java Bean property of
 link:{jedis-jedispool-api-url}[`JedisPool`], or as a primitive value
 accepted by link:{jedis-jedispool-constructor-api-url}[its
 constructor].  Because the `JedisPool` class inherits from the
 link:{jedis-pool-api-url}[`Pool`] class, its writable Java Bean
 properties are available as well.

Accordingly, the `JedisPool` properties that can be set are as
follows, where `instanceName` should be replaced with the actual named
used in application code:

[role="flex, md7"]
|===
| `redis.clients.jedis.JedisPool.instanceName.clientName`
| `redis.clients.jedis.JedisPool.instanceName.connectionTimeout`
| `redis.clients.jedis.JedisPool.instanceName.database`
| `redis.clients.jedis.JedisPool.instanceName.host`
| `redis.clients.jedis.JedisPool.instanceName.password`
| `redis.clients.jedis.JedisPool.instanceName.port`
| `redis.clients.jedis.JedisPool.instanceName.socketTimeout`
| `redis.clients.jedis.JedisPool.instanceName.ssl`
|===

Any documentation for these properties that exists may be found in the
javadocs for the link:{jedis-jedispool-api-url}[`JedisPool`] and
link:{jedis-pool-api-url}[`Pool`] classes.

Injection without a `@Named` annotation is also possible:
[source,java]
----
 @Inject
 private JedisPool ordersPool;
----
In this case, the properties for JedisPoolConfig and JedisPool that can be set will start wih `redis.clients.jedis.JedisPoolConfig.default` and `redis.clients.jedis.JedisPool.default` respectively.

