Skip to content

Client Service Installation and Configuration (client-service)

The client-service manages organizational identity, user sessions, account balances, admin onboarding, and reporting rollups.

The deployed process needs PostgreSQL, Redis, and Kafka. When using the development settings, Eureka must also be running. Use port 9014 for development.

Runtime and Service Metadata

These settings control how the process starts, how it identifies itself in logs/service discovery, and how it shuts down during deployments.

Property Value / Default Env Variable Description
server.port 0 base, 9014 dev SERVER_PORT HTTP port. Base uses random port; dev pins 9014.
server.shutdown graceful SERVER_SHUTDOWN Shutdown mode. Allowed: graceful waits for in-flight requests to finish; immediate stops without waiting.
log.dir client-service LOG_DIR Log directory identifier.
spring.profiles.active dev SPRING_PROFILES_ACTIVE Active Spring profile. Common values: dev for local development, k8s when a Kubernetes profile exists, or any custom profile with a matching application-<profile>.yml.
spring.application.name client-service SPRING_APPLICATION_NAME Service name used by Spring and discovery.
spring.lifecycle.timeout-per-shutdown-phase 90s SPRING_LIFECYCLE_TIMEOUT_PER_SHUTDOWN_PHASE Maximum graceful shutdown phase duration.
spring.main.allow-bean-definition-overriding true SPRING_MAIN_ALLOW_BEAN_DEFINITION_OVERRIDING Allows duplicate bean names to be replaced at startup. Allowed: true permits overrides; false fails startup on duplicate bean definitions.
info.app.name Customer Service Human-readable service name shown by the actuator info endpoint.
info.app.description This service is responsible for Customer. Human-readable service purpose shown by the actuator info endpoint.
info.app.version 1.0 Application version shown by the actuator info endpoint.

Actuator, Tracing, and Logging

Actuator is Spring Boot's operational endpoint layer. It exposes health, metrics, environment, and diagnostic endpoints. Tracing adds request correlation identifiers so operators can follow one request across logs and services.

Property Value / Default Env Variable Description
management.endpoints.web.exposure.include * MANAGEMENT_ENDPOINTS_WEB_EXPOSURE_INCLUDE Actuator endpoints exposed over HTTP. Allowed examples: * exposes all; health,info exposes only health and info. Restrict this in production if actuator is reachable outside the private network.
management.info.env.enabled true MANAGEMENT_INFO_ENV_ENABLED Environment-backed actuator info. Allowed: true includes configured info values; false hides environment-backed info.
management.endpoint.health.probes.enabled true MANAGEMENT_ENDPOINT_HEALTH_PROBES_ENABLED Enables Kubernetes-style health probes. Allowed: true creates liveness/readiness health groups; false exposes only standard health behavior.
management.tracing.sampling.probability 1.0 MANAGEMENT_TRACING_SAMPLING_PROBABILITY Fraction of requests sampled for tracing. Allowed range: 0.0 samples none, 1.0 samples all, values between sample a percentage.
logging.pattern.level %5p [${spring.application.name:},%X{traceId:-},%X{spanId:-},%X{correlationId:-}] LOGGING_PATTERN_LEVEL Log level pattern with trace and correlation IDs.
logging.config classpath:log/logback-dev.xml dev LOGGING_CONFIG Logback configuration used in dev.
spring.sleuth.sampler.probability 1.0 dev SPRING_SLEUTH_SAMPLER_PROBABILITY Sleuth tracing sample rate in dev. Allowed range: 0.0 to 1.0.

Eureka Discovery

Eureka is the service registry. This service registers itself there so gateway and other services can discover its network location without hard-coding hostnames.

Property Value / Default Env Variable Description
eureka.client.service-url.defaultZone http://localhost:8761/eureka/ EUREKA_CLIENT_SERVICE_URL_DEFAULTZONE Eureka registry endpoint.
eureka.instance.prefer-ip-address true EUREKA_INSTANCE_PREFER_IP_ADDRESS Registration address type. Allowed: true registers the instance IP address; false registers hostname.

