diff --git a/.gitignore b/.gitignore index 42bd319..793a0d6 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,7 @@ target/ # custom project files -backups/** +bin/** # intellij idea specific *.iml diff --git a/README.md b/README.md index 5bd0dca..4795e65 100644 --- a/README.md +++ b/README.md @@ -1,40 +1,89 @@ # Remal Gombi ## 1) Overview -This is an integrated development framework running in Docker containers. -The environment provides the following services: -- **Private Certificate Authority infrastructure**: PKI -- **Directory Service**: LDAP -- **Access Management infrastructure**: authentication, authorization, OAUTH2, etc. -- **Vault Service**: identity-based secret and encryption management system to store key/values -- **Distributed event streaming platform**: high-performance data pipelines, streaming analytics and data integration -- A software **platform to search, analyze and visualize the machine-generated data** and events gathered from the websites, applications, sensors, devices etc. - -The framework provides the following base Docker images: -- OpenJDK 11 and 17 base Docker images -- Apache Tomcat 9 base image +This is an integrated development framework running in Docker containers. The containers can be used in `production` environments as well. + +Gombi provides the following services: +- _Private Certificate Authority infrastructure (PKI)_ +- _LDAP Directory Service_ +- _Access Management infrastructure_: authentication, authorization, OAUTH2, etc. +- _Distributed key/value store_: identity-based secret and encryption management system to store key/values with Hashicorp Vault +- _Distributed event streaming platform_: high-performance data pipelines, streaming analytics and data integration with Kafka +- _A powerful open-source distributed and scalable in-memory data cache_ +- _Data Analytics & Visualization platforms_: to search, analyze and visualize the machine-generated data and events gathered from the applications, sensors, devices etc. +- _Java 11, 17 and 21 containers as a service (CaaS)_: run Spring Boot applications/microservices ![docker image hierarchy](docs/diagrams/images/docker-image-hierarchy.png) -## 2) Components of the environment -* Base Docker Images: - * [Remal Base](docker/base/base) +## 2) Docker Images provided +* Base Image: + * [Remal Base](docker/base/base): based on Alpine + + +* Java JDK Images: * [OpenJDK-11](docker/core/openjdk-11) * [OpenJDK-17](docker/core/openjdk-17) + * [OpenJDK-21](docker/core/openjdk-21) + + +* Private Certificate Authority Server (PKI): + * [OpenVPN/Easy-RSA](docker/infrastructure/easy-rsa-pki): complete Private Certificate Authority Server to manage the server certificates + + +* Access Management platform: + * [ForgeRock Access Management platform](docker/infrastructure/forgerock-am): Authentication, Authorization, OAUTH, SSO, Federation, etc. + * [ForgeRock Directory Service](docker/infrastructure/forgerock-ds): LDAP server + + +* Distributed Service Registry and key/value store: + * [Hashicorp Consul](docker/infrastructure/hcp-consul): Service Registry and Discovery + distributed key/value store + * [Hashicorp Vault](docker/infrastructure/hcp-vault): key/value store + + +* Jave Web Container Images * [Apache Tomcat 9](docker/infrastructure/tomcat-9) -* Service Docker Images: - * Private Certificate Authority (CA) Infrastructure: [OpenVPN easy-rsa (simple shell based CA utility)](docker/infrastructure/easy-rsa-pki) - * Vault Service: [HashiCorp Vault](docker/infrastructure/hcp-vault) - * Directory Service (LDAP): [ForgeRock Directory Server](docker/infrastructure/forgerock-ds) - * Access Management (authentication, authorization): [ForgeRock Access Management](docker/infrastructure/forgerock-am) -## 3) Deployment -For more details, check [this](docker/README.md). -## 4) Demo Web application +* Monitoring, analytics and interactive visualization: + * [Prometheus](docker/monitoring/prometheus): event monitoring, collecting and alerting, it records metrics in a time series database + * [Grafana](docker/monitoring/grafana): analytics and interactive visualization web application with charts, graphs, and alerts + + +* Java runners + * [OpenJDK-21 Runner](docker/application/java-21-runner) + * [OpenJDK-21 Runner with Postgres Database Server](docker/application/java-21-postgres-runner) + + +## 3) Build the images + +## 4) How to start +1. Build the sample projects + ~~~ + $ cd gombi/projects + $ mvn clean package + ~~~ + +2. Copy the artifacts (*.war) into the directory that will be mapped into the `Java Runners` container. + + The default directories: + * `$HOME/Java/gombi/bin/echo-service` + * `$HOME/Java/gombi/bin/user-service` + + The path cen be changed in the compose file: `projects/docker-compose.yml` + +3. Start the Remal-Gombi Docker stack + ~~~ + $ cd gombi/projects + $ mvn clean package + ~~~ + ## 5) License and Copyright -Copyright (c) 2020-2023 Remal Software, Arnold Somogyi. All rights reserved. +Copyright (c) 2020-2025 Remal Software, Arnold Somogyi. All rights reserved. + +## Appendix 1) Reference Dockerfile +* Reference Dockerfile: [docker/docker-compose-reference.yml](docker/docker-compose-reference.yml) file. +* For more details, check [this](docker/README.md). trackgit-views diff --git a/RELEASE.md b/RELEASE.md index 154165e..d028abf 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -12,6 +12,25 @@ Images and its versions in this release: * ds-7.3:0.0.1-remal * am-7.3:0.0.1-remal +## [0.1.0] - 15/Jan/2025 +### Docker Images +* Update EasyRSA to version 3.2.1 +* Update Hashicorp Consul to version 1.20 +* Update Grafana to version 11.4.0 +* Update Prometheus to version 3.0.1 +* Improved releasing process: the same image tag is used everywhere +* Improved the way the key and value pairs are imported into the KV store in the `java-21-runner' image +* Fix for parallel EsyRSA execution issue, [#1279](https://github.com/OpenVPN/easy-rsa/issues/1279) +* Fixed missing SAN issue in generated certificate: `failed to verify certificate: x509: certificate relies on legacy Common Name field, use SANs instead` +* Fixed a problem where Grafana did not install the first time the container was launched. +* Fixed a problem where ForgeRock Directory Services did not install the first time the container was launched. + +### Java projects +* Maven dependency improvements: use dependency-management +* SSL configuration improvement: use of SSL bundles and better `RestTemplate` configuration +* Update to Spring Boot 3.4.1 +* Improved the meters naming in Micrometer + trackgit-views diff --git a/docker/.env b/docker/.env new file mode 100644 index 0000000..95775c9 --- /dev/null +++ b/docker/.env @@ -0,0 +1 @@ +DOMAIN_NAME=hello.com diff --git a/docker/README.md b/docker/README.md index e6c3272..955e453 100644 --- a/docker/README.md +++ b/docker/README.md @@ -167,6 +167,14 @@ Images and its types: **PKI** * Lists entries in a keystore: `keytool -list -v -keystore -storepass ` * Test HTTPS connection: `curl https://user-service.hello.com:8443/actuator/health` +* How to check Subject Alternative Names for an SSL/TLS certificate? + ~~~ + $ apk add openssl + $ openssl s_client -connect website.example:443 - trackgit-views - diff --git a/docker/application/java-21-postgres-runner/setenv.sh b/docker/application/java-21-postgres-runner/setenv.sh index dcb3fec..c724104 100755 --- a/docker/application/java-21-postgres-runner/setenv.sh +++ b/docker/application/java-21-postgres-runner/setenv.sh @@ -8,10 +8,9 @@ # Copyright (c) 2020-2024 Remal Software and Arnold Somogyi All rights reserved # ****************************************************************************** export IMAGE_NAME="remal-java-21-postgres-runner" -export IMAGE_TAG="0.0.2" export IMAGE_DESCRIPTION="Remal Java 21 Runner with Postgres database server" export IMAGE_AUTHOR="Arnold Somogyi " -export IMAGE_FROM="remal-java-21-runner:0.5.0" +export IMAGE_FROM="remal-java-21-runner:$4" export BUILD_TYPE=${1:-fat} export PUSH_IMAGE=${2:-false} export DOMAIN_NAME=${3:-hello.com} diff --git a/docker/application/java-21-runner/Dockerfile b/docker/application/java-21-runner/Dockerfile index ba9384b..af67055 100644 --- a/docker/application/java-21-runner/Dockerfile +++ b/docker/application/java-21-runner/Dockerfile @@ -7,7 +7,7 @@ # # Copyright (c) 2020-2024 Remal Software and Arnold Somogyi All rights reserved # ****************************************************************************** -ARG IMAGE_FROM=${IMAGE_FROM} +ARG IMAGE_FROM="not-set" ARG BUILD_TYPE="fat" FROM ${IMAGE_FROM} AS base diff --git a/docker/application/java-21-runner/RELEASE.md b/docker/application/java-21-runner/RELEASE.md deleted file mode 100644 index 4bb26dc..0000000 --- a/docker/application/java-21-runner/RELEASE.md +++ /dev/null @@ -1,18 +0,0 @@ -# Release info - -All notable changes to this project will be documented in this file. - -## [0.5.0] - 25/Jul/2024 -#### Added -* a new environment variable with default value for Kafka integration: `KAFKA_SERVERS="kafka-1.hello.com:19092, kafka-2.hello.com:19092"`. - The default value can be overwritten from the `docker-compose.yml` file and value can be used from bash or Spring Boot `application.properties` file. -#### Modified -* Improvement in the `get_first_jar` function. - -## [0.0.1] - 24/Feb/2024 -#### Added -* install `HashiCorp Consul Client` - - - trackgit-views - diff --git a/docker/application/java-21-runner/container-scripts/startup/70151_kv-importer.sh b/docker/application/java-21-runner/container-scripts/startup/70151_kv-importer.sh index 013afd9..951d8fb 100755 --- a/docker/application/java-21-runner/container-scripts/startup/70151_kv-importer.sh +++ b/docker/application/java-21-runner/container-scripts/startup/70151_kv-importer.sh @@ -26,6 +26,8 @@ file_exists() { printf "%s | [WARN] file \"%s\" not found\n" "$(date +"%Y-%m-%d %H:%M:%S")" "$file_to_check" log_end "$0" exit 0 + else + printf "%s | [DEBUG] file \"%s\" has been successfully extracted\n" "$(date +"%Y-%m-%d %H:%M:%S")" "$file_to_check" fi } @@ -44,6 +46,34 @@ cleanup_workspace() { rm -R "$workspace_home" } +# ------------------------------------------------------------------------------ +# Unpack the given file from the ZIP. +# +# Arguments: +# arg 1: source zip file +# arg 2: target directory to extract the file +# arg 3: the file to extract from the ZIP +# ------------------------------------------------------------------------------ +extract_file() { + local archive_file target_dir fie_to_extract + archive_file="$1" + target_dir="$2" + fie_to_extract="$3" + + if [ -z "$archive_file" ]; then + printf "%s | [WARN] there is nothing to unpack\n" "$(date +"%Y-%m-%d %H:%M:%S")" + else + printf "%s | [DEBUG] unpacking the \"%s\" file from \"%s\" to \"%s\"...\n" "$(date +"%Y-%m-%d %H:%M:%S")" "$fie_to_extract" "$archive_file" "$target_dir" + + # Ignore a specific exit code that appears if there file to extract not found in the ZIP. + # + # Exit codes (see the full list here: https://linux.die.net/man/1/unzip): + # 9: the specified zipfiles were not found + # 11: no matching files were found + unzip -j "$archive_file" "$fie_to_extract" -d "$target_dir" || (exit "$(($? == 11 ? 0 : $?))") + fi +} + # ------------------------------------------------------------------------------ # Get the key context for the Hashicorp Consul KV store. # The property key in the Consul KV store should always start with “config” name @@ -52,8 +82,8 @@ cleanup_workspace() { # # For example, if # - java code: @Value("${app.hello}") -# - application.properties: spring.application.name=echo-service -# then the full path of the key is config/echo-service/app.hello +# - application.properties: spring.application.name=welcome-service +# then the full path of the key is config/welcome-service/app.hello # # Arguments # arg 1: property file @@ -88,7 +118,7 @@ get_first_jar() { local jars_home jars_home="$1" - printf "%s | [INFO] getting the first JAR file from the \"%s\" directory...\n" "$(date +"%Y-%m-%d %H:%M:%S")" "$jars_home" + printf "%s | [INFO] getting the first JAR file from \"%s\" directory...\n" "$(date +"%Y-%m-%d %H:%M:%S")" "$jars_home" local files number_of_files files=($(find "$jars_home" -type f -name "*.jar")) @@ -143,41 +173,27 @@ insert_kv() { done < "$properties_file" } -# ------------------------------------------------------------------------------ -# Unpack the given ZIP archive file. -# -# Arguments: -# arg 1: zip file to extract -# arg 2: target directory to extract the file -# ------------------------------------------------------------------------------ -unpack_jar() { - local archive_file target - archive_file="$1" - target="$2" - - if [ -z "$archive_file" ]; then - printf "%s | [WARN] there is nothing to unpack\n" "$(date +"%Y-%m-%d %H:%M:%S")" - else - printf "%s | [DEBUG] unpacking the \"%s\" file to \"%s\"...\n" "$(date +"%Y-%m-%d %H:%M:%S")" "$archive_file" "$target" - unzip -q "$archive_file" -d "$target" - fi -} - # ------------------------------------------------------------------------------ # Main program starts here. # ------------------------------------------------------------------------------ log_start "$0" +printf "%s | [INFO] inserting key/values into Hashicorp Consul...\n" "$(date +"%Y-%m-%d %H:%M:%S")" UNPACK_DIR="/tmp/extracted-jar" -KV_PROP_FILE="$UNPACK_DIR/BOOT-INF/classes/config.properties" -APP_PROP_FILE="$UNPACK_DIR/BOOT-INF/classes/application.properties" -printf "%s | [INFO] inserting key/values into Hashicorp Consul...\n" "$(date +"%Y-%m-%d %H:%M:%S")" +PATH_TO_PROP_FILE="BOOT-INF/classes" +APP_PROP_FILE="application.properties" +KV_PROP_FILE="config.properties" + get_first_jar "$JAR_HOME" JAR_FILE -unpack_jar "$JAR_FILE" "$UNPACK_DIR" -file_exists "$KV_PROP_FILE" -file_exists "$APP_PROP_FILE" -get_kv_context "$APP_PROP_FILE" CONTEXT -insert_kv "$KV_PROP_FILE" "$CONTEXT" + +extract_file "$JAR_FILE" "$UNPACK_DIR" "$PATH_TO_PROP_FILE/$APP_PROP_FILE" +file_exists "$UNPACK_DIR/$APP_PROP_FILE" + +extract_file "$JAR_FILE" "$UNPACK_DIR" "$PATH_TO_PROP_FILE/$KV_PROP_FILE" +file_exists "$UNPACK_DIR/$KV_PROP_FILE" + +get_kv_context "$UNPACK_DIR/$APP_PROP_FILE" CONTEXT +insert_kv "$UNPACK_DIR/$KV_PROP_FILE" "$CONTEXT" cleanup_workspace "$UNPACK_DIR" log_end "$0" diff --git a/docker/application/java-21-runner/setenv.sh b/docker/application/java-21-runner/setenv.sh index 1a3e079..a28e95b 100755 --- a/docker/application/java-21-runner/setenv.sh +++ b/docker/application/java-21-runner/setenv.sh @@ -8,10 +8,9 @@ # Copyright (c) 2020-2024 Remal Software and Arnold Somogyi All rights reserved # ****************************************************************************** export IMAGE_NAME="remal-java-21-runner" -export IMAGE_TAG="0.5.0" export IMAGE_DESCRIPTION="Remal Java 21 Runner" export IMAGE_AUTHOR="Arnold Somogyi " -export IMAGE_FROM="remal-consul:1.2.0" +export IMAGE_FROM="remal-consul:$4" export BUILD_TYPE=${1:-fat} export PUSH_IMAGE=${2:-false} export DOMAIN_NAME=${3:-hello.com} diff --git a/docker/base/base/Dockerfile b/docker/base/base/Dockerfile index 6d3405f..2d37353 100644 --- a/docker/base/base/Dockerfile +++ b/docker/base/base/Dockerfile @@ -6,7 +6,7 @@ # # Copyright (c) 2020-2023 Remal Software and Arnold Somogyi All rights reserved # ****************************************************************************** -ARG IMAGE_FROM=${IMAGE_FROM} +ARG IMAGE_FROM="not-set" FROM ${IMAGE_FROM} EXPOSE 22/tcp diff --git a/docker/base/base/RELEASE.md b/docker/base/base/RELEASE.md deleted file mode 100644 index 2507019..0000000 --- a/docker/base/base/RELEASE.md +++ /dev/null @@ -1,24 +0,0 @@ -# Release info - -All notable changes to this project will be documented in this file. - -## [0.0.1] - 13/Mar/2023 -#### Added -* `bash` and `sh` Unix shells -* ssh server -* `root` user password set to `password` -* configure the bash console for ssh login -* customized bash prompt that shows the container name and version -* `ll` and `ls` bash aliases -* execution of scripts files from `/docker.first-boot` directory during the very first star of the container -* execution of script files from `/docker.startup` directory when the container starts -* `shutdown-actions.sh` script, called before container stops completely - -## [0.0.2] - 24/Apr/2024 -#### Modified -* Improvement in the `wait_until_text_found` method of the `shared.sh` script. -* Improvement in log. - - - trackgit-views - diff --git a/docker/base/base/setenv.sh b/docker/base/base/setenv.sh index 16fb01b..712fb1d 100755 --- a/docker/base/base/setenv.sh +++ b/docker/base/base/setenv.sh @@ -8,10 +8,9 @@ # Copyright (c) 2020-2023 Remal Software and Arnold Somogyi All rights reserved # ****************************************************************************** export IMAGE_NAME="remal-base" -export IMAGE_TAG="0.0.2" export IMAGE_DESCRIPTION="Remal Base Docker image" export IMAGE_AUTHOR="Arnold Somogyi " -export IMAGE_FROM="alpine:3.19.1" +export IMAGE_FROM="alpine:3.21.0" export BUILD_TYPE="${1:-fat}" export PUSH_IMAGE="${2:-false}" export DOMAIN_NAME=${3:-hello.com} diff --git a/docker/build.sh b/docker/build.sh index df3db42..57cdb68 100755 --- a/docker/build.sh +++ b/docker/build.sh @@ -20,17 +20,21 @@ if [ "$#" -ne 1 ]; then fi SCRIPT=$(realpath "$0") -SCRIPT_PATH=$(dirname "$SCRIPT") -IMAGE_SRC=$SCRIPT_PATH/${1##*docker/} -. "$IMAGE_SRC/setenv.sh" "slim" "false" "remal.com" +SCRIPT_HOME=$(dirname "$SCRIPT") +IMAGE_SRC="$SCRIPT_HOME/$1" +IMAGE_TAG="0.9.0" -printf "script home: %s\n" "$SCRIPT_PATH" -printf "source code: %s\n" "$IMAGE_SRC" -printf "build type: %s\n" "$BUILD_TYPE" -printf "base image: %s\n" "$IMAGE_FROM" -printf "image image: %s\n\n" "$IMAGE_NAME:$IMAGE_TAG" +# set environment +. "$IMAGE_SRC/setenv.sh" "slim" "false" "remal.com" "$IMAGE_TAG" + +printf "SCRIPT_HOME: %s\n" "$SCRIPT_HOME" +printf "IMAGE_SRC: %s\n" "$IMAGE_SRC" +printf "BUILD_TYPE: %s\n" "$BUILD_TYPE" +printf "IMAGE_FROM: %s\n" "$IMAGE_FROM" +printf "image name: %s\n\n" "$IMAGE_NAME:$IMAGE_TAG" docker build \ + --build-arg "BUILDKIT_DOCKERFILE_CHECK=skip=SecretsUsedInArgOrEnv" \ --no-cache \ --build-arg BUILD_TYPE="$BUILD_TYPE" \ --build-arg IMAGE_NAME="$IMAGE_NAME" \ @@ -52,8 +56,8 @@ if [ "$PUSH_IMAGE" = true ] ; then fi printf "Image has been built successfully. Details:\n" -printf " - script home: %s\n" "$SCRIPT_PATH" -printf " - source code: %s\n" "$IMAGE_SRC" -printf " - build type: %s\n" "$BUILD_TYPE" -printf " - base image: %s\n" "$IMAGE_FROM" +printf " - SCRIPT_HOME: %s\n" "$SCRIPT_HOME" +printf " - IMAGE_SRC: %s\n" "$IMAGE_SRC" +printf " - BUILD_TYPE: %s\n" "$BUILD_TYPE" +printf " - IMAGE_FROM: %s\n" "$IMAGE_FROM" printf " - image image: %s\n\n" "$IMAGE_NAME:$IMAGE_TAG" diff --git a/docker/core/openjdk-11/Dockerfile b/docker/core/openjdk-11/Dockerfile index d84f974..b786ea6 100644 --- a/docker/core/openjdk-11/Dockerfile +++ b/docker/core/openjdk-11/Dockerfile @@ -6,7 +6,7 @@ # # Copyright (c) 2020-2023 Remal Software and Arnold Somogyi All rights reserved # ****************************************************************************** -ARG IMAGE_FROM=${IMAGE_FROM} +ARG IMAGE_FROM="not-set" FROM ${IMAGE_FROM} EXPOSE 22/tcp diff --git a/docker/core/openjdk-11/RELEASE.md b/docker/core/openjdk-11/RELEASE.md deleted file mode 100644 index c31f491..0000000 --- a/docker/core/openjdk-11/RELEASE.md +++ /dev/null @@ -1,12 +0,0 @@ -# Release info - -All notable changes to this project will be documented in this file. - -## [0.0.1] - 15/Mar/2023 -#### Added -* base image: Remal `base` Docker image -* install `open-jdk 11` - - - trackgit-views - diff --git a/docker/core/openjdk-11/setenv.sh b/docker/core/openjdk-11/setenv.sh index 158f664..8440d19 100755 --- a/docker/core/openjdk-11/setenv.sh +++ b/docker/core/openjdk-11/setenv.sh @@ -8,10 +8,9 @@ # Copyright (c) 2020-2023 Remal Software and Arnold Somogyi All rights reserved # ****************************************************************************** export IMAGE_NAME="remal-openjdk-11" -export IMAGE_TAG="0.0.1" export IMAGE_DESCRIPTION="OpenJDK 11 Docker image" export IMAGE_AUTHOR="Arnold Somogyi " -export IMAGE_FROM="remal-base:0.0.2" +export IMAGE_FROM="remal-base:$4" export BUILD_TYPE="${1:-fat}" export PUSH_IMAGE="${2:-false}" export DOMAIN_NAME=${3:-hello.com} diff --git a/docker/core/openjdk-17/Dockerfile b/docker/core/openjdk-17/Dockerfile index 00a2206..38a2245 100644 --- a/docker/core/openjdk-17/Dockerfile +++ b/docker/core/openjdk-17/Dockerfile @@ -6,7 +6,7 @@ # # Copyright (c) 2020-2023 Remal Software and Arnold Somogyi All rights reserved # ****************************************************************************** -ARG IMAGE_FROM=${IMAGE_FROM} +ARG IMAGE_FROM="not-set" FROM ${IMAGE_FROM} EXPOSE 22/tcp diff --git a/docker/core/openjdk-17/RELEASE.md b/docker/core/openjdk-17/RELEASE.md deleted file mode 100644 index a3e766a..0000000 --- a/docker/core/openjdk-17/RELEASE.md +++ /dev/null @@ -1,12 +0,0 @@ -# Release info - -All notable changes to this project will be documented in this file. - -## [0.0.1] - 15/Mar/2023 -#### Added -* base image: Remal `base` Docker image -* install `open-jdk 17` - - - trackgit-views - diff --git a/docker/core/openjdk-17/setenv.sh b/docker/core/openjdk-17/setenv.sh index b67d637..1e2c6a1 100755 --- a/docker/core/openjdk-17/setenv.sh +++ b/docker/core/openjdk-17/setenv.sh @@ -8,10 +8,9 @@ # Copyright (c) 2020-2023 Remal Software and Arnold Somogyi All rights reserved # ****************************************************************************** export IMAGE_NAME="remal-openjdk-17" -export IMAGE_TAG="0.0.1" export IMAGE_DESCRIPTION="OpenJDK 17 Docker image" export IMAGE_AUTHOR="Arnold Somogyi " -export IMAGE_FROM="remal-base:0.0.2" +export IMAGE_FROM="remal-base:$4" export BUILD_TYPE="${1:-fat}" export PUSH_IMAGE="${2:-false}" export DOMAIN_NAME=${3:-hello.com} diff --git a/docker/core/openjdk-21/Dockerfile b/docker/core/openjdk-21/Dockerfile index 6eb4dbe..4f2b59d 100644 --- a/docker/core/openjdk-21/Dockerfile +++ b/docker/core/openjdk-21/Dockerfile @@ -6,7 +6,7 @@ # # Copyright (c) 2020-2024 Remal Software and Arnold Somogyi All rights reserved # ****************************************************************************** -ARG IMAGE_FROM=${IMAGE_FROM} +ARG IMAGE_FROM="not-set" FROM ${IMAGE_FROM} EXPOSE 22/tcp diff --git a/docker/core/openjdk-21/RELEASE.md b/docker/core/openjdk-21/RELEASE.md deleted file mode 100644 index d74843a..0000000 --- a/docker/core/openjdk-21/RELEASE.md +++ /dev/null @@ -1,12 +0,0 @@ -# Release info - -All notable changes to this project will be documented in this file. - -## [0.0.1] - 22/Mar/2024 -#### Added -* base image: Remal `base` Docker image -* install `open-jdk 21` - - - trackgit-views - diff --git a/docker/core/openjdk-21/setenv.sh b/docker/core/openjdk-21/setenv.sh index 6da350a..1cf6674 100755 --- a/docker/core/openjdk-21/setenv.sh +++ b/docker/core/openjdk-21/setenv.sh @@ -8,10 +8,9 @@ # Copyright (c) 2020-2024 Remal Software and Arnold Somogyi All rights reserved # ****************************************************************************** export IMAGE_NAME="remal-openjdk-21" -export IMAGE_TAG="0.0.1" export IMAGE_DESCRIPTION="OpenJDK 21 Docker image" export IMAGE_AUTHOR="Arnold Somogyi " -export IMAGE_FROM="remal-base:0.0.2" +export IMAGE_FROM="remal-base:$4" export BUILD_TYPE="${1:-fat}" export PUSH_IMAGE="${2:-false}" export DOMAIN_NAME=${3:-hello.com} diff --git a/docker/docker-compose-reference.yml b/docker/docker-compose-reference.yml index 922d894..0371176 100644 --- a/docker/docker-compose-reference.yml +++ b/docker/docker-compose-reference.yml @@ -1,8 +1,7 @@ -version: '3' services: # ----- Private Certificate Authority Server ------------------------------- pki: - image: remal-private-ca:0.0.1 + image: remal-private-ca:0.9.0 container_name: pki.${DOMAIN_NAME} hostname: pki.${DOMAIN_NAME} ports: @@ -16,7 +15,7 @@ services: # ----- LDAP Directory Server ---------------------------------------------- ds: - image: remal-ds-7.3:0.0.1 + image: remal-ds-7.3:0.9.0 container_name: ds.${DOMAIN_NAME} hostname: ds.${DOMAIN_NAME} depends_on: @@ -39,7 +38,7 @@ services: # ----- Access Management Server ------------------------------------------- forgerock-am: - image: remal-am-7.3:0.0.1 + image: remal-am-7.3:0.9.0 container_name: am.${DOMAIN_NAME} hostname: am.${DOMAIN_NAME} depends_on: @@ -59,7 +58,7 @@ services: # ----- Hashicorp Vault ---------------------------------------------------- vault: - image: remal-vault:0.0.1 + image: remal-vault:0.9.0 container_name: vault.${DOMAIN_NAME} hostname: vault.${DOMAIN_NAME} depends_on: @@ -72,7 +71,7 @@ services: # ----- Hashicorp Consul --------------------------------------------------- consul: - image: remal-consul:1.2.0 + image: remal-consul:0.9.0 container_name: consul.hello.com hostname: consul.hello.com depends_on: @@ -83,11 +82,41 @@ services: environment: - PKI_HOST=pki.${DOMAIN_NAME} + # ----- Monitoring: Prometheus --------------------------------------------- + prometheus: + image: remal-prometheus:0.9.0 + container_name: prometheus.${DOMAIN_NAME} + hostname: prometheus.${DOMAIN_NAME} + depends_on: + - consul + ports: + - "13072:22" # SSH + - "13073:9090" # HTTPS + environment: + - PKI_HOST=pki.${DOMAIN_NAME} + - CONSUL_HOST=consul.${DOMAIN_NAME} + + # ----- Monitoring: Grafana ------------------------------------------------ + grafana: + image: remal-grafana:0.9.0 + container_name: grafana.${DOMAIN_NAME} + hostname: grafana.${DOMAIN_NAME} + depends_on: + - prometheus + ports: + - "13082:22" # SSH + - "13083:3000" # HTTPS + environment: + - PKI_HOST=pki.${DOMAIN_NAME} + - PROMETHEUS_HOST=prometheus.${DOMAIN_NAME} + - GRAFANA_USER=admin + - GRAFANA_PASSWORD=password + # ----- Services ----------------------------------------------------------- echo-service: - image: remal-java-21-runner:0.5.0 - container_name: echo-service.hello.com - hostname: echo-service.hello.com + image: remal-java-21-runner:0.9.0 + container_name: welcome-service.hello.com + hostname: welcome-service.hello.com depends_on: - consul ports: @@ -101,7 +130,7 @@ services: - $HOME/dev/workspace/java/remal/volumes/service-hello:/jar-to-run user-service: - image: remal-java-21-postgres-runner:0.0.2 + image: remal-java-21-postgres-runner:0.9.0 container_name: user-service.hello.com hostname: user-service.hello.com depends_on: diff --git a/index.html b/docker/index.html similarity index 99% rename from index.html rename to docker/index.html index 2c7ba34..cc09a0f 100644 --- a/index.html +++ b/docker/index.html @@ -2,7 +2,7 @@ - Remal Gombi + Remal Gombi - Ports -

