diff --git a/.github/workflows/ci-backend.yml b/.github/workflows/ci-backend.yml
index e87981ec..07354a40 100644
--- a/.github/workflows/ci-backend.yml
+++ b/.github/workflows/ci-backend.yml
@@ -7,30 +7,25 @@
# documentation.
name: Backend Java CI with Maven
-
+
+defaults:
+ run:
+ working-directory: backend
+
on:
push:
paths:
- 'backend/**'
- - 'preload/**'
branches: [ "main" ]
pull_request:
paths:
- 'backend/**'
- - 'preload/**'
branches: [ "main" ]
jobs:
build:
runs-on: ubuntu-latest
- strategy:
- matrix:
- directory: ['backend', 'preload']
-
- defaults:
- run:
- working-directory: ${{ matrix.directory }}
steps:
- uses: actions/checkout@v4
@@ -48,7 +43,7 @@ jobs:
- name: Create container image
if: github.ref == 'refs/heads/main'
env:
- IMAGE_ID: ghcr.io/${{ github.repository }}/${{ matrix.directory }}
+ IMAGE_ID: ghcr.io/${{ github.repository }}/backend
VERSION: main
run: |
# Convert to lowercase
@@ -59,8 +54,3 @@ jobs:
-Dspring-boot.build-image.imageName=$IMAGE_ID:$VERSION
docker push $IMAGE_ID:$VERSION
- # Optional: Uploads the full dependency graph to GitHub to improve the quality of Dependabot alerts this repository can receive
- - name: Update dependency graph
- uses: advanced-security/maven-dependency-submission-action@v4
- with:
- directory: ${{ matrix.directory }}
diff --git a/.github/workflows/ci-sfera-mock.yml b/.github/workflows/ci-sfera-mock.yml
index dc7f25ba..4102012c 100644
--- a/.github/workflows/ci-sfera-mock.yml
+++ b/.github/workflows/ci-sfera-mock.yml
@@ -54,8 +54,3 @@ jobs:
-Dspring-boot.build-image.imageName=$IMAGE_ID:$VERSION
docker push $IMAGE_ID:$VERSION
- # Optional: Uploads the full dependency graph to GitHub to improve the quality of Dependabot alerts this repository can receive
- - name: Update dependency graph
- uses: advanced-security/maven-dependency-submission-action@v4
- with:
- directory: sfera-mock
diff --git a/backend/pom.xml b/backend/pom.xml
index 47d1d810..96a9010b 100644
--- a/backend/pom.xml
+++ b/backend/pom.xml
@@ -29,6 +29,7 @@
21
2.0.21
+ 1.3.0
@@ -63,6 +64,10 @@
org.jetbrains.kotlin
kotlin-stdlib
+
+ org.springframework.modulith
+ spring-modulith-starter-core
+
org.springdoc
@@ -117,8 +122,25 @@
postgresql
test
+
+ org.springframework.modulith
+ spring-modulith-starter-test
+ test
+
+
+
+
+ org.springframework.modulith
+ spring-modulith-bom
+ ${spring-modulith.version}
+ pom
+ import
+
+
+
+
${project.basedir}/src/main/kotlin
${project.basedir}/src/test/kotlin
diff --git a/backend/src/main/kotlin/ch/sbb/backend/application/ServicePointsService.kt b/backend/src/main/kotlin/ch/sbb/backend/application/ServicePointsService.kt
deleted file mode 100644
index 416c55ef..00000000
--- a/backend/src/main/kotlin/ch/sbb/backend/application/ServicePointsService.kt
+++ /dev/null
@@ -1,13 +0,0 @@
-package ch.sbb.backend.application
-
-import ch.sbb.backend.api.ServicePointDto
-import ch.sbb.backend.domain.servicepoints.ServicePoint
-
-interface ServicePointsService {
-
- fun findByUic(uic: Int): ServicePoint?
-
- fun update(servicePoints: List): List
-
- fun getAll(): List
-}
diff --git a/backend/src/main/kotlin/ch/sbb/backend/infrastructure/configuration/OpenApiConfig.kt b/backend/src/main/kotlin/ch/sbb/backend/common/OpenApiConfig.kt
similarity index 98%
rename from backend/src/main/kotlin/ch/sbb/backend/infrastructure/configuration/OpenApiConfig.kt
rename to backend/src/main/kotlin/ch/sbb/backend/common/OpenApiConfig.kt
index 8ff59abc..c8879b8c 100644
--- a/backend/src/main/kotlin/ch/sbb/backend/infrastructure/configuration/OpenApiConfig.kt
+++ b/backend/src/main/kotlin/ch/sbb/backend/common/OpenApiConfig.kt
@@ -1,4 +1,4 @@
-package ch.sbb.backend.infrastructure.configuration
+package ch.sbb.backend.common
import io.swagger.v3.oas.models.Components
import io.swagger.v3.oas.models.OpenAPI
diff --git a/backend/src/main/kotlin/ch/sbb/backend/application/RequestLogger.kt b/backend/src/main/kotlin/ch/sbb/backend/common/RequestLogger.kt
similarity index 97%
rename from backend/src/main/kotlin/ch/sbb/backend/application/RequestLogger.kt
rename to backend/src/main/kotlin/ch/sbb/backend/common/RequestLogger.kt
index 6904f12b..e065094f 100644
--- a/backend/src/main/kotlin/ch/sbb/backend/application/RequestLogger.kt
+++ b/backend/src/main/kotlin/ch/sbb/backend/common/RequestLogger.kt
@@ -1,4 +1,4 @@
-package ch.sbb.backend.application
+package ch.sbb.backend.common
import jakarta.servlet.http.HttpServletRequest
import org.slf4j.Logger
@@ -7,7 +7,6 @@ import org.slf4j.event.Level
import org.springframework.http.HttpHeaders
import org.springframework.util.StopWatch
-
class RequestLogger(
private val stopWatch: StopWatch,
private val level: Level
diff --git a/backend/src/main/kotlin/ch/sbb/backend/application/RequestLoggingFilter.kt b/backend/src/main/kotlin/ch/sbb/backend/common/RequestLoggingFilter.kt
similarity index 95%
rename from backend/src/main/kotlin/ch/sbb/backend/application/RequestLoggingFilter.kt
rename to backend/src/main/kotlin/ch/sbb/backend/common/RequestLoggingFilter.kt
index 1ed0e2ed..c693897d 100644
--- a/backend/src/main/kotlin/ch/sbb/backend/application/RequestLoggingFilter.kt
+++ b/backend/src/main/kotlin/ch/sbb/backend/common/RequestLoggingFilter.kt
@@ -1,4 +1,4 @@
-package ch.sbb.backend.application
+package ch.sbb.backend.common
import jakarta.servlet.Filter
import jakarta.servlet.FilterChain
diff --git a/backend/src/main/kotlin/ch/sbb/backend/infrastructure/configuration/WebSecurityConfig.kt b/backend/src/main/kotlin/ch/sbb/backend/common/WebSecurityConfig.kt
similarity index 97%
rename from backend/src/main/kotlin/ch/sbb/backend/infrastructure/configuration/WebSecurityConfig.kt
rename to backend/src/main/kotlin/ch/sbb/backend/common/WebSecurityConfig.kt
index aa0a5671..a2f9f002 100644
--- a/backend/src/main/kotlin/ch/sbb/backend/infrastructure/configuration/WebSecurityConfig.kt
+++ b/backend/src/main/kotlin/ch/sbb/backend/common/WebSecurityConfig.kt
@@ -1,4 +1,4 @@
-package ch.sbb.backend.infrastructure.configuration
+package ch.sbb.backend.common
import com.nimbusds.jose.proc.SecurityContext
import com.nimbusds.jwt.proc.DefaultJWTProcessor
@@ -17,7 +17,6 @@ import org.springframework.security.oauth2.server.resource.authentication.JwtAut
import org.springframework.security.oauth2.server.resource.authentication.JwtGrantedAuthoritiesConverter
import org.springframework.security.web.SecurityFilterChain
-
@Configuration
@EnableWebSecurity
class WebSecurityConfig {
@@ -33,7 +32,7 @@ class WebSecurityConfig {
@Bean
fun filterChain(http: HttpSecurity): SecurityFilterChain {
http {
- authorizeRequests {
+ authorizeHttpRequests {
authorize("/swagger-ui/**", permitAll)
authorize("/v3/api-docs/**", permitAll)
authorize("/actuator/health/**", permitAll)
diff --git a/backend/src/main/kotlin/ch/sbb/backend/domain/logging/LogEntry.kt b/backend/src/main/kotlin/ch/sbb/backend/domain/logging/LogEntry.kt
deleted file mode 100644
index e663543e..00000000
--- a/backend/src/main/kotlin/ch/sbb/backend/domain/logging/LogEntry.kt
+++ /dev/null
@@ -1,22 +0,0 @@
-package ch.sbb.backend.domain.logging
-
-import java.time.OffsetDateTime
-
-data class LogEntry(
- private val time: OffsetDateTime,
- private val source: String,
- private val message: String,
- private val level: LogLevel,
- private val metadata: Map? = emptyMap()
-) {
- fun toSplunkRequest(): SplunkRequest {
- val fields = metadata?.toMutableMap() ?: mutableMapOf()
- fields["level"] = level.name
- return SplunkRequest(
- event = message,
- fields = fields,
- source = source,
- time = time,
- )
- }
-}
diff --git a/backend/src/main/kotlin/ch/sbb/backend/domain/logging/LogLevel.kt b/backend/src/main/kotlin/ch/sbb/backend/domain/logging/LogLevel.kt
deleted file mode 100644
index cda070f5..00000000
--- a/backend/src/main/kotlin/ch/sbb/backend/domain/logging/LogLevel.kt
+++ /dev/null
@@ -1,10 +0,0 @@
-package ch.sbb.backend.domain.logging
-
-enum class LogLevel {
- TRACE,
- DEBUG,
- INFO,
- WARNING,
- ERROR,
- FATAL
-}
diff --git a/backend/src/main/kotlin/ch/sbb/backend/domain/logging/LogService.kt b/backend/src/main/kotlin/ch/sbb/backend/domain/logging/LogService.kt
deleted file mode 100644
index 525fc4d7..00000000
--- a/backend/src/main/kotlin/ch/sbb/backend/domain/logging/LogService.kt
+++ /dev/null
@@ -1,5 +0,0 @@
-package ch.sbb.backend.domain.logging
-
-interface LogService {
- fun logs(logEntries: List)
-}
diff --git a/backend/src/main/kotlin/ch/sbb/backend/domain/logging/MultiTenantLogService.kt b/backend/src/main/kotlin/ch/sbb/backend/domain/logging/MultiTenantLogService.kt
deleted file mode 100644
index 5ec9b437..00000000
--- a/backend/src/main/kotlin/ch/sbb/backend/domain/logging/MultiTenantLogService.kt
+++ /dev/null
@@ -1,43 +0,0 @@
-package ch.sbb.backend.domain.logging
-
-import ch.sbb.backend.application.TenantContext
-import ch.sbb.backend.application.rest.LogEntryRequest
-import ch.sbb.backend.application.rest.LogLevelRequest
-import ch.sbb.backend.domain.tenancy.ConfigTenantService
-import ch.sbb.backend.domain.tenancy.TenantId
-import ch.sbb.backend.infrastructure.configuration.LogDestination
-import org.springframework.stereotype.Service
-
-@Service
-class MultitenantLogService(
- private val tenantService: ConfigTenantService,
- private val splunkLogService: SplunkLogService
-) {
-
- fun logs(logs: List) {
- getLogService(TenantContext.current().tenantId).logs(logs.map {
- LogEntry(
- it.time, it.source, it.message, level(it.level), it.metadata
- )
- })
- }
-
- private fun level(level: LogLevelRequest): LogLevel {
- return when (level) {
- LogLevelRequest.TRACE -> LogLevel.TRACE
- LogLevelRequest.DEBUG -> LogLevel.DEBUG
- LogLevelRequest.INFO -> LogLevel.INFO
- LogLevelRequest.WARNING -> LogLevel.WARNING
- LogLevelRequest.ERROR -> LogLevel.ERROR
- LogLevelRequest.FATAL -> LogLevel.FATAL
- }
- }
-
- private fun getLogService(tenantId: TenantId): LogService {
- val logDestination = tenantService.getById(tenantId).logDestination
- return when (logDestination) {
- LogDestination.SPLUNK -> splunkLogService
- }
- }
-}
-
diff --git a/backend/src/main/kotlin/ch/sbb/backend/domain/servicepoints/ServicePoint.kt b/backend/src/main/kotlin/ch/sbb/backend/domain/servicepoints/ServicePoint.kt
deleted file mode 100644
index 4bd4a375..00000000
--- a/backend/src/main/kotlin/ch/sbb/backend/domain/servicepoints/ServicePoint.kt
+++ /dev/null
@@ -1,19 +0,0 @@
-package ch.sbb.backend.domain.servicepoints
-
-import ch.sbb.backend.api.ServicePointDto
-
-data class ServicePoint(
- val uic: Int,
- val designation: String,
- val abbreviation: String
-) {
- fun toApi(): ServicePointDto {
- return ServicePointDto(uic, designation, abbreviation)
- }
-
- companion object {
- fun toApi(servicePoints: List): List {
- return servicePoints.map { it.toApi() }
- }
- }
-}
diff --git a/backend/src/main/kotlin/ch/sbb/backend/domain/tenancy/TenantService.kt b/backend/src/main/kotlin/ch/sbb/backend/domain/tenancy/TenantService.kt
deleted file mode 100644
index ac507d29..00000000
--- a/backend/src/main/kotlin/ch/sbb/backend/domain/tenancy/TenantService.kt
+++ /dev/null
@@ -1,8 +0,0 @@
-package ch.sbb.backend.domain.tenancy
-
-import ch.sbb.backend.infrastructure.configuration.Tenant
-
-interface TenantService {
- fun getByIssuerUri(issuerUri: String): Tenant
- fun getById(tenantId: TenantId): Tenant
-}
diff --git a/backend/src/main/kotlin/ch/sbb/backend/infrastructure/configuration/LogDestination.kt b/backend/src/main/kotlin/ch/sbb/backend/infrastructure/configuration/LogDestination.kt
deleted file mode 100644
index 0fbf5119..00000000
--- a/backend/src/main/kotlin/ch/sbb/backend/infrastructure/configuration/LogDestination.kt
+++ /dev/null
@@ -1,5 +0,0 @@
-package ch.sbb.backend.infrastructure.configuration
-
-enum class LogDestination {
- SPLUNK
-}
diff --git a/backend/src/main/kotlin/ch/sbb/backend/infrastructure/entities/ServicePointEntity.kt b/backend/src/main/kotlin/ch/sbb/backend/infrastructure/entities/ServicePointEntity.kt
deleted file mode 100644
index 8b2c5d56..00000000
--- a/backend/src/main/kotlin/ch/sbb/backend/infrastructure/entities/ServicePointEntity.kt
+++ /dev/null
@@ -1,12 +0,0 @@
-package ch.sbb.backend.infrastructure.entities
-
-import jakarta.persistence.Entity
-import jakarta.persistence.Id
-
-@Entity(name = "service_points")
- class ServicePointEntity(
- @Id
- var uic: Int,
- var designation: String,
- var abbreviation: String
-)
diff --git a/backend/src/main/kotlin/ch/sbb/backend/infrastructure/repositories/ServicePointsRepository.kt b/backend/src/main/kotlin/ch/sbb/backend/infrastructure/repositories/ServicePointsRepository.kt
deleted file mode 100644
index 241260c9..00000000
--- a/backend/src/main/kotlin/ch/sbb/backend/infrastructure/repositories/ServicePointsRepository.kt
+++ /dev/null
@@ -1,10 +0,0 @@
-package ch.sbb.backend.infrastructure.repositories
-
-import ch.sbb.backend.infrastructure.entities.ServicePointEntity
-import org.springframework.data.repository.ListCrudRepository
-import org.springframework.stereotype.Repository
-
-@Repository
-interface ServicePointsRepository : ListCrudRepository {
- fun findByUic(uic: Int): ServicePointEntity?
-}
diff --git a/backend/src/main/kotlin/ch/sbb/backend/infrastructure/services/ServicePointsServiceImpl.kt b/backend/src/main/kotlin/ch/sbb/backend/infrastructure/services/ServicePointsServiceImpl.kt
deleted file mode 100644
index 204a75a8..00000000
--- a/backend/src/main/kotlin/ch/sbb/backend/infrastructure/services/ServicePointsServiceImpl.kt
+++ /dev/null
@@ -1,33 +0,0 @@
-package ch.sbb.backend.infrastructure.services
-
-import ch.sbb.backend.api.ServicePointDto
-import ch.sbb.backend.application.ServicePointsService
-import ch.sbb.backend.domain.servicepoints.ServicePoint
-import ch.sbb.backend.infrastructure.entities.ServicePointEntity
-import ch.sbb.backend.infrastructure.repositories.ServicePointsRepository
-import org.springframework.stereotype.Service
-
-@Service
-class ServicePointsServiceImpl(private val servicePointsRepository: ServicePointsRepository) :
- ServicePointsService {
- override fun findByUic(uic: Int): ServicePoint? {
- return servicePointsRepository.findByUic(uic)?.mapToServicePoint()
- }
-
- override fun update(servicePoints: List): List {
- return servicePointsRepository.saveAll(servicePoints.map { it.toEntity() })
- .map { it.mapToServicePoint() }
- }
-
- override fun getAll(): List {
- return servicePointsRepository.findAll().map { it.mapToServicePoint() }
- }
-
- fun ServicePointEntity.mapToServicePoint(): ServicePoint {
- return ServicePoint(uic, designation, abbreviation)
- }
-
- fun ServicePointDto.toEntity(): ServicePointEntity {
- return ServicePointEntity(uic, designation, abbreviation)
- }
-}
diff --git a/backend/src/main/kotlin/ch/sbb/backend/application/TenantContext.kt b/backend/src/main/kotlin/ch/sbb/backend/logging/application/TenantContext.kt
similarity index 85%
rename from backend/src/main/kotlin/ch/sbb/backend/application/TenantContext.kt
rename to backend/src/main/kotlin/ch/sbb/backend/logging/application/TenantContext.kt
index 28d88725..90785803 100644
--- a/backend/src/main/kotlin/ch/sbb/backend/application/TenantContext.kt
+++ b/backend/src/main/kotlin/ch/sbb/backend/logging/application/TenantContext.kt
@@ -1,6 +1,6 @@
-package ch.sbb.backend.application
+package ch.sbb.backend.logging.application
-import ch.sbb.backend.domain.tenancy.TenantId
+import ch.sbb.backend.logging.domain.TenantId
import org.springframework.security.core.context.SecurityContextHolder
import org.springframework.security.oauth2.jwt.Jwt
diff --git a/backend/src/main/kotlin/ch/sbb/backend/application/rest/LogEntryRequest.kt b/backend/src/main/kotlin/ch/sbb/backend/logging/application/rest/LogEntryRequest.kt
similarity index 77%
rename from backend/src/main/kotlin/ch/sbb/backend/application/rest/LogEntryRequest.kt
rename to backend/src/main/kotlin/ch/sbb/backend/logging/application/rest/LogEntryRequest.kt
index 4bf0e7d8..b662da43 100644
--- a/backend/src/main/kotlin/ch/sbb/backend/application/rest/LogEntryRequest.kt
+++ b/backend/src/main/kotlin/ch/sbb/backend/logging/application/rest/LogEntryRequest.kt
@@ -1,5 +1,7 @@
-package ch.sbb.backend.application.rest
+package ch.sbb.backend.logging.application.rest
+import ch.sbb.backend.logging.domain.LogEntry
+import ch.sbb.backend.logging.domain.LogLevel
import io.swagger.v3.oas.annotations.media.Schema
import java.time.OffsetDateTime
@@ -30,4 +32,8 @@ data class LogEntryRequest(
example = "{\"deviceId\": \"abcde123\", \"appVersion\": \"1.2.0\"}"
)
val metadata: Map? = emptyMap()
-)
+) {
+ fun toLogEntry(): LogEntry {
+ return LogEntry(time, source, message, LogLevel(level.name), metadata)
+ }
+}
diff --git a/backend/src/main/kotlin/ch/sbb/backend/application/rest/LogLevelRequest.kt b/backend/src/main/kotlin/ch/sbb/backend/logging/application/rest/LogLevelRequest.kt
similarity index 67%
rename from backend/src/main/kotlin/ch/sbb/backend/application/rest/LogLevelRequest.kt
rename to backend/src/main/kotlin/ch/sbb/backend/logging/application/rest/LogLevelRequest.kt
index 5da22869..94506144 100644
--- a/backend/src/main/kotlin/ch/sbb/backend/application/rest/LogLevelRequest.kt
+++ b/backend/src/main/kotlin/ch/sbb/backend/logging/application/rest/LogLevelRequest.kt
@@ -1,4 +1,4 @@
-package ch.sbb.backend.application.rest
+package ch.sbb.backend.logging.application.rest
enum class LogLevelRequest {
TRACE,
diff --git a/backend/src/main/kotlin/ch/sbb/backend/application/rest/LoggingController.kt b/backend/src/main/kotlin/ch/sbb/backend/logging/application/rest/LoggingController.kt
similarity index 86%
rename from backend/src/main/kotlin/ch/sbb/backend/application/rest/LoggingController.kt
rename to backend/src/main/kotlin/ch/sbb/backend/logging/application/rest/LoggingController.kt
index d5226e26..ac8cab63 100644
--- a/backend/src/main/kotlin/ch/sbb/backend/application/rest/LoggingController.kt
+++ b/backend/src/main/kotlin/ch/sbb/backend/logging/application/rest/LoggingController.kt
@@ -1,6 +1,6 @@
-package ch.sbb.backend.application.rest
+package ch.sbb.backend.logging.application.rest
-import ch.sbb.backend.domain.logging.MultitenantLogService
+import ch.sbb.backend.logging.domain.service.LoggingService
import io.swagger.v3.oas.annotations.Operation
import io.swagger.v3.oas.annotations.media.Content
import io.swagger.v3.oas.annotations.media.Schema
@@ -16,7 +16,7 @@ import org.springframework.web.bind.annotation.RestController
@RestController
@RequestMapping("api/v1/logging")
@Tag(name = "Logging", description = "API for logging")
-class LoggingController(private val multitenantLogService: MultitenantLogService) {
+class LoggingController(private val loggingService: LoggingService) {
@Operation(summary = "Log messages from clients")
@ApiResponse(responseCode = "200", description = "Logs successfully saved")
@@ -39,6 +39,6 @@ class LoggingController(private val multitenantLogService: MultitenantLogService
)
@PostMapping("/logs", consumes = ["application/json"])
fun logs(@RequestBody logs: List) {
- multitenantLogService.logs(logs)
+ loggingService.saveAll(logs.map { it.toLogEntry() })
}
}
diff --git a/backend/src/main/kotlin/ch/sbb/backend/logging/domain/LogDestination.kt b/backend/src/main/kotlin/ch/sbb/backend/logging/domain/LogDestination.kt
new file mode 100644
index 00000000..667c6886
--- /dev/null
+++ b/backend/src/main/kotlin/ch/sbb/backend/logging/domain/LogDestination.kt
@@ -0,0 +1,5 @@
+package ch.sbb.backend.logging.domain
+
+enum class LogDestination {
+ SPLUNK
+}
diff --git a/backend/src/main/kotlin/ch/sbb/backend/logging/domain/LogEntry.kt b/backend/src/main/kotlin/ch/sbb/backend/logging/domain/LogEntry.kt
new file mode 100644
index 00000000..8a85c5ab
--- /dev/null
+++ b/backend/src/main/kotlin/ch/sbb/backend/logging/domain/LogEntry.kt
@@ -0,0 +1,11 @@
+package ch.sbb.backend.logging.domain
+
+import java.time.OffsetDateTime
+
+data class LogEntry(
+ val time: OffsetDateTime,
+ val source: String,
+ val message: String,
+ val level: LogLevel,
+ val metadata: Map? = emptyMap()
+)
diff --git a/backend/src/main/kotlin/ch/sbb/backend/logging/domain/LogLevel.kt b/backend/src/main/kotlin/ch/sbb/backend/logging/domain/LogLevel.kt
new file mode 100644
index 00000000..3c2cd97c
--- /dev/null
+++ b/backend/src/main/kotlin/ch/sbb/backend/logging/domain/LogLevel.kt
@@ -0,0 +1,12 @@
+package ch.sbb.backend.logging.domain
+
+data class LogLevel(val value: String) {
+ companion object {
+ val TRACE = LogLevel("TRACE")
+ val DEBUG = LogLevel("DEBUG")
+ val INFO = LogLevel("INFO")
+ val WARNING = LogLevel("WARNING")
+ val ERROR = LogLevel("ERROR")
+ val FATAL = LogLevel("FATAL")
+ }
+}
diff --git a/backend/src/main/kotlin/ch/sbb/backend/infrastructure/configuration/Tenant.kt b/backend/src/main/kotlin/ch/sbb/backend/logging/domain/Tenant.kt
similarity index 75%
rename from backend/src/main/kotlin/ch/sbb/backend/infrastructure/configuration/Tenant.kt
rename to backend/src/main/kotlin/ch/sbb/backend/logging/domain/Tenant.kt
index d6cdb54a..41fed3cd 100644
--- a/backend/src/main/kotlin/ch/sbb/backend/infrastructure/configuration/Tenant.kt
+++ b/backend/src/main/kotlin/ch/sbb/backend/logging/domain/Tenant.kt
@@ -1,4 +1,4 @@
-package ch.sbb.backend.infrastructure.configuration
+package ch.sbb.backend.logging.domain
data class Tenant(
var name: String,
diff --git a/backend/src/main/kotlin/ch/sbb/backend/domain/tenancy/TenantId.kt b/backend/src/main/kotlin/ch/sbb/backend/logging/domain/TenantId.kt
similarity index 83%
rename from backend/src/main/kotlin/ch/sbb/backend/domain/tenancy/TenantId.kt
rename to backend/src/main/kotlin/ch/sbb/backend/logging/domain/TenantId.kt
index 8edaa0e7..b8f12f48 100644
--- a/backend/src/main/kotlin/ch/sbb/backend/domain/tenancy/TenantId.kt
+++ b/backend/src/main/kotlin/ch/sbb/backend/logging/domain/TenantId.kt
@@ -1,4 +1,4 @@
-package ch.sbb.backend.domain.tenancy
+package ch.sbb.backend.logging.domain
import java.util.*
diff --git a/backend/src/main/kotlin/ch/sbb/backend/logging/domain/repository/LoggingRepository.kt b/backend/src/main/kotlin/ch/sbb/backend/logging/domain/repository/LoggingRepository.kt
new file mode 100644
index 00000000..3041a63c
--- /dev/null
+++ b/backend/src/main/kotlin/ch/sbb/backend/logging/domain/repository/LoggingRepository.kt
@@ -0,0 +1,7 @@
+package ch.sbb.backend.logging.domain.repository
+
+import ch.sbb.backend.logging.domain.LogEntry
+
+interface LoggingRepository {
+ fun saveAll(logs: List)
+}
diff --git a/backend/src/main/kotlin/ch/sbb/backend/logging/domain/repository/TenantRepository.kt b/backend/src/main/kotlin/ch/sbb/backend/logging/domain/repository/TenantRepository.kt
new file mode 100644
index 00000000..cdfe8792
--- /dev/null
+++ b/backend/src/main/kotlin/ch/sbb/backend/logging/domain/repository/TenantRepository.kt
@@ -0,0 +1,8 @@
+package ch.sbb.backend.logging.domain.repository
+
+import ch.sbb.backend.logging.domain.Tenant
+
+interface TenantRepository {
+ fun current(): Tenant
+ fun getByIssuerUri(issuerUri: String): Tenant
+}
diff --git a/backend/src/main/kotlin/ch/sbb/backend/logging/domain/service/DomainLoggingService.kt b/backend/src/main/kotlin/ch/sbb/backend/logging/domain/service/DomainLoggingService.kt
new file mode 100644
index 00000000..0310939d
--- /dev/null
+++ b/backend/src/main/kotlin/ch/sbb/backend/logging/domain/service/DomainLoggingService.kt
@@ -0,0 +1,12 @@
+package ch.sbb.backend.logging.domain.service
+
+import ch.sbb.backend.logging.domain.LogEntry
+import ch.sbb.backend.logging.domain.repository.LoggingRepository
+
+class DomainLoggingService(
+ private val loggingRepository: LoggingRepository
+) : LoggingService {
+ override fun saveAll(logEntries: List) {
+ loggingRepository.saveAll(logEntries)
+ }
+}
diff --git a/backend/src/main/kotlin/ch/sbb/backend/logging/domain/service/DomainTenantService.kt b/backend/src/main/kotlin/ch/sbb/backend/logging/domain/service/DomainTenantService.kt
new file mode 100644
index 00000000..7da0ff01
--- /dev/null
+++ b/backend/src/main/kotlin/ch/sbb/backend/logging/domain/service/DomainTenantService.kt
@@ -0,0 +1,14 @@
+package ch.sbb.backend.logging.domain.service
+
+import ch.sbb.backend.logging.domain.Tenant
+import ch.sbb.backend.logging.domain.repository.TenantRepository
+
+class DomainTenantService(private val tenantRepository: TenantRepository) : TenantService {
+ override fun getByIssuerUri(issuerUri: String): Tenant {
+ return tenantRepository.getByIssuerUri(issuerUri)
+ }
+
+ override fun current(): Tenant {
+ return tenantRepository.current()
+ }
+}
diff --git a/backend/src/main/kotlin/ch/sbb/backend/logging/domain/service/LoggingService.kt b/backend/src/main/kotlin/ch/sbb/backend/logging/domain/service/LoggingService.kt
new file mode 100644
index 00000000..8575852e
--- /dev/null
+++ b/backend/src/main/kotlin/ch/sbb/backend/logging/domain/service/LoggingService.kt
@@ -0,0 +1,7 @@
+package ch.sbb.backend.logging.domain.service
+
+import ch.sbb.backend.logging.domain.LogEntry
+
+interface LoggingService {
+ fun saveAll(logEntries: List)
+}
diff --git a/backend/src/main/kotlin/ch/sbb/backend/logging/domain/service/TenantService.kt b/backend/src/main/kotlin/ch/sbb/backend/logging/domain/service/TenantService.kt
new file mode 100644
index 00000000..9a53c0b3
--- /dev/null
+++ b/backend/src/main/kotlin/ch/sbb/backend/logging/domain/service/TenantService.kt
@@ -0,0 +1,8 @@
+package ch.sbb.backend.logging.domain.service
+
+import ch.sbb.backend.logging.domain.Tenant
+
+interface TenantService {
+ fun getByIssuerUri(issuerUri: String): Tenant
+ fun current(): Tenant
+}
diff --git a/backend/src/main/kotlin/ch/sbb/backend/domain/tenancy/ConfigTenantService.kt b/backend/src/main/kotlin/ch/sbb/backend/logging/infrastructure/ConfigTenantRepository.kt
similarity index 52%
rename from backend/src/main/kotlin/ch/sbb/backend/domain/tenancy/ConfigTenantService.kt
rename to backend/src/main/kotlin/ch/sbb/backend/logging/infrastructure/ConfigTenantRepository.kt
index 15f1a061..b8890a91 100644
--- a/backend/src/main/kotlin/ch/sbb/backend/domain/tenancy/ConfigTenantService.kt
+++ b/backend/src/main/kotlin/ch/sbb/backend/logging/infrastructure/ConfigTenantRepository.kt
@@ -1,18 +1,22 @@
-package ch.sbb.backend.domain.tenancy
+package ch.sbb.backend.logging.infrastructure
-import ch.sbb.backend.infrastructure.configuration.Tenant
-import ch.sbb.backend.infrastructure.configuration.TenantConfig
+import ch.sbb.backend.logging.application.TenantContext
+import ch.sbb.backend.logging.domain.Tenant
+import ch.sbb.backend.logging.domain.TenantId
+import ch.sbb.backend.logging.domain.repository.TenantRepository
+import ch.sbb.backend.logging.infrastructure.config.TenantConfig
import org.apache.logging.log4j.LogManager
import org.apache.logging.log4j.Logger
-import org.springframework.stereotype.Service
+import org.springframework.stereotype.Component
-/**
- * Service providing tenant information based on the iss claim of the JWT token.
- */
-@Service
-class ConfigTenantService(private val tenantConfig: TenantConfig) : TenantService {
+@Component
+class ConfigTenantRepository(private val tenantConfig: TenantConfig) : TenantRepository {
- private val logger: Logger = LogManager.getLogger(ConfigTenantService::class.java)
+ private val logger: Logger = LogManager.getLogger(ConfigTenantRepository::class.java)
+
+ override fun current(): Tenant {
+ return getById(TenantContext.current().tenantId)
+ }
override fun getByIssuerUri(issuerUri: String): Tenant {
val tenant: Tenant =
@@ -25,7 +29,7 @@ class ConfigTenantService(private val tenantConfig: TenantConfig) : TenantServic
return tenant
}
- override fun getById(tenantId: TenantId): Tenant {
+ private fun getById(tenantId: TenantId): Tenant {
return tenantConfig.tenants.stream().filter { t -> tenantId == TenantId(t.id) }
.findAny()
.orElseThrow { IllegalArgumentException("unknown tenant") }
diff --git a/backend/src/main/kotlin/ch/sbb/backend/logging/infrastructure/SplunkLoggingRepository.kt b/backend/src/main/kotlin/ch/sbb/backend/logging/infrastructure/SplunkLoggingRepository.kt
new file mode 100644
index 00000000..8d0d11d5
--- /dev/null
+++ b/backend/src/main/kotlin/ch/sbb/backend/logging/infrastructure/SplunkLoggingRepository.kt
@@ -0,0 +1,13 @@
+package ch.sbb.backend.logging.infrastructure
+
+import ch.sbb.backend.logging.domain.LogEntry
+import ch.sbb.backend.logging.domain.repository.LoggingRepository
+import ch.sbb.backend.logging.infrastructure.rest.SplunkHecClient
+import org.springframework.stereotype.Component
+
+@Component
+class SplunkLoggingRepository(private val splunkHecClient: SplunkHecClient) : LoggingRepository {
+ override fun saveAll(logs: List) {
+ splunkHecClient.sendLogs(logs)
+ }
+}
diff --git a/backend/src/main/kotlin/ch/sbb/backend/logging/infrastructure/config/LoggingBeanConfiguration.kt b/backend/src/main/kotlin/ch/sbb/backend/logging/infrastructure/config/LoggingBeanConfiguration.kt
new file mode 100644
index 00000000..534aa6c7
--- /dev/null
+++ b/backend/src/main/kotlin/ch/sbb/backend/logging/infrastructure/config/LoggingBeanConfiguration.kt
@@ -0,0 +1,24 @@
+package ch.sbb.backend.logging.infrastructure.config
+
+import ch.sbb.backend.logging.domain.repository.LoggingRepository
+import ch.sbb.backend.logging.domain.repository.TenantRepository
+import ch.sbb.backend.logging.domain.service.DomainLoggingService
+import ch.sbb.backend.logging.domain.service.DomainTenantService
+import ch.sbb.backend.logging.domain.service.LoggingService
+import ch.sbb.backend.logging.domain.service.TenantService
+import org.springframework.context.annotation.Bean
+import org.springframework.context.annotation.Configuration
+
+@Configuration
+class LoggingBeanConfiguration {
+
+ @Bean
+ fun logService(loggingRepository: LoggingRepository): LoggingService {
+ return DomainLoggingService(loggingRepository)
+ }
+
+ @Bean
+ fun teanantService(tenantRepository: TenantRepository): TenantService {
+ return DomainTenantService(tenantRepository)
+ }
+}
diff --git a/backend/src/main/kotlin/ch/sbb/backend/infrastructure/configuration/TenantConfig.kt b/backend/src/main/kotlin/ch/sbb/backend/logging/infrastructure/config/TenantConfig.kt
similarity index 78%
rename from backend/src/main/kotlin/ch/sbb/backend/infrastructure/configuration/TenantConfig.kt
rename to backend/src/main/kotlin/ch/sbb/backend/logging/infrastructure/config/TenantConfig.kt
index ce70f27f..e17a6e2b 100644
--- a/backend/src/main/kotlin/ch/sbb/backend/infrastructure/configuration/TenantConfig.kt
+++ b/backend/src/main/kotlin/ch/sbb/backend/logging/infrastructure/config/TenantConfig.kt
@@ -1,5 +1,6 @@
-package ch.sbb.backend.infrastructure.configuration
+package ch.sbb.backend.logging.infrastructure.config
+import ch.sbb.backend.logging.domain.Tenant
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.context.annotation.Configuration
diff --git a/backend/src/main/kotlin/ch/sbb/backend/infrastructure/configuration/TenantJwsKeySelector.kt b/backend/src/main/kotlin/ch/sbb/backend/logging/infrastructure/config/TenantJwsKeySelector.kt
similarity index 84%
rename from backend/src/main/kotlin/ch/sbb/backend/infrastructure/configuration/TenantJwsKeySelector.kt
rename to backend/src/main/kotlin/ch/sbb/backend/logging/infrastructure/config/TenantJwsKeySelector.kt
index 3d769e84..de120e68 100644
--- a/backend/src/main/kotlin/ch/sbb/backend/infrastructure/configuration/TenantJwsKeySelector.kt
+++ b/backend/src/main/kotlin/ch/sbb/backend/logging/infrastructure/config/TenantJwsKeySelector.kt
@@ -1,6 +1,7 @@
-package ch.sbb.backend.infrastructure.configuration
+package ch.sbb.backend.logging.infrastructure.config
-import ch.sbb.backend.domain.tenancy.ConfigTenantService
+import ch.sbb.backend.logging.domain.Tenant
+import ch.sbb.backend.logging.domain.repository.TenantRepository
import com.nimbusds.jose.JWSHeader
import com.nimbusds.jose.proc.JWSAlgorithmFamilyJWSKeySelector
import com.nimbusds.jose.proc.JWSKeySelector
@@ -19,7 +20,7 @@ import java.util.concurrent.ConcurrentHashMap
* For a more detailed description see [Spring Security Documentation](https://docs.spring.io/spring-security/reference/servlet/oauth2/resource-server/multitenancy.html#_parsing_the_claim_only_once).
*/
@Component
-class TenantJWSKeySelector(private val tenantService: ConfigTenantService) :
+class TenantJWSKeySelector(private val tenantRepository: TenantRepository) :
JWTClaimsSetAwareJWSKeySelector {
private val selectors: MutableMap> = ConcurrentHashMap()
@@ -34,8 +35,8 @@ class TenantJWSKeySelector(private val tenantService: ConfigTenantService) :
}
private fun fromTenant(issuerUri: String): JWSKeySelector {
- val tenant: Tenant = tenantService.getByIssuerUri(issuerUri)
- return fromUri(tenant.jwkSetUri!!)
+ val tenant: Tenant = tenantRepository.getByIssuerUri(issuerUri)
+ return fromUri(tenant.jwkSetUri)
}
private fun fromUri(uri: String): JWSKeySelector {
diff --git a/backend/src/main/kotlin/ch/sbb/backend/domain/logging/SplunkLogService.kt b/backend/src/main/kotlin/ch/sbb/backend/logging/infrastructure/rest/SplunkHecClient.kt
similarity index 60%
rename from backend/src/main/kotlin/ch/sbb/backend/domain/logging/SplunkLogService.kt
rename to backend/src/main/kotlin/ch/sbb/backend/logging/infrastructure/rest/SplunkHecClient.kt
index b1ed99cc..842b9f66 100644
--- a/backend/src/main/kotlin/ch/sbb/backend/domain/logging/SplunkLogService.kt
+++ b/backend/src/main/kotlin/ch/sbb/backend/logging/infrastructure/rest/SplunkHecClient.kt
@@ -1,5 +1,6 @@
-package ch.sbb.backend.domain.logging
+package ch.sbb.backend.logging.infrastructure.rest
+import ch.sbb.backend.logging.domain.LogEntry
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Value
import org.springframework.http.HttpStatus
@@ -9,17 +10,17 @@ import org.springframework.web.reactive.function.client.WebClientResponseExcepti
import org.springframework.web.server.ResponseStatusException
@Service
-class SplunkLogService(
+class SplunkHecClient(
@Value("\${splunk.url}") private val url: String,
@Value("\${splunk.token}") private val token: String
-) : LogService {
- private val log = LoggerFactory.getLogger(SplunkLogService::class.java)
+) {
+ private val log = LoggerFactory.getLogger(SplunkHecClient::class.java)
private val webClient: WebClient = WebClient.create(url)
- override fun logs(logEntries: List) {
+ fun sendLogs(logEntries: List) {
webClient.post()
.headers { it["Authorization"] = "Splunk $token" }
- .bodyValue(logEntries.map { it.toSplunkRequest() })
+ .bodyValue(logEntries.map { mapToRequest(it) })
.retrieve()
.bodyToMono(Object::class.java)
.doOnError(WebClientResponseException::class.java) {
@@ -28,4 +29,15 @@ class SplunkLogService(
}
.block()
}
+
+ private fun mapToRequest(logEntry: LogEntry): SplunkRequest {
+ val fields = logEntry.metadata?.toMutableMap() ?: mutableMapOf()
+ fields["level"] = logEntry.level.value
+ return SplunkRequest(
+ event = logEntry.message,
+ fields = fields,
+ source = logEntry.source,
+ time = logEntry.time,
+ )
+ }
}
diff --git a/backend/src/main/kotlin/ch/sbb/backend/domain/logging/SplunkRequest.kt b/backend/src/main/kotlin/ch/sbb/backend/logging/infrastructure/rest/SplunkRequest.kt
similarity index 90%
rename from backend/src/main/kotlin/ch/sbb/backend/domain/logging/SplunkRequest.kt
rename to backend/src/main/kotlin/ch/sbb/backend/logging/infrastructure/rest/SplunkRequest.kt
index dfc0332c..640103a3 100644
--- a/backend/src/main/kotlin/ch/sbb/backend/domain/logging/SplunkRequest.kt
+++ b/backend/src/main/kotlin/ch/sbb/backend/logging/infrastructure/rest/SplunkRequest.kt
@@ -1,4 +1,4 @@
-package ch.sbb.backend.domain.logging
+package ch.sbb.backend.logging.infrastructure.rest
import com.fasterxml.jackson.annotation.JsonInclude
import java.time.OffsetDateTime
diff --git a/backend/src/main/kotlin/ch/sbb/backend/preload/domain/TrainIdentification.kt b/backend/src/main/kotlin/ch/sbb/backend/preload/domain/TrainIdentification.kt
new file mode 100644
index 00000000..44cf92d6
--- /dev/null
+++ b/backend/src/main/kotlin/ch/sbb/backend/preload/domain/TrainIdentification.kt
@@ -0,0 +1,11 @@
+package ch.sbb.backend.preload.domain
+
+import java.time.LocalDate
+import java.time.OffsetDateTime
+
+data class TrainIdentification(
+ val operationalTrainNumber: String,
+ val startDate: LocalDate,
+ val company: String,
+ val startDateTime: OffsetDateTime
+)
diff --git a/backend/src/main/kotlin/ch/sbb/backend/preload/domain/repository/TrainIdentificationRepository.kt b/backend/src/main/kotlin/ch/sbb/backend/preload/domain/repository/TrainIdentificationRepository.kt
new file mode 100644
index 00000000..1a11b6fa
--- /dev/null
+++ b/backend/src/main/kotlin/ch/sbb/backend/preload/domain/repository/TrainIdentificationRepository.kt
@@ -0,0 +1,7 @@
+package ch.sbb.backend.preload.domain.repository
+
+import ch.sbb.backend.preload.domain.TrainIdentification
+
+interface TrainIdentificationRepository {
+ fun save(trainIdentification: TrainIdentification)
+}
diff --git a/backend/src/main/kotlin/ch/sbb/backend/preload/infrastructure/entities/TrainIdentificationEntity.kt b/backend/src/main/kotlin/ch/sbb/backend/preload/infrastructure/entities/TrainIdentificationEntity.kt
new file mode 100644
index 00000000..4729f466
--- /dev/null
+++ b/backend/src/main/kotlin/ch/sbb/backend/preload/infrastructure/entities/TrainIdentificationEntity.kt
@@ -0,0 +1,27 @@
+package ch.sbb.backend.preload.infrastructure.entities
+
+import ch.sbb.backend.preload.domain.TrainIdentification
+import jakarta.persistence.Entity
+import jakarta.persistence.Id
+import jakarta.persistence.IdClass
+import java.time.LocalDate
+import java.time.OffsetDateTime
+
+@Entity(name = "train_identification")
+@IdClass(TrainIdentificationId::class)
+class TrainIdentificationEntity(
+ @Id
+ var operationalTrainNumber: String,
+ @Id
+ var startDate: LocalDate,
+ @Id
+ var company: String,
+ var startDateTime: OffsetDateTime
+) {
+ constructor(trainIdentification: TrainIdentification) : this(
+ trainIdentification.operationalTrainNumber,
+ trainIdentification.startDate,
+ trainIdentification.company,
+ trainIdentification.startDateTime
+ )
+}
diff --git a/backend/src/main/kotlin/ch/sbb/backend/preload/infrastructure/entities/TrainIdentificationId.kt b/backend/src/main/kotlin/ch/sbb/backend/preload/infrastructure/entities/TrainIdentificationId.kt
new file mode 100644
index 00000000..0008bc4a
--- /dev/null
+++ b/backend/src/main/kotlin/ch/sbb/backend/preload/infrastructure/entities/TrainIdentificationId.kt
@@ -0,0 +1,33 @@
+package ch.sbb.backend.preload.infrastructure.entities
+
+import java.io.Serializable
+import java.time.LocalDate
+
+class TrainIdentificationId(
+ val operationalTrainNumber: String = "",
+ val startDate: LocalDate = LocalDate.now(),
+ val company: String = ""
+) : Serializable {
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) return true
+ if (javaClass != other?.javaClass) return false
+
+ other as TrainIdentificationId
+
+ if (operationalTrainNumber != other.operationalTrainNumber) return false
+ if (startDate != other.startDate) return false
+ if (company != other.company) return false
+
+ return true
+ }
+
+ override fun hashCode(): Int {
+ var result = operationalTrainNumber.hashCode()
+ result = 31 * result + startDate.hashCode()
+ result = 31 * result + company.hashCode()
+ return result
+ }
+}
+
+
diff --git a/backend/src/main/kotlin/ch/sbb/backend/preload/infrastructure/repositories/PostgreSQLTrainIdentificationRepository.kt b/backend/src/main/kotlin/ch/sbb/backend/preload/infrastructure/repositories/PostgreSQLTrainIdentificationRepository.kt
new file mode 100644
index 00000000..a6d6afd2
--- /dev/null
+++ b/backend/src/main/kotlin/ch/sbb/backend/preload/infrastructure/repositories/PostgreSQLTrainIdentificationRepository.kt
@@ -0,0 +1,14 @@
+package ch.sbb.backend.preload.infrastructure.repositories
+
+import ch.sbb.backend.preload.domain.TrainIdentification
+import ch.sbb.backend.preload.domain.repository.TrainIdentificationRepository
+import ch.sbb.backend.preload.infrastructure.entities.TrainIdentificationEntity
+import org.springframework.stereotype.Component
+
+@Component
+class PostgreSQLTrainIdentificationRepository(private val trainIdentificationRepository: SpringDataJpaTrainIdentificationRepository) :
+ TrainIdentificationRepository {
+ override fun save(trainIdentification: TrainIdentification) {
+ trainIdentificationRepository.save(TrainIdentificationEntity(trainIdentification))
+ }
+}
diff --git a/backend/src/main/kotlin/ch/sbb/backend/preload/infrastructure/repositories/SpringDataJpaTrainIdentificationRepository.kt b/backend/src/main/kotlin/ch/sbb/backend/preload/infrastructure/repositories/SpringDataJpaTrainIdentificationRepository.kt
new file mode 100644
index 00000000..0ed8497c
--- /dev/null
+++ b/backend/src/main/kotlin/ch/sbb/backend/preload/infrastructure/repositories/SpringDataJpaTrainIdentificationRepository.kt
@@ -0,0 +1,10 @@
+package ch.sbb.backend.preload.infrastructure.repositories
+
+import ch.sbb.backend.preload.infrastructure.entities.TrainIdentificationEntity
+import ch.sbb.backend.preload.infrastructure.entities.TrainIdentificationId
+import org.springframework.data.repository.ListCrudRepository
+import org.springframework.stereotype.Repository
+
+@Repository
+interface SpringDataJpaTrainIdentificationRepository :
+ ListCrudRepository {}
diff --git a/backend/src/main/kotlin/ch/sbb/backend/api/ServicePointDto.kt b/backend/src/main/kotlin/ch/sbb/backend/servicepoints/application/ServicePointReponse.kt
similarity index 86%
rename from backend/src/main/kotlin/ch/sbb/backend/api/ServicePointDto.kt
rename to backend/src/main/kotlin/ch/sbb/backend/servicepoints/application/ServicePointReponse.kt
index 3b4b7869..eff7cf8c 100644
--- a/backend/src/main/kotlin/ch/sbb/backend/api/ServicePointDto.kt
+++ b/backend/src/main/kotlin/ch/sbb/backend/servicepoints/application/ServicePointReponse.kt
@@ -1,9 +1,9 @@
-package ch.sbb.backend.api
+package ch.sbb.backend.servicepoints.application
import io.swagger.v3.oas.annotations.media.Schema
@Schema(name = "ServicePoint")
-data class ServicePointDto(
+data class ServicePointReponse(
@Schema(
description = "UIC-Code, combination of uicCountryCode and numberShort. Length: 7",
diff --git a/backend/src/main/kotlin/ch/sbb/backend/application/rest/ServicePointsController.kt b/backend/src/main/kotlin/ch/sbb/backend/servicepoints/application/ServicePointsController.kt
similarity index 60%
rename from backend/src/main/kotlin/ch/sbb/backend/application/rest/ServicePointsController.kt
rename to backend/src/main/kotlin/ch/sbb/backend/servicepoints/application/ServicePointsController.kt
index f6068870..4399bc6e 100644
--- a/backend/src/main/kotlin/ch/sbb/backend/application/rest/ServicePointsController.kt
+++ b/backend/src/main/kotlin/ch/sbb/backend/servicepoints/application/ServicePointsController.kt
@@ -1,8 +1,6 @@
-package ch.sbb.backend.application.rest
+package ch.sbb.backend.servicepoints.application
-import ch.sbb.backend.api.ServicePointDto
-import ch.sbb.backend.application.ServicePointsService
-import ch.sbb.backend.domain.servicepoints.ServicePoint
+import ch.sbb.backend.servicepoints.domain.service.ServicePointService
import io.swagger.v3.oas.annotations.Operation
import io.swagger.v3.oas.annotations.media.Content
import io.swagger.v3.oas.annotations.media.Schema
@@ -17,31 +15,7 @@ import org.springframework.web.bind.annotation.*
@RestController
@RequestMapping("api/v1/service-points")
@Tag(name = "Service Points", description = "API for service points")
-class ServicePointsController(private val servicePointsService: ServicePointsService) {
-
- @Operation(summary = "Update service points")
- @ApiResponse(responseCode = "200", description = "Service points successfully updated")
- @ApiResponse(
- responseCode = "400", description = "Invalid input", content = [
- Content(
- mediaType = APPLICATION_JSON_VALUE,
- schema = Schema(ref = "#/components/schemas/ErrorResponse")
- )
- ]
- )
- @ApiResponse(responseCode = "401", description = "Unauthorized")
- @ApiResponse(
- responseCode = "500", description = "Internal server error", content = [
- Content(
- mediaType = "application/json",
- schema = Schema(ref = "#/components/schemas/ErrorResponse")
- )
- ]
- )
- @PutMapping(consumes = ["application/json"])
- fun updateServicePoints(@RequestBody servicePoints: List) {
- servicePointsService.update(servicePoints)
- }
+class ServicePointsController(private val servicePointService: ServicePointService) {
@Operation(summary = "Get all service points")
@ApiResponse(responseCode = "200", description = "Service points successfully retrieved")
@@ -60,8 +34,8 @@ class ServicePointsController(private val servicePointsService: ServicePointsSer
)
@ResponseBody
@GetMapping(produces = [APPLICATION_JSON_VALUE])
- fun getAllServicePoints(): ResponseEntity> {
- return ResponseEntity.ok(ServicePoint.toApi(servicePointsService.getAll()))
+ fun getAllServicePoints(): ResponseEntity> {
+ return ResponseEntity.ok(servicePointService.getAll().map { ServicePointReponse(it.uic, it.designation, it.abbreviation) })
}
@Operation(summary = "Get service point by UIC")
@@ -86,8 +60,8 @@ class ServicePointsController(private val servicePointsService: ServicePointsSer
)
@ResponseBody
@GetMapping("/{uic}", produces = [APPLICATION_JSON_VALUE])
- fun getServicePoint(@PathVariable uic: Int): ResponseEntity {
- return servicePointsService.findByUic(uic)?.let { ResponseEntity.ok(it.toApi()) }
+ fun getServicePoint(@PathVariable uic: Int): ResponseEntity {
+ return servicePointService.findByUic(uic)?.let { ResponseEntity.ok(ServicePointReponse(it.uic, it.abbreviation, it.designation)) }
?: ResponseEntity.notFound().build()
}
}
diff --git a/backend/src/main/kotlin/ch/sbb/backend/servicepoints/domain/ServicePoint.kt b/backend/src/main/kotlin/ch/sbb/backend/servicepoints/domain/ServicePoint.kt
new file mode 100644
index 00000000..9c3a0aa0
--- /dev/null
+++ b/backend/src/main/kotlin/ch/sbb/backend/servicepoints/domain/ServicePoint.kt
@@ -0,0 +1,8 @@
+package ch.sbb.backend.servicepoints.domain
+
+
+data class ServicePoint(
+ val uic: Int,
+ val designation: String,
+ val abbreviation: String
+)
diff --git a/backend/src/main/kotlin/ch/sbb/backend/servicepoints/domain/repository/ServicePointRepository.kt b/backend/src/main/kotlin/ch/sbb/backend/servicepoints/domain/repository/ServicePointRepository.kt
new file mode 100644
index 00000000..1f2063d3
--- /dev/null
+++ b/backend/src/main/kotlin/ch/sbb/backend/servicepoints/domain/repository/ServicePointRepository.kt
@@ -0,0 +1,10 @@
+package ch.sbb.backend.servicepoints.domain.repository
+
+import ch.sbb.backend.servicepoints.domain.ServicePoint
+
+interface ServicePointRepository {
+ fun findByUic(uic: Int): ServicePoint?
+ fun findAll(): List
+ fun saveAll(servicePoints: List)
+ fun save(servicePoint: ServicePoint)
+}
diff --git a/backend/src/main/kotlin/ch/sbb/backend/servicepoints/domain/service/DomainServicePointService.kt b/backend/src/main/kotlin/ch/sbb/backend/servicepoints/domain/service/DomainServicePointService.kt
new file mode 100644
index 00000000..20fa6058
--- /dev/null
+++ b/backend/src/main/kotlin/ch/sbb/backend/servicepoints/domain/service/DomainServicePointService.kt
@@ -0,0 +1,24 @@
+package ch.sbb.backend.servicepoints.domain.service
+
+import ch.sbb.backend.servicepoints.domain.ServicePoint
+import ch.sbb.backend.servicepoints.domain.repository.ServicePointRepository
+
+class DomainServicePointService(private val servicePointRepository: ServicePointRepository) :
+ ServicePointService {
+ override fun getAll(): List {
+ return servicePointRepository.findAll()
+ }
+
+ override fun findByUic(uic: Int): ServicePoint? {
+ return servicePointRepository.findByUic(uic)
+ }
+
+ override fun updateAll(servicePoints: List) {
+ servicePointRepository.saveAll(servicePoints)
+ }
+
+ override fun create(servicePoint: ServicePoint) {
+ servicePointRepository.save(servicePoint)
+ }
+
+}
diff --git a/backend/src/main/kotlin/ch/sbb/backend/servicepoints/domain/service/ServicePointService.kt b/backend/src/main/kotlin/ch/sbb/backend/servicepoints/domain/service/ServicePointService.kt
new file mode 100644
index 00000000..b8fb703a
--- /dev/null
+++ b/backend/src/main/kotlin/ch/sbb/backend/servicepoints/domain/service/ServicePointService.kt
@@ -0,0 +1,10 @@
+package ch.sbb.backend.servicepoints.domain.service
+
+import ch.sbb.backend.servicepoints.domain.ServicePoint
+
+interface ServicePointService {
+ fun getAll(): List
+ fun findByUic(uic: Int): ServicePoint?
+ fun updateAll(servicePoints: List)
+ fun create(servicePoint: ServicePoint)
+}
diff --git a/backend/src/main/kotlin/ch/sbb/backend/servicepoints/infrastructure/configuration/PostgreSQLConfiguration.kt b/backend/src/main/kotlin/ch/sbb/backend/servicepoints/infrastructure/configuration/PostgreSQLConfiguration.kt
new file mode 100644
index 00000000..33c8a247
--- /dev/null
+++ b/backend/src/main/kotlin/ch/sbb/backend/servicepoints/infrastructure/configuration/PostgreSQLConfiguration.kt
@@ -0,0 +1,7 @@
+package ch.sbb.backend.servicepoints.infrastructure.configuration
+
+import ch.sbb.backend.servicepoints.infrastructure.repositories.SpringDataJpaServicePointRepository
+import org.springframework.data.jpa.repository.config.EnableJpaRepositories
+
+@EnableJpaRepositories(basePackageClasses = [SpringDataJpaServicePointRepository::class])
+class PostgreSQLConfiguration
diff --git a/backend/src/main/kotlin/ch/sbb/backend/servicepoints/infrastructure/configuration/ServicePointsBeanConfiguration.kt b/backend/src/main/kotlin/ch/sbb/backend/servicepoints/infrastructure/configuration/ServicePointsBeanConfiguration.kt
new file mode 100644
index 00000000..73d5f2d2
--- /dev/null
+++ b/backend/src/main/kotlin/ch/sbb/backend/servicepoints/infrastructure/configuration/ServicePointsBeanConfiguration.kt
@@ -0,0 +1,17 @@
+package ch.sbb.backend.servicepoints.infrastructure.configuration
+
+import ch.sbb.backend.servicepoints.domain.service.DomainServicePointService
+import ch.sbb.backend.servicepoints.domain.repository.ServicePointRepository
+import ch.sbb.backend.servicepoints.domain.service.ServicePointService
+import org.springframework.context.annotation.Bean
+import org.springframework.context.annotation.Configuration
+
+@Configuration
+class ServicePointsBeanConfiguration {
+
+ @Bean
+ fun servicePointService(servicePointRepository: ServicePointRepository): ServicePointService {
+ return DomainServicePointService(servicePointRepository)
+ }
+
+}
diff --git a/backend/src/main/kotlin/ch/sbb/backend/servicepoints/infrastructure/entities/ServicePointEntity.kt b/backend/src/main/kotlin/ch/sbb/backend/servicepoints/infrastructure/entities/ServicePointEntity.kt
new file mode 100644
index 00000000..17dcb66b
--- /dev/null
+++ b/backend/src/main/kotlin/ch/sbb/backend/servicepoints/infrastructure/entities/ServicePointEntity.kt
@@ -0,0 +1,25 @@
+package ch.sbb.backend.servicepoints.infrastructure.entities
+
+import ch.sbb.backend.servicepoints.domain.ServicePoint
+import jakarta.persistence.Entity
+import jakarta.persistence.Id
+
+@Entity(name = "service_points")
+class ServicePointEntity(
+ @Id
+ var uic: Int,
+ var designation: String,
+ var abbreviation: String
+) {
+
+
+ constructor(servicePoint: ServicePoint) : this(
+ servicePoint.uic,
+ servicePoint.designation,
+ servicePoint.abbreviation
+ )
+
+ fun toServicePoint():ServicePoint {
+ return ServicePoint(uic,designation, abbreviation)
+ }
+}
diff --git a/backend/src/main/kotlin/ch/sbb/backend/servicepoints/infrastructure/repositories/PostgreSQLServicePointRepository.kt b/backend/src/main/kotlin/ch/sbb/backend/servicepoints/infrastructure/repositories/PostgreSQLServicePointRepository.kt
new file mode 100644
index 00000000..1a96a772
--- /dev/null
+++ b/backend/src/main/kotlin/ch/sbb/backend/servicepoints/infrastructure/repositories/PostgreSQLServicePointRepository.kt
@@ -0,0 +1,26 @@
+package ch.sbb.backend.servicepoints.infrastructure.repositories
+
+import ch.sbb.backend.servicepoints.domain.ServicePoint
+import ch.sbb.backend.servicepoints.domain.repository.ServicePointRepository
+import ch.sbb.backend.servicepoints.infrastructure.entities.ServicePointEntity
+import org.springframework.stereotype.Component
+
+@Component
+class PostgreSQLServicePointRepository(private val servicePointRepository: SpringDataJpaServicePointRepository) :
+ ServicePointRepository {
+ override fun findByUic(uic: Int): ServicePoint? {
+ return servicePointRepository.findByUic(uic)?.toServicePoint()
+ }
+
+ override fun findAll(): List {
+ return servicePointRepository.findAll().map { it.toServicePoint() }
+ }
+
+ override fun saveAll(servicePoints: List) {
+ servicePointRepository.saveAll(servicePoints.map { ServicePointEntity(it) })
+ }
+
+ override fun save(servicePoint: ServicePoint) {
+ servicePointRepository.save(ServicePointEntity(servicePoint))
+ }
+}
diff --git a/backend/src/main/kotlin/ch/sbb/backend/servicepoints/infrastructure/repositories/SpringDataJpaServicePointRepository.kt b/backend/src/main/kotlin/ch/sbb/backend/servicepoints/infrastructure/repositories/SpringDataJpaServicePointRepository.kt
new file mode 100644
index 00000000..3f8abec9
--- /dev/null
+++ b/backend/src/main/kotlin/ch/sbb/backend/servicepoints/infrastructure/repositories/SpringDataJpaServicePointRepository.kt
@@ -0,0 +1,10 @@
+package ch.sbb.backend.servicepoints.infrastructure.repositories
+
+import ch.sbb.backend.servicepoints.infrastructure.entities.ServicePointEntity
+import org.springframework.data.repository.ListCrudRepository
+import org.springframework.stereotype.Repository
+
+@Repository
+interface SpringDataJpaServicePointRepository : ListCrudRepository {
+ fun findByUic(uic: Int): ServicePointEntity?
+}
diff --git a/backend/src/main/kotlin/ch/sbb/backend/servicepoints/infrastructure/rest/AtlasClient.kt b/backend/src/main/kotlin/ch/sbb/backend/servicepoints/infrastructure/rest/AtlasClient.kt
new file mode 100644
index 00000000..289f9ebd
--- /dev/null
+++ b/backend/src/main/kotlin/ch/sbb/backend/servicepoints/infrastructure/rest/AtlasClient.kt
@@ -0,0 +1,6 @@
+package ch.sbb.backend.servicepoints.infrastructure.rest
+
+// To be implemented
+// REST client to retrieve service points from api
+class AtlasClient {
+}
diff --git a/backend/src/main/kotlin/ch/sbb/backend/servicepoints/infrastructure/tasks/ServicePointTask.kt b/backend/src/main/kotlin/ch/sbb/backend/servicepoints/infrastructure/tasks/ServicePointTask.kt
new file mode 100644
index 00000000..03852b3e
--- /dev/null
+++ b/backend/src/main/kotlin/ch/sbb/backend/servicepoints/infrastructure/tasks/ServicePointTask.kt
@@ -0,0 +1,6 @@
+package ch.sbb.backend.servicepoints.infrastructure.tasks
+
+// To be implemented
+// scheduled task to retrieve service points
+class ServicePointTask {
+}
diff --git a/backend/src/main/resources/schema.sql b/backend/src/main/resources/schema.sql
index 43579562..a1d75ca4 100644
--- a/backend/src/main/resources/schema.sql
+++ b/backend/src/main/resources/schema.sql
@@ -1,5 +1,20 @@
-CREATE TABLE IF NOT EXISTS service_points (
- uic INTEGER PRIMARY KEY,
- designation TEXT NOT NULL,
+CREATE TABLE IF NOT EXISTS service_points
+(
+ uic INTEGER PRIMARY KEY,
+ designation TEXT NOT NULL,
abbreviation TEXT NOT NULL
);
+
+CREATE TABLE IF NOT EXISTS train_identification
+(
+ operational_train_number TEXT NOT NULL,
+ start_date DATE NOT NULL,
+ company TEXT NOT NULL,
+ start_date_time TIMESTAMP NOT NULL
+);
+
+CREATE UNIQUE INDEX IF NOT EXISTS train_identification_idx
+ ON train_identification (
+ operational_train_number,
+ start_date, company
+ );
diff --git a/backend/src/test/kotlin/ch/sbb/backend/BaseIT.kt b/backend/src/test/kotlin/ch/sbb/backend/BaseIT.kt
new file mode 100644
index 00000000..664d6fab
--- /dev/null
+++ b/backend/src/test/kotlin/ch/sbb/backend/BaseIT.kt
@@ -0,0 +1,15 @@
+package ch.sbb.backend
+
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
+import org.springframework.boot.test.context.SpringBootTest
+import org.springframework.test.web.servlet.MockMvc
+
+@SpringBootTest
+@AutoConfigureMockMvc
+class BaseIT: BaseTestcontainersTest() {
+
+ @Autowired
+ protected lateinit var mockMvc: MockMvc
+
+}
diff --git a/backend/src/test/kotlin/ch/sbb/backend/application/rest/BaseIT.kt b/backend/src/test/kotlin/ch/sbb/backend/BaseTestcontainersTest.kt
similarity index 54%
rename from backend/src/test/kotlin/ch/sbb/backend/application/rest/BaseIT.kt
rename to backend/src/test/kotlin/ch/sbb/backend/BaseTestcontainersTest.kt
index 78b53d78..f8cabfac 100644
--- a/backend/src/test/kotlin/ch/sbb/backend/application/rest/BaseIT.kt
+++ b/backend/src/test/kotlin/ch/sbb/backend/BaseTestcontainersTest.kt
@@ -1,22 +1,13 @@
-package ch.sbb.backend.application.rest
+package ch.sbb.backend
-import org.springframework.beans.factory.annotation.Autowired
-import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
-import org.springframework.boot.test.context.SpringBootTest
import org.springframework.boot.testcontainers.service.connection.ServiceConnection
-import org.springframework.test.web.servlet.MockMvc
import org.testcontainers.containers.PostgreSQLContainer
import org.testcontainers.junit.jupiter.Container
import org.testcontainers.junit.jupiter.Testcontainers
import org.testcontainers.utility.DockerImageName
-@SpringBootTest
-@AutoConfigureMockMvc
@Testcontainers
-class BaseIT {
-
- @Autowired
- protected lateinit var mockMvc: MockMvc
+open class BaseTestcontainersTest {
companion object {
@Container
diff --git a/backend/src/test/kotlin/ch/sbb/backend/application/rest/ServicePointsControllerTest.kt b/backend/src/test/kotlin/ch/sbb/backend/application/rest/ServicePointsControllerTest.kt
deleted file mode 100644
index 19e3dbcc..00000000
--- a/backend/src/test/kotlin/ch/sbb/backend/application/rest/ServicePointsControllerTest.kt
+++ /dev/null
@@ -1,165 +0,0 @@
-package ch.sbb.backend.application.rest
-
-import org.junit.jupiter.api.Test
-import org.springframework.http.MediaType
-import org.springframework.security.test.context.support.WithMockUser
-import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
-import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put
-import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath
-import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status
-
-
-class ServicePointsControllerTest : BaseIT() {
-
- @Test
- @WithMockUser(authorities = ["ROLE_admin"])
- fun `should update and find service point`() {
- val servicePointsJson = """
- [
- {
- "uic": 8518771,
- "designation": "Biel/Bienne Bözingenfeld/Champ",
- "abbreviation": "BIBD"
- }
- ]
- """.trimIndent()
-
- mockMvc.perform(
- put("/api/v1/service-points")
- .contentType(MediaType.APPLICATION_JSON)
- .content(servicePointsJson)
- )
- .andExpect(status().isOk)
-
- mockMvc.perform(
- get("/api/v1/service-points/8518771")
- )
- .andExpect(status().isOk)
- .andExpect(jsonPath("$.uic").value(8518771))
- .andExpect(jsonPath("$.designation").value("Biel/Bienne Bözingenfeld/Champ"))
- .andExpect(jsonPath("$.abbreviation").value("BIBD"))
- }
-
- @Test
- @WithMockUser(authorities = ["ROLE_admin"])
- fun `should update and find all service point`() {
- val servicePointsJson = """
- [
- {
- "uic": 8518771,
- "designation": "Biel/Bienne Bözingenfeld/Champ",
- "abbreviation": "BIBD"
- },
- {
- "uic": 8583629,
- "designation": "Hinterhunziken",
- "abbreviation": "HHZ"
- }
- ]
- """.trimIndent()
-
- mockMvc.perform(
- put("/api/v1/service-points")
- .contentType(MediaType.APPLICATION_JSON)
- .content(servicePointsJson)
- )
- .andExpect(status().isOk)
-
- mockMvc.perform(
- get("/api/v1/service-points")
- )
- .andExpect(status().isOk)
- .andExpect(jsonPath("$.length()").value(2))
- .andExpect(jsonPath("$[0].uic").value(8583629))
- .andExpect(jsonPath("$[0].designation").value("Hinterhunziken"))
- .andExpect(jsonPath("$[0].abbreviation").value("HHZ"))
- .andExpect(jsonPath("$[1].uic").value(8518771))
- .andExpect(jsonPath("$[1].designation").value("Biel/Bienne Bözingenfeld/Champ"))
- .andExpect(jsonPath("$[1].abbreviation").value("BIBD"))
- }
-
- @Test
- @WithMockUser(authorities = ["ROLE_admin"])
- fun `should update existing service points`() {
- val servicePointsJson = """
- [
- {
- "uic": 8518771,
- "designation": "Biel/Bienne Bözingenfeld/Champ",
- "abbreviation": "BIBD"
- },
- {
- "uic": 8583629,
- "designation": "Hinterhunziken",
- "abbreviation": "HHZ"
- }
- ]
- """.trimIndent()
-
- mockMvc.perform(
- put("/api/v1/service-points")
- .contentType(MediaType.APPLICATION_JSON)
- .content(servicePointsJson)
- )
- .andExpect(status().isOk)
-
-
- val updatedServicePointJson = """
- [
- {
- "uic": 8518771,
- "designation": "Biel/Bienne Bözingenfeld",
- "abbreviation": "BIBD"
- }
- ]
- """.trimIndent()
-
- mockMvc.perform(
- put("/api/v1/service-points")
- .contentType(MediaType.APPLICATION_JSON)
- .content(updatedServicePointJson)
- )
- .andExpect(status().isOk)
-
- mockMvc.perform(
- get("/api/v1/service-points")
- )
- .andExpect(status().isOk)
- .andExpect(jsonPath("$.length()").value(2))
- .andExpect(jsonPath("$[0].uic").value(8583629))
- .andExpect(jsonPath("$[0].designation").value("Hinterhunziken"))
- .andExpect(jsonPath("$[0].abbreviation").value("HHZ"))
- .andExpect(jsonPath("$[1].uic").value(8518771))
- .andExpect(jsonPath("$[1].designation").value("Biel/Bienne Bözingenfeld"))
- .andExpect(jsonPath("$[1].abbreviation").value("BIBD"))
- }
-
- @Test
- @WithMockUser(authorities = ["ROLE_admin"])
- fun `should respond with not found`() {
- mockMvc.perform(
- get("/api/v1/service-points/11111")
- )
- .andExpect(status().isNotFound)
- }
-
- @Test
- @WithMockUser(authorities = ["ROLE_admin"])
- fun `should respond with bad request`() {
- val servicePointsJson = """
- [
- {
- "uic": 8518771,
- "designation": "Biel/Bienne Bözingenfeld/Champ"
- }
- ]
- """.trimIndent()
-
- mockMvc.perform(
- put("/api/v1/service-points")
- .contentType(MediaType.APPLICATION_JSON)
- .content(servicePointsJson)
- )
- .andExpect(status().isBadRequest)
- }
-}
diff --git a/backend/src/test/kotlin/ch/sbb/backend/archunit/ArchUnitTest.kt b/backend/src/test/kotlin/ch/sbb/backend/archunit/ArchUnitTest.kt
deleted file mode 100644
index 65f29603..00000000
--- a/backend/src/test/kotlin/ch/sbb/backend/archunit/ArchUnitTest.kt
+++ /dev/null
@@ -1,14 +0,0 @@
-package ch.sbb.backend.archunit
-
-import com.tngtech.archunit.junit.AnalyzeClasses
-import com.tngtech.archunit.junit.ArchTest
-import com.tngtech.archunit.lang.syntax.ArchRuleDefinition.classes
-
-@AnalyzeClasses(packages = ["ch.sbb.backend"])
-class ArchUnitTest {
-
- @ArchTest
- val `controller classes should be in application` = classes()
- .that().haveSimpleNameEndingWith("Controller")
- .should().resideInAPackage("..application..")
-}
diff --git a/backend/src/test/kotlin/ch/sbb/backend/ddd/ArchUnitTest.kt b/backend/src/test/kotlin/ch/sbb/backend/ddd/ArchUnitTest.kt
new file mode 100644
index 00000000..d9b5cedf
--- /dev/null
+++ b/backend/src/test/kotlin/ch/sbb/backend/ddd/ArchUnitTest.kt
@@ -0,0 +1,55 @@
+package ch.sbb.backend.ddd
+
+import com.tngtech.archunit.core.importer.ImportOption
+import com.tngtech.archunit.junit.AnalyzeClasses
+import com.tngtech.archunit.junit.ArchTest
+import com.tngtech.archunit.lang.ArchRule
+import com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses
+import com.tngtech.archunit.library.Architectures.layeredArchitecture
+import com.tngtech.archunit.library.dependencies.SlicesRuleDefinition.slices
+
+
+@AnalyzeClasses(
+ packages = ["ch.sbb.backend"],
+ importOptions = [ImportOption.DoNotIncludeTests::class]
+)
+class ArchUnitTest {
+
+ @ArchTest
+ val CORRECT_LAYERED_ARCHITECTURE: ArchRule = layeredArchitecture()
+ .consideringAllDependencies()
+ .layer("infrastructure").definedBy("..infrastructure..")
+ .layer("application").definedBy("..application..")
+ .layer("domain").definedBy("..domain..")
+ .whereLayer("infrastructure").mayOnlyBeAccessedByLayers("infrastructure")
+ .whereLayer("application").mayOnlyBeAccessedByLayers("infrastructure")
+ .whereLayer("domain").mayOnlyBeAccessedByLayers("infrastructure", "application")
+
+ @ArchTest
+ val APPLICATION_FREE_OF_CYCLES: ArchRule = slices()
+ .matching("..application.(**)")
+ .should().beFreeOfCycles()
+
+ @ArchTest
+ val DOMAIN_FREE_OF_CYCLES: ArchRule = slices()
+ .matching("..domain.(**)")
+ .should().beFreeOfCycles()
+
+ @ArchTest
+ val INFRASTRUCTURE_FREE_OF_CYCLES: ArchRule = slices()
+ .matching("..infrastructure.(**)")
+ .should().beFreeOfCycles()
+
+ @ArchTest
+ val NO_FRAMEWORK_CODE_IN_DOMAIN: ArchRule = noClasses()
+ .that().resideInAPackage("..domain..")
+ .should().dependOnClassesThat().resideOutsideOfPackages(
+ "ch.sbb..",
+ "java..",
+ "javax..",
+ "org.slf4j..",
+ "kotlin..",
+ "org.jetbrains.annotations.."
+ )
+ .because("our domain core should be independent of frameworks")
+}
diff --git a/backend/src/test/kotlin/ch/sbb/backend/ddd/ModularityTests.kt b/backend/src/test/kotlin/ch/sbb/backend/ddd/ModularityTests.kt
new file mode 100644
index 00000000..27f11a0f
--- /dev/null
+++ b/backend/src/test/kotlin/ch/sbb/backend/ddd/ModularityTests.kt
@@ -0,0 +1,15 @@
+package ch.sbb.backend.ddd
+
+import ch.sbb.backend.BackendApplication
+import org.junit.jupiter.api.Test
+import org.springframework.modulith.core.ApplicationModules
+
+class ModularityTests {
+
+ @Test
+ fun verifiesModularStructure() {
+ val modules: ApplicationModules = ApplicationModules.of(BackendApplication::class.java)
+ modules.forEach { println(it) }
+ modules.verify()
+ }
+}
diff --git a/backend/src/test/kotlin/ch/sbb/backend/domain/logging/MultitenantLogServiceTest.kt b/backend/src/test/kotlin/ch/sbb/backend/domain/logging/MultitenantLogServiceTest.kt
deleted file mode 100644
index 324bfe67..00000000
--- a/backend/src/test/kotlin/ch/sbb/backend/domain/logging/MultitenantLogServiceTest.kt
+++ /dev/null
@@ -1,65 +0,0 @@
-package ch.sbb.backend.domain.logging
-
-import ch.sbb.backend.application.rest.LogEntryRequest
-import ch.sbb.backend.application.rest.LogLevelRequest
-import ch.sbb.backend.domain.tenancy.ConfigTenantService
-import ch.sbb.backend.domain.tenancy.TenantId
-import ch.sbb.backend.infrastructure.configuration.LogDestination
-import ch.sbb.backend.infrastructure.configuration.Tenant
-import org.junit.jupiter.api.BeforeEach
-import org.junit.jupiter.api.Test
-import org.mockito.Mockito.*
-import org.springframework.security.core.Authentication
-import org.springframework.security.core.context.SecurityContext
-import org.springframework.security.core.context.SecurityContextHolder
-import org.springframework.security.oauth2.jwt.Jwt
-import java.time.Instant
-import java.time.OffsetDateTime
-import java.util.*
-
-class MultitenantLogServiceTest {
-
- private lateinit var sut: MultitenantLogService
- private lateinit var tenantService: ConfigTenantService
- private lateinit var splunkLogService: SplunkLogService
-
- private val tid = UUID.randomUUID().toString()
-
- @BeforeEach
- fun setUp() {
- tenantService = mock(ConfigTenantService::class.java)
- splunkLogService = mock(SplunkLogService::class.java)
- sut = MultitenantLogService(tenantService, splunkLogService)
- val securityContext: SecurityContext = mock(SecurityContext::class.java)
- val jwt = Jwt(
- "token",
- Instant.now(),
- Instant.now(),
- mapOf("header" to "value"),
- mapOf("tid" to tid)
- )
- val authentication = mock(Authentication::class.java)
- `when`(authentication.principal).thenReturn(jwt)
- `when`(securityContext.getAuthentication()).thenReturn(authentication)
- SecurityContextHolder.setContext(securityContext)
- }
-
- @Test
- fun `should log messages to splunk`() {
- val tenantId = TenantId(tid)
- val tenantConfig = Tenant("test", "10", "", "", LogDestination.SPLUNK)
- `when`(tenantService.getById(tenantId)).thenReturn(tenantConfig)
-
- val timestamp = OffsetDateTime.now()
- val logEntries = listOf(
- LogEntryRequest(timestamp, "source", "message", LogLevelRequest.INFO)
- )
-
- sut.logs(logEntries)
-
- val expectedLogs = listOf(
- LogEntry(timestamp, "source", "message", LogLevel.INFO)
- )
- verify(splunkLogService, times(1)).logs(expectedLogs)
- }
-}
diff --git a/backend/src/test/kotlin/ch/sbb/backend/logging/DomainLoggingServiceTest.kt b/backend/src/test/kotlin/ch/sbb/backend/logging/DomainLoggingServiceTest.kt
new file mode 100644
index 00000000..de2029be
--- /dev/null
+++ b/backend/src/test/kotlin/ch/sbb/backend/logging/DomainLoggingServiceTest.kt
@@ -0,0 +1,45 @@
+package ch.sbb.backend.logging
+
+import ch.sbb.backend.logging.domain.LogDestination
+import ch.sbb.backend.logging.domain.LogEntry
+import ch.sbb.backend.logging.domain.LogLevel
+import ch.sbb.backend.logging.domain.Tenant
+import ch.sbb.backend.logging.domain.repository.TenantRepository
+import ch.sbb.backend.logging.domain.service.DomainLoggingService
+import ch.sbb.backend.logging.infrastructure.SplunkLoggingRepository
+import org.junit.jupiter.api.BeforeEach
+import org.junit.jupiter.api.Test
+import org.mockito.Mockito.*
+import java.time.OffsetDateTime
+
+class DomainLoggingServiceTest {
+
+ private lateinit var sut: DomainLoggingService
+ private lateinit var tenantRepository: TenantRepository
+ private lateinit var splunkLoggingRepository: SplunkLoggingRepository
+
+ @BeforeEach
+ fun setUp() {
+ tenantRepository = mock(TenantRepository::class.java)
+ splunkLoggingRepository = mock(SplunkLoggingRepository::class.java)
+ sut = DomainLoggingService(splunkLoggingRepository)
+ }
+
+ @Test
+ fun `should log messages to splunk`() {
+ val tenantConfig = Tenant("test", "10", "", "", LogDestination.SPLUNK)
+ `when`(tenantRepository.current()).thenReturn(tenantConfig)
+
+ val timestamp = OffsetDateTime.now()
+ val logEntries = listOf(
+ LogEntry(timestamp, "source", "message", LogLevel.INFO)
+ )
+
+ sut.saveAll(logEntries)
+
+ val expectedLogs = listOf(
+ LogEntry(timestamp, "source", "message", LogLevel.INFO)
+ )
+ verify(splunkLoggingRepository, times(1)).saveAll(expectedLogs)
+ }
+}
diff --git a/backend/src/test/kotlin/ch/sbb/backend/application/rest/LoggingControllerTest.kt b/backend/src/test/kotlin/ch/sbb/backend/logging/LoggingControllerTest.kt
similarity index 90%
rename from backend/src/test/kotlin/ch/sbb/backend/application/rest/LoggingControllerTest.kt
rename to backend/src/test/kotlin/ch/sbb/backend/logging/LoggingControllerTest.kt
index 952a28c4..34b9a5eb 100644
--- a/backend/src/test/kotlin/ch/sbb/backend/application/rest/LoggingControllerTest.kt
+++ b/backend/src/test/kotlin/ch/sbb/backend/logging/LoggingControllerTest.kt
@@ -1,22 +1,23 @@
-package ch.sbb.backend.application.rest
+package ch.sbb.backend.logging
-import ch.sbb.backend.domain.logging.LogEntry
-import ch.sbb.backend.domain.logging.LogLevel
-import ch.sbb.backend.domain.logging.SplunkLogService
+import ch.sbb.backend.BaseIT
+import ch.sbb.backend.logging.domain.LogEntry
+import ch.sbb.backend.logging.domain.LogLevel
+import ch.sbb.backend.logging.infrastructure.rest.SplunkHecClient
import org.junit.jupiter.api.Test
import org.mockito.Mockito.verify
-import org.springframework.boot.test.mock.mockito.MockBean
import org.springframework.http.MediaType
import org.springframework.security.core.authority.SimpleGrantedAuthority
import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.jwt
+import org.springframework.test.context.bean.override.mockito.MockitoBean
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status
import java.time.OffsetDateTime
class LoggingControllerTest : BaseIT() {
- @MockBean
- private lateinit var splunkLogService: SplunkLogService
+ @MockitoBean
+ private lateinit var splunkHecClient: SplunkHecClient
@Test
fun `should log messages with seconds since epoch timestamp`() {
@@ -59,7 +60,7 @@ class LoggingControllerTest : BaseIT() {
)
)
- verify(splunkLogService).logs(expectedLogs)
+ verify(splunkHecClient).sendLogs(expectedLogs)
}
@Test
@@ -120,7 +121,7 @@ class LoggingControllerTest : BaseIT() {
)
)
- verify(splunkLogService).logs(expectedLogs)
+ verify(splunkHecClient).sendLogs(expectedLogs)
}
@Test
diff --git a/backend/src/test/kotlin/ch/sbb/backend/infrastructure/configuration/TenantConfigTest.kt b/backend/src/test/kotlin/ch/sbb/backend/logging/TenantConfigTest.kt
similarity index 84%
rename from backend/src/test/kotlin/ch/sbb/backend/infrastructure/configuration/TenantConfigTest.kt
rename to backend/src/test/kotlin/ch/sbb/backend/logging/TenantConfigTest.kt
index d55211c0..ee1acce7 100644
--- a/backend/src/test/kotlin/ch/sbb/backend/infrastructure/configuration/TenantConfigTest.kt
+++ b/backend/src/test/kotlin/ch/sbb/backend/logging/TenantConfigTest.kt
@@ -1,12 +1,11 @@
-package ch.sbb.backend.infrastructure.configuration
+package ch.sbb.backend.logging
-import ch.sbb.backend.application.rest.BaseIT
+import ch.sbb.backend.BaseIT
+import ch.sbb.backend.logging.infrastructure.config.TenantConfig
import org.junit.jupiter.api.Assertions.*
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
-import org.springframework.boot.test.context.SpringBootTest
-@SpringBootTest
class TenantConfigTest: BaseIT() {
@Autowired
diff --git a/backend/src/test/kotlin/ch/sbb/backend/preload/infrastructure/repositories/TrainIdentificationEntityIntegrationTest.kt b/backend/src/test/kotlin/ch/sbb/backend/preload/infrastructure/repositories/TrainIdentificationEntityIntegrationTest.kt
new file mode 100644
index 00000000..17933c5d
--- /dev/null
+++ b/backend/src/test/kotlin/ch/sbb/backend/preload/infrastructure/repositories/TrainIdentificationEntityIntegrationTest.kt
@@ -0,0 +1,62 @@
+package ch.sbb.backend.preload.infrastructure.repositories
+
+import ch.sbb.backend.BaseTestcontainersTest
+import ch.sbb.backend.preload.domain.TrainIdentification
+import ch.sbb.backend.preload.domain.repository.TrainIdentificationRepository
+import ch.sbb.backend.preload.infrastructure.entities.TrainIdentificationEntity
+import ch.sbb.backend.preload.infrastructure.entities.TrainIdentificationId
+import org.assertj.core.api.Assertions.assertThat
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest
+import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager
+import java.time.LocalDate
+import java.time.OffsetDateTime
+import kotlin.test.Test
+
+@DataJpaTest
+class TrainIdentificationEntityIntegrationTest : BaseTestcontainersTest() {
+
+ @Autowired
+ lateinit var trainIdentificationRepository: SpringDataJpaTrainIdentificationRepository
+
+ @Autowired
+ lateinit var em: TestEntityManager
+
+ @Test
+ fun givenNewTrainIdentifier_whenSave_thenSuccess() {
+ val identifier = "1111"
+ val operationDate = LocalDate.now()
+ val ru = "22"
+ val startTime = OffsetDateTime.now()
+
+ val train = TrainIdentificationEntity(identifier, operationDate, ru, startTime)
+ trainIdentificationRepository.save(train)
+
+ val result = em.find(
+ TrainIdentificationEntity::class.java,
+ TrainIdentificationId(identifier, operationDate, ru)
+ )
+ assertThat(result.startDateTime).isEqualTo(startTime)
+ }
+
+ @Test
+ fun givenTrainIdentifierCreated_whenUpdate_thenSuccess() {
+ val identifier = "1111"
+ val operationDate = LocalDate.now()
+ val ru = "22"
+ val startTime = OffsetDateTime.now()
+
+ val train = TrainIdentificationEntity(identifier, operationDate, ru, startTime)
+ em.persist(train)
+
+ val newStartTime = OffsetDateTime.now()
+ train.startDateTime = newStartTime
+ em.persist(train)
+
+ val result = em.find(
+ TrainIdentificationEntity::class.java,
+ TrainIdentificationId(identifier, operationDate, ru)
+ )
+ assertThat(result.startDateTime).isEqualTo(newStartTime)
+ }
+}
diff --git a/backend/src/test/kotlin/ch/sbb/backend/servicepoints/ServicePointsControllerTest.kt b/backend/src/test/kotlin/ch/sbb/backend/servicepoints/ServicePointsControllerTest.kt
new file mode 100644
index 00000000..9305d509
--- /dev/null
+++ b/backend/src/test/kotlin/ch/sbb/backend/servicepoints/ServicePointsControllerTest.kt
@@ -0,0 +1,34 @@
+package ch.sbb.backend.servicepoints
+
+import ch.sbb.backend.BaseIT
+import org.junit.jupiter.api.Test
+import org.springframework.http.MediaType
+import org.springframework.security.test.context.support.WithMockUser
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put
+import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath
+import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status
+
+
+class ServicePointsControllerTest : BaseIT() {
+
+ @Test
+ @WithMockUser(authorities = ["ROLE_admin"])
+ fun `should respond with not found`() {
+ mockMvc.perform(
+ get("/api/v1/service-points/11111")
+ )
+ .andExpect(status().isNotFound)
+ }
+
+
+ @Test
+ @WithMockUser(authorities = ["ROLE_admin"])
+ fun `should respond with empty`() {
+ mockMvc.perform(
+ get("/api/v1/service-points")
+ )
+ .andExpect(status().isOk)
+ .andExpect(jsonPath("$.length()").value(0))
+ }
+}
diff --git a/backend/src/test/kotlin/ch/sbb/backend/servicepoints/domain/repository/DomainServicePointServiceTest.kt b/backend/src/test/kotlin/ch/sbb/backend/servicepoints/domain/repository/DomainServicePointServiceTest.kt
new file mode 100644
index 00000000..c0480f32
--- /dev/null
+++ b/backend/src/test/kotlin/ch/sbb/backend/servicepoints/domain/repository/DomainServicePointServiceTest.kt
@@ -0,0 +1,30 @@
+package ch.sbb.backend.servicepoints.domain.repository
+
+import ch.sbb.backend.servicepoints.domain.ServicePoint
+import ch.sbb.backend.servicepoints.domain.service.DomainServicePointService
+import org.junit.jupiter.api.BeforeEach
+import org.junit.jupiter.api.Test
+import org.mockito.Mockito.mock
+import org.mockito.Mockito.verify
+
+
+class DomainServicePointServiceTest {
+
+ private lateinit var servicePointRepository: ServicePointRepository
+ private lateinit var tested: DomainServicePointService
+
+ @BeforeEach
+ fun setUp() {
+ servicePointRepository = mock(ServicePointRepository::class.java)
+ tested = DomainServicePointService(servicePointRepository)
+ }
+
+ @Test
+ fun shouldUpdateServicePoints_thenSave() {
+ val servicePoints: List =
+ listOf(ServicePoint(1, "designation", "abbreviation"))
+ tested.updateAll(servicePoints)
+ verify(servicePointRepository).saveAll(servicePoints)
+
+ }
+}
diff --git a/preload/src/main/kotlin/ch/sbb/das/preload/PreloadApplication.kt b/preload/src/main/kotlin/ch/sbb/das/preload/PreloadApplication.kt
deleted file mode 100644
index e1591096..00000000
--- a/preload/src/main/kotlin/ch/sbb/das/preload/PreloadApplication.kt
+++ /dev/null
@@ -1,13 +0,0 @@
-package ch.sbb.das.preload
-
-import org.springframework.boot.autoconfigure.SpringBootApplication
-import org.springframework.boot.runApplication
-import org.springframework.boot.web.servlet.ServletComponentScan
-
-@ServletComponentScan
-@SpringBootApplication
-class PreloadApplication
-
-fun main(args: Array) {
- runApplication(*args)
-}
diff --git a/preload/src/main/kotlin/ch/sbb/das/preload/infrastructure/entities/TrainIdentifierEntity.kt b/preload/src/main/kotlin/ch/sbb/das/preload/infrastructure/entities/TrainIdentifierEntity.kt
deleted file mode 100644
index dcccc919..00000000
--- a/preload/src/main/kotlin/ch/sbb/das/preload/infrastructure/entities/TrainIdentifierEntity.kt
+++ /dev/null
@@ -1,19 +0,0 @@
-package ch.sbb.das.preload.infrastructure.entities
-
-import jakarta.persistence.Entity
-import jakarta.persistence.Id
-import jakarta.persistence.IdClass
-import java.time.LocalDate
-import java.time.OffsetDateTime
-
-@Entity(name = "train_identifier")
-@IdClass(TrainIdentifierId::class)
-class TrainIdentifierEntity(
- @Id
- var identifier: String,
- @Id
- var operationDate: LocalDate,
- @Id
- var ru: String,
- var startDateTime: OffsetDateTime
-)
diff --git a/preload/src/main/kotlin/ch/sbb/das/preload/infrastructure/entities/TrainIdentifierId.kt b/preload/src/main/kotlin/ch/sbb/das/preload/infrastructure/entities/TrainIdentifierId.kt
deleted file mode 100644
index 7fc5a6a9..00000000
--- a/preload/src/main/kotlin/ch/sbb/das/preload/infrastructure/entities/TrainIdentifierId.kt
+++ /dev/null
@@ -1,33 +0,0 @@
-package ch.sbb.das.preload.infrastructure.entities
-
-import java.io.Serializable
-import java.time.LocalDate
-
-class TrainIdentifierId(
- val identifier: String = "",
- val operationDate: LocalDate = LocalDate.now(),
- val ru: String = ""
-) : Serializable {
-
- override fun equals(other: Any?): Boolean {
- if (this === other) return true
- if (javaClass != other?.javaClass) return false
-
- other as TrainIdentifierId
-
- if (identifier != other.identifier) return false
- if (operationDate != other.operationDate) return false
- if (ru != other.ru) return false
-
- return true
- }
-
- override fun hashCode(): Int {
- var result = identifier.hashCode()
- result = 31 * result + operationDate.hashCode()
- result = 31 * result + ru.hashCode()
- return result
- }
-}
-
-
diff --git a/preload/src/main/kotlin/ch/sbb/das/preload/infrastructure/repositories/TrainIdentifiersRepository.kt b/preload/src/main/kotlin/ch/sbb/das/preload/infrastructure/repositories/TrainIdentifiersRepository.kt
deleted file mode 100644
index 2579596f..00000000
--- a/preload/src/main/kotlin/ch/sbb/das/preload/infrastructure/repositories/TrainIdentifiersRepository.kt
+++ /dev/null
@@ -1,9 +0,0 @@
-package ch.sbb.das.preload.infrastructure.repositories
-
-import ch.sbb.das.preload.infrastructure.entities.TrainIdentifierEntity
-import ch.sbb.das.preload.infrastructure.entities.TrainIdentifierId
-import org.springframework.data.repository.ListCrudRepository
-import org.springframework.stereotype.Repository
-
-@Repository
-interface TrainIdentifiersRepository : ListCrudRepository
diff --git a/preload/src/test/kotlin/ch/sbb/das/preload/TrainIdentifierEntityIntegrationTest.kt b/preload/src/test/kotlin/ch/sbb/das/preload/TrainIdentificationEntityIntegrationTest.kt
similarity index 70%
rename from preload/src/test/kotlin/ch/sbb/das/preload/TrainIdentifierEntityIntegrationTest.kt
rename to preload/src/test/kotlin/ch/sbb/das/preload/TrainIdentificationEntityIntegrationTest.kt
index 206327b7..75ea28e9 100644
--- a/preload/src/test/kotlin/ch/sbb/das/preload/TrainIdentifierEntityIntegrationTest.kt
+++ b/preload/src/test/kotlin/ch/sbb/das/preload/TrainIdentificationEntityIntegrationTest.kt
@@ -1,8 +1,8 @@
package ch.sbb.das.preload
-import ch.sbb.das.preload.infrastructure.entities.TrainIdentifierEntity
-import ch.sbb.das.preload.infrastructure.entities.TrainIdentifierId
-import ch.sbb.das.preload.infrastructure.repositories.TrainIdentifiersRepository
+import ch.sbb.das.preload.infrastructure.entities.TrainIdentificationEntity
+import ch.sbb.das.preload.infrastructure.entities.TrainIdentificationId
+import ch.sbb.das.preload.infrastructure.repositories.TrainIdentificationRepository
import org.assertj.core.api.Assertions.assertThat
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest
@@ -18,7 +18,7 @@ import kotlin.test.Test
@DataJpaTest
@Testcontainers
-class TrainIdentifierEntityIntegrationTest {
+class TrainIdentificationEntityIntegrationTest {
companion object {
@Container
@@ -28,7 +28,7 @@ class TrainIdentifierEntityIntegrationTest {
}
@Autowired
- lateinit var trainIdentifiersRepository: TrainIdentifiersRepository
+ lateinit var trainIdentificationRepository: TrainIdentificationRepository
@Autowired
lateinit var em: TestEntityManager
@@ -40,12 +40,12 @@ class TrainIdentifierEntityIntegrationTest {
val ru = "22"
val startTime = OffsetDateTime.now()
- val train = TrainIdentifierEntity(identifier, operationDate, ru, startTime)
- trainIdentifiersRepository.save(train)
+ val train = TrainIdentificationEntity(identifier, operationDate, ru, startTime)
+ trainIdentificationRepository.save(train)
val result = em.find(
- TrainIdentifierEntity::class.java,
- TrainIdentifierId(identifier, operationDate, ru)
+ TrainIdentificationEntity::class.java,
+ TrainIdentificationId(identifier, operationDate, ru)
)
assertThat(result.startDateTime).isEqualTo(startTime)
}
@@ -57,7 +57,7 @@ class TrainIdentifierEntityIntegrationTest {
val ru = "22"
val startTime = OffsetDateTime.now()
- val train = TrainIdentifierEntity(identifier, operationDate, ru, startTime)
+ val train = TrainIdentificationEntity(identifier, operationDate, ru, startTime)
em.persist(train)
val newStartTime = OffsetDateTime.now()
@@ -65,8 +65,8 @@ class TrainIdentifierEntityIntegrationTest {
em.persist(train)
val result = em.find(
- TrainIdentifierEntity::class.java,
- TrainIdentifierId(identifier, operationDate, ru)
+ TrainIdentificationEntity::class.java,
+ TrainIdentificationId(identifier, operationDate, ru)
)
assertThat(result.startDateTime).isEqualTo(newStartTime)
}