JPA, SQL Init, and Flyway

JPA/Hibernate maps Java entities to database tables. SQL init runs startup SQL scripts. Flyway runs versioned database migrations before the application uses the schema.

Property Value / Default Env Variable Description
spring.jpa.database-platform postgres base Base JPA database platform.
spring.jpa.show-sql false SQL statement logging. Allowed: true prints SQL to logs; false keeps logs quieter.
spring.jpa.open-in-view false Keeps database session open during web response rendering. Allowed: true permits lazy loading during response rendering; false closes sessions at transaction boundaries. Services should normally keep this false.
spring.jpa.properties.hibernate.dialect org.hibernate.dialect.PostgreSQLDialect Hibernate dialect.
spring.jpa.hibernate.ddl-auto validate dev Hibernate schema action. Allowed: validate checks schema only; none does nothing; update changes schema automatically; create recreates schema; create-drop recreates then drops on shutdown. Use validate with Flyway-managed schemas.
spring.sql.init.mode always SPRING_SQL_INIT_MODE SQL script execution mode. Allowed: always runs scripts for any database; embedded runs only for embedded databases; never disables SQL init.
spring.sql.init.continue-on-error true SPRING_SQL_INIT_CONTINUE_ON_ERROR SQL init error handling. Allowed: true continues after script errors; false fails startup on script errors.
spring.flyway.enabled true Flyway migration runner. Allowed: true runs migrations at startup; false skips migrations.
spring.flyway.baseline-on-migrate true Baselines a non-empty schema without Flyway history. Allowed: true creates a baseline; false fails if the schema is non-empty and unmanaged.
spring.flyway.baseline-version 0 Baseline version.
spring.flyway.schemas client_service Flyway migration schema.
spring.flyway.default-schema client_service Flyway default schema.
spring.flyway.url jdbc:postgresql://localhost:5432/sms_gateway?currentSchema=client_service DB_URL Flyway JDBC URL.
spring.flyway.user appadmin DB_USERNAME Flyway database user.
spring.flyway.password Required DB_PASSWORD Flyway database password.

Master Datasource

The master datasource is the read/write PostgreSQL connection pool used for commands that change client, user, balance, and reporting state.

Property Value / Default Env Variable Description
datasource.master.url jdbc:postgresql://localhost:5432/sms_gateway?currentSchema=client_service DB_URL Master JDBC URL.
datasource.master.username appadmin DB_USERNAME Master database username.
datasource.master.password Required DB_PASSWORD Master database password.
datasource.master.maximum-pool-size 10 Maximum master pool size.
datasource.master.minimum-idle 2 Minimum idle master connections.
datasource.master.connection-timeout 30000 Connection timeout in milliseconds.
datasource.master.idle-timeout 600000 Idle timeout in milliseconds.
datasource.master.max-lifetime 1800000 Maximum connection lifetime in milliseconds.
datasource.master.pool-name ClientMasterHikariCP Master Hikari pool name.
datasource.master.validation-timeout 5000 Validation timeout in milliseconds.
datasource.master.leak-detection-threshold 60000 Leak detection threshold in milliseconds.

Slave Datasource

The slave datasource is intended for read-heavy operations. If DB_SLAVE_URL is not set, it falls back to the master database URL.

Property Value / Default Env Variable Description
datasource.slave.url Falls back to DB_URL / local client schema URL DB_SLAVE_URL Slave JDBC URL.
datasource.slave.username appadmin DB_USERNAME Slave database username.
datasource.slave.password Required DB_PASSWORD Slave database password.
datasource.slave.maximum-pool-size 2 Maximum slave pool size.
datasource.slave.minimum-idle 1 Minimum idle slave connections.
datasource.slave.connection-timeout 30000 Connection timeout in milliseconds.
datasource.slave.idle-timeout 600000 Idle timeout in milliseconds.
datasource.slave.max-lifetime 1800000 Maximum connection lifetime in milliseconds.
datasource.slave.pool-name ClientSlaveHikariCP Slave Hikari pool name.
datasource.slave.validation-timeout 5000 Validation timeout in milliseconds.
datasource.slave.leak-detection-threshold 60000 Leak detection threshold in milliseconds.