Remal-Gombi Docker Containers

+

Remal-Gombi Docker Containers and Ports

diff --git a/docker/infrastructure/easy-rsa-pki/Dockerfile b/docker/infrastructure/easy-rsa-pki/Dockerfile index 4e153cd..e38b0fe 100644 --- a/docker/infrastructure/easy-rsa-pki/Dockerfile +++ b/docker/infrastructure/easy-rsa-pki/Dockerfile @@ -6,7 +6,7 @@ # # Copyright (c) 2020-2023 Remal Software and Arnold Somogyi All rights reserved # ****************************************************************************** -ARG IMAGE_FROM=${IMAGE_FROM} +ARG IMAGE_FROM="not-set" ARG BUILD_TYPE="fat" FROM ${IMAGE_FROM} AS base @@ -20,7 +20,7 @@ ENV IMAGE_NAME="private-ca" \ IMAGE_AUTHOR="Arnold Somogyi " \ \ EASYRSA_HOME="/opt/easy-rsa" \ - EASYRSA_INSTALL_KIT="EasyRSA-3.1.7.tgz" \ + EASYRSA_INSTALL_KIT="EasyRSA-3.2.1.tgz" \ \ EASYRSA_REQ_CN="remal.com" \ EASYRSA_REQ_COUNTRY="HU" \ diff --git a/docker/infrastructure/easy-rsa-pki/RELEASE.md b/docker/infrastructure/easy-rsa-pki/RELEASE.md deleted file mode 100644 index fb56d16..0000000 --- a/docker/infrastructure/easy-rsa-pki/RELEASE.md +++ /dev/null @@ -1,13 +0,0 @@ -# Release info - -All notable changes to this project will be documented in this file. - -## [0.0.1] - 19/Mar/2023 -#### Added -* install and configure `easy-rsa` -* generate a private CA certificate -* bash script (`generate-cert.sh`) to generate server certificates - - - trackgit-views - diff --git a/docker/infrastructure/easy-rsa-pki/bin/EasyRSA-3.1.7.tgz b/docker/infrastructure/easy-rsa-pki/bin/EasyRSA-3.2.1.tgz similarity index 100% rename from docker/infrastructure/easy-rsa-pki/bin/EasyRSA-3.1.7.tgz rename to docker/infrastructure/easy-rsa-pki/bin/EasyRSA-3.2.1.tgz diff --git a/docker/infrastructure/easy-rsa-pki/container-scripts/generate-cert.sh b/docker/infrastructure/easy-rsa-pki/container-scripts/generate-cert.sh index 1b7fbd7..b0d430e 100755 --- a/docker/infrastructure/easy-rsa-pki/container-scripts/generate-cert.sh +++ b/docker/infrastructure/easy-rsa-pki/container-scripts/generate-cert.sh @@ -72,14 +72,14 @@ function generate_cert_req_and_key() { cd "$EASYRSA_HOME" || { println "invalid path: %s" "$EASYRSA_HOME"; exit 1; } if [[ -z "${san-}" ]]; then - printf "%s | [DEBUG] certificate request without SAN\n" "$(date +"%Y-%m-%d %H:%M:%S")" + printf "%s | [DEBUG] generating a certificate request...\n" "$(date +"%Y-%m-%d %H:%M:%S")" ./easyrsa \ --batch \ --passout="pass:$EASYRSA_PASS" \ --req-cn="$domain" \ gen-req "$domain" else - printf "%s | [DEBUG] certificate request with SAN: %s\n" "$(date +"%Y-%m-%d %H:%M:%S")" "$san" + printf "%s | [DEBUG] generating a certificate request with SAN: %s...\n" "$(date +"%Y-%m-%d %H:%M:%S")" "$san" ./easyrsa \ --batch \ --passout="pass:$EASYRSA_PASS" \ @@ -106,6 +106,7 @@ function signing_cert_req() { cd "$EASYRSA_HOME" || { println "invalid path: %s" "$EASYRSA_HOME"; exit 1; } ./easyrsa \ + --copy-ext \ --batch \ --passin="pass:$EASYRSA_PASS" \ sign-req \ @@ -126,16 +127,50 @@ function export_to_keystore() { ./easyrsa \ --passin="pass:$EASYRSA_PASS" \ --passout="pass:$EASYRSA_PASS" \ - export-p12 "$domain" usefn + export-p12 "$domain" cd "$work_dir" || { println "invalid path: %s" "$work_dir"; exit 1; } } +# ------------------------------------------------------------------------------ +# EasyRSA is a simple tool and is not designed to be run multiple times +# concurrently. This means that you must ensure that you do not run the tool +# more than once in parallel. +# +# Running multiple EasyRSA jobs in parallel cause that the same 'serial number' +# is reused multiple times by EasyRSA and the certificates generated will have the +# same 'serial number'. This causes various problems, such as a +# SEC_ERROR_REUSED_ISSUER_AND_SERIAL error in the web browser. +# +# This function checks whether EasyRSA is running or not and only continues if +# it is not. +# ------------------------------------------------------------------------------ +function wait_for_easyrsa_has_completed() { + local pid + + while : ; do + pid=$(pidof easyrsa) || true + if [ -n "$pid" ]; then + printf "%s | [DEBUG] EasyRSA is running, pid: %s\n" "$(date +"%Y-%m-%d %H:%M:%S")" "$pid" + printf "%s | [DEBUG] wait for EasyRSA to finish its work...\n" "$(date +"%Y-%m-%d %H:%M:%S")" + sleep 1 + else + printf "%s | [DEBUG] EasyRSA is not used by any other container, so let's continue\n" "$(date +"%Y-%m-%d %H:%M:%S")" + break + fi + done +} + # ------------------------------------------------------------------------------ # Main program starts here. # ------------------------------------------------------------------------------ validate_arguments "$@" show_context "$@" + +wait_for_easyrsa_has_completed generate_cert_req_and_key "$2" "${3:-}" + +wait_for_easyrsa_has_completed signing_cert_req "$1" "$2" + export_to_keystore "$2" import_to_keystore "ca-cert" "$EASYRSA_HOME/pki/ca.crt" "$EASYRSA_HOME/pki/private/$2.p12" "$EASYRSA_PASS" diff --git a/docker/infrastructure/easy-rsa-pki/container-scripts/init/30102_install-easyrsa.sh b/docker/infrastructure/easy-rsa-pki/container-scripts/init/30102_install-easyrsa.sh index 8592230..84d1f4a 100755 --- a/docker/infrastructure/easy-rsa-pki/container-scripts/init/30102_install-easyrsa.sh +++ b/docker/infrastructure/easy-rsa-pki/container-scripts/init/30102_install-easyrsa.sh @@ -39,5 +39,6 @@ printf "%s | [INFO ] generating the root CA key and certificate...\n" "$(date +" build-ca # generating a server certificate for this server -./generate-cert.sh "server" "$(hostname)" +FQDN=$(hostname -f) +./generate-cert.sh "server" "$FQDN" "DNS:$FQDN,DNS:localhost,IP:127.0.0.1" log_end "$0" diff --git a/docker/infrastructure/easy-rsa-pki/setenv.sh b/docker/infrastructure/easy-rsa-pki/setenv.sh index 6fbeec7..287a40f 100755 --- a/docker/infrastructure/easy-rsa-pki/setenv.sh +++ b/docker/infrastructure/easy-rsa-pki/setenv.sh @@ -8,10 +8,9 @@ # Copyright (c) 2020-2023 Remal Software and Arnold Somogyi All rights reserved # ****************************************************************************** export IMAGE_NAME="remal-private-ca" -export IMAGE_TAG="0.0.1" export IMAGE_DESCRIPTION="Private Certificate Authority server" export IMAGE_AUTHOR="Arnold Somogyi " -export IMAGE_FROM="remal-openjdk-17:0.0.1" +export IMAGE_FROM="remal-openjdk-17:$4" export BUILD_TYPE="${1:-fat}" export PUSH_IMAGE="${2:-false}" export DOMAIN_NAME=${3:-hello.com} diff --git a/docker/infrastructure/forgerock-am/Dockerfile b/docker/infrastructure/forgerock-am/Dockerfile index ed5b79e..6f1b804 100644 --- a/docker/infrastructure/forgerock-am/Dockerfile +++ b/docker/infrastructure/forgerock-am/Dockerfile @@ -6,7 +6,7 @@ # # Copyright (c) 2020-2023 Remal Software and Arnold Somogyi All rights reserved # ****************************************************************************** -ARG IMAGE_FROM=${IMAGE_FROM} +ARG IMAGE_FROM="not-set" ARG BUILD_TYPE="fat" FROM ${IMAGE_FROM} AS base diff --git a/docker/infrastructure/forgerock-am/RELEASE.md b/docker/infrastructure/forgerock-am/RELEASE.md deleted file mode 100644 index 7107bac..0000000 --- a/docker/infrastructure/forgerock-am/RELEASE.md +++ /dev/null @@ -1,11 +0,0 @@ -# Release info - -All notable changes to this project will be documented in this file. - -## [0.0.1] - 03/Jun/2023 -#### Added -* install forgerock access management server version 7.3 - - - trackgit-views - diff --git a/docker/infrastructure/forgerock-am/container-scripts/init/30403_configure-tomcat-https.sh b/docker/infrastructure/forgerock-am/container-scripts/init/30403_configure-tomcat-https.sh index 2b24a27..8664959 100755 --- a/docker/infrastructure/forgerock-am/container-scripts/init/30403_configure-tomcat-https.sh +++ b/docker/infrastructure/forgerock-am/container-scripts/init/30403_configure-tomcat-https.sh @@ -50,7 +50,7 @@ FQDN=$(hostname -f) KEYSTORE_HOME="/tmp" KEYSTORE_FILE="$FQDN.p12" -generate_certificate "server" "$FQDN" +generate_certificate "server" "$FQDN" "DNS:$FQDN,DNS:localhost,IP:127.0.0.1" copy_from_remote_machine "$PKI_HOST" "$SSH_USER" "$SSH_PASSWORD" "/opt/easy-rsa/pki/private/$KEYSTORE_FILE" "$KEYSTORE_HOME" tomcat_configuration "$FQDN" log_end "$0" diff --git a/docker/infrastructure/forgerock-am/setenv.sh b/docker/infrastructure/forgerock-am/setenv.sh index 8505910..501fff7 100755 --- a/docker/infrastructure/forgerock-am/setenv.sh +++ b/docker/infrastructure/forgerock-am/setenv.sh @@ -8,10 +8,9 @@ # Copyright (c) 2020-2023 Remal Software and Arnold Somogyi All rights reserved # ****************************************************************************** export IMAGE_NAME="remal-am-7.3" -export IMAGE_TAG="0.0.1" export IMAGE_DESCRIPTION="ForgeRock Directory Server 7.3.0" export IMAGE_AUTHOR="Arnold Somogyi " -export IMAGE_FROM="remal-tomcat-9:0.0.1" +export IMAGE_FROM="remal-tomcat-9:$4" export BUILD_TYPE=${1:-fat} export PUSH_IMAGE=${2:-false} export DOMAIN_NAME=${3:-hello.com} diff --git a/docker/infrastructure/forgerock-ds/Dockerfile b/docker/infrastructure/forgerock-ds/Dockerfile index 8a7aa9e..01b52fa 100644 --- a/docker/infrastructure/forgerock-ds/Dockerfile +++ b/docker/infrastructure/forgerock-ds/Dockerfile @@ -6,7 +6,7 @@ # # Copyright (c) 2020-2023 Remal Software and Arnold Somogyi All rights reserved # ****************************************************************************** -ARG IMAGE_FROM=${IMAGE_FROM} +ARG IMAGE_FROM="not-set" ARG BUILD_TYPE="fat" FROM ${IMAGE_FROM} AS base diff --git a/docker/infrastructure/forgerock-ds/RELEASE.md b/docker/infrastructure/forgerock-ds/RELEASE.md deleted file mode 100644 index 50a4785..0000000 --- a/docker/infrastructure/forgerock-ds/RELEASE.md +++ /dev/null @@ -1,12 +0,0 @@ -# Release info - -All notable changes to this project will be documented in this file. - -## [0.0.1] - 29/Jan/2023 -#### Added -* install forgerock directory-service server version 7.3 -* LDAP and config backup and restore scripts - - - trackgit-views - diff --git a/docker/infrastructure/forgerock-ds/container-scripts/init/30303_install-ds.sh b/docker/infrastructure/forgerock-ds/container-scripts/init/30303_install-ds.sh index 33dd07a..8a1c47d 100755 --- a/docker/infrastructure/forgerock-ds/container-scripts/init/30303_install-ds.sh +++ b/docker/infrastructure/forgerock-ds/container-scripts/init/30303_install-ds.sh @@ -156,7 +156,7 @@ KEYSTORE_HOME="/tmp" KEYSTORE_FILE="$FQDN.p12" KEYSTORE_PASSWORD="changeit" -generate_certificate "server" "$FQDN" +generate_certificate "serverClient" "$FQDN" "DNS:$FQDN,DNS:localhost,IP:127.0.0.1" copy_from_remote_machine "$PKI_HOST" "$SSH_USER" "$SSH_PASSWORD" "/opt/easy-rsa/pki/private/$KEYSTORE_FILE" "$KEYSTORE_HOME" if [ "$NEW_DS_DEPLOYMENT_KEY" == "true" ]; then generate_ds_deployment_key; fi generate_ds_master_key "$KEYSTORE_HOME/$KEYSTORE_FILE" "$KEYSTORE_PASSWORD" diff --git a/docker/infrastructure/forgerock-ds/setenv.sh b/docker/infrastructure/forgerock-ds/setenv.sh index 7d06ab4..271113a 100755 --- a/docker/infrastructure/forgerock-ds/setenv.sh +++ b/docker/infrastructure/forgerock-ds/setenv.sh @@ -8,10 +8,9 @@ # Copyright (c) 2020-2023 Remal Software and Arnold Somogyi All rights reserved # ****************************************************************************** export IMAGE_NAME="remal-ds-7.3" -export IMAGE_TAG="0.0.1" export IMAGE_DESCRIPTION="ForgeRock Directory Server 7.3.0" export IMAGE_AUTHOR="Arnold Somogyi " -export IMAGE_FROM="remal-openjdk-17:0.0.1" +export IMAGE_FROM="remal-openjdk-17:$4" export BUILD_TYPE=${1:-fat} export PUSH_IMAGE=${2:-false} export DOMAIN_NAME=${3:-hello.com} diff --git a/docker/infrastructure/hcp-consul/Dockerfile b/docker/infrastructure/hcp-consul/Dockerfile index c671ac7..406a143 100644 --- a/docker/infrastructure/hcp-consul/Dockerfile +++ b/docker/infrastructure/hcp-consul/Dockerfile @@ -6,7 +6,7 @@ # # Copyright (c) 2020-2023 Remal Software and Arnold Somogyi All rights reserved # ****************************************************************************** -ARG IMAGE_FROM=${IMAGE_FROM} +ARG IMAGE_FROM="not-set" ARG BUILD_TYPE="fat" FROM ${IMAGE_FROM} AS base @@ -22,7 +22,7 @@ ENV IMAGE_NAME="remal-consul" \ PKI_HOST="pki.remal.com" \ KEYSTORE_HOME="/tmp" \ \ - CONSUL_INSTALL_KIT="consul_1.18.2_linux_386.zip" \ + CONSUL_INSTALL_KIT="consul_1.20.1_linux_386.zip" \ CONSUL_CONFIG_TEMPLATE_DIR="/tmp/consul-config-template" \ CONSUL_CONFIG_DIR="/tmp/consul-config" \ CONSUL_DATA_DIR="/tmp/consul-data" diff --git a/docker/infrastructure/hcp-consul/RELEASE.md b/docker/infrastructure/hcp-consul/RELEASE.md deleted file mode 100644 index 9772bc2..0000000 --- a/docker/infrastructure/hcp-consul/RELEASE.md +++ /dev/null @@ -1,19 +0,0 @@ -# Release info - -All notable changes to this project will be documented in this file. - -## [0.0.1] - 23/Oct/2023 -#### Added -* install HashiCorp Consul version 1.17.2 - -## [1.1.0] - 09/Apr/2024 -#### Modified -* update HashiCorp Consul to version 1.18.1 - -## [1.2.0] - 20/May/2024 -#### Modified -* update HashiCorp Consul to version 1.18.2 - -* - trackgit-views - diff --git a/docker/infrastructure/hcp-consul/bin/consul_1.18.2_linux_386.zip b/docker/infrastructure/hcp-consul/bin/consul_1.20.1_linux_386.zip similarity index 100% rename from docker/infrastructure/hcp-consul/bin/consul_1.18.2_linux_386.zip rename to docker/infrastructure/hcp-consul/bin/consul_1.20.1_linux_386.zip diff --git a/docker/infrastructure/hcp-consul/setenv.sh b/docker/infrastructure/hcp-consul/setenv.sh index fe5b2e0..b9fb5f5 100755 --- a/docker/infrastructure/hcp-consul/setenv.sh +++ b/docker/infrastructure/hcp-consul/setenv.sh @@ -8,10 +8,9 @@ # Copyright (c) 2020-2023 Remal Software and Arnold Somogyi All rights reserved # ****************************************************************************** export IMAGE_NAME="remal-consul" -export IMAGE_TAG="1.2.0" export IMAGE_DESCRIPTION="HashiCorp Consul 1.18" export IMAGE_AUTHOR="Arnold Somogyi " -export IMAGE_FROM="remal-openjdk-21:0.0.1" +export IMAGE_FROM="remal-openjdk-21:$4" export BUILD_TYPE=${1:-fat} export PUSH_IMAGE=${2:-false} export DOMAIN_NAME=${3:-hello.com} diff --git a/docker/infrastructure/hcp-vault/Dockerfile b/docker/infrastructure/hcp-vault/Dockerfile index 5cd82ee..7593f65 100644 --- a/docker/infrastructure/hcp-vault/Dockerfile +++ b/docker/infrastructure/hcp-vault/Dockerfile @@ -6,7 +6,7 @@ # # Copyright (c) 2020-2023 Remal Software and Arnold Somogyi All rights reserved # ****************************************************************************** -ARG IMAGE_FROM=${IMAGE_FROM} +ARG IMAGE_FROM="not-set" ARG BUILD_TYPE="fat" FROM ${IMAGE_FROM} AS base diff --git a/docker/infrastructure/hcp-vault/README.md b/docker/infrastructure/hcp-vault/README.md index 74e3451..8914de8 100644 --- a/docker/infrastructure/hcp-vault/README.md +++ b/docker/infrastructure/hcp-vault/README.md @@ -6,7 +6,7 @@ version: '3' services: # ----- Private Certificate Authority Server ------------------------------- pki: - image: remal-private-ca:0.0.1 + image: remal-private-ca:0.9.0 container_name: pki hostname: pki.hello.com ports: @@ -20,7 +20,7 @@ services: # ----- Hashirorp Vault service -------------------------------------------- vault: - image: remal-vault:0.0.1 + image: remal-vault:0.9.0 container_name: vault hostname: vault.hello.com depends_on: diff --git a/docker/infrastructure/hcp-vault/RELEASE.md b/docker/infrastructure/hcp-vault/RELEASE.md deleted file mode 100644 index f20a00d..0000000 --- a/docker/infrastructure/hcp-vault/RELEASE.md +++ /dev/null @@ -1,11 +0,0 @@ -# Release info - -All notable changes to this project will be documented in this file. - -## [0.0.1] - 29/July/2023 -#### Added -* install HashiCorp Vault - - - trackgit-views - diff --git a/docker/infrastructure/hcp-vault/container-scripts/init/30503_install-vault.sh b/docker/infrastructure/hcp-vault/container-scripts/init/30503_install-vault.sh index 71d05c6..65c879f 100755 --- a/docker/infrastructure/hcp-vault/container-scripts/init/30503_install-vault.sh +++ b/docker/infrastructure/hcp-vault/container-scripts/init/30503_install-vault.sh @@ -115,7 +115,7 @@ log_start "$0" FQDN=$(hostname -f) CA_CERTIFICATE_FILENAME="ca" -generate_certificate "server" "$FQDN" +generate_certificate "server" "$FQDN" "DNS:$FQDN,DNS:localhost,IP:127.0.0.1" copy_from_remote_machine "$PKI_HOST" "$SSH_USER" "$SSH_PASSWORD" "/opt/easy-rsa/pki/private/$FQDN.key" "$KEYSTORE_HOME" copy_from_remote_machine "$PKI_HOST" "$SSH_USER" "$SSH_PASSWORD" "/opt/easy-rsa/pki/issued/$FQDN.crt" "$KEYSTORE_HOME" copy_from_remote_machine "$PKI_HOST" "$SSH_USER" "$SSH_PASSWORD" "/opt/easy-rsa/pki/$CA_CERTIFICATE_FILENAME.crt" "$KEYSTORE_HOME" diff --git a/docker/infrastructure/hcp-vault/setenv.sh b/docker/infrastructure/hcp-vault/setenv.sh index b116d7c..8645ffd 100755 --- a/docker/infrastructure/hcp-vault/setenv.sh +++ b/docker/infrastructure/hcp-vault/setenv.sh @@ -8,10 +8,9 @@ # Copyright (c) 2020-2023 Remal Software and Arnold Somogyi All rights reserved # ****************************************************************************** export IMAGE_NAME="remal-vault" -export IMAGE_TAG="0.0.1" export IMAGE_DESCRIPTION="HashiCorp Vault 1.14" export IMAGE_AUTHOR="Arnold Somogyi " -export IMAGE_FROM="remal-base:0.0.2" +export IMAGE_FROM="remal-base:$4" export BUILD_TYPE=${1:-fat} export PUSH_IMAGE=${2:-false} export DOMAIN_NAME=${3:-hello.com} diff --git a/docker/infrastructure/tomcat-9/Dockerfile b/docker/infrastructure/tomcat-9/Dockerfile index af79e7a..57c0b0d 100644 --- a/docker/infrastructure/tomcat-9/Dockerfile +++ b/docker/infrastructure/tomcat-9/Dockerfile @@ -6,7 +6,7 @@ # # Copyright (c) 2020-2023 Remal Software and Arnold Somogyi All rights reserved # ****************************************************************************** -ARG IMAGE_FROM=${IMAGE_FROM} +ARG IMAGE_FROM="not-set" ARG BUILD_TYPE="fat" FROM ${IMAGE_FROM} AS base diff --git a/docker/infrastructure/tomcat-9/RELEASE.md b/docker/infrastructure/tomcat-9/RELEASE.md deleted file mode 100644 index cf90ab8..0000000 --- a/docker/infrastructure/tomcat-9/RELEASE.md +++ /dev/null @@ -1,12 +0,0 @@ -# Release info - -All notable changes to this project will be documented in this file. - -## [0.0.1] - 28/Jan/2023 -#### Added -* Apache Tomcat 9 -* web console user: `admin`/`password` - - - trackgit-views - diff --git a/docker/infrastructure/tomcat-9/setenv.sh b/docker/infrastructure/tomcat-9/setenv.sh index 5f6798a..f5b9e4e 100755 --- a/docker/infrastructure/tomcat-9/setenv.sh +++ b/docker/infrastructure/tomcat-9/setenv.sh @@ -8,10 +8,9 @@ # Copyright (c) 2020-2023 Remal Software and Arnold Somogyi All rights reserved # ****************************************************************************** export IMAGE_NAME="remal-tomcat-9" -export IMAGE_TAG="0.0.1" export IMAGE_DESCRIPTION="Apache Tomcat 9 Docker image" export IMAGE_AUTHOR="Arnold Somogyi " -export IMAGE_FROM="remal-openjdk-11:0.0.1" +export IMAGE_FROM="remal-openjdk-11:$4" export BUILD_TYPE=${1:-fat} export PUSH_IMAGE=${2:-false} export DOMAIN_NAME=${3:-hello.com} diff --git a/docker/monitoring/grafana/Dockerfile b/docker/monitoring/grafana/Dockerfile index 8193c44..26f6f82 100644 --- a/docker/monitoring/grafana/Dockerfile +++ b/docker/monitoring/grafana/Dockerfile @@ -6,7 +6,7 @@ # # Copyright (c) 2020-2024 Remal Software and Arnold Somogyi All rights reserved # ****************************************************************************** -ARG IMAGE_FROM=${IMAGE_FROM} +ARG IMAGE_FROM="not-set" ARG BUILD_TYPE="fat" FROM ${IMAGE_FROM} AS base @@ -25,7 +25,7 @@ ENV IMAGE_NAME="remal-grafana" \ PROMETHEUS_PORT="9090" \ PROMETHEUS_PROTOCOL="https" \ \ - GRAFANA_INSTALL_KIT="grafana-enterprise-10.4.2.linux-amd64.tar.gz" \ + GRAFANA_INSTALL_KIT="grafana-enterprise-11.4.0.linux-amd64.tar.gz" \ GRAFANA_HOME="/opt/grafana" \ GRAFANA_PROTOCOL="https" \ GRAFANA_PORT=3000 \ diff --git a/docker/monitoring/grafana/RELEASE.md b/docker/monitoring/grafana/RELEASE.md deleted file mode 100644 index b98aaca..0000000 --- a/docker/monitoring/grafana/RELEASE.md +++ /dev/null @@ -1,11 +0,0 @@ -# Release info - -All notable changes to this project will be documented in this file. - -## [0.0.1] - 13/Apr/2024 -#### Added -* install `Grafana` - - - trackgit-views - diff --git a/docker/monitoring/grafana/bin/grafana-enterprise-10.4.2.linux-amd64.tar.gz b/docker/monitoring/grafana/bin/grafana-enterprise-11.4.0.linux-amd64.tar.gz similarity index 100% rename from docker/monitoring/grafana/bin/grafana-enterprise-10.4.2.linux-amd64.tar.gz rename to docker/monitoring/grafana/bin/grafana-enterprise-11.4.0.linux-amd64.tar.gz diff --git a/docker/monitoring/grafana/container-scripts/grafana-functions.sh b/docker/monitoring/grafana/container-scripts/grafana-functions.sh index 533ddfc..e6a1379 100755 --- a/docker/monitoring/grafana/container-scripts/grafana-functions.sh +++ b/docker/monitoring/grafana/container-scripts/grafana-functions.sh @@ -13,8 +13,10 @@ # Create Grafana data-sources using the Grafana rest endpoints. # ------------------------------------------------------------------------------ function create_grafana_datasources() { - local json_files + local json_files fqdn json_files="$GRAFANA_HOME/customization/datasources/*.json" + fqdn=$(hostname -f) + printf "%s | [INFO] creating Grafana data-sources...\n" "$(date +"%Y-%m-%d %H:%M:%S")" printf "%s | [DEBUG] GRAFANA_HOME: \"%s\"\n" "$(date +"%Y-%m-%d %H:%M:%S")" "$GRAFANA_HOME" @@ -23,6 +25,7 @@ function create_grafana_datasources() { printf "%s | [DEBUG] GRAFANA_USER: \"%s\"\n" "$(date +"%Y-%m-%d %H:%M:%S")" "$GRAFANA_USER" printf "%s | [DEBUG] GRAFANA_PASSWORD: \"%s\"\n" "$(date +"%Y-%m-%d %H:%M:%S")" "$GRAFANA_PASSWORD" printf "%s | [DEBUG] GRAFANA_PROTOCOL: \"%s\"\n" "$(date +"%Y-%m-%d %H:%M:%S")" "$GRAFANA_PROTOCOL" + printf "%s | [DEBUG] FQDN: \"%s\"\n" "$(date +"%Y-%m-%d %H:%M:%S")" "$fqdn" start_grafana for file in $json_files; do @@ -32,7 +35,7 @@ function create_grafana_datasources() { -H "Content-Type: application/json" \ --user "$GRAFANA_USER":"$GRAFANA_PASSWORD" \ --data-binary @"$file" \ - "$GRAFANA_PROTOCOL"://localhost:"$GRAFANA_PORT"/api/datasources + "$GRAFANA_PROTOCOL://$fqdn:$GRAFANA_PORT/api/datasources" printf "\n" done; stop_grafana @@ -75,7 +78,7 @@ function prepare_grafana_datasource_files() { local json_files json_files="$GRAFANA_HOME/customization/datasources/*.json" - printf "%s | [INFO] updating Grafana custom datasource json files...\n" "$(date +"%Y-%m-%d %H:%M:%S")" + printf "%s | [INFO] updating Grafana datasource json files...\n" "$(date +"%Y-%m-%d %H:%M:%S")" printf "%s | [DEBUG] PROMETHEUS_HOST: \"%s\"\n" "$(date +"%Y-%m-%d %H:%M:%S")" "$PROMETHEUS_HOST" printf "%s | [DEBUG] json_files: \"%s\"\n" "$(date +"%Y-%m-%d %H:%M:%S")" "$json_files" diff --git a/docker/monitoring/grafana/container-scripts/init/40203_add-ca-cert-to-linux.sh b/docker/monitoring/grafana/container-scripts/init/40203_add-ca-cert-to-linux.sh index 728e758..37e1da0 100755 --- a/docker/monitoring/grafana/container-scripts/init/40203_add-ca-cert-to-linux.sh +++ b/docker/monitoring/grafana/container-scripts/init/40203_add-ca-cert-to-linux.sh @@ -11,7 +11,7 @@ . /shared.sh log_start "$0" -cp /tmp/ca.crt /usr/local/share/ca-certificates/ +mkdir -p /usr/local/share/ca-certificates && cp /tmp/ca.crt /usr/local/share/ca-certificates/ cat /usr/local/share/ca-certificates/ca.crt >> /etc/ssl/certs/ca-certificates.crt log_end "$0" diff --git a/docker/monitoring/grafana/setenv.sh b/docker/monitoring/grafana/setenv.sh index 2118983..461bca7 100755 --- a/docker/monitoring/grafana/setenv.sh +++ b/docker/monitoring/grafana/setenv.sh @@ -8,10 +8,9 @@ # Copyright (c) 2020-2024 Remal Software and Arnold Somogyi All rights reserved # ****************************************************************************** export IMAGE_NAME="remal-grafana" -export IMAGE_TAG="0.0.1" export IMAGE_DESCRIPTION="Remal Grafana" export IMAGE_AUTHOR="Arnold Somogyi " -export IMAGE_FROM="remal-base:0.0.2" +export IMAGE_FROM="remal-base:$4" export BUILD_TYPE=${1:-fat} export PUSH_IMAGE=${2:-false} export DOMAIN_NAME=${3:-hello.com} diff --git a/docker/monitoring/prometheus/Dockerfile b/docker/monitoring/prometheus/Dockerfile index 8d36ced..97f5dca 100644 --- a/docker/monitoring/prometheus/Dockerfile +++ b/docker/monitoring/prometheus/Dockerfile @@ -6,7 +6,7 @@ # # Copyright (c) 2020-2024 Remal Software and Arnold Somogyi All rights reserved # ****************************************************************************** -ARG IMAGE_FROM=${IMAGE_FROM} +ARG IMAGE_FROM="not-set" ARG BUILD_TYPE="fat" FROM ${IMAGE_FROM} AS base @@ -23,7 +23,7 @@ ENV IMAGE_NAME="remal-prometheus" \ KEYSTORE_HOME="/tmp" \ CONSUL_HOST="consul.hello.com" \ \ - PROMETHEUS_INSTALL_KIT="prometheus-2.51.1.linux-amd64.tar.gz" \ + PROMETHEUS_INSTALL_KIT="prometheus-3.0.1.linux-amd64.tar.gz" \ PROMETHEUS_HOME="/opt/prometheus" \ PROMETHEUS_CONFIG="/opt/prometheus/prometheus.yml" \ PROMETHEUS_WEB_CONFIG="/opt/prometheus/web-config.yml" \ diff --git a/docker/monitoring/prometheus/RELEASE.md b/docker/monitoring/prometheus/RELEASE.md deleted file mode 100644 index d9aa715..0000000 --- a/docker/monitoring/prometheus/RELEASE.md +++ /dev/null @@ -1,11 +0,0 @@ -# Release info - -All notable changes to this project will be documented in this file. - -## [0.0.1] - 06/Apr/2024 -#### Added -* install `Prometheus` - - - trackgit-views - diff --git a/docker/monitoring/prometheus/bin/prometheus-2.51.1.linux-amd64.tar.gz b/docker/monitoring/prometheus/bin/prometheus-3.0.1.linux-amd64.tar.gz similarity index 100% rename from docker/monitoring/prometheus/bin/prometheus-2.51.1.linux-amd64.tar.gz rename to docker/monitoring/prometheus/bin/prometheus-3.0.1.linux-amd64.tar.gz diff --git a/docker/monitoring/prometheus/setenv.sh b/docker/monitoring/prometheus/setenv.sh index 500fd8e..4002c2e 100755 --- a/docker/monitoring/prometheus/setenv.sh +++ b/docker/monitoring/prometheus/setenv.sh @@ -8,10 +8,9 @@ # Copyright (c) 2020-2024 Remal Software and Arnold Somogyi All rights reserved # ****************************************************************************** export IMAGE_NAME="remal-prometheus" -export IMAGE_TAG="0.0.1" export IMAGE_DESCRIPTION="Remal Prometheus" export IMAGE_AUTHOR="Arnold Somogyi " -export IMAGE_FROM="remal-base:0.0.2" +export IMAGE_FROM="remal-base:$4" export BUILD_TYPE=${1:-fat} export PUSH_IMAGE=${2:-false} export DOMAIN_NAME=${3:-hello.com} diff --git a/gombi.sh b/gombi.sh index 71aac3c..d7fec86 100755 --- a/gombi.sh +++ b/gombi.sh @@ -40,6 +40,54 @@ COLOR_YELLOW="\e[38;5;226m" STYLE_BOLD="\033[1m" STYLE_DEFAULT="\033[0m" +# ------------------------------------------------------------------------------ +# Copy artifact to a Docker Volume. +# +# Arguments: +# arg 1: project name +# ------------------------------------------------------------------------------ +function copy_to_volume { + local project source_dir target_dir + project="$1" + source_dir="$WORKSPACE/projects/$project/target/" + target_dir="$WORKSPACE/bin/$project" + + printf "\n%b> coping artifact to a Docker shared volume...%b\n" "$COLOR_YELLOW" "$STYLE_DEFAULT" + printf " source: '%s'\n" "$source_dir$project-*.jar" + printf " target: '%s'\n" "$target_dir" + + # to ensure this never expands to /* + rm -rf "${target_dir:?}/"* + mkdir -p "$target_dir" + rsync --archive \ + --include '*.jar' \ + --exclude '**' \ + --verbose \ + "$source_dir" \ + "$target_dir" +} + +# ------------------------------------------------------------------------------ +# Deploy a docker container and run it in the background. +# +# Arguments: +# arg 1: relative directory that points to the image source code +# ------------------------------------------------------------------------------ +function demo_start { + local dir environment_file docker_compose_file + dir="$1" + environment_file="$WORKSPACE/$dir/$ENVIRONMENT_FILE" + docker_compose_file="$WORKSPACE/$dir/docker-compose.yml" + + printf "\n%b> starting the '%s' docker stack...%b\n" "$COLOR_YELLOW" "Demo" "$STYLE_DEFAULT" + printf " environment-file: '%s'\n" "$environment_file" + printf " docker-compose.yml: '%s'\n" "$docker_compose_file" + + copy_to_volume "remal-gombi-user-service" + copy_to_volume "remal-gombi-welcome-service" + docker compose --env-file="$environment_file" -f "$docker_compose_file" up +} + # ------------------------------------------------------------------------------ # Show the logs of running Docker containers. # ------------------------------------------------------------------------------ @@ -72,26 +120,6 @@ function docker_container_remove { fi } -# ------------------------------------------------------------------------------ -# Deploy a docker container and run it in the background. -# -# Arguments: -# arg 1: task description string -# arg 2: relative directory that points to the image source code -# ------------------------------------------------------------------------------ -function docker_stack_up { - local title dir environment_file docker_compose_file - title="$1" - dir="$2" - environment_file="$WORKSPACE/$dir/$ENVIRONMENT_FILE" - docker_compose_file="$WORKSPACE/$dir/docker-compose.yml" - - printf "\n%b> starting the '%s' docker stack...%b\n" "$COLOR_YELLOW" "$title" "$STYLE_DEFAULT" - printf "%b environment-file: '%s'%b\n" "$COLOR_YELLOW" "$environment_file" "$STYLE_DEFAULT" - printf "%b docker-compose.yml: '%s'%b\n" "$COLOR_YELLOW" "$docker_compose_file" "$STYLE_DEFAULT" - docker-compose --env-file="$environment_file" -f "$docker_compose_file" up -} - # ------------------------------------------------------------------------------ # Show the running docker containers' details. # ------------------------------------------------------------------------------ @@ -152,7 +180,7 @@ function docker_image_show { function get_name { local string string="$1" - cut -d';' -f1 <<<"$string" | echo "'$(cat)'" + cut -d';' -f1 <<<"$string" | echo "$(cat)" } # ------------------------------------------------------------------------------ @@ -235,7 +263,7 @@ function show_help() { printf " %be2: build %s image%b\n" "$COLOR_GREEN" "$(get_name "$LABEL_JAVA_21_POSTGRES_RUNNER")" "$STYLE_DEFAULT" printf " ------------------------------------------------------------\n" printf " %bstart a Docker environment%b\n" "$COLOR_YELLOW" "$STYLE_DEFAULT" - printf " %bi1: start the 'hello-world' Docker stack%b\n" "$COLOR_GREEN" "$STYLE_DEFAULT" + printf " %bi1: start the 'Demo' Docker stack%b\n" "$COLOR_GREEN" "$STYLE_DEFAULT" printf " ------------------------------------------------------------\n" printf " %bu: list Remal Docker images%b\n" "$COLOR_YELLOW" "$STYLE_DEFAULT" printf " %bv: list Remal Docker containers%b\n" "$COLOR_YELLOW" "$STYLE_DEFAULT" @@ -244,7 +272,7 @@ function show_help() { printf " %by: remove of all Remal Docker images%b\n" "$COLOR_YELLOW" "$STYLE_DEFAULT" printf "\n" printf "Contact: arnold.somogyi@gmail.com\n" - printf "Copyright (c) 2020-2023 Remal Software and Arnold Somogyi All rights reserved\n" + printf "Copyright (c) 2020-2024 Remal Software and Arnold Somogyi All rights reserved\n" fi } @@ -329,9 +357,9 @@ if match "$COMMAND" "u"; then docker_image_show; fi if match "$COMMAND" "v"; then docker_container_show; fi # docker runners -if match "$COMMAND" "i1"; then docker_stack_up "hello-world" "projects"; fi +if match "$COMMAND" "i1"; then demo_start "projects"; fi if match "$COMMAND" "w"; then docker_container_logs; fi show_execution_time "$START" "$#" -printf "Bye!\n" \ No newline at end of file +printf "Bye!\n" diff --git a/projects/docker-compose.yml b/projects/docker-compose.yml index b031cb6..60982c8 100644 --- a/projects/docker-compose.yml +++ b/projects/docker-compose.yml @@ -1,8 +1,7 @@ -version: '3' services: # ----- Private Certificate Authority Server ------------------------------- pki: - image: remal-private-ca:0.0.1 + image: remal-private-ca:0.9.0 container_name: pki.${DOMAIN_NAME} hostname: pki.${DOMAIN_NAME} ports: @@ -16,7 +15,7 @@ services: # ----- Hashicorp Consul --------------------------------------------------- consul: - image: remal-consul:1.2.0 + image: remal-consul:0.9.0 container_name: consul.${DOMAIN_NAME} hostname: consul.${DOMAIN_NAME} depends_on: @@ -27,26 +26,9 @@ services: environment: - PKI_HOST=pki.${DOMAIN_NAME} - # ----- echo-service-1 ---------------------------------------------------- - echo-service-1: - image: remal-java-21-runner:0.5.0 - container_name: echo-service-1.${DOMAIN_NAME} - hostname: echo-service-1.${DOMAIN_NAME} - depends_on: - - consul - ports: - - "14212:22" # SSH - - "14213:8000" # JVM debug - - "14214:8443" # HTTPS - environment: - - PKI_HOST=pki.${DOMAIN_NAME} - - CONSUL_SERVER_HOSTNAME=consul.${DOMAIN_NAME} - volumes: - - $HOME/dev/workspace/java/remal/bin/echo-service:/jar-to-run - # ----- user-service-1 ----------------------------------------------------- user-service-1: - image: remal-java-21-postgres-runner:0.0.2 + image: remal-java-21-postgres-runner:0.9.0 container_name: user-service-1.${DOMAIN_NAME} hostname: user-service-1.${DOMAIN_NAME} depends_on: @@ -64,11 +46,11 @@ services: - DB_APP_USER=application - DB_APP_PASSWORD=password volumes: - - $HOME/dev/workspace/java/remal/bin/user-service:/jar-to-run + - $HOME/Java/gombi/bin/remal-gombi-user-service:/jar-to-run # ----- user-service-2 ----------------------------------------------------- user-service-2: - image: remal-java-21-postgres-runner:0.0.2 + image: remal-java-21-postgres-runner:0.9.0 container_name: user-service-2.${DOMAIN_NAME} hostname: user-service-2.${DOMAIN_NAME} depends_on: @@ -86,11 +68,28 @@ services: - DB_APP_USER=application - DB_APP_PASSWORD=password volumes: - - $HOME/dev/workspace/java/remal/bin/user-service:/jar-to-run + - $HOME/Java/gombi/bin/remal-gombi-user-service:/jar-to-run + + # ----- welcome-service-1 -------------------------------------------------- + welcome-service-1: + image: remal-java-21-runner:0.9.0 + container_name: welcome-service-1.${DOMAIN_NAME} + hostname: welcome-service-1.${DOMAIN_NAME} + depends_on: + - consul + ports: + - "14212:22" # SSH + - "14213:8000" # JVM debug + - "14214:8443" # HTTPS + environment: + - PKI_HOST=pki.${DOMAIN_NAME} + - CONSUL_SERVER_HOSTNAME=consul.${DOMAIN_NAME} + volumes: + - $HOME/Java/gombi/bin/remal-gombi-welcome-service:/jar-to-run # ----- Monitoring: Prometheus --------------------------------------------- prometheus: - image: remal-prometheus:0.0.1 + image: remal-prometheus:0.9.0 container_name: prometheus.${DOMAIN_NAME} hostname: prometheus.${DOMAIN_NAME} depends_on: @@ -104,7 +103,7 @@ services: # ----- Monitoring: Grafana ------------------------------------------------ grafana: - image: remal-grafana:0.0.1 + image: remal-grafana:0.9.0 container_name: grafana.${DOMAIN_NAME} hostname: grafana.${DOMAIN_NAME} depends_on: diff --git a/projects/echo-service/src/main/java/com/remal/gombi/hello/service/echo/configuration/RestTemplateConfiguration.java b/projects/echo-service/src/main/java/com/remal/gombi/hello/service/echo/configuration/RestTemplateConfiguration.java deleted file mode 100644 index ae4e27e..0000000 --- a/projects/echo-service/src/main/java/com/remal/gombi/hello/service/echo/configuration/RestTemplateConfiguration.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2020-2024 Remal Software and Arnold Somogyi All rights reserved - * - * Since: February 2024 - * Author: Arnold Somogyi - * - * Description: - * Spring bean configuration. - */ -package com.remal.gombi.hello.service.echo.configuration; - -import com.remal.gombi.hello.service.echo.exception.InitializationException; -import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; -import org.apache.hc.client5.http.impl.classic.HttpClients; -import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder; -import org.apache.hc.client5.http.io.HttpClientConnectionManager; -import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory; -import org.apache.hc.core5.ssl.SSLContextBuilder; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.io.ResourceLoader; -import org.springframework.http.client.ClientHttpRequestFactory; -import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; -import org.springframework.web.client.RestTemplate; - -import javax.net.ssl.SSLContext; -import java.io.File; -import java.io.IOException; -import java.security.KeyManagementException; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.cert.CertificateException; - -@Configuration -public class RestTemplateConfiguration { - - private final ResourceLoader resourceLoader; - - @Value("${server.ssl.key-store}") - private String trustStore; - - @Value("${server.ssl.key-store-password}") - private String trustStorePassword; - - public RestTemplateConfiguration(ResourceLoader resourceLoader) { - this.resourceLoader = resourceLoader; - } - - /** - * Rest template configuration for HTTPS. - * - * @return restTemplate instance - */ - @Bean - public RestTemplate restTemplate() { - try { - File trustStoreFileResource = resourceLoader.getResource(trustStore).getFile(); - SSLContext sslContext = new SSLContextBuilder() - .loadTrustMaterial(trustStoreFileResource, trustStorePassword.toCharArray()) - .build(); - SSLConnectionSocketFactory connectionFactory = new SSLConnectionSocketFactory(sslContext); - HttpClientConnectionManager connectionManager = PoolingHttpClientConnectionManagerBuilder.create() - .setSSLSocketFactory(connectionFactory) - .build(); - CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(connectionManager).build(); - ClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient); - return new RestTemplate(requestFactory); - - } catch (IOException - | NoSuchAlgorithmException - | KeyStoreException - | CertificateException - | KeyManagementException e) { - throw new InitializationException("Error while initializing the RestTemplate.", e); - } - } -} diff --git a/projects/echo-service/src/main/java/com/remal/gombi/hello/service/echo/controller/EchoController.java b/projects/echo-service/src/main/java/com/remal/gombi/hello/service/echo/controller/EchoController.java deleted file mode 100644 index b52f2bf..0000000 --- a/projects/echo-service/src/main/java/com/remal/gombi/hello/service/echo/controller/EchoController.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2020-2024 Remal Software and Arnold Somogyi All rights reserved - * - * Since: February 2024 - * Author: Arnold Somogyi - * - * Description: - * Spring REST endpoint. - */ -package com.remal.gombi.hello.service.echo.controller; - -import com.remal.gombi.hello.commons.model.User; -import com.remal.gombi.hello.commons.monitoring.MethodStatistics; -import com.remal.gombi.hello.service.echo.service.ConfigurationService; -import com.remal.gombi.hello.service.echo.service.UserService; -import lombok.extern.slf4j.Slf4j; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.util.Objects; - -@Slf4j -@RestController -@RequestMapping("/api") -public class EchoController { - - private final ConfigurationService configuration; - private final UserService userService; - - /** - * Constructor with object injections. - * - * @param userService object to be injected by spring - */ - public EchoController(UserService userService, - ConfigurationService configuration) { - this.userService = userService; - this.configuration = configuration; - } - - private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyy-MM-dd HH:mm:ss"); - - @GetMapping("echo") - @MethodStatistics - public String echo() { - String description = (Math.random() < 0.5) ? configuration.getOptionA() : configuration.getOptionB(); - User user = userService.getUser("1"); - user.setDescription(description); - - String now = LocalDateTime.now().format(DATE_TIME_FORMATTER); - String message = String.format("Hello %s, the time is %s.", user.getEmail(), now); - message += Objects.nonNull((user.getDescription())) ? "
" + user.getDescription() : ""; - - return message; - } - - @GetMapping("joke") - @MethodStatistics - public String joke() { - return "When Alexander Graham Bell invented the telephone, he had three missed calls from Chuck Norris"; - } -} diff --git a/projects/echo-service/src/main/java/com/remal/gombi/hello/service/echo/exception/InitializationException.java b/projects/echo-service/src/main/java/com/remal/gombi/hello/service/echo/exception/InitializationException.java deleted file mode 100644 index e51b483..0000000 --- a/projects/echo-service/src/main/java/com/remal/gombi/hello/service/echo/exception/InitializationException.java +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (c) 2020-2024 Remal Software and Arnold Somogyi All rights reserved - * - * Since: February 2024 - * Author: Arnold Somogyi - * - * Description: - * Custom exception class. - */ -package com.remal.gombi.hello.service.echo.exception; - -public class InitializationException extends RuntimeException { - - public InitializationException(String message, Exception e) { - super(message, e); - } -} diff --git a/projects/hello-commons/pom.xml b/projects/hello-commons/pom.xml deleted file mode 100644 index fb6348a..0000000 --- a/projects/hello-commons/pom.xml +++ /dev/null @@ -1,87 +0,0 @@ - - - - 4.0.0 - - com.remal.hello - hello-commons - 0.0.1 - hello-commons - Hello REST service. - - - 21 - 21 - UTF-8 - - 6.0.0 - 1.18.32 - 1.13.0 - 4.1.1 - 3.3.0 - - - - - - org.springframework.boot - spring-boot-starter-aop - ${spring.boot.version} - provided - - - org.springframework.cloud - spring-cloud-starter-consul-discovery - ${spring.cloud.starter.consul.version} - provided - - - - org.projectlombok - lombok - ${lombok.version} - provided - - - - io.micrometer - micrometer-registry-prometheus - ${micrometer.version} - - - - jakarta.servlet - jakarta.servlet-api - ${jakarta.servlet.api.version} - provided - - - - - - - - org.springframework.boot - spring-boot-maven-plugin - ${spring.boot.version} - - - - build-info - - - - - - - \ No newline at end of file diff --git a/projects/index.html b/projects/index.html new file mode 100644 index 0000000..1f13a6a --- /dev/null +++ b/projects/index.html @@ -0,0 +1,305 @@ + + + + + Remal Gombi Demo + + + +

