Skip to content

Profiles and Environment Separation

Paulo Gomes da Cruz Junior edited this page Sep 11, 2026 · 6 revisions

Profiles and Environment Separation

Purpose

This page documents how profile activation and environment separation work across the two Waste Plus backend applications:

  • nr-waste-plus-backend
  • nr-waste-plus-legacy

The goal is to keep environment behavior predictable while allowing each service to evolve independently.

Common Model Across Both Backends

Both applications use the same high-level separation model:

  • Spring profiles to switch runtime behavior by environment
  • Maven profiles to control build and test pipelines
  • Environment variables for deployment-time injection of secrets and platform-specific values
  • Container profile to enable structured production logging

nr-waste-plus-backend (Spring Boot 4)

Spring runtime profiles

Profile Purpose
default Local development baseline from application.yml
container Structured JSON logging and container runtime behavior
dev-paulushc Developer-specific local profile
prod Production runtime behavior (typically combined with container in deployment)

Maven build profiles

Maven profile Purpose
all-tests Full verification pipeline
dev Developer-oriented build flow
integration-test Integration test execution
prod Production-oriented build
native GraalVM native image build

Environment boundary summary

  • Frontend-facing BFF endpoint surface under /api/**
  • External API integration via configured endpoints and keys
  • PostgreSQL-backed preferences persistence
  • Typical container activation pattern: SPRING_PROFILES_ACTIVE=container,prod

nr-waste-plus-legacy (Spring Boot 3)

Spring runtime profiles

Profile Purpose
default (test) Test defaults, Flyway test setup, relaxed local settings
container Structured JSON logging for container runtime
prod Production runtime behavior

Maven build profiles

Maven profile Purpose
all-tests Unit + integration + quality gates
dev Development build flow
integration-test Integration-only execution
prod Production build (unit tests skipped in this profile)
native GraalVM native image build

Environment boundary summary

  • Oracle-backed reporting and code-table APIs
  • Environment-level district scoping via configured values
  • Oracle TLS and credentials injected at deployment
  • OpenShift init-container flow for Oracle certificate handling

Environment Variable Responsibilities

The two services share many deployment inputs but apply them differently.

Shared security and platform variables

Variable family Purpose
COGNITO_* OAuth2/JWT validation and identity-provider integration
APP_ZONE, SECURITY_ENV Environment and security context alignment
APP_VERSION Metrics and logging tagging
LOGGING_LEVEL Runtime log verbosity tuning

Backend-focused variables

Variable family Purpose
POSTGRES_* PostgreSQL connectivity for preferences storage
FORESTCLIENTAPI_* Forest Client API address and authentication
LEGACY_URL URL to legacy backend integration
ALLOWED_ORIGINS Frontend/CORS integration
SELF_URI Service self-reference for security and routing contexts

Legacy-focused variables

Variable family Purpose
DATABASE_* and SERVICE_NAME Oracle connectivity
ORACLEDB_* Oracle TLS certificate and keystore material
ALLOWED_DISTRICTS District-level domain scoping
SELF_URI Service self-reference for environment-aware behavior

Recommended Operating Pattern

To reduce configuration drift between services:

  1. Keep profile names stable across repositories whenever behavior is equivalent.
  2. Keep secret material strictly in environment variables or platform secrets.
  3. Keep local developer overrides in developer-specific profiles.
  4. Keep container, prod, and native behavior explicit in both runtime and build profiles.

Known Constraint

The legacy service remains on Spring Boot 3 due to Oracle-related constraints tracked in issue #341. This version split is intentional and should be reflected in profile and deployment decisions.

Developer Local Setup

IDE baseline

  • Backend development supports IntelliJ IDEA and Eclipse.
  • Recommended setup uses IntelliJ with Google style formatting.
  • Local runtime requires database access:
    • backend app: PostgreSQL
    • legacy app: Oracle

Each developer should keep personal runtime overrides in a profile-specific file inside config/, for example:

  • application-dev-jsmith.yml
  • application-dev-jsmith.properties

Activate your local profile when running the service:

--spring.profiles.active=dev-jsmith

Override strategy

  • Baseline values live in src/main/resources/application.yml.
  • Prefer overriding values under ca.bc.gov.nrs where possible.
  • Secrets and environment-specific addresses should be injected via environment variables.

Environment Variable Catalog

Variable Purpose
SERVER_PORT Reconfigures HTTP server port
COGNITO_REGION OAuth2 Cognito region
COGNITO_USER_POOL OAuth2 Cognito user pool id
POSTGRES_HOST PostgreSQL host
POSTGRES_DATABASE PostgreSQL database name
POSTGRES_USER PostgreSQL username
POSTGRES_PASSWORD PostgreSQL password
DATABASE_HOST Oracle database host
DATABASE_PORT Oracle database port
SERVICE_NAME Oracle database service name
DATABASE_USER Oracle database username
DATABASE_PASSWORD Oracle database password
ORACLEDB_KEYSTORE Oracle certificate keystore file
ORACLEDB_SECRET Oracle certificate key/secret
SECURITY_ENV Security environment aligned with app zone
ALLOWED_DISTRICTS District allow-list
APP_ZONE Deployment zone (dev/test/prod)
SELF_URI Service self URL
FORESTCLIENTAPI_ADDRESS Forest Client API base URL
FORESTCLIENTAPI_KEY Forest Client API key
LEGACY_URL Legacy backend URL
ALLOWED_ORIGINS Frontend URL/CORS origin
APP_VERSION Version tag for metrics/logging
LOGGING_LEVEL Runtime logging level

Configuration Examples

Backend base configuration

ca:
	bc:
		gov:
			nrs:
				self-uri: ${SELF_URI:http://localhost:8080}
				forest-client-api:
					address: ${FORESTCLIENTAPI_ADDRESS:https://nr-forest-client-api-prod.api.gov.bc.ca/api}
					key: ${FORESTCLIENTAPI_KEY:placeholder-api-key}
				legacy-api:
					address: ${LEGACY_URL:http://127.0.0.1:9090}
				frontend:
					url: ${ALLOWED_ORIGINS:http://localhost:3000}
					cors:
						headers:
							- x-requested-with
							- X-REQUESTED-WITH
							- authorization
							- Authorization
							- Content-Type
							- content-type
							- credential
							- CREDENTIAL
							- X-XSRF-TOKEN
							- access-control-allow-origin
							- Access-Control-Allow-Origin
							- DNT
							- Keep-Alive,
							- User-Agent,
							- X-Requested-With,
							- If-Modified-Since,
							- Cache-Control,
							- Content-Range,
							- Range
							- Location
							- location
							- X-B3-TraceId
							- x-b3-traceid
							- X-B3-TRACEID
							- X-B3-SpanId
							- x-b3-spanid
							- X-B3-SPANID
						methods:
							- OPTIONS
							- GET
							- POST
							- PUT
							- DELETE
						age: 5m

Backend personal local override

spring:
	datasource:
		jdbcUrl: jdbc:postgresql://127.0.0.1:5432/postgres
		username: postgres
		password: default
#  jpa:
#    show-sql: true
	security:
		oauth2:
			resourceserver:
				jwt:
					jwk-set-uri: https://cognito-idp.ca-central-1.amazonaws.com/ca-central-1_norarealid/.well-known/jwks.json
					issuer-uri: https://cognito-idp.ca-central-1.amazonaws.com/ca-central-1_norarealid
	flyway:
		schemas: hrs
		default-schema: hrs

ca:
	bc:
		gov:
			nrs:
				environment: local
				forest-client-api:
					address: http://127.0.0.1:9001/api
					key: notarealkeybutclose
				legacy-api:
					address: http://localhost:9090

#logging:
#  level:
#    org:.hibernate.SQL: DEBUG
#    org.hibernate.type.descriptor.sql: TRACE
#    org.springframework.web: DEBUG
#    org.hibernate.SQL: DEBUG
#    org.hibernate.stat: DEBUG
#    org.hibernate.SQL_SLOW: INFO
#    org.hibernate.orm.jdbc.bind: TRACE

Legacy base configuration

ca:
	bc:
		gov:
			nrs:
				self-uri: ${SELF_URI:http://localhost:9090}
				environment: ${SECURITY_ENV:local}
				districts: ${ALLOWED_DISTRICTS:DCK,DSQ,DVA,DKM,DSC,DFN,DSI,DCR,DMK,DQC,DKA,DCS,DOS,DSE,DCC,DMH,DQU,DNI,DND,DRM,DPG,DSS,DPC}
				oracle:
					keystore: ${ORACLEDB_KEYSTORE:jssecacerts-path}
					secret: ${ORACLEDB_SECRET:changeit}

Legacy personal local override

spring:
	datasource:
		url: jdbc:oracle:thin:@tcp://127.0.0.1/WASTE
		username: THE
		password: default
		hikari:
			leakDetectionThreshold: 240000
#  jpa:
#    show-sql: true
	security:
		oauth2:
			resourceserver:
				jwt:
					jwk-set-uri: https://cognito-idp.ca-central-1.amazonaws.com/ca-central-1_norarealid/.well-known/jwks.json
					issuer-uri: https://cognito-idp.ca-central-1.amazonaws.com/ca-central-1_norarealid

ca:
	bc:
		gov:
			nrs:
				environment: local

#logging:
#  level:
#    org:.hibernate.SQL: DEBUG
#    org.hibernate.type.descriptor.sql: TRACE
#    org.springframework.web: DEBUG
#    org.hibernate.SQL: DEBUG
#    org.hibernate.stat: DEBUG
#    org.hibernate.SQL_SLOW: INFO
#    org.hibernate.orm.jdbc.bind: TRACE

IDE Configuration Notes

Code style assets

Run configuration references

Lombok setup for Eclipse

If Eclipse does not process Lombok annotations:

  1. Run a Maven command (for example mvn clean compile) to ensure Lombok is downloaded.
  2. Locate the jar under local Maven repository path org/projectlombok/lombok/.
  3. Run java -jar lombok-X.Y.Z.jar.
  4. Select Eclipse in the installer and apply the update.
  5. Restart Eclipse.

Reference:

Waste Plus Wiki

Home

Architecture

Codes

Decisions

Knowledge Base

Development

Changes

Clone this wiki locally