Configuration properties
The tSM system is built on top of Spring Boot, which allows it to leverage Spring’s powerful externalized configuration capabilities. In tSM, configuration is primarily managed through the application.yml
file, which defines common properties that apply to all microservices. These configurations can be easily customized for different environments such as development, testing, and production.
tSM also supports optional usage of Spring Cloud Config to centralize configuration across multiple microservices. This setup ensures consistency and easier management of shared properties like data sources, messaging services (Kafka), and environment-specific settings.
Please consult Spring Externalized Configuration for more info.
Common Configuration for tSM Microservices
In tSM, every microservice shares some common configuration properties, which can be centrally managed. This is especially useful when using Spring Cloud Config, where you can maintain one application.yml
for all services. Here’s an example of a minimal common configuration:
# ----------------------------------------------------------------------------
# Common configuration
# ----------------------------------------------------------------------------
tsm:
prefix: projectX
datasource:
host: my.postgres.database:5401
database: tsm
username: tsm_admin
password: myPass
elastic:
address: tsm-elastic
username: elastic
password: elasticdata
kafka:
address: my.kafka.cluster:9092
autocreate:
partitions: 2
elk:
enabled: true
logstash:
url: tsm-log-server:5044
locale:
locale: cs-CZ
timezone: "Europe/Prague"
Explanation of Common Properties:
- tsm.prefix: A unique identifier for the project, which is used to distinguish between different projects in the same environment. It is used as a prefix for all Kafka topics, elasticsearch indexes, and other project-specific settings.
- tsm.datasource: Defines the database connection details for tSM microservices.
- tsm.elastic: Specifies the ElasticSearch configuration for logging and searching within tSM.
- tsm.kafka: Configures Kafka settings, including the address of the Kafka broker and partition settings.
- tsm.elk: Controls ELK stack logging, including connection to Logstash.
- tsm.locale: Sets locale and timezone settings for tSM microservices.
These properties are common across all tSM microservices and ensure consistency in the way services connect to databases, messaging queues, and logging systems.
Deployment Options
When deploying tSM microservices, you have multiple options to manage configurations. The most common approach is using Spring Cloud Config for cloud environments, such as Kubernetes (K8s), where configurations are managed centrally and shared across all microservices. For on-premise deployments, configurations are typically managed locally via application.yml
files.
Cloud Config Deployment
In cloud-based deployments, such as Kubernetes, Spring Cloud Config can be used to manage configuration files centrally. This enables easy scaling and maintenance of configurations across all microservices.
To use Spring Cloud Config, you need to specify the configuration source using the spring.config.import
environment variable. This can be done directly in the Kubernetes deployment spec.
Example: Kubernetes Deployment with Spring Cloud Config
spec:
containers:
- env:
- name: spring.config.import
value: 'configserver:http://tsm-config-server'
image: 'registry.datalite.cz/tsm/tsm-calendar:2.2'
In this example:
- spring.config.import points to the Spring Cloud Config server URL, which provides the configurations for the microservice.
- The tsm-calendar microservice image is pulled from the registry and uses the configurations provided by the config server.
To deploy the Spring Cloud Config server, you need to ensure that it is configured to pull configurations from a Git repository or other storage. Here's an example Kubernetes configuration for deploying the config server:
spec:
containers:
- env:
- name: JAVA_TOOL_OPTIONS
value: '-Xms150m -Xmx150m'
- name: spring.cloud.config.server.git.uri
value: https://gitlab.datalite.cz/tsm/config.git
- name: spring.cloud.config.server.git.username
value: user
- name: spring.cloud.config.server.git.password
value: pass
- name: encrypt.key
value: myPass
image: 'registry.datalite.cz/tsm/tsm-config-server:2.2'
Make sure you have the Spring Cloud Config Server up and running and pointing to the correct repository where your application.yml files are stored.
On-Premise Deployment
For on-premise deployments, configurations are typically managed locally by placing the application.yml file directly in the classpath of the microservice. No external configuration server is required, and each microservice will load its configuration from the local file system.
Built in Configuration Properties
The following properties are common to all profiles, environments, and customizations.
They are included to all microservices and can be overridden by the environment or profile.
# ------------------------------------------------------------
# Base shared settings (apply to every profile and environment)
# ------------------------------------------------------------
tsm:
kafka:
# Global topic prefix injected from an env variable or parent YAML
prefix: ${tsm.prefix} # e.g. “prod”, “test”, “local”
# Dead-letter queue: messages that failed processing are routed here
dlqTopic: ${tsm.kafka.prefix}-tsm-dlq
# Default consumer-group name for all listeners in this service
consumerGroupId: ${tsm.name}
# List of common topics
topics:
# Cache-invalidation events across micro-services
tsmCacheMaintanance: ${tsm.kafka.prefix}-tsm-cache-maintanance
elastic:
index:
# Index name prefix in Elasticsearch
prefix: ${tsm.prefix}
storedScript:
autoUpdate:
# Auto-upload stored scripts to Elasticsearch on startup
enabled: true
# ------------------------------------------------------------
# Embedded server (Spring Boot)
# ------------------------------------------------------------
server:
port: ${tsm.port} # Listening port
max-http-request-header-size: 64KB # Max size of HTTP request headers
# ------------------------------------------------------------
# Spring Boot – global configuration
# ------------------------------------------------------------
spring:
application:
name: ${tsm.name} # Service name (logs, Actuator /info, etc.)
# ---------- Kafka ----------
kafka:
bootstrap-servers: ${tsm.kafka.address} # Comma-separated broker list
consumer:
group-id: ${tsm.kafka.consumerGroupId} # Default group-id
auto-offset-reset: earliest # No offset? Start from beginning
# ErrorHandlingDeserializer catches (de)serialization errors
key-deserializer: org.springframework.kafka.support.serializer.ErrorHandlingDeserializer
value-deserializer: org.springframework.kafka.support.serializer.ErrorHandlingDeserializer
properties:
spring.deserializer.key.delegate.class: org.apache.kafka.common.serialization.StringDeserializer
spring.deserializer.value.delegate.class: org.apache.kafka.common.serialization.StringDeserializer
max.poll.interval.ms: 3600000 # Long-running message processing
max.poll.records: 20 # Messages fetched per poll
producer:
key-serializer: org.apache.kafka.common.serialization.StringSerializer
value-serializer: org.apache.kafka.common.serialization.StringSerializer
# ---------- Data source ----------
datasource:
# JDBC URL built from env variables (host, database, schema, extra params)
url: jdbc:postgresql://${tsm.datasource.host}/${tsm.datasource.database:tsm}?currentSchema=${tsm.datasource.schema}${tsm.datasource.params:}
username: ${tsm.datasource.username}
password: ${tsm.datasource.password}
hikari:
maximum-pool-size: 30 # Max connections in the pool
minimum-idle: 2 # Minimum idle connections
# ---------- JPA / Hibernate ----------
jpa:
properties:
hibernate:
# JSON (B) mapper for Kotlin + Jackson → PostgreSQL jsonb type
type.json_format_mapper: cz.datalite.tsm.db.KotlinJacksonFormatMapper
jdbc:
lob.non_contextual_creation: true # Fix for large-object creation
batch_size: 100 # Batch size for bulk ops
hibernate:
ddl-auto: none # Flyway manages the schema
open-in-view: true # Keep session open for lazy-load
# ---------- Jackson ----------
jackson:
mapper:
DEFAULT_VIEW_INCLUSION: true # Fields without @JsonView are always included
# ---------- FreeMarker ----------
freemarker:
template-loader-path: classpath:/templates
suffix: .ftl
# ---------- Flyway ----------
flyway:
default-schema: ${tsm.datasource.schema}
schemas: ${tsm.datasource.schema}
locations: classpath:db/release-*/**/{vendor} # Multiple version folders
group: true # Group migrations with the same version
placeholder-prefix: $$FLYWAY$${ # Placeholder syntax in SQL scripts
validate-migration-naming: true
baseline-on-migrate: true
baseline-version: 10.01.0.001 # Initial baseline if DB is empty
baseline-description: TSM Init
out-of-order: true # Allow hot-fix versions out of sequence
# ---------- Redis / Redisson ----------
redis:
redisson:
file: classpath:redisson.yaml # Deployment-provided Redisson config
# ---------- Auto-configuration exclusions ----------
autoconfigure:
exclude:
- org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRepositoriesAutoConfiguration
- org.springframework.boot.autoconfigure.elasticsearch.ReactiveElasticsearchClientAutoConfiguration
- org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration
# ---------- Spring Cloud ----------
cloud:
openfeign:
httpclient.enabled: true # Use Apache HttpClient (supports PATCH)
lazy-attributes-resolution: true # Delay Feign bean initialization
cache.enabled: false # Work-around for occasional startup loop
client:
config: # Global timeouts for all Feign clients
default:
exception-propagation-policy: UNWRAP
logger-level: FULL
connectTimeout: 30000 # 30 s
readTimeout: 30000 # 30 s
discovery:
reactive.enabled: false # Force blocking discovery client
# ------------------------------------------------------------
# Feign (outside Spring Cloud) – enable Apache HttpClient
# ------------------------------------------------------------
feign:
httpclient.enabled: true
# ------------------------------------------------------------
# JaVers – auditing library
# ------------------------------------------------------------
javers:
auditable-aspect-enabled: false
packages-to-scan: cz.datalite.tsm
sqlSchemaManagementEnabled: false
# ------------------------------------------------------------
# Camunda (workflow engine) – defaults
# ------------------------------------------------------------
camunda:
bpm:
database:
schema-update: false # Enable only if admin grants are in place
auto-deployment-enabled: false # Process definitions are deployed via CI/CD
application:
scan-for-process-definitions: false
defaultNumberOfRetries: 1 # Avoid automatic retries for REST calls
defaultSerializationFormat: application/json
tenant-id-provider: cz.datalite.tsm.process.camunda.TsmCamundaTenantIdProvider
generic-properties:
properties:
historyTimeToLive: P365D # Keep process history for one year
loggingContextActivityId: tsm.camunda.activityId
loggingContextBusinessKey: tsm.camunda.businessKey
loggingContextProcessDefinitionId: tsm.camunda.processDefinitionId
loggingContextProcessInstanceId: tsm.camunda.processInstanceId
loggingContextApplicationName:
loggingContextTenantId:
# ------------------------------------------------------------
# Spring Boot Actuator – endpoints and health checks
# ------------------------------------------------------------
management:
endpoint:
health:
show-details: always # Show full health details to everyone
probes.enabled: true # Enable liveness / readiness view
endpoints:
web:
exposure.include: flyway,loggers,logfile,env,info,health,configprops,metrics,scheduledtasks,threaddump,heapdump,prometheus
health:
camunda.enabled: false # Enable after upgrading to Camunda 7.20.1
redis.enabled: false # Turn on only if Redis is actually used
# ------------------------------------------------------------
# Custom bean toggles
# ------------------------------------------------------------
bean:
RequestLoggerConfiguration.enabled: true # Log every inbound/outbound HTTP request
tsm-user-management
tsm:
# HTTP port on which the TSM User-Management service listens
port: 8088
# Application name (used in logs, tracing, etc.)
name: tsm-user-management
datasource:
# Database schema that holds TSM tables
schema: um # “um” = user-management schema
kafka:
# Kafka consumer group for all listeners in this service
consumerGroupId: tsm-user-management
topics:
# Topic with user-related events (create / update / delete)
tsmUser: ${tsm.kafka.prefix}-tsm-user
# Topic with WorkForce Management work-resource updates
tsmWfmWorkresource: ${tsm.kafka.prefix}-wfm-workresource
# Topic with calendar events (holidays, shifts, etc.)
tsmCalendar: ${tsm.kafka.prefix}-tsm-calendar
planner:
# When true, send updates about work-resources to the external planner
update-workresource: true
security:
ad-config:
# Toggle LDAP authentication against Active Directory
ldap-auth-enabled: false # true → users are authenticated via AD
# Toggle scheduled sync of users / groups from AD to local DB
ldap-sync-enabled: false # true → periodic sync runs
# LDAP endpoint (protocol + host + port)
url: ldap://todo.todo:389 # e.g. ldap://ad.company.com:389
# Kerberos / AD DNS domain; leave blank to infer from base-dn
domain: # e.g. company.com
# Root DN under which all user / group objects reside
base-dn: OU=TODO,DC=in,DC=customer,DC=domain
# Optional narrower subtree to search (overrides base-dn if set)
search-base:
# Service account (bind DN or UPN) used to query the directory
mng-user: Service-account@customer.com
# Password for the service account — keep this secure!
mng-password:
radius: # Auth via RADIUS server; roles sync on login
radius-auth-enabled: false # true → enable RADIUS authentication
# One or more RADIUS servers separated by “|”
server: 127.0.0.1 # Ensure ports 1812 (auth) & 1813 (acct) are open
# Shared secret that must match the RADIUS server configuration
sharedSecret: testing123
database:
# Allow classic username/password auth against internal DB
password-auth-enabled: true # Set false to disable local fallback
management:
health:
ldap:
# Include LDAP in Actuator /health only if LDAP is used and should affect status
enabled: false # true → app hits LDAP to report health
# common config
spring:
flyway:
out-of-order: true
jmx:
enabled: false
banner:
location: classpath:tsm-banner.txt
application:
name: ${tsm.name}
javers:
sqlSchema: um
# Remove too verbose logging
logging:
level:
org.apache.kafka: WARN
org.springframework.cloud.openfeign.FeignClientFactoryBean: WARN
org.flywaydb.core.internal.license.VersionPrinter: WARN
com.zaxxer.hikari.HikariDataSource: WARN