Redis

Redis stores token/session data and fast lookup keys. Pool settings limit how many Redis connections the service keeps open.

Property Value / Default Env Variable Description
redis.host localhost REDIS_HOST Redis host.
redis.port 6379 REDIS_PORT Redis port.
redis.password Empty REDIS_PASSWORD Redis password.
redis.database.index 5 REDIS_DATABASE_INDEX Redis logical database.
redis.pool.max.connection 30 Maximum Redis pool size.
redis.pool.max.idle.connection 10 Maximum idle Redis connections.
redis.pool.min.idle.connection 0 Minimum idle Redis connections.
redis.key.prefix.accesstoken client:accesstoken: Redis access token key prefix.
redis.key.prefix.idtoken client:idtoken: Redis identity token key prefix.

Token keys used by the service

The service does not currently use the two token prefix settings above. It stores access tokens as sms:token:{rawJwt} and refresh tokens as sms:refresh:{sha256(refreshToken)}. Changing the prefix settings does not rename existing Redis keys or move active sessions.

JWT and Admin Security

JWT settings control user access-token and refresh-token lifetimes. admin.api.key protects privileged internal/admin endpoints.

Property Value / Default Env Variable Description
jwt.secret.key Required JWT_SECRET_KEY JWT signing key. Must match gateway validation key.
jwt.expiry-ms 3600000 base, 86400000 dev JWT_EXPIRY_MS Access token lifetime in milliseconds. Dev overrides the base value.
jwt.refresh-expiry-ms 604800000 JWT_REFRESH_EXPIRY_MS Refresh token lifetime in milliseconds.
admin.api.key Required ADMIN_API_KEY Shared admin key for admin/internal endpoints.

JWT_SECRET_KEY must decode from Base64 to suitable HS512 key material and must match gateway-service. A mismatch allows login but causes the gateway to reject the returned access token. Startup fails when ADMIN_API_KEY is blank, shorter than 32 characters, or equals CHANGE_ME_IN_PRODUCTION.

Kafka and Reporting

Kafka carries asynchronous reporting events. The reporting consumer reads events and updates client-service reporting tables.

Property Value / Default Env Variable Description
spring.kafka.bootstrap-servers localhost:9092 KAFKA_BOOTSTRAP_SERVERS Kafka bootstrap servers.
spring.kafka.consumer.group-id client-service-reporting REPORTING_CONSUMER_GROUP Reporting consumer group ID.
spring.kafka.consumer.auto-offset-reset earliest Offset reset policy when no committed offset exists. Allowed: earliest starts from the oldest retained message; latest starts from new messages only; none fails if no offset exists.
spring.kafka.consumer.key-deserializer org.apache.kafka.common.serialization.StringDeserializer Consumer key deserializer.
spring.kafka.consumer.value-deserializer org.apache.kafka.common.serialization.StringDeserializer Consumer value deserializer.
spring.kafka.producer.key-serializer org.apache.kafka.common.serialization.StringSerializer Producer key serializer.
spring.kafka.producer.value-serializer org.apache.kafka.common.serialization.StringSerializer Producer value serializer.
reporting.topic sms.reporting REPORTING_TOPIC Reporting Kafka topic.
reporting.consumer.enabled true REPORTING_CONSUMER_ENABLED Reporting event consumption. Allowed: true consumes reporting events in this service; false disables this consumer on this node.

Malformed reporting events and known events that cannot be deserialized are routed to sms.reporting.dlt. Transient database failures retry with exponential backoff before the same destination. The service has no DLT replay consumer, so retain and monitor this topic.

