From e123b7f9600c32406c3e3cf9f9d21a7c4cf631b6 Mon Sep 17 00:00:00 2001 From: G8XSU <3442979+G8XSU@users.noreply.github.com> Date: Fri, 6 Sep 2024 15:51:46 -0700 Subject: [PATCH 1/3] Read application properties from env first. Prioritize environment variables over configuration file properties. This allows the service to adapt dynamically to different deployment environments by overriding config file settings with environment-specific values when available. --- .../main/java/org/vss/guice/BaseModule.java | 40 ++++++++++++------- app/src/main/resources/application.properties | 26 ++++++++++++ app/src/main/resources/hikariJdbc.properties | 23 ----------- 3 files changed, 51 insertions(+), 38 deletions(-) create mode 100644 app/src/main/resources/application.properties delete mode 100644 app/src/main/resources/hikariJdbc.properties diff --git a/app/src/main/java/org/vss/guice/BaseModule.java b/app/src/main/java/org/vss/guice/BaseModule.java index 69a5d4f..94c169a 100644 --- a/app/src/main/java/org/vss/guice/BaseModule.java +++ b/app/src/main/java/org/vss/guice/BaseModule.java @@ -52,38 +52,48 @@ class HikariCPDataSource { static { try (InputStream input = HikariCPDataSource.class.getClassLoader() - .getResourceAsStream("hikariJdbc.properties")) { - Properties hikariJdbcProperties = new Properties(); - hikariJdbcProperties.load(input); + .getResourceAsStream("application.properties")) { + Properties applicationProperties = new Properties(); + applicationProperties.load(input); - config.setJdbcUrl(hikariJdbcProperties.getProperty("jdbc.url")); - config.setUsername(hikariJdbcProperties.getProperty("jdbc.username")); - config.setPassword(hikariJdbcProperties.getProperty("jdbc.password")); + config.setJdbcUrl(getEnvOrConfigProperty("vss.jdbc.url", applicationProperties)); + config.setUsername(getEnvOrConfigProperty("vss.jdbc.username", applicationProperties)); + config.setPassword(getEnvOrConfigProperty("vss.jdbc.password", applicationProperties)); config.setMaximumPoolSize( - Integer.parseInt(hikariJdbcProperties.getProperty("hikaricp.maxPoolSize"))); + Integer.parseInt(getEnvOrConfigProperty("vss.hikaricp.maxPoolSize", applicationProperties))); config.setMinimumIdle( - Integer.parseInt(hikariJdbcProperties.getProperty("hikaricp.minimumIdle"))); + Integer.parseInt(getEnvOrConfigProperty("vss.hikaricp.minimumIdle", applicationProperties))); config.setConnectionTimeout( - Long.parseLong(hikariJdbcProperties.getProperty("hikaricp.connectionTimeout"))); + Long.parseLong(getEnvOrConfigProperty("vss.hikaricp.connectionTimeout", applicationProperties))); config.setIdleTimeout( - Long.parseLong(hikariJdbcProperties.getProperty("hikaricp.idleTimeout"))); + Long.parseLong(getEnvOrConfigProperty("vss.hikaricp.idleTimeout", applicationProperties))); config.setMaxLifetime( - Long.parseLong(hikariJdbcProperties.getProperty("hikaricp.maxLifetime"))); + Long.parseLong(getEnvOrConfigProperty("vss.hikaricp.maxLifetime", applicationProperties))); config.addDataSourceProperty("cachePrepStmts", - hikariJdbcProperties.getProperty("hikaricp.cachePrepStmts")); + getEnvOrConfigProperty("vss.hikaricp.cachePrepStmts", applicationProperties)); config.addDataSourceProperty("prepStmtCacheSize", - hikariJdbcProperties.getProperty("hikaricp.prepStmtCacheSize")); + getEnvOrConfigProperty("vss.hikaricp.prepStmtCacheSize", applicationProperties)); config.addDataSourceProperty("prepStmtCacheSqlLimit", - hikariJdbcProperties.getProperty("hikaricp.prepStmtCacheSqlLimit")); + getEnvOrConfigProperty("vss.hikaricp.prepStmtCacheSqlLimit", applicationProperties)); dataSource = new HikariDataSource(config); } catch (IOException e) { - throw new RuntimeException("Unable to read hikariJdbcProperties from resources"); + throw new RuntimeException("Unable to read application.properties from resources"); } } + // Retrieves the value of a specified property, first checking environment variables, + // then falling back to provided configuration properties if the environment variable is not set. + private static String getEnvOrConfigProperty(String key, Properties hikariJdbcProperties) { + String propertyValue = System.getenv(key); + if (StringUtils.isBlank(propertyValue)) { + propertyValue = hikariJdbcProperties.getProperty(key); + } + return propertyValue; + } + private HikariCPDataSource() { } } diff --git a/app/src/main/resources/application.properties b/app/src/main/resources/application.properties new file mode 100644 index 0000000..0563da8 --- /dev/null +++ b/app/src/main/resources/application.properties @@ -0,0 +1,26 @@ +# Application Properties File +# Contains default application properties, these are meant to be changed according to application needs. +# Each property can be overridden by setting an environment variable with the same name. +# For example, to override 'vss.jdbc.url', set an environment variable 'vss.jdbc.url' with the new value. + +vss.jdbc.url=jdbc:postgresql://localhost:5432/postgres +vss.jdbc.username=postgres +vss.jdbc.password=YOU_MUST_CHANGE_THIS_PASSWORD + +# Idle Timeout +vss.hikaricp.minimumIdle=10 + +# Set connectionTimeout to 30 secs +vss.hikaricp.connectionTimeout=30000 + +# Set idle timeout to 10 minutes +vss.hikaricp.idleTimeout=600000 + +# Set Maximum lifetime of a connection to 30minutes +vss.hikaricp.maxLifetime=1800000 + +# Performance Optimizations +vss.hikaricp.maxPoolSize=50 +vss.hikaricp.cachePrepStmts=true +vss.hikaricp.prepStmtCacheSize=250 +vss.hikaricp.prepStmtCacheSqlLimit=2048 diff --git a/app/src/main/resources/hikariJdbc.properties b/app/src/main/resources/hikariJdbc.properties deleted file mode 100644 index b30d4ca..0000000 --- a/app/src/main/resources/hikariJdbc.properties +++ /dev/null @@ -1,23 +0,0 @@ -# Default properties, these are meant to be changed according to application needs. - -jdbc.url=jdbc:postgresql://localhost:5432/postgres -jdbc.username=postgres -jdbc.password=YOU_MUST_CHANGE_THIS_PASSWORD - -# Idle Timeout -hikaricp.minimumIdle=10 - -# Set connectionTimeout to 30 secs -hikaricp.connectionTimeout=30000 - -# Set idle timeout to 10 minutes -hikaricp.idleTimeout=600000 - -# Set Maximum lifetime of a connection to 30minutes -hikaricp.maxLifetime=1800000 - -# Performance Optimizations -hikaricp.maxPoolSize=50 -hikaricp.cachePrepStmts=true -hikaricp.prepStmtCacheSize=250 -hikaricp.prepStmtCacheSqlLimit=2048 From 12ecd1fc89846523451e55172626851b4ea11cd3 Mon Sep 17 00:00:00 2001 From: G8XSU <3442979+G8XSU@users.noreply.github.com> Date: Fri, 6 Sep 2024 15:54:06 -0700 Subject: [PATCH 2/3] Change default war filename to vss --- .github/workflows/build-and-deploy.yml | 2 +- app/build.gradle | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-and-deploy.yml b/.github/workflows/build-and-deploy.yml index df49883..6fadc6f 100644 --- a/.github/workflows/build-and-deploy.yml +++ b/.github/workflows/build-and-deploy.yml @@ -60,7 +60,7 @@ jobs: ./gradlew --version ./gradlew build - docker cp app/build/libs/app-1.0.war tomcat:/usr/local/tomcat/webapps/vss.war + docker cp app/build/libs/vss-1.0.war tomcat:/usr/local/tomcat/webapps/vss.war - name: Hit endpoint to verify service is up run: | diff --git a/app/build.gradle b/app/build.gradle index 1e48eee..80c4fbc 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -30,6 +30,10 @@ idea { group 'org.vss' version '1.0' +war { + archiveFileName = "vss-${project.version}.war" +} + dependencies { implementation "com.google.protobuf:protobuf-java:$protobufVersion" From fe1fc921b33e2f88b9a717d1b12414d4486b2a71 Mon Sep 17 00:00:00 2001 From: G8XSU <3442979+G8XSU@users.noreply.github.com> Date: Fri, 6 Sep 2024 16:05:28 -0700 Subject: [PATCH 3/3] Add Docker configuration. Add docker-compose and Dockerfile, which spins up a postgres and vss instance. We override env variables such as vss.jdbc.url, to point to postgres container. --- Dockerfile | 12 ++++++++++++ docker-compose.yml | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 Dockerfile create mode 100644 docker-compose.yml diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..83a49fb --- /dev/null +++ b/Dockerfile @@ -0,0 +1,12 @@ +# Use official Tomcat base image +FROM tomcat:jre17 + +# Copy WAR file +COPY app/build/libs/vss-1.0.war /usr/local/tomcat/webapps/vss.war + +ENV vss.jdbc.url="jdbc:postgresql://postgres:5432/postgres" +ENV vss.jdbc.username=postgres +ENV vss.jdbc.password=YOU_MUST_CHANGE_THIS_PASSWORD + +EXPOSE 8080 +CMD ["catalina.sh", "run"] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..bd6f464 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,33 @@ +version: '3.8' +services: + postgres: + image: postgres:15 + environment: + POSTGRES_DB: postgres + POSTGRES_USER: postgres + POSTGRES_PASSWORD: YOU_MUST_CHANGE_THIS_PASSWORD + volumes: + - postgres-data:/var/lib/postgresql/data + - ./app/src/main/java/org/vss/impl/postgres/sql/v0_create_vss_db.sql:/docker-entrypoint-initdb.d/init.sql + ports: + - "5432:5432" + networks: + - app-network + + tomcat: + build: + context: . + container_name: tomcat + depends_on: + - postgres + ports: + - "8080:8080" + networks: + - app-network + +volumes: + postgres-data: + +networks: + app-network: + driver: bridge