Remal-Gombi Demo Docker Containers and Ports

+ +
+ + + + + + + + + + + + +
Open terminal:sshpass -p password ssh -oStrictHostKeyChecking=no root@localhost -p <port>
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Container nameDescriptionPortsCommands
user-service-1Remal sample user-service + + + + + + + + + + + + + + + + + + + + + + + + + +
14112:22SSH
14113:8000JVM debug
14114:8443HTTPS
14115:5432Postgres
+
+ GET https://localhost:14114/api/user/zappee +
+ POST https://localhost:14114/api/user +

+ Actuator: https://localhost:14114/actuator +
+ JDBC: jdbc:postgresql://localhost:14115/postgres (postgres/password) +
user-service-2Remal sample user-service + + + + + + + + + + + + + + + + + + + + + + + + + +
14122:22SSH
14123:8000JVM debug
14124:8443HTTPS
14125:5432Postgres
+
+ GET https://localhost:14124/api/user/zappee +
+ POST https://localhost:14114/api/user +

+ Actuator: https://localhost:14124/actuator +
+ JDBC: jdbc:postgresql://localhost:14125/postgres (postgres/password) +
welcome-service-1Remal sample welcome-service + + + + + + + + + + + + + + + + + + + +
14212:22SSH
14213:8000JVM debug
14214:8443HTTPS
+
+ Rest: https://localhost:14214/api/welcome/zappee +
+ Rest: https://localhost:14214/api/joke +
+ Actuator: https://localhost:14214/actuator +
grafana + Grafana +
+ It is a tool used to analyze and visualize data. +
+ + + + + + + + + + + + + + + + + + + +
13082:22SSH
13083:3000web console, HTTPS
:1331container up signal
+
+ https://localhost:13083 (admin/password) +
prometheus + Prometheus +
+ An open-source monitoring system with a dimensional data model. +
+ + + + + + + + + + + + + + + + + + + +
13072:22SSH
13073:9090web console, HTTPS
:1331container up signal
+
+ https://localhost:13073 +
consul + HashiCorp Consul +
+ Tool for managing your infrastructure's services and configs. +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
13062:22SSH
13063:8501web console, HTTPS
:8500Hashicorp Consul port
:1331container up signal
+
+ https://localhost:13063 +
private-caprivate Certificate Authority server + + + + + + + + + + + + + +
13012:22SSH
:1331container up signal
+
+ + \ No newline at end of file diff --git a/projects/pom.xml b/projects/pom.xml index b7961aa..9de25df 100644 --- a/projects/pom.xml +++ b/projects/pom.xml @@ -13,14 +13,102 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - c - hello + + org.springframework.boot + spring-boot-starter-parent + 3.4.1 + + + com.remal.gombi + gombi 0.1.0 pom + + full + 21 + UTF-8 + + 3.4.1 + 4.2.0 + 1.18.36 + 1.14.2 + 6.0.0 + 42.7.3 + + + + + + + org.springframework.boot + spring-boot-starter-aop + ${spring-boot.version} + provided + + + org.springframework.cloud + spring-cloud-starter-consul-discovery + ${spring-cloud-starter-consul.version} + provided + + + org.springframework.cloud + spring-cloud-starter-consul-config + ${spring-cloud-starter-consul.version} + + + + org.projectlombok + lombok + ${lombok.version} + provided + + + + io.micrometer + micrometer-registry-prometheus + ${micrometer.version} + + + + jakarta.servlet + jakarta.servlet-api + ${jakarta.servlet.api.version} + provided + + + + org.postgresql + postgresql + ${postgresql.version} + + + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot.version} + + + + build-info + + + + + + + + - hello-commons - echo-service - user-service + remal-gombi-commons + remal-gombi-user-service + remal-gombi-welcome-service diff --git a/projects/remal-gombi-commons/pom.xml b/projects/remal-gombi-commons/pom.xml new file mode 100644 index 0000000..ac7661d --- /dev/null +++ b/projects/remal-gombi-commons/pom.xml @@ -0,0 +1,55 @@ + + + + 4.0.0 + + remal-gombi-commons + 0.1.0 + gombi-commons + Common functions used by the Remal Gombi projects. + jar + + + com.remal.gombi + gombi + 0.1.0 + + + + + + org.springframework.boot + spring-boot-starter-aop + + + org.springframework.cloud + spring-cloud-starter-consul-discovery + + + + org.projectlombok + lombok + + + + io.micrometer + micrometer-registry-prometheus + + + + jakarta.servlet + jakarta.servlet-api + + + + \ No newline at end of file diff --git a/projects/hello-commons/src/main/java/com/remal/gombi/hello/commons/Internet.java b/projects/remal-gombi-commons/src/main/java/com/remal/gombi/hello/commons/Internet.java similarity index 100% rename from projects/hello-commons/src/main/java/com/remal/gombi/hello/commons/Internet.java rename to projects/remal-gombi-commons/src/main/java/com/remal/gombi/hello/commons/Internet.java diff --git a/projects/remal-gombi-commons/src/main/java/com/remal/gombi/hello/commons/exception/EntryNotExistException.java b/projects/remal-gombi-commons/src/main/java/com/remal/gombi/hello/commons/exception/EntryNotExistException.java new file mode 100644 index 0000000..f68bda1 --- /dev/null +++ b/projects/remal-gombi-commons/src/main/java/com/remal/gombi/hello/commons/exception/EntryNotExistException.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2020-2025 Remal Software and Arnold Somogyi All rights reserved + * + * Since: January 2025 + * Author: Arnold Somogyi + * + * Description: + * A runtime exception that is thrown in case of empty result. It + * generates a HTTP 404 response. + */ +package com.remal.gombi.hello.commons.exception; + +import lombok.extern.slf4j.Slf4j; + +import java.util.Objects; + +@Slf4j +public class EntryNotExistException extends RuntimeException { + + /** + * Exception can be thrown if the result of a search returns with + * empty/null element. + * + * @param clazz type of the result + * @param field name of the field being searched + * @param value identifier of the item you are looking for + */ + public EntryNotExistException(Class clazz, String field, String value) { + super(String.format( + "The entry was not found: {class: \"%s\", field: \"%s\", value: \"%s\"}", + Objects.isNull(clazz) ? "null" : clazz.getCanonicalName(), + field, + value)); + log.error(getMessage()); + } +} diff --git a/projects/hello-commons/src/main/java/com/remal/gombi/hello/commons/model/User.java b/projects/remal-gombi-commons/src/main/java/com/remal/gombi/hello/commons/model/User.java similarity index 93% rename from projects/hello-commons/src/main/java/com/remal/gombi/hello/commons/model/User.java rename to projects/remal-gombi-commons/src/main/java/com/remal/gombi/hello/commons/model/User.java index d490f19..fc81173 100644 --- a/projects/hello-commons/src/main/java/com/remal/gombi/hello/commons/model/User.java +++ b/projects/remal-gombi-commons/src/main/java/com/remal/gombi/hello/commons/model/User.java @@ -18,6 +18,7 @@ @ToString public class User { private String username; + private String firstName; private String email; private String description; } diff --git a/projects/hello-commons/src/main/java/com/remal/gombi/hello/commons/monitoring/MethodStatistics.java b/projects/remal-gombi-commons/src/main/java/com/remal/gombi/hello/commons/monitoring/MethodStatistics.java similarity index 100% rename from projects/hello-commons/src/main/java/com/remal/gombi/hello/commons/monitoring/MethodStatistics.java rename to projects/remal-gombi-commons/src/main/java/com/remal/gombi/hello/commons/monitoring/MethodStatistics.java diff --git a/projects/hello-commons/src/main/java/com/remal/gombi/hello/commons/monitoring/MethodStatisticsAspect.java b/projects/remal-gombi-commons/src/main/java/com/remal/gombi/hello/commons/monitoring/MethodStatisticsAspect.java similarity index 62% rename from projects/hello-commons/src/main/java/com/remal/gombi/hello/commons/monitoring/MethodStatisticsAspect.java rename to projects/remal-gombi-commons/src/main/java/com/remal/gombi/hello/commons/monitoring/MethodStatisticsAspect.java index 076c6af..f082f6a 100644 --- a/projects/hello-commons/src/main/java/com/remal/gombi/hello/commons/monitoring/MethodStatisticsAspect.java +++ b/projects/remal-gombi-commons/src/main/java/com/remal/gombi/hello/commons/monitoring/MethodStatisticsAspect.java @@ -31,8 +31,11 @@ enum ProceedStatus { ok, error } - private static final String TEMPLATE_WITH_RETURN = "method call ended: {name: {}, arguments: {}, return: {}, execution-in-ms: {}}"; - private static final String TEMPLATE_NO_RETURN = "method call ended: {name: {}, arguments: {}, return: , execution-in-ms: {}}"; + private static final String TEMPLATE_WITH_RETURN = "< call ended: {name: {}, arguments: {}, return: {}, execution-in-ms: {}}"; + private static final String TEMPLATE_NO_RETURN = "< call ended: {name: {}, arguments: {}, return: , execution-in-ms: {}}"; + + private static final String METER_NAME_COUNTER = "remal_method_calls"; + private static final String METER_NAME_TIMER = "remal_method_execution_time"; private final CompositeMeterRegistry meterRegistry; @@ -48,6 +51,7 @@ public MethodStatisticsAspect(CompositeMeterRegistry meterRegistry) { @Around("@annotation(com.remal.gombi.hello.commons.monitoring.MethodStatistics)") public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable { long startInNano = System.nanoTime(); + long endInNano = -1; String className = joinPoint.getTarget().getClass().getSimpleName(); String methodName = joinPoint.getSignature().getName(); String fullQualifiedMethodName = className + "." + methodName; @@ -60,9 +64,9 @@ public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable { String arguments = getArgumentsAsString(joinPoint); if (parameters.logToLogfile()) { if (arguments.isEmpty()) { - log.debug("calling the {}() method...", fullQualifiedMethodName); + log.debug("> calling the {}()...", fullQualifiedMethodName); } else { - log.debug("calling the {}() method with parameters: {}...", fullQualifiedMethodName, arguments); + log.debug("> calling the {}() with parameters: {}...", fullQualifiedMethodName, arguments); } } @@ -71,28 +75,33 @@ public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable { // log the result of the call if (parameters.countMethodCalls()) { - getCounter(fullQualifiedMethodName, ProceedStatus.ok).increment(); + registerMethodCall(fullQualifiedMethodName, ProceedStatus.ok); } String returnValue = getReturnValueAsString(o); - long endInMilli = (System.nanoTime() - startInNano) / 1000000; + endInNano = System.nanoTime() - startInNano; + var endInMilliseconds = TimeUnit.MILLISECONDS.convert(endInNano, TimeUnit.NANOSECONDS); if (parameters.logToLogfile()) { if (Objects.nonNull(o)) { - log.debug(TEMPLATE_WITH_RETURN, fullQualifiedMethodName, arguments, returnValue, endInMilli); + log.debug(TEMPLATE_WITH_RETURN, fullQualifiedMethodName, arguments, returnValue, endInMilliseconds); } else { - log.debug(TEMPLATE_NO_RETURN, fullQualifiedMethodName, arguments, endInMilli); + log.debug(TEMPLATE_NO_RETURN, fullQualifiedMethodName, arguments, endInMilliseconds); } } return o; } catch(Throwable t) { if (parameters.countMethodCalls()) { - getCounter(fullQualifiedMethodName, ProceedStatus.error).increment(); + registerMethodCall(fullQualifiedMethodName, ProceedStatus.error); } throw new Throwable(t); } finally { if (parameters.executionTimeStatistic()) { - getTimer(fullQualifiedMethodName).record(System.nanoTime() - startInNano, TimeUnit.NANOSECONDS); + if (endInNano == -1) { + // an unexpected exception has appeared during the method call + endInNano = System.nanoTime() - startInNano; + } + registerMethodExecutionTime(fullQualifiedMethodName, endInNano); } } } @@ -124,19 +133,27 @@ private String getReturnValueAsString(Object object) { return ""; } - private Timer getTimer(String id) { - return Timer - .builder("java_method_execution_time") + private void registerMethodExecutionTime(String id, long executionTimeInNano) { + var endInMilliseconds = TimeUnit.MILLISECONDS.convert(executionTimeInNano, TimeUnit.NANOSECONDS); + log.debug("registering the method execution time to Micrometer: " + + "{meter-name: \"{}\", method: \"{}\", execution-time-in-ms: {}}...", + METER_NAME_TIMER, id, endInMilliseconds); + Timer + .builder(METER_NAME_TIMER) .tag("id", id) - .description("execution time of a Java method") - .register(meterRegistry); + .description("Execution time of a Java method") + .register(meterRegistry) + .record(executionTimeInNano, TimeUnit.NANOSECONDS); } - private Counter getCounter(String id, ProceedStatus status) { - return Counter - .builder("java_method_call") + private void registerMethodCall(String id, ProceedStatus status) { + log.debug("registering the method call to Micrometer: {meter-name: \"{}\", method: \"{}\", status: \"{}\"}", + METER_NAME_COUNTER, id, status.name()); + Counter + .builder(METER_NAME_COUNTER) .tags("id", id, "status", status.name()) - .description("total number of the method calls") - .register(meterRegistry); + .description("Total number of the method calls") + .register(meterRegistry) + .increment(); } } diff --git a/projects/hello-commons/src/main/java/com/remal/gombi/hello/commons/spring/discovery/ConsulServiceDiscovery.java b/projects/remal-gombi-commons/src/main/java/com/remal/gombi/hello/commons/spring/discovery/ConsulServiceDiscovery.java similarity index 60% rename from projects/hello-commons/src/main/java/com/remal/gombi/hello/commons/spring/discovery/ConsulServiceDiscovery.java rename to projects/remal-gombi-commons/src/main/java/com/remal/gombi/hello/commons/spring/discovery/ConsulServiceDiscovery.java index 293bc5e..4e7f926 100644 --- a/projects/hello-commons/src/main/java/com/remal/gombi/hello/commons/spring/discovery/ConsulServiceDiscovery.java +++ b/projects/remal-gombi-commons/src/main/java/com/remal/gombi/hello/commons/spring/discovery/ConsulServiceDiscovery.java @@ -36,13 +36,19 @@ public URI getServiceUri(String serviceId) { log.debug("getting service URIs for {}...", serviceId); List serviceInstances = discoveryClient.getInstances(serviceId); - log.debug("service URIs for {}: {}", - serviceId, - serviceInstances.stream().map(x -> x.getUri().toString()).collect(Collectors.joining(", "))); - - int randomIndex = ThreadLocalRandom.current().nextInt(serviceInstances.size()); - URI uri = serviceInstances.get(randomIndex).getUri(); - log.info("selected URI for {} is {}", serviceId, uri); - return uri; + var serviceUris = serviceInstances.size(); + if (serviceUris == 0) { + var message = String.format("No service URL registered in the service-registry for \"%s\".", serviceId); + throw new IllegalArgumentException(message); + } else { + log.debug("service URIs for {}: {}", + serviceId, + serviceInstances.stream().map(x -> x.getUri().toString()).collect(Collectors.joining(", "))); + + int randomIndex = ThreadLocalRandom.current().nextInt(serviceInstances.size()); + URI uri = serviceInstances.get(randomIndex).getUri(); + log.info("selected URI for {} is {}", serviceId, uri); + return uri; + } } } diff --git a/projects/user-service/README.md b/projects/remal-gombi-user-service/README.md similarity index 100% rename from projects/user-service/README.md rename to projects/remal-gombi-user-service/README.md diff --git a/projects/user-service/pom.xml b/projects/remal-gombi-user-service/pom.xml similarity index 62% rename from projects/user-service/pom.xml rename to projects/remal-gombi-user-service/pom.xml index 59d1f82..f9d3e24 100644 --- a/projects/user-service/pom.xml +++ b/projects/remal-gombi-user-service/pom.xml @@ -14,26 +14,15 @@ 4.0.0 - org.springframework.boot - spring-boot-starter-parent - 3.3.0 - + com.remal.gombi + gombi + 0.1.0 - com.remal.hello - user-service - 0.0.2 - user-service - User REST service. - - - 21 - - 1.18.32 - 42.7.3 - 0.0.1 - 4.1.1 - + remal-gombi-user-service + 0.1.0 + gombi-user-service + Sample user REST service. @@ -52,25 +41,21 @@ org.springframework.cloud spring-cloud-starter-consul-discovery - ${spring.cloud.starter.consul.version} org.springframework.cloud spring-cloud-starter-consul-config - ${spring.cloud.starter.consul.version} - com.remal.hello - hello-commons - ${remal.hello.commons.version} + com.remal.gombi + remal-gombi-commons + ${project.version} org.projectlombok lombok - ${lombok.version} - provided @@ -80,7 +65,6 @@ org.postgresql postgresql - ${postgresql.version} @@ -90,13 +74,6 @@ org.springframework.boot spring-boot-maven-plugin - - - - build-info - - - diff --git a/projects/user-service/src/main/java/com/remal/gombi/hello/service/user/Application.java b/projects/remal-gombi-user-service/src/main/java/com/remal/gombi/hello/service/user/Application.java similarity index 100% rename from projects/user-service/src/main/java/com/remal/gombi/hello/service/user/Application.java rename to projects/remal-gombi-user-service/src/main/java/com/remal/gombi/hello/service/user/Application.java diff --git a/projects/user-service/src/main/java/com/remal/gombi/hello/service/user/configuration/MicrometerConfiguration.java b/projects/remal-gombi-user-service/src/main/java/com/remal/gombi/hello/service/user/configuration/MicrometerConfiguration.java similarity index 100% rename from projects/user-service/src/main/java/com/remal/gombi/hello/service/user/configuration/MicrometerConfiguration.java rename to projects/remal-gombi-user-service/src/main/java/com/remal/gombi/hello/service/user/configuration/MicrometerConfiguration.java diff --git a/projects/remal-gombi-user-service/src/main/java/com/remal/gombi/hello/service/user/controller/UserController.java b/projects/remal-gombi-user-service/src/main/java/com/remal/gombi/hello/service/user/controller/UserController.java new file mode 100644 index 0000000..5e39897 --- /dev/null +++ b/projects/remal-gombi-user-service/src/main/java/com/remal/gombi/hello/service/user/controller/UserController.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2020-2024 Remal Software and Arnold Somogyi All rights reserved + * + * Since: February 2024 + * Author: Arnold Somogyi + * + * Description: + * Spring REST endpoint. + */ +package com.remal.gombi.hello.service.user.controller; + +import com.remal.gombi.hello.commons.exception.EntryNotExistException; +import com.remal.gombi.hello.commons.model.User; +import com.remal.gombi.hello.commons.monitoring.MethodStatistics; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.*; + +import java.util.HashMap; +import java.util.Objects; + +@Slf4j +@RestController +@RequestMapping("/api/user") +public class UserController { + + private static final HashMap users = new HashMap<>(); + + @GetMapping("/{username}") + @MethodStatistics + public User getUserByUsername(@PathVariable("username") String username) { + var user = users.get(username); + if (Objects.isNull(user)) { + throw new EntryNotExistException(User.class, "username", username); + } + return user; + } + + @PostMapping("/") + @MethodStatistics + public void saveUser(@RequestBody User user) { + users.put(user.getUsername(), user); + } +} diff --git a/projects/remal-gombi-user-service/src/main/java/com/remal/gombi/hello/service/user/error/ApiExceptionHandler.java b/projects/remal-gombi-user-service/src/main/java/com/remal/gombi/hello/service/user/error/ApiExceptionHandler.java new file mode 100644 index 0000000..c901c95 --- /dev/null +++ b/projects/remal-gombi-user-service/src/main/java/com/remal/gombi/hello/service/user/error/ApiExceptionHandler.java @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2020-2025 Remal Software and Arnold Somogyi All rights reserved + * + * Since: January 2025 + * Author: Arnold Somogyi + * + * Description: + * Spring's global exception handler. It generates HTTP responses based on + * the thrown exception. + */ +package com.remal.gombi.hello.service.user.error; + +import com.remal.gombi.hello.commons.exception.EntryNotExistException; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; + +@ControllerAdvice +public class ApiExceptionHandler { + + @ExceptionHandler(EntryNotExistException.class) + public ResponseEntity handleEntryNotExist(EntryNotExistException e) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(e.getMessage()); + } +} diff --git a/projects/user-service/src/main/resources/application.properties b/projects/remal-gombi-user-service/src/main/resources/application.properties similarity index 81% rename from projects/user-service/src/main/resources/application.properties rename to projects/remal-gombi-user-service/src/main/resources/application.properties index aacad24..c6db34b 100644 --- a/projects/user-service/src/main/resources/application.properties +++ b/projects/remal-gombi-user-service/src/main/resources/application.properties @@ -1,10 +1,6 @@ # embedded web server server.port=8443 -server.ssl.key-store-type=PKCS12 -server.ssl.key-store=file:/tmp/${FQDN}.p12 -server.ssl.key-store-password=changeit -server.ssl.key-alias=${FQDN} -server.ssl.enabled=true +server.ssl.bundle=web-server # spring core spring.application.name=@project.name@ @@ -34,7 +30,7 @@ spring.cloud.consul.discovery.query-passing=true # application monitoring management.prometheus.metrics.export.enabled=true -management.endpoint.prometheus.enabled=true +management.endpoint.prometheus.access=unrestricted management.endpoints.web.exposure.include=info,health,prometheus # database @@ -51,3 +47,10 @@ spring.jpa.properties.hibernate.format_sql=true spring.sql.init.mode=always spring.sql.init.platform=postgresql spring.sql.init.continue-on-error=false + +# spring ssh-bundle configuration +# embedded web server +spring.ssl.bundle.jks.web-server.key.alias=${FQDN} +spring.ssl.bundle.jks.web-server.keystore.location=file:/tmp/${FQDN}.p12 +spring.ssl.bundle.jks.web-server.keystore.password=changeit +spring.ssl.bundle.jks.web-server.keystore.type=PKCS12 diff --git a/projects/echo-service/src/main/resources/banner.txt b/projects/remal-gombi-user-service/src/main/resources/banner.txt similarity index 100% rename from projects/echo-service/src/main/resources/banner.txt rename to projects/remal-gombi-user-service/src/main/resources/banner.txt diff --git a/projects/user-service/src/main/resources/data-postgresql.sql b/projects/remal-gombi-user-service/src/main/resources/data-postgresql.sql similarity index 100% rename from projects/user-service/src/main/resources/data-postgresql.sql rename to projects/remal-gombi-user-service/src/main/resources/data-postgresql.sql diff --git a/projects/user-service/src/main/resources/schema-postgresql.sql b/projects/remal-gombi-user-service/src/main/resources/schema-postgresql.sql similarity index 100% rename from projects/user-service/src/main/resources/schema-postgresql.sql rename to projects/remal-gombi-user-service/src/main/resources/schema-postgresql.sql diff --git a/projects/echo-service/README.md b/projects/remal-gombi-welcome-service/README.md similarity index 100% rename from projects/echo-service/README.md rename to projects/remal-gombi-welcome-service/README.md diff --git a/projects/echo-service/pom.xml b/projects/remal-gombi-welcome-service/pom.xml similarity index 56% rename from projects/echo-service/pom.xml rename to projects/remal-gombi-welcome-service/pom.xml index 7482807..d3d9ea5 100644 --- a/projects/echo-service/pom.xml +++ b/projects/remal-gombi-welcome-service/pom.xml @@ -14,27 +14,16 @@ 4.0.0 - org.springframework.boot - spring-boot-starter-parent - 3.3.0 - + com.remal.gombi + gombi + 0.1.0 - com.remal.hello - echo-service - 0.0.2 - echo-service + remal-gombi-welcome-service + 0.1.0 + gombi-welcome-service Echo REST service. - - 21 - - 5.2 - 1.18.32 - 0.0.1 - 4.1.1 - - @@ -52,31 +41,21 @@ org.springframework.cloud spring-cloud-starter-consul-discovery - ${spring.cloud.starter.consul.version} org.springframework.cloud spring-cloud-starter-consul-config - ${spring.cloud.starter.consul.version} - com.remal.hello - hello-commons - ${remal.hello.commons.version} + com.remal.gombi + remal-gombi-commons + ${project.version} org.projectlombok lombok - ${lombok.version} - provided - - - - org.apache.httpcomponents.client5 - httpclient5 - ${apache.httpclient5.version} @@ -86,14 +65,8 @@ org.springframework.boot spring-boot-maven-plugin - - - - build-info - - - + diff --git a/projects/echo-service/src/main/java/com/remal/gombi/hello/service/echo/Application.java b/projects/remal-gombi-welcome-service/src/main/java/com/remal/gombi/hello/service/welcome/Application.java similarity index 93% rename from projects/echo-service/src/main/java/com/remal/gombi/hello/service/echo/Application.java rename to projects/remal-gombi-welcome-service/src/main/java/com/remal/gombi/hello/service/welcome/Application.java index ccb2c92..e13b457 100644 --- a/projects/echo-service/src/main/java/com/remal/gombi/hello/service/echo/Application.java +++ b/projects/remal-gombi-welcome-service/src/main/java/com/remal/gombi/hello/service/welcome/Application.java @@ -7,7 +7,7 @@ * Description: * Spring application entry point. */ -package com.remal.gombi.hello.service.echo; +package com.remal.gombi.hello.service.welcome; import org.springframework.boot.WebApplicationType; import org.springframework.boot.autoconfigure.SpringBootApplication; diff --git a/projects/echo-service/src/main/java/com/remal/gombi/hello/service/echo/configuration/MicrometerConfiguration.java b/projects/remal-gombi-welcome-service/src/main/java/com/remal/gombi/hello/service/welcome/configuration/MicrometerConfiguration.java similarity index 95% rename from projects/echo-service/src/main/java/com/remal/gombi/hello/service/echo/configuration/MicrometerConfiguration.java rename to projects/remal-gombi-welcome-service/src/main/java/com/remal/gombi/hello/service/welcome/configuration/MicrometerConfiguration.java index bce5b70..4bd95ab 100644 --- a/projects/echo-service/src/main/java/com/remal/gombi/hello/service/echo/configuration/MicrometerConfiguration.java +++ b/projects/remal-gombi-welcome-service/src/main/java/com/remal/gombi/hello/service/welcome/configuration/MicrometerConfiguration.java @@ -7,7 +7,7 @@ * Description: * Application monitoring with Micrometer. */ -package com.remal.gombi.hello.service.echo.configuration; +package com.remal.gombi.hello.service.welcome.configuration; import com.remal.gombi.hello.commons.Internet; import io.micrometer.core.instrument.Metrics; diff --git a/projects/remal-gombi-welcome-service/src/main/java/com/remal/gombi/hello/service/welcome/configuration/RestTemplateConfiguration.java b/projects/remal-gombi-welcome-service/src/main/java/com/remal/gombi/hello/service/welcome/configuration/RestTemplateConfiguration.java new file mode 100644 index 0000000..b2cadc9 --- /dev/null +++ b/projects/remal-gombi-welcome-service/src/main/java/com/remal/gombi/hello/service/welcome/configuration/RestTemplateConfiguration.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2020-2024 Remal Software and Arnold Somogyi All rights reserved + * + * Since: February 2024 + * Author: Arnold Somogyi + * + * Description: + * Spring bean configuration. + */ +package com.remal.gombi.hello.service.welcome.configuration; + + +import org.springframework.boot.ssl.SslBundles; +import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.client.RestTemplate; + +@Configuration +public class RestTemplateConfiguration { + + private static final String SSL_BUNDLE_ID = "rest-template"; + + /** + * Rest template configuration for HTTPS. + * + * @return restTemplate instance + */ + @Bean + public RestTemplate restTemplate(RestTemplateBuilder builder, SslBundles sslBundles) { + return builder.sslBundle(sslBundles.getBundle(SSL_BUNDLE_ID)).build(); + } +} diff --git a/projects/echo-service/src/main/java/com/remal/gombi/hello/service/echo/configuration/ServiceDiscoveryConfiguration.java b/projects/remal-gombi-welcome-service/src/main/java/com/remal/gombi/hello/service/welcome/configuration/ServiceDiscoveryConfiguration.java similarity index 91% rename from projects/echo-service/src/main/java/com/remal/gombi/hello/service/echo/configuration/ServiceDiscoveryConfiguration.java rename to projects/remal-gombi-welcome-service/src/main/java/com/remal/gombi/hello/service/welcome/configuration/ServiceDiscoveryConfiguration.java index b6236b4..dbbb2b9 100644 --- a/projects/echo-service/src/main/java/com/remal/gombi/hello/service/echo/configuration/ServiceDiscoveryConfiguration.java +++ b/projects/remal-gombi-welcome-service/src/main/java/com/remal/gombi/hello/service/welcome/configuration/ServiceDiscoveryConfiguration.java @@ -7,7 +7,7 @@ * Description: * Service discovery. */ -package com.remal.gombi.hello.service.echo.configuration; +package com.remal.gombi.hello.service.welcome.configuration; import com.remal.gombi.hello.commons.spring.discovery.ConsulServiceDiscovery; import org.springframework.cloud.client.discovery.DiscoveryClient; diff --git a/projects/remal-gombi-welcome-service/src/main/java/com/remal/gombi/hello/service/welcome/controller/WelcomeController.java b/projects/remal-gombi-welcome-service/src/main/java/com/remal/gombi/hello/service/welcome/controller/WelcomeController.java new file mode 100644 index 0000000..8cddbc0 --- /dev/null +++ b/projects/remal-gombi-welcome-service/src/main/java/com/remal/gombi/hello/service/welcome/controller/WelcomeController.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2020-2024 Remal Software and Arnold Somogyi All rights reserved + * + * Since: February 2024 + * Author: Arnold Somogyi + * + * Description: + * Spring REST endpoint. + */ +package com.remal.gombi.hello.service.welcome.controller; + +import com.remal.gombi.hello.commons.monitoring.MethodStatistics; +import com.remal.gombi.hello.service.welcome.service.TemplateService; +import com.remal.gombi.hello.service.welcome.service.UserService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Objects; + +@Slf4j +@RestController +@RequestMapping("/api") +public class WelcomeController { + + private final TemplateService templateService; + private final UserService userService; + + /** + * Constructor with object injections. + * + * @param userService object to be injected by spring + */ + public WelcomeController(UserService userService, + TemplateService templateService) { + this.userService = userService; + this.templateService = templateService; + } + + private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyy-MM-dd HH:mm:ss"); + + @GetMapping("welcome/{username}") + @MethodStatistics + public String welcome(@PathVariable String username) { + var template = templateService.getWelcomeTemplate(); + return generateWelcomeMessage(username, template); + } + + @GetMapping("welcome-back/{username}") + @MethodStatistics + public String welcomeBack(@PathVariable String username) { + var template = templateService.getWelcomeBackTemplate(); + return generateWelcomeMessage(username, template); + } + + private String generateWelcomeMessage(String username, String template) { + var user = userService.getUser(username); + var message = Objects.isNull(user) ? "Unknown user." : String.format(template, user.getFirstName()); + var now = LocalDateTime.now().format(DATE_TIME_FORMATTER); + return now + "
" + message; + } + + @GetMapping("joke") + @MethodStatistics + public String joke() { + return "When Alexander Graham Bell invented the telephone, he had three missed calls from Chuck Norris"; + } +} diff --git a/projects/echo-service/src/main/java/com/remal/gombi/hello/service/echo/service/ConfigurationService.java b/projects/remal-gombi-welcome-service/src/main/java/com/remal/gombi/hello/service/welcome/service/TemplateService.java similarity index 58% rename from projects/echo-service/src/main/java/com/remal/gombi/hello/service/echo/service/ConfigurationService.java rename to projects/remal-gombi-welcome-service/src/main/java/com/remal/gombi/hello/service/welcome/service/TemplateService.java index 38ed1c2..d0b5830 100644 --- a/projects/echo-service/src/main/java/com/remal/gombi/hello/service/echo/service/ConfigurationService.java +++ b/projects/remal-gombi-welcome-service/src/main/java/com/remal/gombi/hello/service/welcome/service/TemplateService.java @@ -7,14 +7,20 @@ * Description: * This a Spring-Bean with RefreshScope that allows for beans to be * refreshed dynamically at runtime. If a bean is refreshed then the next - * time the bean is accessed (i.e. a method is executed) a new instance is - * created. + * time the bean is accessed (i.e. call the getter method) a new instance + * is created. + * * Beans with @RefreshScope feature will be dynamically updated when a * value in the Hashicorp Consul KV store has changed. This configuration * keeps up-to-date the configuration values without restarting the spring * boot application. + * + * +1: + * Access to values from the VK store can be monitored by adding the + * @MethodStatistics annotation to the method. The statistics data is + * stored in Prometheus and can be viewed in Grafana. */ -package com.remal.gombi.hello.service.echo.service; +package com.remal.gombi.hello.service.welcome.service; import com.remal.gombi.hello.commons.monitoring.MethodStatistics; import lombok.extern.slf4j.Slf4j; @@ -25,21 +31,21 @@ @Component @RefreshScope @Slf4j -public class ConfigurationService { +public class TemplateService { - @Value("${description.option.a}") - private String optionA; + @Value("${template.welcome}") + private String welcomeTemplate; - @Value("${description.option.b}") - private String optionB; + @Value("${template.welcome-back}") + private String welcomeBackTemplate; @MethodStatistics(logToLogfile = false) - public String getOptionA() { - return optionA; + public String getWelcomeTemplate() { + return welcomeTemplate; } @MethodStatistics(logToLogfile = false) - public String getOptionB() { - return optionB; + public String getWelcomeBackTemplate() { + return welcomeBackTemplate; } } diff --git a/projects/echo-service/src/main/java/com/remal/gombi/hello/service/echo/service/UserService.java b/projects/remal-gombi-welcome-service/src/main/java/com/remal/gombi/hello/service/welcome/service/UserService.java similarity index 77% rename from projects/echo-service/src/main/java/com/remal/gombi/hello/service/echo/service/UserService.java rename to projects/remal-gombi-welcome-service/src/main/java/com/remal/gombi/hello/service/welcome/service/UserService.java index 87edce4..afda6b9 100644 --- a/projects/echo-service/src/main/java/com/remal/gombi/hello/service/echo/service/UserService.java +++ b/projects/remal-gombi-welcome-service/src/main/java/com/remal/gombi/hello/service/welcome/service/UserService.java @@ -7,11 +7,12 @@ * Description: * Service discovery. */ -package com.remal.gombi.hello.service.echo.service; +package com.remal.gombi.hello.service.welcome.service; import com.remal.gombi.hello.commons.model.User; import com.remal.gombi.hello.commons.spring.discovery.ConsulServiceDiscovery; import org.springframework.stereotype.Service; +import org.springframework.web.client.RestClient; import org.springframework.web.client.RestTemplate; import java.net.URI; @@ -33,10 +34,11 @@ public UserService(ConsulServiceDiscovery serviceDiscovery, RestTemplate restTem public User getUser(String userId) { URI uri = getServiceUri().resolve("/api/user/" + userId); - return restTemplate.getForObject(uri, User.class); + RestClient restClient = RestClient.create(restTemplate); + return restClient.get().uri(uri).retrieve().body(User.class); } private URI getServiceUri() { - return serviceDiscovery.getServiceUri("user-service"); + return serviceDiscovery.getServiceUri("gombi-user-service"); } } diff --git a/projects/echo-service/src/main/resources/application.properties b/projects/remal-gombi-welcome-service/src/main/resources/application.properties similarity index 64% rename from projects/echo-service/src/main/resources/application.properties rename to projects/remal-gombi-welcome-service/src/main/resources/application.properties index 67a5847..f8a85f3 100644 --- a/projects/echo-service/src/main/resources/application.properties +++ b/projects/remal-gombi-welcome-service/src/main/resources/application.properties @@ -1,10 +1,6 @@ # embedded web server server.port=8443 -server.ssl.key-store-type=PKCS12 -server.ssl.key-store=file:/tmp/${FQDN}.p12 -server.ssl.key-store-password=changeit -server.ssl.key-alias=${FQDN} -server.ssl.enabled=true +server.ssl.bundle=web-server # spring core spring.application.name=@project.name@ @@ -34,5 +30,16 @@ spring.cloud.consul.config.name=com/remal/gombi/@project.name@ # application monitoring management.prometheus.metrics.export.enabled=true -management.endpoint.prometheus.enabled=true +management.endpoint.prometheus.access=unrestricted management.endpoints.web.exposure.include=info,health,prometheus + +# spring ssh-bundle configuration +# embedded web server +spring.ssl.bundle.jks.web-server.key.alias=${FQDN} +spring.ssl.bundle.jks.web-server.keystore.location=file:/tmp/${FQDN}.p12 +spring.ssl.bundle.jks.web-server.keystore.password=changeit +spring.ssl.bundle.jks.web-server.keystore.type=PKCS12 +# configure RestClient to use HTTPS correctly +spring.ssl.bundle.jks.rest-template.truststore.location=file:/tmp/${FQDN}.p12 +spring.ssl.bundle.jks.rest-template.truststore.password=changeit +spring.ssl.bundle.jks.rest-template.truststore.type=PKCS12 diff --git a/projects/user-service/src/main/resources/banner.txt b/projects/remal-gombi-welcome-service/src/main/resources/banner.txt similarity index 100% rename from projects/user-service/src/main/resources/banner.txt rename to projects/remal-gombi-welcome-service/src/main/resources/banner.txt diff --git a/projects/echo-service/src/main/resources/config.properties b/projects/remal-gombi-welcome-service/src/main/resources/config.properties similarity index 83% rename from projects/echo-service/src/main/resources/config.properties rename to projects/remal-gombi-welcome-service/src/main/resources/config.properties index 824a187..7fff06b 100644 --- a/projects/echo-service/src/main/resources/config.properties +++ b/projects/remal-gombi-welcome-service/src/main/resources/config.properties @@ -9,5 +9,5 @@ # during the Docker container startup and the missing key/value pairs will # be inserted into Hashicorp Consul. ################################################################################ -description.option.a=What a wonderful day -description.option.b=Lorem ipsum dolor sit amet. +template.welcome=You are welcomed %s! +template.welcome-back=%a, it’s great to have you back with us! diff --git a/projects/test-requests.http b/projects/test-requests.http new file mode 100644 index 0000000..114e697 --- /dev/null +++ b/projects/test-requests.http @@ -0,0 +1,13 @@ +### save user +POST https://localhost:14114/api/user/ +Content-Type: application/json + +{ + "username": "zappee", + "firstName": "Arnold", + "email": "arnold@gmail.com", + "description": "Java developer" +} + +### get user +GET https://localhost:14114/api/user/zappee diff --git a/projects/user-service/src/main/java/com/remal/gombi/hello/service/user/controller/UserController.java b/projects/user-service/src/main/java/com/remal/gombi/hello/service/user/controller/UserController.java deleted file mode 100644 index 5a2589f..0000000 --- a/projects/user-service/src/main/java/com/remal/gombi/hello/service/user/controller/UserController.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2020-2024 Remal Software and Arnold Somogyi All rights reserved - * - * Since: February 2024 - * Author: Arnold Somogyi - * - * Description: - * Spring REST endpoint. - */ -package com.remal.gombi.hello.service.user.controller; - -import com.remal.gombi.hello.commons.model.User; -import com.remal.gombi.hello.commons.monitoring.MethodStatistics; -import lombok.extern.slf4j.Slf4j; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -@Slf4j -@RestController -@RequestMapping("/api/user") -public class UserController { - - @GetMapping("/{id}") - @MethodStatistics - public User getUser(@PathVariable("id") String id) { - return User.builder() - .username(id) - .email("arnold.somogyi@gmail.com") - .description("project owner") - .build(); - } -} diff --git a/update-binaries.sh b/update-binaries.sh index 8c41db6..4333f72 100755 --- a/update-binaries.sh +++ b/update-binaries.sh @@ -29,11 +29,11 @@ BINARIES=( "AM-7.3.0.war;docker/infrastructure/forgerock-am/bin" "AM-SSOConfiguratorTools-5.1.3.18.zip;docker/infrastructure/forgerock-am/bin" "apache-tomcat-9.0.71.tar.gz;docker/infrastructure/tomcat-9/bin" - "EasyRSA-3.1.7.tgz;docker/infrastructure/easy-rsa-pki/bin" - "consul_1.18.2_linux_386.zip;docker/infrastructure/hcp-consul/bin" + "EasyRSA-3.2.1.tgz;docker/infrastructure/easy-rsa-pki/bin" + "consul_1.20.1_linux_386.zip;docker/infrastructure/hcp-consul/bin" "vault_1.15.0_linux_386.zip;docker/infrastructure/hcp-vault/bin" - "prometheus-2.51.1.linux-amd64.tar.gz;docker/monitoring/prometheus/bin" - "grafana-enterprise-10.4.2.linux-amd64.tar.gz;docker/monitoring/grafana/bin" + "prometheus-3.0.1.linux-amd64.tar.gz;docker/monitoring/prometheus/bin" + "grafana-enterprise-11.4.0.linux-amd64.tar.gz;docker/monitoring/grafana/bin" ) # ----------------------------------------------------------------------------