Skip to content

Commit

Permalink
core: improve tools to log and reproduce requests
Browse files Browse the repository at this point in the history
Signed-off-by: Eloi Charpentier <[email protected]>
  • Loading branch information
eckter committed Jan 29, 2025
1 parent 2b56d3e commit ecb261f
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 65 deletions.
54 changes: 0 additions & 54 deletions core/src/main/java/fr/sncf/osrd/cli/ReproduceRequest.java

This file was deleted.

91 changes: 91 additions & 0 deletions core/src/main/java/fr/sncf/osrd/cli/ReproduceRequest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package fr.sncf.osrd.cli

import com.beust.jcommander.Parameter
import com.beust.jcommander.Parameters
import com.squareup.moshi.JsonAdapter
import fr.sncf.osrd.api.ElectricalProfileSetManager
import fr.sncf.osrd.api.InfraManager
import fr.sncf.osrd.api.api_v2.pathfinding.PathfindingBlocksEndpointV2
import fr.sncf.osrd.api.api_v2.pathfinding.pathfindingRequestAdapter
import fr.sncf.osrd.api.api_v2.standalone_sim.SimulationEndpoint
import fr.sncf.osrd.api.api_v2.standalone_sim.SimulationRequest
import fr.sncf.osrd.api.api_v2.stdcm.STDCMEndpointV2
import fr.sncf.osrd.api.api_v2.stdcm.stdcmRequestAdapter
import fr.sncf.osrd.utils.jacoco.ExcludeFromGeneratedCodeCoverage
import java.io.IOException
import java.nio.file.Path
import java.util.concurrent.TimeUnit
import okhttp3.OkHttpClient
import okio.buffer
import okio.source
import org.slf4j.Logger
import org.slf4j.LoggerFactory

@Parameters(commandDescription = "Debug tool to reproduce a request based on a payload json file")
class ReproduceRequest : CliCommand {
@Parameter(
names = ["--stdcm-payload-path"],
description = "Path to the json payload file to load"
)
private var stdcmPayloadPath: String? = null

@Parameter(
names = ["--pathfinding-payload-path"],
description = "Path to the json payload file to load"
)
private var pathfindingPayloadPath: String? = null

@Parameter(
names = ["--simulation-payload-path"],
description = "Path to the json payload file to load"
)
private var simulationPayloadPath: String? = null

@Parameter(
names = ["--editoast-url"],
description = "The base URL of editoast (used to query infrastructures)"
)
private var editoastUrl = "http://localhost:8090/"

@Parameter(
names = ["--editoast-authorization"],
description = "The HTTP Authorization header sent to editoast"
)
private var editoastAuthorization = "x-osrd-skip-authz"
private val logger: Logger = LoggerFactory.getLogger("Pathfinding")

@ExcludeFromGeneratedCodeCoverage
override fun run(): Int {
try {
val httpClient = OkHttpClient.Builder().readTimeout(120, TimeUnit.SECONDS).build()
val infraManager = InfraManager(editoastUrl, editoastAuthorization, httpClient)

fun <T> loadRequest(path: String, adapter: JsonAdapter<T>): T {
val fileSource = Path.of(path).source()
val bufferedSource = fileSource.buffer()
return checkNotNull(adapter.fromJson(bufferedSource))
}
if (stdcmPayloadPath != null) {
logger.info("running stdcm request at $stdcmPayloadPath")
STDCMEndpointV2(infraManager)
.run(loadRequest(stdcmPayloadPath!!, stdcmRequestAdapter))
}
if (pathfindingPayloadPath != null) {
logger.info("running pathfinding request at $pathfindingPayloadPath")
PathfindingBlocksEndpointV2(infraManager)
.run(loadRequest(pathfindingPayloadPath!!, pathfindingRequestAdapter))
}
if (simulationPayloadPath != null) {
logger.info("running simulation request at $simulationPayloadPath")
val electricalProfileSetManager =
ElectricalProfileSetManager(editoastUrl, editoastAuthorization, httpClient)
SimulationEndpoint(infraManager, electricalProfileSetManager)
.run(loadRequest(simulationPayloadPath!!, SimulationRequest.adapter))
}
logger.info("done")
} catch (e: IOException) {
throw RuntimeException(e)
}
return 0
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,11 @@ import fr.sncf.osrd.utils.indexing.*
import fr.sncf.osrd.utils.units.Length
import fr.sncf.osrd.utils.units.Offset
import fr.sncf.osrd.utils.units.meters
import java.io.File
import java.time.Duration
import java.time.Instant
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
import java.util.*
import org.slf4j.Logger
import org.slf4j.LoggerFactory
Expand All @@ -45,14 +48,27 @@ class NoPathFoundException(val response: PathfindingBlockResponse) : Exception()
val pathfindingLogger: Logger = LoggerFactory.getLogger("Pathfinding")

class PathfindingBlocksEndpointV2(private val infraManager: InfraManager) : Take {

override fun act(req: Request): Response {
val body = RqPrint(req).printBody()
val request =
pathfindingRequestAdapter.fromJson(body)
?: return RsWithStatus(RsText("Missing request body"), 400)

val logRequest = System.getenv("LOG_PATHFINDING_REQUESTS")
if (logRequest?.equals("true", ignoreCase = true) == true) {
val time = LocalDateTime.now()
val formatted = time.format(DateTimeFormatter.ofPattern("MM-dd-HH:mm:ss:SSS"))
File("pathfinding-$formatted.json").printWriter().use {
it.println(pathfindingRequestAdapter.indent(" ").toJson(request))
}
}

return run(request)
}

fun run(request: PathfindingBlockRequest): Response {
val recorder = DiagnosticRecorderImpl(false)
try {
val body = RqPrint(req).printBody()
val request =
pathfindingRequestAdapter.fromJson(body)
?: return RsWithStatus(RsText("Missing request body"), 400)
// Load infra
val infra = infraManager.getInfra(request.infra, request.expectedVersion, recorder)
val res = runPathfinding(infra, request)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ import fr.sncf.osrd.utils.DistanceRangeMap
import fr.sncf.osrd.utils.distanceRangeMapOf
import fr.sncf.osrd.utils.indexing.StaticIdxList
import fr.sncf.osrd.utils.indexing.mutableStaticIdxArrayListOf
import java.io.File
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
import org.takes.Request
import org.takes.Response
import org.takes.Take
Expand All @@ -31,14 +34,26 @@ class SimulationEndpoint(
private val electricalProfileSetManager: ElectricalProfileSetManager
) : Take {
override fun act(req: Request): Response {
// Parse request input
val body = RqPrint(req).printBody()
val request =
SimulationRequest.adapter.fromJson(body)
?: return RsWithStatus(RsText("missing request body"), 400)

val logRequest = System.getenv("LOG_SIMULATION_REQUESTS")
if (logRequest?.equals("true", ignoreCase = true) == true) {
val time = LocalDateTime.now()
val formatted = time.format(DateTimeFormatter.ofPattern("MM-dd-HH:mm:ss:SSS"))
File("simulation-$formatted.json").printWriter().use {
it.println(SimulationRequest.adapter.indent(" ").toJson(request))
}
}
return run(request)
}

fun run(request: SimulationRequest): Response {
val recorder = DiagnosticRecorderImpl(false)
try {
// Parse request input
val body = RqPrint(req).printBody()
val request =
SimulationRequest.adapter.fromJson(body)
?: return RsWithStatus(RsText("missing request body"), 400)

// load infra
val infra = infraManager.getInfra(request.infra, request.expectedVersion, recorder)

Expand Down

0 comments on commit ecb261f

Please sign in to comment.