Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 29 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,33 @@ http://localhost:8080/adm

**Note**: Login with demo username "tbrown" and password "password". Use env "local-demo", app "testapp", ver "1.0.0".

### Ports
The containers publish these ports on the host. If another project already uses some of them, or you run a second copy of adm, set other ports in a `.env` file next to `compose.yaml`, which Compose reads, or in the environment:

| Variable | Default | Port of |
|---|---|---|
| ADM_HTTPS_PORT | 8443 | app (HTTPS) |
| ADM_HTTP_PORT | 8080 | app (HTTP) |
| ADM_MANAGEMENT_PORT | 9990 | Wildfly management |
| ADM_KEYCLOAK_PORT | 8081 | Keycloak |
| ADM_KEYCLOAK_MANAGEMENT_PORT | 9991 | Keycloak management |
| ADM_ORACLE_PORT | 1521 | Oracle |
| ADM_ORACLE_EM_PORT | 5500 | Oracle Enterprise Manager |
| ADM_SSHD_PORT | 1234 | sshd (the demo data's "local-dev" env deploys to port 1234) |

For example, a `.env` for a second copy:
```
ADM_HTTPS_PORT=18443
ADM_HTTP_PORT=18080
ADM_MANAGEMENT_PORT=19990
ADM_KEYCLOAK_PORT=18081
ADM_KEYCLOAK_MANAGEMENT_PORT=19991
ADM_ORACLE_PORT=11521
ADM_ORACLE_EM_PORT=15500
ADM_SSHD_PORT=11234
```
Compose names the containers, network, and images after the project's directory, such as `adm-oracle-1`, so a copy in another directory, such as a git worktree, gets its own. Each copy uses about 4 GB of memory.

## Install
This application requires a Java 17+ JVM and standard library to run, plus a Jakarta EE 10 application server (developed with Wildfly).

Expand Down Expand Up @@ -91,7 +118,7 @@ Further, the local DataSource must also leverage localhost port forwarding so th

The [server](https://github.com/JeffersonLab/wildfly/blob/main/scripts/server-setup.sh) and [app](https://github.com/JeffersonLab/wildfly/blob/main/scripts/app-setup.sh) setup scripts can be used to setup a local instance of Wildfly.

The user you use to run Wildfly needs to have an SSH public/private key pair (ssh-keygen) in the default location (~/.ssh). The public key needs to be added to the `authorized_keys` file of user `testuser` in the container named "sshd". This can be done by creating a file named `.env` in the root of the project containing the env name "TEST_USER_AUTHORIZED_KEY" with value being Wildfly user's public key. This env will then be passed in via deps.yaml environment setting.
The user you use to run Wildfly needs to have an SSH public/private key pair (ssh-keygen) in the default location (~/.ssh). The public key needs to be added to the `authorized_keys` file of user `testuser` in the container of the `sshd` service. This can be done by creating a file named `.env` in the root of the project containing the env name "TEST_USER_AUTHORIZED_KEY" with value being Wildfly user's public key. This env will then be passed in via deps.yaml environment setting.

The unit tests run with `gradlew build`, or alone with `gradlew test`. They need no database, Wildfly, or containers: the SSH tests start their own in-process SSH server.

Expand All @@ -100,7 +127,7 @@ The integration tests run against the app and its services in containers, built
docker compose -f build.yaml up -d --build
gradlew integrationTest
```
They wait up to 5 minutes for the services to start (set `ADM_READY_TIMEOUT_SECONDS` to change that), then log in with the demo users and the `adm` client's service account, as CI deploys do. They add their own app envs to deploy to, and remove them afterwards. To test an app on other ports, set `ADM_URL` (default `https://localhost:8443/adm`) and `KEYCLOAK_URL` (default `http://localhost:8081/auth`).
They wait up to 5 minutes for the services to start (set `ADM_READY_TIMEOUT_SECONDS` to change that), then log in with the demo users and the `adm` client's service account, as CI deploys do. They add their own app envs to deploy to, and remove them afterwards. They use the same [ports](#ports) as Compose, including those in `.env`. To test an app elsewhere, set `ADM_URL` (default `https://localhost:8443/adm`) and `KEYCLOAK_URL` (default `http://localhost:8081/auth`).

## Release
1. Bump the version number in the VERSION file and commit and push to GitHub (using [Semantic Versioning](https://semver.org/)).
Expand Down
11 changes: 11 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,17 @@ tasks.register('integrationTest', Test) {
// The services may still be starting, and they are not up to date with the source files
outputs.upToDateWhen { false }

// Use the ports in .env, as docker compose does; the environment takes precedence
def dotEnv = file('.env')
if (dotEnv.exists()) {
dotEnv.eachLine { line ->
def m = line =~ /^\s*(ADM_\w+)\s*=\s*["']?(.*?)["']?\s*$/
if (m.matches() && !System.getenv(m.group(1))) {
environment m.group(1), m.group(2)
}
}
}

testLogging {
events "passed", "skipped", "failed"
exceptionFormat = "full"
Expand Down
13 changes: 6 additions & 7 deletions compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,30 @@ services:
extends:
file: deps.yaml
service: oracle
container_name: adm-oracle

keycloak:
extends:
file: deps.yaml
service: keycloak
container_name: adm-keycloak

sshd:
extends:
file: deps.yaml
service: sshd
container_name: adm-sshd
environment:
# Using the demo/test public key below
TEST_USER_AUTHORIZED_KEY: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC4s2lC5RHzhbpj+GkxcuOAZLr1ta0Ebo9P5zUhBEmDUiiRfXAwZc83MrEqFfgmGUNeY5vMnwdFpJsTiKs2nqAqJTyHy7GnN39e4JRFg3mLV8AV/S+o8/F1ez94jvfNaIH+6vW25uKfqSe/pVAqPVlEvs4x29zT5JcSyNt+0w+E0Jm4WQakvlU1IWgcUXIy4fsjd0g6CFX/z0WwJtMkjzJlyiJUHNBCNuSvMUC2khDpCYvft5lqTNwvaB809BRnuP2/ejhwK2JGGPe9snqXQnlfO4CrujguoJT8FqhbzqLKVj/YhvENUMQGT9pt2wtKglVLUf5R48eeivNpAWX7tTXH jboss@adm"

adm:
hostname: adm
container_name: adm-dev
ports:
- "8443:8443"
- "8080:8080"
- "9990:9990"
- "${ADM_HTTPS_PORT:-8443}:8443"
- "${ADM_HTTP_PORT:-8080}:8080"
- "${ADM_MANAGEMENT_PORT:-9990}:9990"
environment:
# The browser reaches Keycloak and the app on the host's ports
KEYCLOAK_FRONTEND_SERVER_URL: 'http://localhost:${ADM_KEYCLOAK_PORT:-8081}/auth'
FRONTEND_SERVER_URL: 'https://localhost:${ADM_HTTPS_PORT:-8443}'
# This is demo/test public key
RSA_PUBLIC_KEY: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC4s2lC5RHzhbpj+GkxcuOAZLr1ta0Ebo9P5zUhBEmDUiiRfXAwZc83MrEqFfgmGUNeY5vMnwdFpJsTiKs2nqAqJTyHy7GnN39e4JRFg3mLV8AV/S+o8/F1ez94jvfNaIH+6vW25uKfqSe/pVAqPVlEvs4x29zT5JcSyNt+0w+E0Jm4WQakvlU1IWgcUXIy4fsjd0g6CFX/z0WwJtMkjzJlyiJUHNBCNuSvMUC2khDpCYvft5lqTNwvaB809BRnuP2/ejhwK2JGGPe9snqXQnlfO4CrujguoJT8FqhbzqLKVj/YhvENUMQGT9pt2wtKglVLUf5R48eeivNpAWX7tTXH jboss@adm"
# This is demo/test private key
Expand Down
17 changes: 7 additions & 10 deletions deps.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@ services:
oracle:
image: gvenzl/oracle-xe:21.3.0
hostname: oracle
container_name: oracle
ports:
- "1521:1521"
- "5500:5500"
- "${ADM_ORACLE_PORT:-1521}:1521"
- "${ADM_ORACLE_EM_PORT:-5500}:5500"
environment:
ORACLE_PASSWORD: testing
TZ: 'America/New_York'
Expand All @@ -15,19 +14,18 @@ services:
keycloak:
image: jeffersonlab/keycloak:2.6.0
hostname: keycloak
container_name: keycloak
ports:
- "8081:8080"
- "9991:9990"
- "${ADM_KEYCLOAK_PORT:-8081}:8080"
- "${ADM_KEYCLOAK_MANAGEMENT_PORT:-9991}:9990"
environment:
KC_FRONTEND_URL: 'http://localhost:8081/auth'
KC_FRONTEND_URL: 'http://localhost:${ADM_KEYCLOAK_PORT:-8081}/auth'
KC_BACKEND_URL: 'http://keycloak:8080/auth'
KC_HTTP_RELATIVE_PATH: '/auth'
KC_BOOTSTRAP_ADMIN_USERNAME: 'admin'
KC_BOOTSTRAP_ADMIN_PASSWORD: 'admin'
KC_CLIENT_NAME: adm
KC_RESOURCE: adm
KC_REDIRECT_URIS: '["https://localhost:8443/adm/*"]'
KC_REDIRECT_URIS: '["https://localhost:${ADM_HTTPS_PORT:-8443}/adm/*"]'
volumes:
- ./container/keycloak/initdb.d/03_customize.sh:/container-entrypoint-initdb.d/03_customize.sh

Expand All @@ -37,8 +35,7 @@ services:
context: .
dockerfile: Dockerfile-sshd
hostname: sshd
container_name: sshd
ports:
- "1234:22"
- "${ADM_SSHD_PORT:-1234}:22"
environment:
TEST_USER_AUTHORIZED_KEY: ${TEST_USER_AUTHORIZED_KEY}
15 changes: 10 additions & 5 deletions src/integration/java/org/jlab/adm/Adm.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,15 @@
/**
* The running app and its Keycloak, as started by {@code docker compose -f build.yaml up}.
*
* <p>The environment variables ADM_URL and KEYCLOAK_URL point the tests at other ports.
* <p>The tests use the same ports as docker compose: ADM_HTTPS_PORT and ADM_KEYCLOAK_PORT, which
* the integrationTest task also reads from .env. ADM_URL and KEYCLOAK_URL override the URLs.
*/
final class Adm {

static final String ADM_URL = env("ADM_URL", "https://localhost:8443/adm");
static final String KEYCLOAK_URL = env("KEYCLOAK_URL", "http://localhost:8081/auth");
static final String ADM_URL =
env("ADM_URL", "https://localhost:" + env("ADM_HTTPS_PORT", "8443") + "/adm");
static final String KEYCLOAK_URL =
env("KEYCLOAK_URL", "http://localhost:" + env("ADM_KEYCLOAK_PORT", "8081") + "/auth");

/** The app in the demo data */
static final String APP = "testapp";
Expand Down Expand Up @@ -85,10 +88,12 @@ static synchronized void awaitReady() throws InterruptedException {

while (!ready && Instant.now().isBefore(end)) {
try {
HttpResponse<String> response = get("/log", serviceAccountToken());
// The admin's password login works once Keycloak's setup scripts have all run
HttpResponse<String> response = get("/log", adminToken());
ready = response.statusCode() == 200;
problem = "GET /log returned " + response.statusCode();
} catch (IOException | RuntimeException e) {
} catch (IOException | RuntimeException | AssertionError e) {
// Such as a failed token request while Keycloak is still creating the realm
problem = e.toString();
}

Expand Down
Loading