diff --git a/java/autonomousdb-wallet-secret-sample/README.md b/java/autonomousdb-wallet-secret-sample/README.md new file mode 100644 index 00000000..e75c467e --- /dev/null +++ b/java/autonomousdb-wallet-secret-sample/README.md @@ -0,0 +1,55 @@ +# Java Sample Using an Oracle Wallet as a Kubernetes Secret + +In this minimalistic Java sample we show you how to use a wallet downloaded by the [Oracle Database Operator for Kubernetes](https://github.com/oracle/oracle-database-operator). + +An example is also provided to use a wallet downloaded from the Cloud Console. + +This microservice can also be used to validate connectivity with the database by looking at its log or issuing http requests. + +## Configuration + +To configure the database wallet you only need to update [src/main/k8s/app.yaml](src/main/k8s/app.yaml) to use the same secret name that you used to download the wallet with the Operator. + +The key part to understand its simplicity is that the deployment file uses the same mount path that the container configures in the oracle.net.wallet_location VM parameter [src/main/docker/Dockerfile](src/main/docker/Dockerfile). You don't need to change this file if you are going to use the example's mount path. + +If you want to configure a previously downloaded wallet you can just create the secret (and use the same secret name for the Pod's spec) pointing to the directory where you unzipped the wallet: + +```sh +kubectl create secret generic instance-wallet --from-file= +``` +The Java microservice retrieves username, password and url also from a secret. To create it you can use the following script as an example: + +```sh +kubectl create secret generic user-jdbc \ + --from-literal=user='' \ + --from-literal=password='' \ + --from-literal=url='jdbc:oracle:thin:@' +``` +## Install, build and deploy + +It is as simple as to build the maven project, create the docker image and deploy the Pod: + +```sh +mvn clean install +docker build -t adb-health-check target +kubectl apply -f target/app.yaml +``` + +## Usage + +After successsful installation you can validate first connectivity through the Pod's log: + +```sh +kubectl logs pods/adb-health-check +'Database version: Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production' +'Version 19.13.0.1.0' +'Retrieveing connections: true' +``` + +And you can use the Pod's http listener to validate connectivity (for local tests you can just port forward a local port): + +```sh +kubectl port-forward adb-health-check 8080:8080 & +curl -X GET http://localhost:8080 +'{"database-version": "19.0", "database-sysdate": "2021-10-06 15:38:43"}' +``` diff --git a/java/autonomousdb-wallet-secret-sample/pom.xml b/java/autonomousdb-wallet-secret-sample/pom.xml new file mode 100644 index 00000000..c4ae17f2 --- /dev/null +++ b/java/autonomousdb-wallet-secret-sample/pom.xml @@ -0,0 +1,162 @@ + + 4.0.0 + adb-health-check + adb-health-check + 0.0.1-SNAPSHOT + demok8s + + + adb-health-check + com.oracle.healthcheck.Client + 11 + ${maven.compiler.source} + libs + ${project.build.directory}/${libs.classpath.prefix} + UTF-8 + UTF-8 + -Dfile.encoding=UTF-8 + etc/checkstyle.xml + + + + + ${project.artifactId} + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + + org.apache.maven.plugins + maven-surefire-plugin + 2.19.1 + + + org.junit.platform + junit-platform-surefire-provider + 1.1.0 + + + + + org.apache.maven.plugins + maven-dependency-plugin + 3.1.1 + + + org.apache.maven.plugins + maven-resources-plugin + 3.1.0 + + + org.apache.maven.plugins + maven-jar-plugin + 3.1.2 + + + + true + ${libs.classpath.prefix} + ${mainClass} + + + + + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + copy-dependencies + prepare-package + + copy-dependencies + + + ${copied.libs.dir} + false + false + true + true + runtime + test + + + + + + org.apache.maven.plugins + maven-resources-plugin + + + copy-dockerfile + process-resources + + copy-resources + + + ${project.build.directory} + + + src/main/docker + true + + Dockerfile + + + + true + src/main/k8s + + app.yaml + + + + + + + + + + + + + com.oracle.database.jdbc + ojdbc11 + 21.3.0.0 + + + com.oracle.database.jdbc + ucp + 21.3.0.0 + + + com.oracle.database.ha + ons + 21.3.0.0 + + + com.oracle.database.security + oraclepki + 21.3.0.0 + + + com.oracle.database.security + osdt_core + 21.3.0.0 + + + com.oracle.database.security + osdt_cert + 21.3.0.0 + + + \ No newline at end of file diff --git a/java/autonomousdb-wallet-secret-sample/src/main/docker/Dockerfile b/java/autonomousdb-wallet-secret-sample/src/main/docker/Dockerfile new file mode 100644 index 00000000..eabb2099 --- /dev/null +++ b/java/autonomousdb-wallet-secret-sample/src/main/docker/Dockerfile @@ -0,0 +1,16 @@ +FROM openjdk:11 + +RUN mkdir /app +COPY libs /app/libs +COPY ${project.artifactId}.jar /app + +# The driver will look for the wallet in folder /app/wallet +# This value must match the one in the mountPath of the container +# Reference in src/main/k8s/app.yaml + +CMD ["java", \ + "-Doracle.net.tns_admin=/app/wallet", \ + "-Doracle.net.wallet_location=/app/wallet", \ + "-Doracle.jdbc.fanEnabled=false", \ + "-jar", \ + "/app/${project.artifactId}.jar"] \ No newline at end of file diff --git a/java/autonomousdb-wallet-secret-sample/src/main/java/com/oracle/healthcheck/Client.java b/java/autonomousdb-wallet-secret-sample/src/main/java/com/oracle/healthcheck/Client.java new file mode 100644 index 00000000..72c8e471 --- /dev/null +++ b/java/autonomousdb-wallet-secret-sample/src/main/java/com/oracle/healthcheck/Client.java @@ -0,0 +1,107 @@ +/* +** Copyright (c) 2021 Oracle and/or its affiliates. +** +** The Universal Permissive License (UPL), Version 1.0 +** +** Subject to the condition set forth below, permission is hereby granted to any +** person obtaining a copy of this software, associated documentation and/or data +** (collectively the "Software"), free of charge and under any and all copyright +** rights in the Software, and any and all patent rights owned or freely +** licensable by each licensor hereunder covering either (i) the unmodified +** Software as contributed to or provided by such licensor, or (ii) the Larger +** Works (as defined below), to deal in both +** +** (a) the Software, and +** (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if +** one is included with the Software (each a "Larger Work" to which the Software +** is contributed by such licensors), +** +** without restriction, including without limitation the rights to copy, create +** derivative works of, display, perform, and distribute the Software and make, +** use, sell, offer for sale, import, export, have made, and have sold the +** Software and the Larger Work(s), and to sublicense the foregoing rights on +** either these or other terms. +** +** This license is subject to the following condition: +** The above copyright notice and either this complete permission notice or at +** a minimum a reference to the UPL must be included in all copies or +** substantial portions of the Software. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +** SOFTWARE. +*/ + +package com.oracle.healthcheck; + +import java.io.IOException; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; + +import javax.net.ssl.HttpsURLConnection; + +import com.sun.net.httpserver.HttpServer; + +import oracle.jdbc.internal.OracleConnection; +import oracle.jdbc.pool.OracleDataSource; + +public class Client { + + public static void main(String[] args) + throws SQLException, IOException { + + // Retrieve user credentials from environment variables. + // They are set in the Pod from a Secret in src/main/k8s/app.yaml + OracleDataSource ds = new OracleDataSource(); + ds.setURL(System.getenv("url")); + ds.setUser(System.getenv("user")); + ds.setPassword(System.getenv("password")); + + // Validate and log connection + OracleConnection connection = (OracleConnection) ds.getConnection(); + System.out.println("Retrieving connections: " + connection.isValid(0)); + System.out + .println("Database version: " + + connection.getMetaData().getDatabaseMajorVersion() + "." + + connection.getMetaData().getDatabaseMinorVersion()); + + // Start an HttpServer listening on port 8080 to send database status. + HttpServer server = HttpServer.create(new InetSocketAddress(8080), 0); + server.createContext("/", (httpExchange) -> { + + try (OracleConnection conn = (OracleConnection) ds.getConnection(); + Statement stmt = conn.createStatement()) { + + // Database message: version and sysdate + ResultSet rs = stmt.executeQuery("select SYSDATE from dual"); + rs.next(); + + String message = "{\"database-version\": \"" + + conn.getMetaData().getDatabaseMajorVersion() + "." + + conn.getMetaData().getDatabaseMinorVersion() + + "\", \"database-sysdate\": \"" + rs.getString(1) + "\"}"; + System.out.println(message); + + // Send message, status and flush + httpExchange + .sendResponseHeaders(HttpsURLConnection.HTTP_OK, message.length()); + OutputStream os = httpExchange.getResponseBody(); + os.write(message.getBytes()); + os.close(); + + } catch (SQLException e) { + e.printStackTrace(); + } + }); + + server.setExecutor(null); + server.start(); + } +} \ No newline at end of file diff --git a/java/autonomousdb-wallet-secret-sample/src/main/k8s/app.yaml b/java/autonomousdb-wallet-secret-sample/src/main/k8s/app.yaml new file mode 100644 index 00000000..6ba5a744 --- /dev/null +++ b/java/autonomousdb-wallet-secret-sample/src/main/k8s/app.yaml @@ -0,0 +1,38 @@ +kind: Pod +apiVersion: v1 +metadata: + name: adb-health-check +spec: + volumes: + - name: wallet + secret: +# Either the secret name of the downloaded wallet with the kubernetes operator +# TODO add link to operator +# Or the secret name holding the wallet created ad-hoc: +# kubectl create secret generic instance-wallet --from-file= + secretName: instance-wallet + containers: + - name: adb-health-check + image: adb-health-check + imagePullPolicy: IfNotPresent + volumeMounts: + - name: wallet +# mountPath must coincide with the one selected for oracle.net.wallet_location + mountPath: "/app/wallet" + readOnly: true + env: + - name: user + valueFrom: + secretKeyRef: + name: user-jdbc + key: user + - name: password + valueFrom: + secretKeyRef: + name: user-jdbc + key: password + - name: url + valueFrom: + secretKeyRef: + name: user-jdbc + key: url \ No newline at end of file