diff --git a/.gitignore b/.gitignore
index 09a65951451..e846e4963ad 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
+*~
*.class
*.ctxt
.mtj.tmp/
diff --git a/etc/scripts/build.sh b/etc/scripts/build.sh
index f02009867a8..4a664aaf5fb 100755
--- a/etc/scripts/build.sh
+++ b/etc/scripts/build.sh
@@ -43,9 +43,10 @@ if [ "${WERCKER}" = "true" ] ; then
apt-get update && apt-get -y install graphviz
fi
+inject_credentials
+
mvn -f ${WS_DIR}/pom.xml \
clean install \
- -Pexamples,spotbugs,javadoc,docs,sources,ossrh-releases \
- --fail-at-end
+ -Pexamples,spotbugs,javadoc,docs,sources,ossrh-releases
-examples/archetypes/test-archetypes.sh
\ No newline at end of file
+examples/archetypes/test-archetypes.sh
diff --git a/etc/scripts/release.sh b/etc/scripts/release.sh
index 837bc79161e..fb07f2191bc 100755
--- a/etc/scripts/release.sh
+++ b/etc/scripts/release.sh
@@ -181,55 +181,6 @@ update_version(){
fi
}
-inject_credentials(){
- # Add private_key from IDENTITY_FILE
- if [ -n "${IDENTITY_FILE}" ] && [ ! -e ~/.ssh ]; then
- mkdir ~/.ssh/ 2>/dev/null || true
- echo -e "${IDENTITY_FILE}" > ~/.ssh/id_rsa
- chmod og-rwx ~/.ssh/id_rsa
- echo -e "Host *" >> ~/.ssh/config
- echo -e "\tStrictHostKeyChecking no" >> ~/.ssh/config
- echo -e "\tUserKnownHostsFile /dev/null" >> ~/.ssh/config
- fi
-
- # Add GPG key pair
- if [ -n "${GPG_PUBLIC_KEY}" ] && [ -n "${GPG_PRIVATE_KEY}" ] ; then
- mkdir ~/.gnupg 2>/dev/null || true
- chmod 700 ~/.gnupg
- echo "pinentry-mode loopback" > ~/.gnupg/gpg.conf
- echo -e "${GPG_PUBLIC_KEY}" > ~/.gnupg/helidon_pub.gpg
- gpg --import --no-tty --batch ~/.gnupg/helidon_pub.gpg
- echo -e "${GPG_PRIVATE_KEY}" > ~/.gnupg/helidon_sec.gpg
- gpg --allow-secret-key-import --import --no-tty --batch ~/.gnupg/helidon_sec.gpg
- fi
-
- # Add docker config from DOCKER_CONFIG_FILE
- if [ -n "${DOCKER_CONFIG_FILE}" ] && [ ! -e ~/.docker ]; then
- mkdir ~/.docker/ 2>/dev/null || true
- printf "${DOCKER_CONFIG_FILE}" > ~/.docker/config.json
- chmod og-rwx ~/.docker/config.json
- fi
-
- # Add maven settings from MAVEN_SETTINGS_FILE
- if [ -n "${MAVEN_SETTINGS_FILE}" ] ; then
- mkdir ~/.m2/ 2>/dev/null || true
- echo -e "${MAVEN_SETTINGS_FILE}" > ~/.m2/settings.xml
- fi
-
- # Add maven settings security from MAVEN_SETTINGS_SECURITY_FILE
- if [ -n "${MAVEN_SETTINGS_SECURITY_FILE}" ] ; then
- mkdir ~/.m2/ 2>/dev/null || true
- echo -e "${MAVEN_SETTINGS_SECURITY_FILE}" > ~/.m2/settings-security.xml
- fi
-
- # Add maven settings security from MAVEN_SETTINGS_SECURITY_FILE
- # Only if none exist on the system
- if [ -n "${MAVEN_SETTINGS_SECURITY_FILE}" ] && [ ! -e ~/.m2/settings-security.xml ]; then
- mkdir ~/.m2/ 2>/dev/null || true
- echo "${MAVEN_SETTINGS_SECURITY_FILE}" > ~/.m2/settings-security.xml
- fi
-}
-
release_build(){
# Inject credentials in CI env
inject_credentials
diff --git a/etc/scripts/wercker-env.sh b/etc/scripts/wercker-env.sh
index 9b4e8d40401..2820146188e 100644
--- a/etc/scripts/wercker-env.sh
+++ b/etc/scripts/wercker-env.sh
@@ -17,7 +17,70 @@
# WERCKER=true when running inside a wercker pipeline
+inject_credentials(){
+ # Add private_key from IDENTITY_FILE
+ if [ -n "${IDENTITY_FILE}" ] && [ ! -e ~/.ssh ]; then
+ mkdir ~/.ssh/ 2>/dev/null || true
+ echo -e "${IDENTITY_FILE}" > ~/.ssh/id_rsa
+ chmod og-rwx ~/.ssh/id_rsa
+ echo -e "Host *" >> ~/.ssh/config
+ echo -e "\tStrictHostKeyChecking no" >> ~/.ssh/config
+ echo -e "\tUserKnownHostsFile /dev/null" >> ~/.ssh/config
+ fi
+
+ # Add GPG key pair
+ if [ -n "${GPG_PUBLIC_KEY}" ] && [ -n "${GPG_PRIVATE_KEY}" ] ; then
+ mkdir ~/.gnupg 2>/dev/null || true
+ chmod 700 ~/.gnupg
+ echo "pinentry-mode loopback" > ~/.gnupg/gpg.conf
+ echo -e "${GPG_PUBLIC_KEY}" > ~/.gnupg/helidon_pub.gpg
+ gpg --import --no-tty --batch ~/.gnupg/helidon_pub.gpg
+ echo -e "${GPG_PRIVATE_KEY}" > ~/.gnupg/helidon_sec.gpg
+ gpg --allow-secret-key-import --import --no-tty --batch ~/.gnupg/helidon_sec.gpg
+ fi
+
+ # Add docker config from DOCKER_CONFIG_FILE
+ if [ -n "${DOCKER_CONFIG_FILE}" ] && [ ! -e ~/.docker ]; then
+ mkdir ~/.docker/ 2>/dev/null || true
+ printf "${DOCKER_CONFIG_FILE}" > ~/.docker/config.json
+ chmod og-rwx ~/.docker/config.json
+ fi
+
+ # Add maven settings from MAVEN_SETTINGS_FILE
+ if [ -n "${MAVEN_SETTINGS_FILE}" ] ; then
+ mkdir ~/.m2/ 2>/dev/null || true
+ echo -e "${MAVEN_SETTINGS_FILE}" > ~/.m2/settings.xml
+ fi
+
+ # Add maven settings security from MAVEN_SETTINGS_SECURITY_FILE
+ # Only if none exist on the system
+ if [ -n "${MAVEN_SETTINGS_SECURITY_FILE}" ] && [ ! -e ~/.m2/settings-security.xml ]; then
+ mkdir ~/.m2/ 2>/dev/null || true
+ echo "${MAVEN_SETTINGS_SECURITY_FILE}" > ~/.m2/settings-security.xml
+ fi
+}
+
if [ "${WERCKER}" = "true" ] ; then
- export MAVEN_OPTS="-Dmaven.repo.local=${WERCKER_CACHE_DIR}/local_repository"
+ export MAVEN_OPTS="-Dmaven.repo.local=${WERCKER_CACHE_DIR}/local_repository -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn"
rm -rf ~/.m2/settings* ~/.gitconfig ~/.ssh ${WERCKER_CACHE_DIR}/local_repository/io/helidon
+ # Work around https://github.com/oracle/oci-java-sdk/issues/25
+ TEMP_OCI_SDK_DIR=$(mktemp -d "oci-java-sdk.XXX")
+ git clone \
+ --depth 1 \
+ --branch \
+ v$(mvn -B -f "${WERCKER_ROOT}/pom.xml" \
+ -Dexpression=version.lib.oci-java-sdk-objectstorage org.apache.maven.plugins:maven-help-plugin:3.1.0:evaluate | grep '^[0-9]') \
+ "https://github.com/oracle/oci-java-sdk.git" \
+ "${TEMP_OCI_SDK_DIR}" && \
+ mvn -B -U -f "${TEMP_OCI_SDK_DIR}/pom.xml" \
+ -Dmaven.test.skip=true \
+ -Dmaven.source.skip=true \
+ -Dmaven.javadoc.skip=true \
+ -Dlombok.delombok.skip=true \
+ -pl bmc-objectstorage \
+ -am \
+ install && \
+ rm -rf "${TEMP_OCI_SDK_DIR}"
fi
+
+
diff --git a/examples/integrations/cdi/datasource-hikaricp/pom.xml b/examples/integrations/cdi/datasource-hikaricp/pom.xml
new file mode 100644
index 00000000000..70b19881bb7
--- /dev/null
+++ b/examples/integrations/cdi/datasource-hikaricp/pom.xml
@@ -0,0 +1,239 @@
+
+
+
+ 4.0.0
+
+ helidon-integrations-examples-datasource-hikaricp
+
+ Helidon Integrations: DataSource/HikariCP Example
+ Helidon Integrations DataSource Hikari Connection Pool Example
+
+
+ io.helidon.integrations.examples
+ helidon-integrations-examples-project
+ 0.10.3-SNAPSHOT
+
+
+
+
+
+ io.helidon.integrations.cdi
+ helidon-integrations-cdi-datasource-hikaricp
+ ${project.version}
+
+
+
+
+
+
+
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+ test
+
+
+
+ org.hamcrest
+ hamcrest-all
+ test
+
+
+
+
+
+ com.oracle.jdbc
+ ojdbc8
+ runtime
+
+
+
+ org.jboss.weld.se
+ weld-se-core
+ runtime
+
+
+ org.jboss.spec.javax.el
+ jboss-el-api_3.0_spec
+
+
+ org.jboss.spec.javax.interceptor
+ jboss-interceptors-api_1.2_spec
+
+
+
+
+
+ io.helidon.integrations.cdi
+ helidon-integrations-cdi-datasource-hikaricp
+ runtime
+
+
+
+ org.jboss
+ jandex
+ runtime
+
+
+
+ io.helidon.microprofile.server
+ helidon-microprofile-server
+ runtime
+
+
+ org.glassfish.hk2.external
+ javax.inject
+
+
+
+
+
+ io.helidon.microprofile.config
+ helidon-microprofile-config-cdi
+ runtime
+
+
+
+ javax.activation
+ javax.activation-api
+ runtime
+
+
+
+
+
+ javax.enterprise
+ cdi-api
+ compile
+
+
+
+ javax.ws.rs
+ javax.ws.rs-api
+ compile
+
+
+
+ redis.clients
+ jedis
+ compile
+
+
+
+ org.eclipse.microprofile.config
+ microprofile-config-api
+ compile
+
+
+
+
+
+
+
+ src/main/resources
+ true
+
+
+
+
+ maven-dependency-plugin
+
+
+ Copy all project dependencies to ${project.build.directory}/${dependenciesDirectory} for Docker image construction
+ prepare-package
+
+ copy-dependencies
+
+
+ ${project.build.directory}/${dependenciesDirectory}
+ false
+ false
+ true
+ true
+ runtime
+ test
+
+
+
+
+
+ maven-jar-plugin
+
+
+
+ true
+ ${dependenciesDirectory}
+ io.helidon.microprofile.server.Main
+
+
+
+
+
+ maven-resources-plugin
+
+
+ Copy Dockerfile and Kubernetes resources
+ process-resources
+
+ copy-resources
+
+
+ ${project.build.directory}
+
+
+ src/main/docker
+ true
+
+ Dockerfile
+
+
+
+ true
+ src/main/k8s
+
+ datasource.secrets.template
+ app.yaml
+
+
+
+
+
+
+
+
+ maven-surefire-plugin
+
+
+
+
+
+
+
+
+
+ libs
+ ${project.artifactId}
+ ${project.basedir}/src/main/spotbugs/exclusions.xml
+
+
+
diff --git a/examples/integrations/cdi/datasource-hikaricp/src/main/docker/Dockerfile b/examples/integrations/cdi/datasource-hikaricp/src/main/docker/Dockerfile
new file mode 100644
index 00000000000..168bc122e14
--- /dev/null
+++ b/examples/integrations/cdi/datasource-hikaricp/src/main/docker/Dockerfile
@@ -0,0 +1,27 @@
+#
+# Copyright (c) 2018 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.
+#
+FROM openjdk:8-jre-alpine
+EXPOSE 8080
+RUN mkdir /app
+COPY ${project.build.finalName}.jar /app
+COPY ${dependenciesDirectory} /app/${dependenciesDirectory}
+CMD [ \
+"sh", "-c", \
+"exec java \
+-XX:+UnlockExperimentalVMOptions \
+-XX:+UseCGroupMemoryLimitForHeap \
+-jar /app/${project.build.finalName}.jar" \
+]
diff --git a/examples/integrations/cdi/datasource-hikaricp/src/main/java/io/helidon/integrations/examples/datasource/hikaricp/jaxrs/TablesResource.java b/examples/integrations/cdi/datasource-hikaricp/src/main/java/io/helidon/integrations/examples/datasource/hikaricp/jaxrs/TablesResource.java
new file mode 100644
index 00000000000..25b536ca8c7
--- /dev/null
+++ b/examples/integrations/cdi/datasource-hikaricp/src/main/java/io/helidon/integrations/examples/datasource/hikaricp/jaxrs/TablesResource.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2018 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.
+ */
+package io.helidon.integrations.examples.datasource.hikaricp.jaxrs;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Objects;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.sql.DataSource;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+/**
+ * A JAX-RS resource class in {@linkplain ApplicationScoped
+ * application scope} rooted at {@code /tables}.
+ *
+ * @see #get()
+ */
+@Path("/tables")
+@ApplicationScoped
+public class TablesResource {
+
+ private final DataSource dataSource;
+
+ /**
+ * Creates a new {@link TablesResource}.
+ *
+ * @param dataSource the {@link DataSource} to use to acquire
+ * database table names; must not be {@code null}
+ *
+ * @exception NullPointerException if {@code dataSource} is {@code
+ * null}
+ */
+ @Inject
+ public TablesResource(@Named("example") final DataSource dataSource) {
+ super();
+ this.dataSource = Objects.requireNonNull(dataSource);
+ }
+
+ /**
+ * Returns a {@link Response} which, if successful, contains a
+ * newline-separated list of Oracle database table names.
+ *
+ *
This method never returns {@code null}.
+ *
+ * @return a non-{@code null} {@link Response}
+ *
+ * @exception SQLException if a database error occurs
+ */
+ @GET
+ @Produces(MediaType.TEXT_PLAIN)
+ public Response get() throws SQLException {
+ final StringBuilder sb = new StringBuilder();
+ try (Connection connection = this.dataSource.getConnection();
+ PreparedStatement ps =
+ connection.prepareStatement(" SELECT TABLE_NAME"
+ + " FROM ALL_TABLES "
+ + "ORDER BY TABLE_NAME ASC");
+ ResultSet rs = ps.executeQuery()) {
+ while (rs.next()) {
+ sb.append(rs.getString(1)).append("\n");
+ }
+ }
+ final Response returnValue = Response.ok()
+ .entity(sb.toString())
+ .build();
+ return returnValue;
+ }
+
+}
diff --git a/examples/integrations/cdi/datasource-hikaricp/src/main/java/io/helidon/integrations/examples/datasource/hikaricp/jaxrs/package-info.java b/examples/integrations/cdi/datasource-hikaricp/src/main/java/io/helidon/integrations/examples/datasource/hikaricp/jaxrs/package-info.java
new file mode 100644
index 00000000000..372c3918304
--- /dev/null
+++ b/examples/integrations/cdi/datasource-hikaricp/src/main/java/io/helidon/integrations/examples/datasource/hikaricp/jaxrs/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2018 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.
+ */
+
+/**
+ * Provides JAX-RS-related classes and interfaces for this example
+ * project.
+ */
+package io.helidon.integrations.examples.datasource.hikaricp.jaxrs;
diff --git a/examples/integrations/cdi/datasource-hikaricp/src/main/resources/META-INF/beans.xml b/examples/integrations/cdi/datasource-hikaricp/src/main/resources/META-INF/beans.xml
new file mode 100644
index 00000000000..607db5743cc
--- /dev/null
+++ b/examples/integrations/cdi/datasource-hikaricp/src/main/resources/META-INF/beans.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
diff --git a/examples/integrations/cdi/datasource-hikaricp/src/main/resources/META-INF/microprofile-config.properties b/examples/integrations/cdi/datasource-hikaricp/src/main/resources/META-INF/microprofile-config.properties
new file mode 100644
index 00000000000..8a8e63c52ea
--- /dev/null
+++ b/examples/integrations/cdi/datasource-hikaricp/src/main/resources/META-INF/microprofile-config.properties
@@ -0,0 +1,29 @@
+#
+# Copyright (c) 2018 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.
+#
+
+# Default database properties.
+# See
+# https://container-registry.oracle.com/pls/apex/f?p=113:4:102624334361221::NO:::
+# and
+# https://technology.amis.nl/2017/11/18/run-oracle-database-in-docker-using-prebaked-image-from-oracle-container-registry-a-two-minute-guide/
+javax.sql.DataSource.example.dataSourceClassName=oracle.jdbc.pool.OracleDataSource
+javax.sql.DataSource.example.dataSource.url = jdbc:oracle:thin:@localhost:1527:ORCL
+javax.sql.DataSource.example.dataSource.user = sys as sysoper
+javax.sql.DataSource.example.dataSource.password = Oracle
+
+# Microprofile server properties
+server.port=8080
+server.host=0.0.0.0
diff --git a/examples/integrations/cdi/datasource-hikaricp/src/main/spotbugs/exclusions.xml b/examples/integrations/cdi/datasource-hikaricp/src/main/spotbugs/exclusions.xml
new file mode 100644
index 00000000000..0e98aa554c9
--- /dev/null
+++ b/examples/integrations/cdi/datasource-hikaricp/src/main/spotbugs/exclusions.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
diff --git a/examples/integrations/cdi/jedis/pom.xml b/examples/integrations/cdi/jedis/pom.xml
new file mode 100644
index 00000000000..4f23e201883
--- /dev/null
+++ b/examples/integrations/cdi/jedis/pom.xml
@@ -0,0 +1,232 @@
+
+
+
+ 4.0.0
+
+ helidon-integrations-examples-jedis
+
+ Helidon Integrations Jedis Example
+ ${project.name}
+
+
+ io.helidon.integrations.examples
+ helidon-integrations-examples-project
+ 0.10.3-SNAPSHOT
+
+
+
+
+
+ io.helidon.integrations.cdi
+ helidon-integrations-cdi-jedis
+ ${project.version}
+
+
+
+
+
+
+
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+ test
+
+
+
+ org.hamcrest
+ hamcrest-all
+ test
+
+
+
+
+
+ org.jboss.weld.se
+ weld-se-core
+ runtime
+
+
+ org.jboss.spec.javax.el
+ jboss-el-api_3.0_spec
+
+
+ org.jboss.spec.javax.interceptor
+ jboss-interceptors-api_1.2_spec
+
+
+
+
+
+ io.helidon.integrations.cdi
+ helidon-integrations-cdi-jedis
+ runtime
+
+
+
+ org.jboss
+ jandex
+ runtime
+
+
+
+ io.helidon.microprofile.server
+ helidon-microprofile-server
+ runtime
+
+
+ org.glassfish.hk2.external
+ javax.inject
+
+
+
+
+
+ io.helidon.microprofile.config
+ helidon-microprofile-config-cdi
+ runtime
+
+
+
+ javax.activation
+ javax.activation-api
+ runtime
+
+
+
+
+
+ javax.enterprise
+ cdi-api
+ compile
+
+
+
+ javax.ws.rs
+ javax.ws.rs-api
+ compile
+
+
+
+ redis.clients
+ jedis
+ compile
+
+
+
+ org.eclipse.microprofile.config
+ microprofile-config-api
+ compile
+
+
+
+
+
+
+
+ src/main/resources
+ true
+
+
+
+
+ maven-dependency-plugin
+
+
+ Copy all project dependencies to ${project.build.directory}/${dependenciesDirectory} for Docker image construction
+ prepare-package
+
+ copy-dependencies
+
+
+ ${project.build.directory}/${dependenciesDirectory}
+ false
+ false
+ true
+ true
+ runtime
+ test
+
+
+
+
+
+ maven-jar-plugin
+
+
+
+ true
+ ${dependenciesDirectory}
+ io.helidon.microprofile.server.Main
+
+
+
+
+
+ maven-resources-plugin
+
+
+ Copy Dockerfile and Kubernetes resources
+ process-resources
+
+ copy-resources
+
+
+ ${project.build.directory}
+
+
+ src/main/docker
+ true
+
+ Dockerfile
+
+
+
+ true
+ src/main/k8s
+
+ jedis.secrets.template
+ app.yaml
+
+
+
+
+
+
+
+
+ maven-surefire-plugin
+
+
+
+
+
+
+
+
+
+ libs
+ ${project.artifactId}
+ ${project.basedir}/src/main/spotbugs/exclusions.xml
+
+
+
diff --git a/examples/integrations/cdi/jedis/src/main/docker/Dockerfile b/examples/integrations/cdi/jedis/src/main/docker/Dockerfile
new file mode 100644
index 00000000000..168bc122e14
--- /dev/null
+++ b/examples/integrations/cdi/jedis/src/main/docker/Dockerfile
@@ -0,0 +1,27 @@
+#
+# Copyright (c) 2018 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.
+#
+FROM openjdk:8-jre-alpine
+EXPOSE 8080
+RUN mkdir /app
+COPY ${project.build.finalName}.jar /app
+COPY ${dependenciesDirectory} /app/${dependenciesDirectory}
+CMD [ \
+"sh", "-c", \
+"exec java \
+-XX:+UnlockExperimentalVMOptions \
+-XX:+UseCGroupMemoryLimitForHeap \
+-jar /app/${project.build.finalName}.jar" \
+]
diff --git a/examples/integrations/cdi/jedis/src/main/java/io/helidon/integrations/examples/jedis/jaxrs/Application.java b/examples/integrations/cdi/jedis/src/main/java/io/helidon/integrations/examples/jedis/jaxrs/Application.java
new file mode 100644
index 00000000000..93643524e0f
--- /dev/null
+++ b/examples/integrations/cdi/jedis/src/main/java/io/helidon/integrations/examples/jedis/jaxrs/Application.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2018 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.
+ */
+package io.helidon.integrations.examples.jedis.jaxrs;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.ws.rs.ApplicationPath;
+
+/**
+ * A JAX-RS {@link javax.ws.rs.core.Application application} in
+ * {@linkplain ApplicationScoped application scope}.
+ *
+ * @see #getClasses()
+ */
+@ApplicationScoped
+@ApplicationPath("/")
+public class Application extends javax.ws.rs.core.Application {
+
+ private final Set> classes;
+
+ /**
+ * Creates a new {@link Application}.
+ */
+ public Application() {
+ super();
+ final Set> classes = new HashSet<>();
+ classes.add(RedisClientResource.class);
+ this.classes = Collections.unmodifiableSet(classes);
+ }
+
+ /**
+ * Returns a non-{@code null} {@linkplain
+ * java.util.Collections#unmodifiableSet(Set) immutable
+ * Set} of {@link Class}es that comprise this JAX-RS
+ * application.
+ *
+ * @return a non-{@code null} {@linkplain
+ * java.util.Collections#unmodifiableSet(Set) immutable
+ * Set}
+ */
+ @Override
+ public Set> getClasses() {
+ return this.classes;
+ }
+
+}
diff --git a/examples/integrations/cdi/jedis/src/main/java/io/helidon/integrations/examples/jedis/jaxrs/RedisClientResource.java b/examples/integrations/cdi/jedis/src/main/java/io/helidon/integrations/examples/jedis/jaxrs/RedisClientResource.java
new file mode 100644
index 00000000000..138e9329b87
--- /dev/null
+++ b/examples/integrations/cdi/jedis/src/main/java/io/helidon/integrations/examples/jedis/jaxrs/RedisClientResource.java
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 2018 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.
+ */
+package io.helidon.integrations.examples.jedis.jaxrs;
+
+import java.util.Objects;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
+import javax.inject.Provider;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+
+import redis.clients.jedis.Jedis;
+
+/**
+ * A JAX-RS resource class rooted at {@code /jedis}.
+ *
+ * @see #get(String)
+ *
+ * @see #set(UriInfo, String, String)
+ *
+ * @see #del(String)
+ */
+@Path("/jedis")
+@ApplicationScoped
+public class RedisClientResource {
+
+ private final Provider clientProvider;
+
+ /**
+ * Creates a new {@link RedisClientResource}.
+ *
+ * @param clientProvider a {@link Provider} of a {@link Jedis}
+ * instance; must not be {@code null}
+ *
+ * @exception NullPointerException if {@code clientProvider} is
+ * {@code null}
+ */
+ @Inject
+ public RedisClientResource(final Provider clientProvider) {
+ super();
+ this.clientProvider = Objects.requireNonNull(clientProvider);
+ }
+
+ /**
+ * Returns a non-{@code null} {@link Response} which, if successful,
+ * will contain any value indexed under the supplied Redis key.
+ *
+ *
This method never returns {@code null}.
+ *
+ * @param key the key whose value should be deleted; must not be
+ * {@code null}
+ *
+ * @return a non-{@code null} {@link Response}
+ *
+ * @see #set(UriInfo, String, String)
+ *
+ * @see #del(String)
+ */
+ @GET
+ @Path("/{key}")
+ @Produces(MediaType.TEXT_PLAIN)
+ public Response get(@PathParam("key") final String key) {
+ final Response returnValue;
+ if (key == null || key.isEmpty()) {
+ returnValue = Response.status(400)
+ .build();
+ } else {
+ final String response = this.clientProvider.get().get(key);
+ if (response == null) {
+ returnValue = Response.status(404)
+ .build();
+ } else {
+ returnValue = Response.ok()
+ .entity(response)
+ .build();
+ }
+ }
+ return returnValue;
+ }
+
+ /**
+ * Sets a value under a key in a Redis system.
+ *
+ * @param uriInfo a {@link UriInfo} describing the current request;
+ * must not be {@code null}
+ *
+ * @param key the key in question; must not be {@code null}
+ *
+ * @param value the value to set; may be {@code null}
+ *
+ * @return a non-{@code null} {@link Response} indicating the status
+ * of the operation
+ *
+ * @exception NullPointerException if {@code uriInfo} is {@code
+ * null}
+ *
+ * @see #del(String)
+ */
+ @PUT
+ @Path("/{key}")
+ @Consumes(MediaType.TEXT_PLAIN)
+ public Response set(@Context final UriInfo uriInfo,
+ @PathParam("key") final String key,
+ final String value) {
+ Objects.requireNonNull(uriInfo);
+ final Response returnValue;
+ if (key == null || key.isEmpty() || value == null) {
+ returnValue = Response.status(400)
+ .build();
+ } else {
+ final Object priorValue = this.clientProvider.get().getSet(key, value);
+ if (priorValue == null) {
+ returnValue = Response.created(uriInfo.getRequestUri())
+ .build();
+ } else {
+ returnValue = Response.ok()
+ .build();
+ }
+ }
+ return returnValue;
+ }
+
+ /**
+ * Deletes a value from Redis.
+ *
+ * @param key the key identifying the value to delete; must not be
+ * {@code null}
+ *
+ * @return a non-{@code null} {@link Response} describing the result
+ * of the operation
+ *
+ * @see #get(String)
+ *
+ * @see #set(UriInfo, String, String)
+ */
+ @DELETE
+ @Path("/{key}")
+ @Produces(MediaType.TEXT_PLAIN)
+ public Response del(@PathParam("key") final String key) {
+ final Response returnValue;
+ if (key == null || key.isEmpty()) {
+ returnValue = Response.status(400)
+ .build();
+ } else {
+ final Long numberOfKeysDeleted = this.clientProvider.get().del(key);
+ if (numberOfKeysDeleted == null || numberOfKeysDeleted.longValue() <= 0L) {
+ returnValue = Response.status(404)
+ .build();
+ } else {
+ returnValue = Response.noContent()
+ .build();
+ }
+ }
+ return returnValue;
+ }
+
+}
diff --git a/examples/integrations/cdi/jedis/src/main/java/io/helidon/integrations/examples/jedis/jaxrs/package-info.java b/examples/integrations/cdi/jedis/src/main/java/io/helidon/integrations/examples/jedis/jaxrs/package-info.java
new file mode 100644
index 00000000000..d9d222a8d99
--- /dev/null
+++ b/examples/integrations/cdi/jedis/src/main/java/io/helidon/integrations/examples/jedis/jaxrs/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2018 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.
+ */
+
+/**
+ * Provides JAX-RS-related classes and interfaces for this example
+ * project.
+ */
+package io.helidon.integrations.examples.jedis.jaxrs;
diff --git a/examples/integrations/cdi/jedis/src/main/k8s/app.yaml b/examples/integrations/cdi/jedis/src/main/k8s/app.yaml
new file mode 100644
index 00000000000..29a1257ac02
--- /dev/null
+++ b/examples/integrations/cdi/jedis/src/main/k8s/app.yaml
@@ -0,0 +1,50 @@
+#
+# Copyright (c) 2018 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.
+#
+
+kind: Service
+apiVersion: v1
+metadata:
+ name: ${project.artifactId}
+ labels:
+ app: ${project.artifactId}
+spec:
+ type: NodePort
+ selector:
+ app: ${project.artifactId}
+ ports:
+ - port: 8080
+ targetPort: 8080
+ name: http
+---
+kind: Deployment
+apiVersion: extensions/v1beta1
+metadata:
+ name: ${project.artifactId}
+spec:
+ replicas: 1
+ template:
+ metadata:
+ labels:
+ app: ${project.artifactId}
+ version: v1
+ spec:
+ containers:
+ - name: ${project.artifactId}
+ image: ${project.artifactId}
+ imagePullPolicy: IfNotPresent
+ ports:
+ - containerPort: 8080
+---
diff --git a/examples/integrations/cdi/jedis/src/main/resources/META-INF/beans.xml b/examples/integrations/cdi/jedis/src/main/resources/META-INF/beans.xml
new file mode 100644
index 00000000000..607db5743cc
--- /dev/null
+++ b/examples/integrations/cdi/jedis/src/main/resources/META-INF/beans.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
diff --git a/examples/integrations/cdi/jedis/src/main/resources/META-INF/microprofile-config.properties b/examples/integrations/cdi/jedis/src/main/resources/META-INF/microprofile-config.properties
new file mode 100644
index 00000000000..71e89c2ff14
--- /dev/null
+++ b/examples/integrations/cdi/jedis/src/main/resources/META-INF/microprofile-config.properties
@@ -0,0 +1,22 @@
+#
+# Copyright (c) 2018 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.
+#
+
+# Jedis properties
+redis.clients.jedis.JedisPool.default.port=6379
+
+# Microprofile server properties
+server.port=8080
+server.host=0.0.0.0
diff --git a/examples/integrations/cdi/jedis/src/main/spotbugs/exclusions.xml b/examples/integrations/cdi/jedis/src/main/spotbugs/exclusions.xml
new file mode 100644
index 00000000000..f5b4e738068
--- /dev/null
+++ b/examples/integrations/cdi/jedis/src/main/spotbugs/exclusions.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
diff --git a/examples/integrations/cdi/oci-objectstorage/README.adoc b/examples/integrations/cdi/oci-objectstorage/README.adoc
new file mode 100644
index 00000000000..8f6278666bd
--- /dev/null
+++ b/examples/integrations/cdi/oci-objectstorage/README.adoc
@@ -0,0 +1,24 @@
+= OCI Object Storage CDI Integration Example
+
+== Build
+
+----
+mvn clean install
+----
+
+== Deploy to Kubernetes
+
+First you need to create Kubernetes secrets to store sensitive OCI
+information.
+
+To start, make a copy of the Bash script located (after building the
+project) in `target/oci.secrets.template` and name it whatever you
+like. This guide will refer to it as, simply, `oci.secrets`.
+
+Now edit `oci.secrets` to contain the information you'll need to
+connect to OCI services.
+
+Once you have properly customized the variables in `oci.secrets`, you
+can execute it. `kubectl`, invoked by the script, will create a
+Kubernetes secret that will contain all the OCI connectivity
+information.
diff --git a/examples/integrations/cdi/oci-objectstorage/pom.xml b/examples/integrations/cdi/oci-objectstorage/pom.xml
new file mode 100644
index 00000000000..9b4c0b0e691
--- /dev/null
+++ b/examples/integrations/cdi/oci-objectstorage/pom.xml
@@ -0,0 +1,249 @@
+
+
+
+ 4.0.0
+
+ helidon-integrations-examples-oci-objectstorage
+
+ Helidon Integrations OCI ObjectStorage Example
+ ${project.name}
+
+
+ io.helidon.integrations.examples
+ helidon-integrations-examples-project
+ 0.10.3-SNAPSHOT
+
+
+
+
+
+ io.helidon.integrations.cdi
+ helidon-integrations-cdi-oci-objectstorage
+ ${project.version}
+
+
+
+
+
+
+
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+ test
+
+
+
+ org.hamcrest
+ hamcrest-all
+ test
+
+
+
+ org.slf4j
+ slf4j-simple
+ test
+
+
+
+
+
+ org.jboss.weld.se
+ weld-se-core
+ runtime
+
+
+ org.jboss.spec.javax.el
+ jboss-el-api_3.0_spec
+
+
+ org.jboss.spec.javax.interceptor
+ jboss-interceptors-api_1.2_spec
+
+
+
+
+
+ io.helidon.integrations.cdi
+ helidon-integrations-cdi-oci-objectstorage
+ runtime
+
+
+ org.glassfish.hk2.external
+ javax.inject
+
+
+
+
+
+ org.jboss
+ jandex
+ runtime
+
+
+
+ io.helidon.microprofile.server
+ helidon-microprofile-server
+ runtime
+
+
+
+ io.helidon.microprofile.config
+ helidon-microprofile-config-cdi
+ runtime
+
+
+
+ javax.activation
+ javax.activation-api
+ runtime
+
+
+
+
+
+ javax.enterprise
+ cdi-api
+ compile
+
+
+
+ com.oracle.oci.sdk
+ oci-java-sdk-objectstorage
+ compile
+ pom
+
+
+ org.glassfish.hk2.external
+ javax.inject
+
+
+
+
+
+ org.eclipse.microprofile.config
+ microprofile-config-api
+ compile
+
+
+
+
+
+
+
+ src/main/resources
+ true
+
+
+
+
+ maven-dependency-plugin
+
+
+ Copy all project dependencies to ${project.build.directory}/${dependenciesDirectory} for Docker image construction
+ prepare-package
+
+ copy-dependencies
+
+
+ ${project.build.directory}/${dependenciesDirectory}
+ false
+ false
+ true
+ true
+ runtime
+ test
+
+
+
+
+
+ maven-jar-plugin
+
+
+
+ true
+ ${dependenciesDirectory}
+ io.helidon.microprofile.server.Main
+
+
+
+
+
+ maven-resources-plugin
+
+
+ Copy Dockerfile and Kubernetes resources
+ process-resources
+
+ copy-resources
+
+
+ ${project.build.directory}
+
+
+ src/main/docker
+ true
+
+ Dockerfile
+
+
+
+ true
+ src/main/k8s
+
+ oci.secrets.template
+ app.yaml
+
+
+
+
+
+
+
+
+ maven-surefire-plugin
+
+
+ ${oci.objectstorage.compartmentId}
+ ${oci.objectstorage.region}
+
+
+
+
+
+
+
+ libs
+ ${project.artifactId}
+ ${project.basedir}/src/main/spotbugs/exclusions.xml
+
+ TODO: For testing only, you need to set your OCI fingerprint here. For more information: https://docs.cloud.oracle.com/iaas/Content/API/Concepts/sdkconfig.htm
+ TODO: For testing only, you need to set the full path to your OCI keyFile here. For more information: https://docs.cloud.oracle.com/iaas/Content/API/Concepts/sdkconfig.htm
+ TODO: For testing only, you need to set your OCI keyFile passphrase here. For more information: https://docs.cloud.oracle.com/iaas/Content/API/Concepts/sdkconfig.htm
+ TODO: For testing only, you need to set your OCI tenancy here. For more information: https://docs.cloud.oracle.com/iaas/Content/API/Concepts/sdkconfig.htm
+ TODO: For testing only, you need to set your OCI user here. For more information: https://docs.cloud.oracle.com/iaas/Content/API/Concepts/sdkconfig.htm
+ TODO: For testing only, you need to set your OCI compartment ID here. For more information: https://docs.cloud.oracle.com/iaas/Content/API/Concepts/sdkconfig.htm
+ TODO: For testing only, you need to set your OCI region here. For more information: https://docs.cloud.oracle.com/iaas/Content/API/Concepts/sdkconfig.htm
+
+
+
diff --git a/examples/integrations/cdi/oci-objectstorage/src/main/docker/Dockerfile b/examples/integrations/cdi/oci-objectstorage/src/main/docker/Dockerfile
new file mode 100644
index 00000000000..d103a8b591a
--- /dev/null
+++ b/examples/integrations/cdi/oci-objectstorage/src/main/docker/Dockerfile
@@ -0,0 +1,34 @@
+#
+# Copyright (c) 2018 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.
+#
+FROM openjdk:8-jre-alpine
+EXPOSE 8080
+RUN mkdir /app
+COPY ${project.build.finalName}.jar /app
+COPY ${dependenciesDirectory} /app/${dependenciesDirectory}
+CMD [ \
+"sh", "-c", \
+"exec java \
+-Doci.auth.fingerprint=\"${OCI_AUTH_FINGERPRINT}\" \
+-Doci.auth.passphraseCharacters=\"${OCI_AUTH_PASSPHRASE}\" \
+-Doci.auth.privateKey=\"${OCI_AUTH_PRIVATEKEY}\" \
+-Doci.auth.tenancy=\"${OCI_AUTH_TENANCY}\" \
+-Doci.auth.user=\"${OCI_AUTH_USER}\" \
+-Doci.objectstorage.compartmentId=\"${OCI_OBJECTSTORAGE_COMPARTMENT}\" \
+-Doci.objectstorage.region=\"${OCI_OBJECTSTORAGE_REGION}\" \
+-XX:+UnlockExperimentalVMOptions \
+-XX:+UseCGroupMemoryLimitForHeap \
+-jar /app/${project.build.finalName}.jar" \
+]
diff --git a/examples/integrations/cdi/oci-objectstorage/src/main/java/io/helidon/integrations/examples/oci/objectstorage/jaxrs/Application.java b/examples/integrations/cdi/oci-objectstorage/src/main/java/io/helidon/integrations/examples/oci/objectstorage/jaxrs/Application.java
new file mode 100644
index 00000000000..4f2e10c1f49
--- /dev/null
+++ b/examples/integrations/cdi/oci-objectstorage/src/main/java/io/helidon/integrations/examples/oci/objectstorage/jaxrs/Application.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2018 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.
+ */
+package io.helidon.integrations.examples.oci.objectstorage.jaxrs;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.ws.rs.ApplicationPath;
+
+/**
+ * A JAX-RS {@linkplain javax.ws.rs.core.Application application} in
+ * {@linkplain ApplicationScoped application scope}.
+ *
+ * @see #getClasses()
+ */
+@ApplicationScoped
+@ApplicationPath("/")
+public class Application extends javax.ws.rs.core.Application {
+
+ private final Set> classes;
+
+ /**
+ * Creates a new {@link Application}.
+ */
+ public Application() {
+ super();
+ final Set> classes = new HashSet<>();
+ classes.add(HelidonLogoResource.class);
+ this.classes = Collections.unmodifiableSet(classes);
+ }
+
+ /**
+ * Returns a non-{@code null} {@linkplain
+ * java.util.Collections#unmodifiableSet(Set) immutable
+ * Set} of {@link Class}es that comprise this JAX-RS
+ * application.
+ *
+ * @return a non-{@code null} {@linkplain
+ * java.util.Collections#unmodifiableSet(Set) immutable
+ * Set}
+ */
+ @Override
+ public Set> getClasses() {
+ return this.classes;
+ }
+
+}
diff --git a/examples/integrations/cdi/oci-objectstorage/src/main/java/io/helidon/integrations/examples/oci/objectstorage/jaxrs/HelidonLogoResource.java b/examples/integrations/cdi/oci-objectstorage/src/main/java/io/helidon/integrations/examples/oci/objectstorage/jaxrs/HelidonLogoResource.java
new file mode 100644
index 00000000000..a7972afe8ec
--- /dev/null
+++ b/examples/integrations/cdi/oci-objectstorage/src/main/java/io/helidon/integrations/examples/oci/objectstorage/jaxrs/HelidonLogoResource.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2018 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.
+ */
+package io.helidon.integrations.examples.oci.objectstorage.jaxrs;
+
+import java.util.Objects;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import com.oracle.bmc.model.BmcException;
+import com.oracle.bmc.objectstorage.ObjectStorage;
+import com.oracle.bmc.objectstorage.requests.GetObjectRequest;
+import com.oracle.bmc.objectstorage.responses.GetObjectResponse;
+import org.eclipse.microprofile.config.inject.ConfigProperty;
+
+/**
+ * A JAX-RS resource class rooted at {@code /logo}.
+ *
+ * @see #getLogo(String, String, String)
+ */
+@Path("/logo")
+@ApplicationScoped
+public class HelidonLogoResource {
+
+ private final ObjectStorage client;
+
+ private final String namespaceName;
+
+ /**
+ * Creates a new {@link HelidonLogoResource}.
+ *
+ * @param client an {@link ObjectStorage} client; must not be {@code
+ * null}
+ *
+ * @param namespaceName the name of an OCI object storage namespace
+ * that will be used; must not be {@code null}
+ *
+ * @exception NullPointerException if either parameter is {@code
+ * null}
+ */
+ @Inject
+ public HelidonLogoResource(final ObjectStorage client,
+ @ConfigProperty(name = "oci.objectstorage.namespace") final String namespaceName) {
+ super();
+ this.client = Objects.requireNonNull(client);
+ this.namespaceName = Objects.requireNonNull(namespaceName);
+ }
+
+ /**
+ * Returns a non-{@code null} {@link Response} which, if successful,
+ * will contain the object stored under the supplied {@code
+ * namespaceName}, {@code bucketName} and {@code objectName}.
+ *
+ * @param namespaceName the OCI object storage namespace to use;
+ * must not be {@code null}
+ *
+ * @param bucketName the OCI object storage bucket name to use; must
+ * not be {@code null}
+ *
+ * @param objectName the OCI object storage object name to use; must
+ * not be {@code null}
+ *
+ * @return a non-{@code null} {@link Response} describing the
+ * operation
+ *
+ * @exception NullPointerException if any of the parameters is
+ * {@code null}
+ */
+ @GET
+ @Path("/{namespaceName}/{bucketName}/{objectName}")
+ @Produces(MediaType.WILDCARD)
+ public Response getLogo(@PathParam("namespaceName") String namespaceName,
+ @PathParam("bucketName") final String bucketName,
+ @PathParam("objectName") final String objectName) {
+ final Response returnValue;
+ if (bucketName == null || bucketName.isEmpty() || objectName == null || objectName.isEmpty()) {
+ returnValue = Response.status(400)
+ .build();
+ } else {
+ if (namespaceName == null || namespaceName.isEmpty()) {
+ namespaceName = this.namespaceName;
+ }
+ Response temp = null;
+ try {
+ final GetObjectRequest request = GetObjectRequest.builder()
+ .namespaceName(namespaceName)
+ .bucketName(bucketName)
+ .objectName(objectName)
+ .build();
+ assert request != null;
+ final GetObjectResponse response = this.client.getObject(request);
+ assert response != null;
+ final Long contentLength = response.getContentLength();
+ assert contentLength != null;
+ if (contentLength.longValue() <= 0L) {
+ temp = Response.noContent()
+ .build();
+ } else {
+ temp = Response.ok()
+ .type(response.getContentType())
+ .entity(response.getInputStream())
+ .build();
+ }
+ } catch (final BmcException bmcException) {
+ final int statusCode = bmcException.getStatusCode();
+ temp = Response.status(statusCode)
+ .build();
+ } finally {
+ returnValue = temp;
+ }
+ }
+ return returnValue;
+ }
+
+}
diff --git a/examples/integrations/cdi/oci-objectstorage/src/main/java/io/helidon/integrations/examples/oci/objectstorage/jaxrs/package-info.java b/examples/integrations/cdi/oci-objectstorage/src/main/java/io/helidon/integrations/examples/oci/objectstorage/jaxrs/package-info.java
new file mode 100644
index 00000000000..14a15746748
--- /dev/null
+++ b/examples/integrations/cdi/oci-objectstorage/src/main/java/io/helidon/integrations/examples/oci/objectstorage/jaxrs/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2018 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.
+ */
+
+/**
+ * Provides JAX-RS-related classes and interfaces for this example
+ * project.
+ */
+package io.helidon.integrations.examples.oci.objectstorage.jaxrs;
diff --git a/examples/integrations/cdi/oci-objectstorage/src/main/k8s/app.yaml b/examples/integrations/cdi/oci-objectstorage/src/main/k8s/app.yaml
new file mode 100644
index 00000000000..45e60c91149
--- /dev/null
+++ b/examples/integrations/cdi/oci-objectstorage/src/main/k8s/app.yaml
@@ -0,0 +1,86 @@
+#
+# Copyright (c) 2018 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.
+#
+
+kind: Service
+apiVersion: v1
+metadata:
+ name: ${project.artifactId}
+ labels:
+ app: ${project.artifactId}
+spec:
+ type: NodePort
+ selector:
+ app: ${project.artifactId}
+ ports:
+ - port: 8080
+ targetPort: 8080
+ name: http
+---
+kind: Deployment
+apiVersion: extensions/v1beta1
+metadata:
+ name: ${project.artifactId}
+spec:
+ replicas: 1
+ template:
+ metadata:
+ labels:
+ app: ${project.artifactId}
+ version: v1
+ spec:
+ containers:
+ - name: ${project.artifactId}
+ image: ${project.artifactId}
+ imagePullPolicy: IfNotPresent
+ ports:
+ - containerPort: 8080
+ env:
+ - name: OCI_AUTH_FINGERPRINT
+ valueFrom:
+ secretKeyRef:
+ name: ${kubernetesSecretName}
+ key: OCI_AUTH_FINGERPRINT
+ - name: OCI_AUTH_PASSPHRASE
+ valueFrom:
+ secretKeyRef:
+ name: ${kubernetesSecretName}
+ key: OCI_AUTH_PASSPHRASE
+ - name: OCI_AUTH_PRIVATEKEY
+ valueFrom:
+ secretKeyRef:
+ name: ${kubernetesSecretName}
+ key: OCI_AUTH_PRIVATEKEY
+ - name: OCI_AUTH_TENANCY
+ valueFrom:
+ secretKeyRef:
+ name: ${kubernetesSecretName}
+ key: OCI_AUTH_TENANCY
+ - name: OCI_AUTH_USER
+ valueFrom:
+ secretKeyRef:
+ name: ${kubernetesSecretName}
+ key: OCI_AUTH_USER
+ - name: OCI_OBJECTSTORAGE_COMPARTMENT
+ valueFrom:
+ secretKeyRef:
+ name: ${kubernetesSecretName}
+ key: OCI_OBJECTSTORAGE_COMPARTMENT
+ - name: OCI_OBJECTSTORAGE_REGION
+ valueFrom:
+ secretKeyRef:
+ name: ${kubernetesSecretName}
+ key: OCI_OBJECTSTORAGE_REGION
+---
diff --git a/examples/integrations/cdi/oci-objectstorage/src/main/k8s/oci.secrets.template b/examples/integrations/cdi/oci-objectstorage/src/main/k8s/oci.secrets.template
new file mode 100644
index 00000000000..366bb687cba
--- /dev/null
+++ b/examples/integrations/cdi/oci-objectstorage/src/main/k8s/oci.secrets.template
@@ -0,0 +1,82 @@
+#!/bin/sh
+#
+# Copyright (c) 2018 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.
+
+# This file is a TEMPLATE for a shell script that will create
+# Kubernetes secrets that will be used to deploy this example program
+# to Kubernetes. If you are reading this from the
+# src/main/resources/k8s directory, bear in mind that it is first
+# copied with Maven filtering applied to the
+# ${project.build.directory} directory, which is normally "target".
+#
+# You should take the target/oci.secrets.template file and make a copy
+# of it. Then, customize the variables below in your copy to contain
+# the required information.
+
+# The name of the secret that Kubernetes will create. It must consist of lower
+# case alphanumeric characters, '-' or '.', and must start and end with an
+# alphanumeric character. The regular expression used for validation is:
+# [a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*
+SECRET_NAME=${kubernetesSecretName}
+
+# The fingerprint for the key pair being used. See
+# https://docs.cloud.oracle.com/iaas/Content/API/Concepts/apisigningkey.htm#How3
+# for more information.
+OCI_AUTH_FINGERPRINT=
+
+# The passphrase used for the key if it is encrypted. See
+# https://docs.cloud.oracle.com/iaas/Content/API/Concepts/apisigningkey.htm#two
+# for more information.
+OCI_AUTH_PASSPHRASE=
+
+# The actual private key contents. This variable is set by default to
+# contain the exact contents of the private key file output by the
+# instructions found at
+# https://docs.cloud.oracle.com/iaas/Content/API/Concepts/apisigningkey.htm#two.
+# However you choose to set this variable, it must contain the exact
+# private key contents, including newlines.
+OCI_AUTH_PRIVATEKEY=$(cat ~/.oci/oci_api_key.pem)
+
+# The OCID of your tenancy. See
+# https://docs.cloud.oracle.com/iaas/Content/API/Concepts/apisigningkey.htm#five
+# for more information.
+OCI_AUTH_TENANCY=
+
+# The OCID of your user. See
+# https://docs.cloud.oracle.com/iaas/Content/API/Concepts/apisigningkey.htm#five
+# for more information. For more on OCIDs in general, see
+# https://docs.cloud.oracle.com/iaas/Content/General/Concepts/identifiers.htm#one.
+OCI_AUTH_USER=
+
+# The OCID of the compartment containing the OCI object storage
+# service you wish to access. For more on OCIDs in general, see
+# https://docs.cloud.oracle.com/iaas/Content/General/Concepts/identifiers.htm#one.
+OCI_OBJECTSTORAGE_COMPARTMENT=
+
+# The region to use. See
+# https://docs.cloud.oracle.com/iaas/Content/General/Concepts/regions.htm
+# for more information.
+OCI_OBJECTSTORAGE_REGION=
+
+# The command below uses the variables above and should not need to be
+# modified.
+kubectl create secret generic ${SECRET_NAME} \
+--from-literal=OCI_AUTH_FINGERPRINT="${OCI_AUTH_FINGERPRINT}" \
+--from-literal=OCI_AUTH_PASSPHRASE="${OCI_AUTH_PASSPHRASE}" \
+--from-literal=OCI_AUTH_PRIVATEKEY="${OCI_AUTH_PRIVATEKEY}" \
+--from-literal=OCI_AUTH_TENANCY="${OCI_AUTH_TENANCY}" \
+--from-literal=OCI_AUTH_USER="${OCI_AUTH_USER}" \
+--from-literal=OCI_OBJECTSTORAGE_COMPARTMENT="${OCI_OBJECTSTORAGE_COMPARTMENT}" \
+--from-literal=OCI_OBJECTSTORAGE_REGION="${OCI_OBJECTSTORAGE_REGION}"
diff --git a/examples/integrations/cdi/oci-objectstorage/src/main/resources/META-INF/beans.xml b/examples/integrations/cdi/oci-objectstorage/src/main/resources/META-INF/beans.xml
new file mode 100644
index 00000000000..607db5743cc
--- /dev/null
+++ b/examples/integrations/cdi/oci-objectstorage/src/main/resources/META-INF/beans.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
diff --git a/examples/integrations/cdi/oci-objectstorage/src/main/resources/META-INF/microprofile-config.properties b/examples/integrations/cdi/oci-objectstorage/src/main/resources/META-INF/microprofile-config.properties
new file mode 100644
index 00000000000..254b9341b77
--- /dev/null
+++ b/examples/integrations/cdi/oci-objectstorage/src/main/resources/META-INF/microprofile-config.properties
@@ -0,0 +1,22 @@
+#
+# Copyright (c) 2018 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.
+#
+
+oci.objectstorage.namespace=${oci.objectstorage.namespaceName}
+
+
+# Microprofile server properties
+server.port=8080
+server.host=0.0.0.0
diff --git a/examples/integrations/cdi/oci-objectstorage/src/main/spotbugs/exclusions.xml b/examples/integrations/cdi/oci-objectstorage/src/main/spotbugs/exclusions.xml
new file mode 100644
index 00000000000..1bf71bd7d24
--- /dev/null
+++ b/examples/integrations/cdi/oci-objectstorage/src/main/spotbugs/exclusions.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
diff --git a/examples/integrations/cdi/pom.xml b/examples/integrations/cdi/pom.xml
new file mode 100644
index 00000000000..cca8a77ecb9
--- /dev/null
+++ b/examples/integrations/cdi/pom.xml
@@ -0,0 +1,80 @@
+
+
+
+ 4.0.0
+
+ io.helidon.integrations.examples
+ helidon-integrations-examples-project
+ pom
+
+ Helidon Integrations Examples Project
+ Helidon Integrations Examples Project
+
+
+ io.helidon.examples
+ helidon-examples-project
+ 0.10.3-SNAPSHOT
+ ../../pom.xml
+
+
+
+
+
+ ${project.groupId}
+ helidon-integrations-examples-datasource-hikaricp
+ ${project.version}
+ jar
+
+
+ ${project.groupId}
+ helidon-integrations-examples-jedis
+ ${project.version}
+ jar
+
+
+ ${project.groupId}
+ helidon-integrations-examples-oci-objectstorage
+ ${project.version}
+ jar
+
+
+ io.helidon.microprofile.config
+ helidon-microprofile-config-cdi
+ jar
+ ${project.version}
+
+
+ io.helidon.microprofile.server
+ helidon-microprofile-server
+ jar
+ ${project.version}
+
+
+
+
+
+ datasource-hikaricp
+ jedis
+ oci-objectstorage
+
+
+
diff --git a/examples/pom.xml b/examples/pom.xml
index ab99267a448..6511f6ae946 100644
--- a/examples/pom.xml
+++ b/examples/pom.xml
@@ -34,5 +34,6 @@
helidon-quickstart-sehelidon-quickstart-mptodos
+ integrations/cdi
diff --git a/integrations/README.adoc b/integrations/README.adoc
new file mode 100644
index 00000000000..2c8a6549918
--- /dev/null
+++ b/integrations/README.adoc
@@ -0,0 +1,18 @@
+= Helidon Integrations
+
+The Helidon Integrations project contains adapter code that integrates
+various useful external services into Helidon MicroProfile.
+
+== `serviceconfiguration`
+
+The `serviceconfiguration` subproject provides mechanisms for
+automatically configuring and in some cases provisioning services.
+
+== `cdi`
+
+The `cdi` subproject contains CDI
+http://docs.jboss.org/cdi/spec/2.0/cdi-spec.html#spi[portable
+extensions] that integrate various external services into CDI
+containers. Some subprojects make use of the `serviceconfiguration`
+subproject described above.
+
diff --git a/integrations/cdi/README.adoc b/integrations/cdi/README.adoc
new file mode 100644
index 00000000000..302dac87083
--- /dev/null
+++ b/integrations/cdi/README.adoc
@@ -0,0 +1,20 @@
+= Helidon CDI Integrations
+
+This subproject contains
+http://docs.jboss.org/cdi/spec/2.0/cdi-spec.html#spi[CDI portable
+extensions] that provide convenient integrations with popular
+libraries and services.
+
+* link:datasource-hikaricp[Datasource using HikariCP]: inject
+ https://docs.oracle.com/javase/8/docs/api/javax/sql/DataSource.html[`DataSource`]
+ objects into your CDI-based application that are backed by the
+ http://brettwooldridge.github.io/HikariCP/[Hikari connection pool].
+
+* link:jedis-cdi[Jedis Client]: inject
+ https://github.com/xetorthio/jedis#jedis[Jedis]
+ client objects into your CDI-based application.
+
+* link:oci-objectstorage-cdi[Oracle Cloud Infrastructure Object Storage]: inject an
+ https://cloud.oracle.com/storage/object-storage/features[OCI Object Storage]
+ client into your CDI-based application.
+
diff --git a/integrations/cdi/datasource-hikaricp/pom.xml b/integrations/cdi/datasource-hikaricp/pom.xml
new file mode 100644
index 00000000000..f07946c672c
--- /dev/null
+++ b/integrations/cdi/datasource-hikaricp/pom.xml
@@ -0,0 +1,123 @@
+
+
+
+ 4.0.0
+
+ helidon-integrations-cdi-datasource-hikaricp
+
+ Helidon HikariCP DataSource CDI Integration
+ ${project.name}
+
+
+ io.helidon.integrations.cdi
+ helidon-integrations-cdi-project
+ 0.10.3-SNAPSHOT
+
+
+
+
+
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+ test
+
+
+ org.hamcrest
+ hamcrest-all
+ test
+
+
+ org.jboss.weld.se
+ weld-se-core
+ test
+
+
+ org.slf4j
+ slf4j-simple
+ test
+
+
+
+
+
+ io.helidon.serviceconfiguration
+ helidon-serviceconfiguration-hikaricp-accs
+ runtime
+ true
+
+
+ io.helidon.serviceconfiguration
+ helidon-serviceconfiguration-hikaricp-localhost
+ runtime
+ true
+
+
+ org.jboss
+ jandex
+ runtime
+ true
+
+
+ io.helidon.microprofile.config
+ helidon-microprofile-config-cdi
+ runtime
+ true
+
+
+
+
+
+ javax.enterprise
+ cdi-api
+ provided
+
+
+
+
+
+ io.helidon.serviceconfiguration
+ helidon-serviceconfiguration-config-source
+ compile
+
+
+ io.helidon.serviceconfiguration
+ helidon-serviceconfiguration-hikaricp
+ compile
+
+
+ com.zaxxer
+ HikariCP
+ compile
+
+
+ org.eclipse.microprofile.config
+ microprofile-config-api
+ compile
+
+
+
+
+ package
+
+
+
diff --git a/integrations/cdi/datasource-hikaricp/src/main/java/io/helidon/integrations/datasource/hikaricp/cdi/HikariCPBackedDataSourceExtension.java b/integrations/cdi/datasource-hikaricp/src/main/java/io/helidon/integrations/datasource/hikaricp/cdi/HikariCPBackedDataSourceExtension.java
new file mode 100644
index 00000000000..574f473206e
--- /dev/null
+++ b/integrations/cdi/datasource-hikaricp/src/main/java/io/helidon/integrations/datasource/hikaricp/cdi/HikariCPBackedDataSourceExtension.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2018 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.
+ */
+package io.helidon.integrations.datasource.hikaricp.cdi;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Objects;
+import java.util.Properties;
+import java.util.Set;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.literal.NamedLiteral;
+import javax.enterprise.inject.spi.AfterBeanDiscovery;
+import javax.enterprise.inject.spi.Extension;
+import javax.enterprise.inject.spi.InjectionPoint;
+import javax.enterprise.inject.spi.ProcessInjectionPoint;
+import javax.inject.Named;
+import javax.sql.DataSource;
+
+import com.zaxxer.hikari.HikariConfig;
+import com.zaxxer.hikari.HikariDataSource;
+import org.eclipse.microprofile.config.Config;
+import org.eclipse.microprofile.config.spi.ConfigSource;
+
+/**
+ * An {@link Extension} that arranges for named {@link DataSource}
+ * injection points to be satisfied.
+ */
+public class HikariCPBackedDataSourceExtension implements Extension {
+
+ private final Set dataSourceNames;
+
+ /**
+ * Creates a new {@link HikariCPBackedDataSourceExtension}.
+ */
+ public HikariCPBackedDataSourceExtension() {
+ super();
+ this.dataSourceNames = new HashSet<>();
+ }
+
+ private void processInjectionPoint(@Observes final ProcessInjectionPoint, T> event) {
+ if (event != null) {
+ final InjectionPoint injectionPoint = event.getInjectionPoint();
+ if (injectionPoint != null) {
+ final Type type = injectionPoint.getType();
+ if (type instanceof Class && DataSource.class.isAssignableFrom((Class>) type)) {
+ final Set qualifiers = injectionPoint.getQualifiers();
+ for (final Annotation qualifier : qualifiers) {
+ if (qualifier instanceof Named) {
+ final String dataSourceName = ((Named) qualifier).value();
+ if (dataSourceName != null && !dataSourceName.isEmpty()) {
+ this.dataSourceNames.add(dataSourceName);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private void afterBeanDiscovery(@Observes final AfterBeanDiscovery event) {
+ if (event != null) {
+ for (final String dataSourceName : this.dataSourceNames) {
+ event.addBean()
+ .addQualifier(NamedLiteral.of(dataSourceName)) // ...and Default and Any?
+ .addTransitiveTypeClosure(HikariDataSource.class)
+ .beanClass(HikariDataSource.class)
+ .scope(ApplicationScoped.class)
+ .produceWith(beans -> new HikariDataSource(new HikariConfig(toProperties(dataSourceName,
+ beans.select(Config.class).get()))))
+ .disposeWith((dataSource, beans) -> dataSource.close());
+ }
+ }
+ }
+
+ private static Properties toProperties(final String dataSourceName, final Config config) {
+ Objects.requireNonNull(dataSourceName);
+ Objects.requireNonNull(config);
+ final Properties returnValue = new Properties();
+
+ // Look up a required one to bootstrap the whole thing if such
+ // bootstrapping happens to be necessary.
+ config.getValue("javax.sql.DataSource." + dataSourceName + ".dataSourceClassName", String.class);
+
+ // The MicroProfile Config specification does not say whether
+ // property names must be cached or must not be cached
+ // (https://github.com/eclipse/microprofile-config/issues/370).
+ // It is implied in the MicroProfile Google group
+ // (https://groups.google.com/d/msg/microprofile/tvjgSR9qL2Q/M2TNUQrOAQAJ),
+ // but not in the specification, that ConfigSources can be
+ // mutable and dynamic. Consequently one would expect their
+ // property names to come and go. Because of this we have to
+ // make sure to get all property names from all ConfigSources
+ // "by hand".
+ //
+ // (The MicroProfile Config specification also does not say
+ // whether a ConfigSource is thread-safe
+ // (https://github.com/eclipse/microprofile-config/issues/369),
+ // so iteration over its coming-and-going dynamic property
+ // names may be problematic, but there's nothing we can do.)
+ //
+ // As of this writing, the Helidon MicroProfile Config
+ // implementation caches all property names up front, which
+ // may not be correct, but is also not forbidden.
+
+ final Iterable extends String> propertyNames = getPropertyNames(config);
+ if (propertyNames != null) {
+ final String prefix = "javax.sql.DataSource." + dataSourceName + ".";
+ final int prefixLength = prefix.length();
+ for (final String propertyName : propertyNames) {
+ if (propertyName != null
+ && propertyName.length() > prefixLength
+ && propertyName.startsWith(prefix)) {
+ returnValue.setProperty(propertyName.substring(prefixLength), config.getValue(propertyName, String.class));
+ }
+ }
+ }
+ return returnValue;
+ }
+
+ private static Set getPropertyNames(final Config config) {
+ final Set returnValue;
+ if (config == null) {
+ returnValue = Collections.emptySet();
+ } else {
+ final Set propertyNames = getPropertyNames(config.getConfigSources());
+ if (propertyNames == null || propertyNames.isEmpty()) {
+ returnValue = Collections.emptySet();
+ } else {
+ returnValue = Collections.unmodifiableSet(propertyNames);
+ }
+ }
+ return returnValue;
+ }
+
+ private static Set getPropertyNames(final Iterable extends ConfigSource> configSources) {
+ final Set returnValue = new HashSet<>();
+ if (configSources != null) {
+ for (final ConfigSource configSource : configSources) {
+ if (configSource != null) {
+ final Set configSourcePropertyNames = configSource.getPropertyNames();
+ if (configSourcePropertyNames != null && !configSourcePropertyNames.isEmpty()) {
+ returnValue.addAll(configSourcePropertyNames);
+ }
+ }
+ }
+ }
+ return Collections.unmodifiableSet(returnValue);
+ }
+
+}
diff --git a/integrations/cdi/datasource-hikaricp/src/main/java/io/helidon/integrations/datasource/hikaricp/cdi/config/HikariCP.java b/integrations/cdi/datasource-hikaricp/src/main/java/io/helidon/integrations/datasource/hikaricp/cdi/config/HikariCP.java
new file mode 100644
index 00000000000..325e8a90a4e
--- /dev/null
+++ b/integrations/cdi/datasource-hikaricp/src/main/java/io/helidon/integrations/datasource/hikaricp/cdi/config/HikariCP.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2018 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.
+ */
+package io.helidon.integrations.datasource.hikaricp.cdi.config;
+
+import io.helidon.service.configuration.api.ServiceConfiguration;
+import io.helidon.service.configuration.microprofile.config.ServiceConfigurationConfigSource;
+
+/**
+ * A {@link ServiceConfigurationConfigSource} that sits atop the
+ * {@code hikaricp} {@link ServiceConfiguration} in effect (if there
+ * is one).
+ *
+ * @author Laird Nelson
+ */
+public final class HikariCP extends ServiceConfigurationConfigSource {
+
+ /**
+ * Creates a new {@link HikariCP}.
+ */
+ public HikariCP() {
+ super();
+ }
+
+}
diff --git a/integrations/cdi/datasource-hikaricp/src/main/java/io/helidon/integrations/datasource/hikaricp/cdi/config/package-info.java b/integrations/cdi/datasource-hikaricp/src/main/java/io/helidon/integrations/datasource/hikaricp/cdi/config/package-info.java
new file mode 100644
index 00000000000..e8ca5483138
--- /dev/null
+++ b/integrations/cdi/datasource-hikaricp/src/main/java/io/helidon/integrations/datasource/hikaricp/cdi/config/package-info.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2018 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.
+ */
+
+/**
+ * Provides classes and interfaces marrying MicroProfile Config
+ * constructs and {@link
+ * io.helidon.service.configuration.api.ServiceConfiguration}
+ * constructs for the Hikari Connection Pool.
+ */
+package io.helidon.integrations.datasource.hikaricp.cdi.config;
diff --git a/integrations/cdi/datasource-hikaricp/src/main/java/io/helidon/integrations/datasource/hikaricp/cdi/package-info.java b/integrations/cdi/datasource-hikaricp/src/main/java/io/helidon/integrations/datasource/hikaricp/cdi/package-info.java
new file mode 100644
index 00000000000..f20f96ab4f9
--- /dev/null
+++ b/integrations/cdi/datasource-hikaricp/src/main/java/io/helidon/integrations/datasource/hikaricp/cdi/package-info.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2018 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 integration for the Hikari
+ * connection pool.
+ */
+package io.helidon.integrations.datasource.hikaricp.cdi;
diff --git a/integrations/cdi/datasource-hikaricp/src/main/resources/META-INF/beans.xml b/integrations/cdi/datasource-hikaricp/src/main/resources/META-INF/beans.xml
new file mode 100644
index 00000000000..9e3d0906833
--- /dev/null
+++ b/integrations/cdi/datasource-hikaricp/src/main/resources/META-INF/beans.xml
@@ -0,0 +1,25 @@
+
+
+
+
diff --git a/integrations/cdi/datasource-hikaricp/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension b/integrations/cdi/datasource-hikaricp/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
new file mode 100644
index 00000000000..50f5852d5c8
--- /dev/null
+++ b/integrations/cdi/datasource-hikaricp/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
@@ -0,0 +1,14 @@
+# Copyright (c) 2018 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.
+io.helidon.integrations.datasource.hikaricp.cdi.HikariCPBackedDataSourceExtension
\ No newline at end of file
diff --git a/integrations/cdi/datasource-hikaricp/src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.ConfigSource b/integrations/cdi/datasource-hikaricp/src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.ConfigSource
new file mode 100644
index 00000000000..be24ff466e1
--- /dev/null
+++ b/integrations/cdi/datasource-hikaricp/src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.ConfigSource
@@ -0,0 +1,14 @@
+# Copyright (c) 2018 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.
+io.helidon.integrations.datasource.hikaricp.cdi.config.HikariCP
\ No newline at end of file
diff --git a/integrations/cdi/jedis-cdi/README.adoc b/integrations/cdi/jedis-cdi/README.adoc
new file mode 100644
index 00000000000..b66256fa4ae
--- /dev/null
+++ b/integrations/cdi/jedis-cdi/README.adoc
@@ -0,0 +1,90 @@
+= Helidon Jedis CDI Integration
+
+The Helidon Jedis CDI Integration project supplies a
+http://docs.jboss.org/cdi/spec/2.0/cdi-spec.html#spi[CDI portable
+extension] that lets the end user inject various
+https://github.com/xetorthio/jedis#jedis[Jedis] objects into her
+CDI-based application.
+
+== Installation
+
+Ensure that the Helidon Jedis CDI Integration project and its runtime
+dependencies are present on your application's runtime classpath.
+
+For Maven users, your `` stanza should look like this:
+
+[source,xml]
+----
+
+ io.helidon.integrations.cdi
+ helidon-integrations-cdi-jedis
+ 1.0.0
+ runtime
+
+----
+
+== Usage
+
+If you want to use a
+https://static.javadoc.io/redis.clients/jedis/2.9.0/redis/clients/jedis/JedisPool.html[`JedisPool`]
+named `orders` in your application code, simply inject it in the
+http://docs.jboss.org/cdi/spec/2.0/cdi-spec.html#injection_and_resolution[usual,
+idiomatic CDI way]. Here is a field injection example:
+
+[source,java]
+----
+@Inject
+@Named("orders")
+private JedisPool ordersPool;
+----
+
+And here is a constructor injection example:
+
+[source,java]
+----
+private final JedisPool ordersPool;
+
+@Inject
+public YourConstructor(@Named("orders") JedisPool pool) {
+ super();
+ this.ordersPool = pool;
+}
+----
+
+The Helidon Jedis CDI Integration project will satisfy this injection
+point with a
+https://static.javadoc.io/redis.clients/jedis/2.9.0/redis/clients/jedis/JedisPool.html[`JedisPool`]
+in
+http://docs.jboss.org/cdi/api/2.0/javax/enterprise/context/ApplicationScoped.html[application
+scope].
+
+To create it, the Helidon Jedis CDI Integration project will use
+https://static.javadoc.io/org.eclipse.microprofile.config/microprofile-config-api/1.3/index.html?overview-summary.html[MicroProfile
+Config] to locate its configuration.
+https://static.javadoc.io/org.eclipse.microprofile.config/microprofile-config-api/1.3/org/eclipse/microprofile/config/Config.html#getPropertyNames--[Property
+names] that start with `redis.clients.jedis.JedisPool.`_dataSourceName_`.` will
+be parsed, and the remaining portion of each such name will be treated
+as a Java bean property of `JedisPool`.
+
+So, for example, a System property with a name like this:
+
+----
+redis.clients.jedis.JedisPool.orders.port
+----
+
+...set to a value of:
+
+----
+6379
+----
+
+...together with other similarly-named properties will result
+ultimately in a `JedisPool` object injectable under the name `orders`
+with a `port` property set to `6379` like so:
+
+[source,java]
+----
+@Inject
+@Named("orders")
+private JedisPool pool;
+----
diff --git a/integrations/cdi/jedis-cdi/pom.xml b/integrations/cdi/jedis-cdi/pom.xml
new file mode 100644
index 00000000000..2effb3fe6bf
--- /dev/null
+++ b/integrations/cdi/jedis-cdi/pom.xml
@@ -0,0 +1,108 @@
+
+
+
+ 4.0.0
+
+ helidon-integrations-cdi-jedis
+
+ Helidon Jedis CDI Integration
+ ${project.name}
+
+
+ io.helidon.integrations.cdi
+ helidon-integrations-cdi-project
+ 0.10.3-SNAPSHOT
+
+
+
+
+
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+ test
+
+
+
+ org.hamcrest
+ hamcrest-all
+ test
+
+
+
+ org.jboss.weld.se
+ weld-se-core
+ test
+
+
+
+ org.slf4j
+ slf4j-simple
+ test
+
+
+
+
+
+ org.jboss
+ jandex
+ runtime
+ true
+
+
+
+ io.helidon.microprofile.config
+ helidon-microprofile-config-cdi
+ runtime
+ true
+
+
+
+
+
+ javax.enterprise
+ cdi-api
+ provided
+
+
+
+
+
+ redis.clients
+ jedis
+ compile
+
+
+
+ org.eclipse.microprofile.config
+ microprofile-config-api
+ compile
+
+
+
+
+
+ package
+
+
+
diff --git a/integrations/cdi/jedis-cdi/src/main/java/io/helidon/integrations/jedis/cdi/JedisExtension.java b/integrations/cdi/jedis-cdi/src/main/java/io/helidon/integrations/jedis/cdi/JedisExtension.java
new file mode 100644
index 00000000000..fa3b266d9e2
--- /dev/null
+++ b/integrations/cdi/jedis-cdi/src/main/java/io/helidon/integrations/jedis/cdi/JedisExtension.java
@@ -0,0 +1,534 @@
+/*
+ * Copyright (c) 2018 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.
+ */
+package io.helidon.integrations.jedis.cdi;
+
+import java.beans.BeanInfo;
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.context.Dependent;
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.CreationException;
+import javax.enterprise.inject.Default;
+import javax.enterprise.inject.Instance;
+import javax.enterprise.inject.literal.NamedLiteral;
+import javax.enterprise.inject.spi.AfterBeanDiscovery;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.InjectionPoint;
+import javax.enterprise.inject.spi.ProcessInjectionPoint;
+import javax.inject.Named;
+import javax.inject.Provider;
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLParameters;
+import javax.net.ssl.SSLSocketFactory;
+
+import org.eclipse.microprofile.config.Config;
+import redis.clients.jedis.Jedis;
+import redis.clients.jedis.JedisPool;
+import redis.clients.jedis.JedisPoolConfig;
+import redis.clients.jedis.Protocol;
+
+/**
+ * An {@link javax.enterprise.inject.spi.Extension} providing CDI
+ * integration for the Jedis
+ * Redis client.
+ *
+ * @see Using
+ * Jedis in a multithreaded environment
+ */
+public class JedisExtension implements javax.enterprise.inject.spi.Extension {
+
+ private static final Map, Map>> CONVERSION_TYPES = new LinkedHashMap<>();
+
+ static {
+
+ final Map> jedisPoolConversionTypes = new HashMap<>();
+ jedisPoolConversionTypes.put("host", String.class);
+ jedisPoolConversionTypes.put("port", Integer.class);
+ jedisPoolConversionTypes.put("connectionTimeout", Integer.class);
+ jedisPoolConversionTypes.put("socketTimeout", Integer.class);
+ jedisPoolConversionTypes.put("password", String.class);
+ jedisPoolConversionTypes.put("database", Integer.class);
+ jedisPoolConversionTypes.put("clientName", String.class);
+ jedisPoolConversionTypes.put("ssl", Boolean.class);
+ CONVERSION_TYPES.put(JedisPool.class, jedisPoolConversionTypes);
+
+ }
+
+ private final Set instanceNames;
+
+ /**
+ * Creates a new {@link JedisExtension}.
+ */
+ public JedisExtension() {
+ super();
+ this.instanceNames = new HashSet<>();
+ }
+
+ private void processJedisInjectionPoint(@Observes final ProcessInjectionPoint, T> e) {
+ if (e != null) {
+ final InjectionPoint injectionPoint = e.getInjectionPoint();
+ if (injectionPoint != null) {
+ final Type type = injectionPoint.getType();
+ assert type instanceof Class;
+ assert Jedis.class.isAssignableFrom((Class>) type);
+ final Set qualifiers = injectionPoint.getQualifiers();
+ for (final Annotation qualifier : qualifiers) {
+ final String instanceName;
+ if (qualifier instanceof Default) {
+ instanceName = "default";
+ } else if (qualifier instanceof Named) {
+ instanceName = ((Named) qualifier).value();
+ } else {
+ instanceName = null;
+ }
+ if (instanceName != null && !instanceName.isEmpty()) {
+ this.instanceNames.add(instanceName);
+ }
+ }
+ }
+ }
+ }
+
+ private > void processJedisProviderInjectionPoint(@Observes final ProcessInjectionPoint, T> e) {
+ if (e != null) {
+ final InjectionPoint injectionPoint = e.getInjectionPoint();
+ if (injectionPoint != null) {
+ final Type type = injectionPoint.getType();
+ assert type instanceof Class;
+ assert Provider.class.isAssignableFrom((Class>) type);
+ final Set qualifiers = injectionPoint.getQualifiers();
+ for (final Annotation qualifier : qualifiers) {
+ final String instanceName;
+ if (qualifier instanceof Default) {
+ instanceName = "default";
+ } else if (qualifier instanceof Named) {
+ instanceName = ((Named) qualifier).value();
+ } else {
+ instanceName = null;
+ }
+ if (instanceName != null && !instanceName.isEmpty()) {
+ this.instanceNames.add(instanceName);
+ }
+ }
+ }
+ }
+ }
+
+
+ private void processJedisPoolInjectionPoint(@Observes final ProcessInjectionPoint, T> e) {
+ if (e != null) {
+ final InjectionPoint injectionPoint = e.getInjectionPoint();
+ if (injectionPoint != null) {
+ final Type type = injectionPoint.getType();
+ assert type instanceof Class;
+ assert JedisPool.class.isAssignableFrom((Class>) type);
+ final Set qualifiers = injectionPoint.getQualifiers();
+ for (final Annotation qualifier : qualifiers) {
+ final String instanceName;
+ if (qualifier instanceof Default) {
+ instanceName = "default";
+ } else if (qualifier instanceof Named) {
+ instanceName = ((Named) qualifier).value();
+ } else {
+ instanceName = null;
+ }
+ if (instanceName != null && !instanceName.isEmpty()) {
+ this.instanceNames.add(instanceName);
+ }
+ }
+ }
+ }
+ }
+
+ @SuppressWarnings("checkstyle:linelength")
+ private > void processJedisPoolProviderInjectionPoint(@Observes final ProcessInjectionPoint, T> e) {
+ if (e != null) {
+ final InjectionPoint injectionPoint = e.getInjectionPoint();
+ if (injectionPoint != null) {
+ final Type type = injectionPoint.getType();
+ assert type instanceof Class;
+ assert Provider.class.isAssignableFrom((Class>) type);
+ final Set qualifiers = injectionPoint.getQualifiers();
+ for (final Annotation qualifier : qualifiers) {
+ final String instanceName;
+ if (qualifier instanceof Default) {
+ instanceName = "default";
+ } else if (qualifier instanceof Named) {
+ instanceName = ((Named) qualifier).value();
+ } else {
+ instanceName = null;
+ }
+ if (instanceName != null && !instanceName.isEmpty()) {
+ this.instanceNames.add(instanceName);
+ }
+ }
+ }
+ }
+ }
+
+ private void processJedisPoolConfigInjectionPoint(@Observes final ProcessInjectionPoint, T> e) {
+ if (e != null) {
+ final InjectionPoint injectionPoint = e.getInjectionPoint();
+ if (injectionPoint != null) {
+ final Type type = injectionPoint.getType();
+ assert type instanceof Class;
+ assert JedisPoolConfig.class.isAssignableFrom((Class>) type);
+ final Set qualifiers = injectionPoint.getQualifiers();
+ for (final Annotation qualifier : qualifiers) {
+ final String instanceName;
+ if (qualifier instanceof Default) {
+ instanceName = "default";
+ } else if (qualifier instanceof Named) {
+ instanceName = ((Named) qualifier).value();
+ } else {
+ instanceName = null;
+ }
+ if (instanceName != null && !instanceName.isEmpty()) {
+ this.instanceNames.add(instanceName);
+ }
+ }
+ }
+ }
+ }
+
+ @SuppressWarnings("checkstyle:linelength")
+ private > void processJedisPoolConfigProviderInjectionPoint(@Observes final ProcessInjectionPoint, T> e) {
+ if (e != null) {
+ final InjectionPoint injectionPoint = e.getInjectionPoint();
+ if (injectionPoint != null) {
+ final Type type = injectionPoint.getType();
+ assert type instanceof Class;
+ assert Provider.class.isAssignableFrom((Class>) type);
+ final Set qualifiers = injectionPoint.getQualifiers();
+ for (final Annotation qualifier : qualifiers) {
+ final String instanceName;
+ if (qualifier instanceof Default) {
+ instanceName = "default";
+ } else if (qualifier instanceof Named) {
+ instanceName = ((Named) qualifier).value();
+ } else {
+ instanceName = null;
+ }
+ if (instanceName != null && !instanceName.isEmpty()) {
+ this.instanceNames.add(instanceName);
+ }
+ }
+ }
+ }
+ }
+
+ private void addBeans(@Observes final AfterBeanDiscovery event, final BeanManager beanManager) throws IntrospectionException {
+ if (event != null && beanManager != null) {
+ for (final String instanceName : this.instanceNames) {
+ if (instanceName != null) {
+
+ final Set qualifiers;
+ if (instanceName.equals("default")) {
+ qualifiers = Collections.singleton(Default.Literal.INSTANCE);
+ } else {
+ qualifiers = Collections.singleton(NamedLiteral.of(instanceName));
+ }
+ final Annotation[] qualifiersArray = qualifiers.toArray(new Annotation[qualifiers.size()]);
+
+ event.addBean()
+ .addTransitiveTypeClosure(JedisPoolConfig.class)
+ .scope(ApplicationScoped.class)
+ .addQualifiers(qualifiers)
+ .produceWith((instance) -> {
+ final JedisPoolConfig returnValue = new JedisPoolConfig();
+ try {
+ this.configure(instance.select(Config.class).get(),
+ returnValue,
+ JedisPoolConfig.class,
+ instanceName);
+ } catch (final IntrospectionException | ReflectiveOperationException e) {
+ throw new CreationException(e.getMessage(), e);
+ }
+ return returnValue;
+ });
+
+ event.addBean()
+ .addTransitiveTypeClosure(JedisPool.class)
+ .scope(ApplicationScoped.class)
+ .addQualifiers(qualifiers)
+ .produceWith(instance -> {
+ return produceJedisPool(instance, instanceName, qualifiersArray);
+ })
+ .disposeWith((p, instance) -> p.destroy());
+
+ event.addBean()
+ .addTransitiveTypeClosure(Jedis.class)
+ .scope(Dependent.class)
+ .addQualifiers(qualifiers)
+ .produceWith(instance ->
+ instance.select(JedisPool.class, qualifiersArray).get().getResource())
+ .disposeWith((j, instance) -> j.close());
+ }
+ }
+ }
+ }
+
+ private static JedisPool produceJedisPool(final Instance