Skip to content

Commit 21ab75a

Browse files
committed
Sample to be used with the Wallet downloaded with the Kubernetes Operator (or a new one stored as a Kubernetes Secret)
Signed-off-by: psilberk <psilberkasten@gmail.com>
1 parent 283863c commit 21ab75a

File tree

5 files changed

+341
-0
lines changed

5 files changed

+341
-0
lines changed
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# Java Sample Using an Oracle Wallet as a Kubernetes Secret
2+
3+
In this minimalistic Java sample we show you how to use a wallet downloaded by the Oracle Database Operator for Kubernetes.
4+
5+
An example is also provided to use a wallet downloaded from the Cloud Console.
6+
7+
This microservice can also be used to validate connectivity with the database by looking at its log or issuing http requests.
8+
9+
## Configuration
10+
11+
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.
12+
13+
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.
14+
15+
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:
16+
17+
```sh
18+
kubectl create secret generic database-wallet --from-file=<path-to-wallets-unzipped-folder>
19+
```
20+
The Java microservice retrieves username, password and url also from a secret. To create it you can use the following script as an example:
21+
22+
```sh
23+
kubectl create secret generic user-jdbc \
24+
--from-literal=user='<username>' \
25+
--from-literal=password='<password>' \
26+
--from-literal=url='jdbc:oracle:thin:@<alias-in-tnsnames.ora>'
27+
```
28+
## Install, build and deploy
29+
30+
It is as simple as to build the maven project, create the docker image and deploy the Pod:
31+
32+
```sh
33+
mvn clean install
34+
docker build -t adb-health-check target
35+
kubectl apply -f target/app.yaml
36+
```
37+
38+
## Usage
39+
40+
After successsful installation you can validate first connectivity through the Pod's log:
41+
42+
```sh
43+
kubectl logs pods/adb-health-check
44+
'Database version: Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production'
45+
'Version 19.13.0.1.0'
46+
'Retrieveing connections: true'
47+
```
48+
49+
And you can use the Pod's http listener to validate connectivity (for local tests you can just port forward a local port):
50+
51+
```sh
52+
kubectl port-forward adb-health-check 8080:8080 &
53+
curl -X GET http://localhost:8080
54+
'{"database-version": "19.0", "database-sysdate": "2021-10-06 15:38:43"}'
55+
```
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
<project xmlns="http://maven.apache.org/POM/4.0.0"
2+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
4+
<modelVersion>4.0.0</modelVersion>
5+
<groupId>adb-health-check</groupId>
6+
<artifactId>adb-health-check</artifactId>
7+
<version>0.0.1-SNAPSHOT</version>
8+
<name>demok8s</name>
9+
10+
<properties>
11+
<package>adb-health-check</package>
12+
<mainClass>com.oracle.healthcheck.Client</mainClass>
13+
<maven.compiler.source>11</maven.compiler.source>
14+
<maven.compiler.target>${maven.compiler.source}</maven.compiler.target>
15+
<libs.classpath.prefix>libs</libs.classpath.prefix>
16+
<copied.libs.dir>${project.build.directory}/${libs.classpath.prefix}</copied.libs.dir>
17+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
18+
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
19+
<argLine>-Dfile.encoding=UTF-8</argLine>
20+
<checkstyle.config.location>etc/checkstyle.xml</checkstyle.config.location>
21+
</properties>
22+
23+
24+
<build>
25+
<finalName>${project.artifactId}</finalName>
26+
<pluginManagement>
27+
<plugins>
28+
<plugin>
29+
<groupId>org.apache.maven.plugins</groupId>
30+
<artifactId>maven-compiler-plugin</artifactId>
31+
<version>3.8.1</version>
32+
</plugin>
33+
<plugin>
34+
<groupId>org.apache.maven.plugins</groupId>
35+
<artifactId>maven-surefire-plugin</artifactId>
36+
<version>2.19.1</version>
37+
<dependencies>
38+
<dependency>
39+
<groupId>org.junit.platform</groupId>
40+
<artifactId>junit-platform-surefire-provider</artifactId>
41+
<version>1.1.0</version>
42+
</dependency>
43+
</dependencies>
44+
</plugin>
45+
<plugin>
46+
<groupId>org.apache.maven.plugins</groupId>
47+
<artifactId>maven-dependency-plugin</artifactId>
48+
<version>3.1.1</version>
49+
</plugin>
50+
<plugin>
51+
<groupId>org.apache.maven.plugins</groupId>
52+
<artifactId>maven-resources-plugin</artifactId>
53+
<version>3.1.0</version>
54+
</plugin>
55+
<plugin>
56+
<groupId>org.apache.maven.plugins</groupId>
57+
<artifactId>maven-jar-plugin</artifactId>
58+
<version>3.1.2</version>
59+
<configuration>
60+
<archive>
61+
<manifest>
62+
<addClasspath>true</addClasspath>
63+
<classpathPrefix>${libs.classpath.prefix}</classpathPrefix>
64+
<mainClass>${mainClass}</mainClass>
65+
</manifest>
66+
</archive>
67+
</configuration>
68+
</plugin>
69+
</plugins>
70+
</pluginManagement>
71+
72+
<plugins>
73+
<plugin>
74+
<groupId>org.apache.maven.plugins</groupId>
75+
<artifactId>maven-dependency-plugin</artifactId>
76+
<executions>
77+
<execution>
78+
<id>copy-dependencies</id>
79+
<phase>prepare-package</phase>
80+
<goals>
81+
<goal>copy-dependencies</goal>
82+
</goals>
83+
<configuration>
84+
<outputDirectory>${copied.libs.dir}</outputDirectory>
85+
<overWriteReleases>false</overWriteReleases>
86+
<overWriteSnapshots>false</overWriteSnapshots>
87+
<overWriteIfNewer>true</overWriteIfNewer>
88+
<overWriteIfNewer>true</overWriteIfNewer>
89+
<includeScope>runtime</includeScope>
90+
<excludeScope>test</excludeScope>
91+
</configuration>
92+
</execution>
93+
</executions>
94+
</plugin>
95+
<plugin>
96+
<groupId>org.apache.maven.plugins</groupId>
97+
<artifactId>maven-resources-plugin</artifactId>
98+
<executions>
99+
<execution>
100+
<id>copy-dockerfile</id>
101+
<phase>process-resources</phase>
102+
<goals>
103+
<goal>copy-resources</goal>
104+
</goals>
105+
<configuration>
106+
<outputDirectory>${project.build.directory}</outputDirectory>
107+
<resources>
108+
<resource>
109+
<directory>src/main/docker</directory>
110+
<filtering>true</filtering>
111+
<includes>
112+
<include>Dockerfile</include>
113+
</includes>
114+
</resource>
115+
<resource>
116+
<filtering>true</filtering>
117+
<directory>src/main/k8s</directory>
118+
<includes>
119+
<include>app.yaml</include>
120+
</includes>
121+
</resource>
122+
</resources>
123+
</configuration>
124+
</execution>
125+
</executions>
126+
</plugin>
127+
</plugins>
128+
</build>
129+
130+
<dependencies>
131+
<dependency>
132+
<groupId>com.oracle.database.jdbc</groupId>
133+
<artifactId>ojdbc11</artifactId>
134+
<version>21.3.0.0</version>
135+
</dependency>
136+
<dependency>
137+
<groupId>com.oracle.database.jdbc</groupId>
138+
<artifactId>ucp</artifactId>
139+
<version>21.3.0.0</version>
140+
</dependency>
141+
<dependency>
142+
<groupId>com.oracle.database.ha</groupId>
143+
<artifactId>ons</artifactId>
144+
<version>21.3.0.0</version>
145+
</dependency>
146+
<dependency>
147+
<groupId>com.oracle.database.security</groupId>
148+
<artifactId>oraclepki</artifactId>
149+
<version>21.3.0.0</version>
150+
</dependency>
151+
<dependency>
152+
<groupId>com.oracle.database.security</groupId>
153+
<artifactId>osdt_core</artifactId>
154+
<version>21.3.0.0</version>
155+
</dependency>
156+
<dependency>
157+
<groupId>com.oracle.database.security</groupId>
158+
<artifactId>osdt_cert</artifactId>
159+
<version>21.3.0.0</version>
160+
</dependency>
161+
</dependencies>
162+
</project>
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
FROM openjdk:11
2+
3+
RUN mkdir /app
4+
COPY libs /app/libs
5+
COPY ${project.artifactId}.jar /app
6+
7+
# The driver will look for the wallet in folder /app/wallet
8+
# This value must match the one in the mountPath of the container
9+
# Reference in src/main/k8s/app.yaml
10+
11+
CMD ["java", \
12+
"-Doracle.net.tns_admin=/app/wallet", \
13+
"-Doracle.net.wallet_location=/app/wallet", \
14+
"-Doracle.jdbc.fanEnabled=false", \
15+
"-jar", \
16+
"/app/${project.artifactId}.jar"]
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package com.oracle.healthcheck;
2+
3+
import java.io.IOException;
4+
import java.io.OutputStream;
5+
import java.net.InetSocketAddress;
6+
import java.sql.ResultSet;
7+
import java.sql.SQLException;
8+
import java.sql.Statement;
9+
10+
import javax.net.ssl.HttpsURLConnection;
11+
12+
import com.sun.net.httpserver.HttpServer;
13+
14+
import oracle.jdbc.internal.OracleConnection;
15+
import oracle.jdbc.pool.OracleDataSource;
16+
17+
public class Client {
18+
19+
public static void main(String[] args)
20+
throws SQLException, IOException {
21+
22+
// Retrieve user credentials from environment variables.
23+
// They are set in the Pod from a Secret in src/main/k8s/app.yaml
24+
OracleDataSource ds = new OracleDataSource();
25+
ds.setURL(System.getenv("url"));
26+
ds.setUser(System.getenv("user"));
27+
ds.setPassword(System.getenv("password"));
28+
29+
// Validate and log connection
30+
OracleConnection connection = (OracleConnection) ds.getConnection();
31+
System.out.println("Retrieving connections: " + connection.isValid(0));
32+
System.out
33+
.println("Database version: "
34+
+ connection.getMetaData().getDatabaseMajorVersion() + "."
35+
+ connection.getMetaData().getDatabaseMinorVersion());
36+
37+
// Start an HttpServer listening on port 8080 to send database status.
38+
HttpServer server = HttpServer.create(new InetSocketAddress(8080), 0);
39+
server.createContext("/", (httpExchange) -> {
40+
41+
try (OracleConnection conn = (OracleConnection) ds.getConnection();
42+
Statement stmt = conn.createStatement()) {
43+
44+
// Database message: version and sysdate
45+
ResultSet rs = stmt.executeQuery("select SYSDATE from dual");
46+
rs.next();
47+
48+
String message = "{\"database-version\": \""
49+
+ conn.getMetaData().getDatabaseMajorVersion() + "."
50+
+ conn.getMetaData().getDatabaseMinorVersion()
51+
+ "\", \"database-sysdate\": \"" + rs.getString(1) + "\"}";
52+
System.out.println(message);
53+
54+
// Send message, status and flush
55+
httpExchange
56+
.sendResponseHeaders(HttpsURLConnection.HTTP_OK, message.length());
57+
OutputStream os = httpExchange.getResponseBody();
58+
os.write(message.getBytes());
59+
os.close();
60+
61+
} catch (SQLException e) {
62+
e.printStackTrace();
63+
}
64+
});
65+
66+
server.setExecutor(null);
67+
server.start();
68+
}
69+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
kind: Pod
2+
apiVersion: v1
3+
metadata:
4+
name: adb-health-check
5+
spec:
6+
volumes:
7+
- name: wallet
8+
secret:
9+
# Either the secret name of the downloaded wallet with the kubernetes operator
10+
# TODO add link to operator
11+
# Or the secret name holding the wallet created ad-hoc:
12+
# kubectl create secret generic database-wallet --from-file=<path to wallet dir>
13+
# secretName: database-wallet
14+
secretName: bindadblocal-instance-wallet
15+
containers:
16+
- name: adb-health-check
17+
image: adb-health-check
18+
imagePullPolicy: IfNotPresent
19+
volumeMounts:
20+
- name: wallet
21+
# mountPath must coincide with the one selected for oracle.net.wallet_location
22+
mountPath: "/app/wallet"
23+
readOnly: true
24+
env:
25+
- name: user
26+
valueFrom:
27+
secretKeyRef:
28+
name: user-jdbc
29+
key: user
30+
- name: password
31+
valueFrom:
32+
secretKeyRef:
33+
name: user-jdbc
34+
key: password
35+
- name: url
36+
valueFrom:
37+
secretKeyRef:
38+
name: user-jdbc
39+
key: url

0 commit comments

Comments
 (0)