Channel Failure Alerts

The reporting consumer counts unique terminal-failure recipient IDs in a Redis rolling window. Reaching the threshold creates an alert plus transactional outbox row. Configure either a webhook or Kafka delivery.

Property Default Env Variable Description
channel-alert.enabled true CHANNEL_ALERT_ENABLED Enables rolling-window evaluation. Redis failures are logged and do not fail reporting ingestion.
channel-alert.threshold 100 CHANNEL_ALERT_THRESHOLD Unique failed recipients required for an alert. Use a positive integer.
channel-alert.window-seconds 300 CHANNEL_ALERT_WINDOW_SECONDS Rolling Redis window.
channel-alert.cooldown-seconds 900 CHANNEL_ALERT_COOLDOWN_SECONDS Minimum time between alerts for one client/channel.
channel-alert.key-prefix channel-failure:v1: CHANNEL_ALERT_KEY_PREFIX Redis key namespace.
channel-alert.ttl-grace-seconds 60 CHANNEL_ALERT_TTL_GRACE_SECONDS Extra TTL after the window.
channel-alert.topic client.channel-alerts CHANNEL_ALERT_TOPIC Kafka delivery destination when webhook URL is empty.
channel-alert.webhook-url Empty CHANNEL_ALERT_WEBHOOK_URL Alert receiver. Any nonblank URL selects webhook instead of Kafka.
channel-alert.webhook-api-key Empty CHANNEL_ALERT_WEBHOOK_API_KEY Optional value sent as X-Api-Key; store as a secret.
channel-alert.webhook-timeout-seconds 5 CHANNEL_ALERT_WEBHOOK_TIMEOUT_SECONDS HTTP connect and read timeout.
channel-alert.advisory-lock-timeout-seconds 2 CHANNEL_ALERT_LOCK_TIMEOUT_SECONDS Intended alert-lock timeout setting.

Terminal failures counted are FAILED, REJECTED, EXPIRED, UNDELIVERED, INVALID_MSISDN, DND, and NOT_AVAILABLE.

Alert Outbox Publisher and Recovery

Property Default Env Variable Description
client.outbox.publisher.enabled true CLIENT_OUTBOX_PUBLISHER_ENABLED Creates the publisher bean. Disable on nodes that must only ingest reports.
client.outbox.publisher.poll-ms 1000 CLIENT_OUTBOX_POLL_MS Fixed delay after a publisher run completes.
client.outbox.publisher.batch-size 50 CLIENT_OUTBOX_BATCH_SIZE Rows claimed per run using SKIP LOCKED.
client.outbox.publisher.send-timeout-ms 5000 CLIENT_OUTBOX_SEND_TIMEOUT_MS Common deadline for the batch's Kafka sends. Webhook calls use the channel-alert timeout.
client.outbox.recovery.enabled true CLIENT_OUTBOX_RECOVERY_ENABLED Reopens eligible failed rows.
client.outbox.recovery.poll-ms 60000 CLIENT_OUTBOX_RECOVERY_POLL_MS Recovery scan interval (code default; not explicitly present in base YAML).
client.outbox.recovery.cooldown-minutes 5 CLIENT_OUTBOX_RECOVERY_COOLDOWN_MINUTES Delay after failure before reopening (code default).
client.outbox.recovery.max-rounds 3 CLIENT_OUTBOX_RECOVERY_MAX_ROUNDS Maximum reopen cycles before manual intervention (code default).
client.outbox.recovery.batch-size 100 CLIENT_OUTBOX_RECOVERY_BATCH_SIZE Failed rows considered per scan (code default).

If multiple instances run, database row claiming prevents duplicate publisher work. Alert threshold coordination uses PostgreSQL advisory transaction locks. Five failed delivery attempts is currently hard-coded before an event is parked; it is not a configuration property.