Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

core: improve tools to log and reproduce requests #10522

Merged
merged 1 commit into from
Jan 29, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading