-
-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #403 from HandyMenny/refactor-javalin
Refactor JavalinApp - Move routes and jsonMapper in separate classes - Unify exception handling - Create new JavalinServer each time with newServer() - Drop /store/status and /version
- Loading branch information
Showing
12 changed files
with
304 additions
and
317 deletions.
There are no files selected for viewing
30 changes: 30 additions & 0 deletions
30
src/main/java/it/smartphonecombo/uecapabilityparser/server/CustomJsonMapper.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package it.smartphonecombo.uecapabilityparser.server | ||
|
||
import io.javalin.json.JsonMapper | ||
import it.smartphonecombo.uecapabilityparser.extension.custom | ||
import java.io.InputStream | ||
import java.lang.reflect.Type | ||
import kotlinx.serialization.ExperimentalSerializationApi | ||
import kotlinx.serialization.KSerializer | ||
import kotlinx.serialization.json.Json | ||
import kotlinx.serialization.json.decodeFromStream | ||
import kotlinx.serialization.serializer | ||
|
||
@OptIn(ExperimentalSerializationApi::class) | ||
@Suppress("UNCHECKED_CAST") | ||
object CustomJsonMapper : JsonMapper { | ||
override fun <T : Any> fromJsonString(json: String, targetType: Type): T { | ||
val deserializer = serializer(targetType) as KSerializer<T> | ||
return Json.custom().decodeFromString(deserializer, json) | ||
} | ||
|
||
override fun <T : Any> fromJsonStream(json: InputStream, targetType: Type): T { | ||
val deserializer = serializer(targetType) as KSerializer<T> | ||
return Json.custom().decodeFromStream(deserializer, json) | ||
} | ||
|
||
override fun toJsonString(obj: Any, type: Type): String { | ||
val serializer = serializer(obj.javaClass) | ||
return Json.custom().encodeToString(serializer, obj) | ||
} | ||
} |
368 changes: 97 additions & 271 deletions
368
src/main/java/it/smartphonecombo/uecapabilityparser/server/JavalinApp.kt
Large diffs are not rendered by default.
Oops, something went wrong.
147 changes: 147 additions & 0 deletions
147
src/main/java/it/smartphonecombo/uecapabilityparser/server/Routes.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
package it.smartphonecombo.uecapabilityparser.server | ||
|
||
import io.javalin.http.ContentType | ||
import io.javalin.http.Context | ||
import it.smartphonecombo.uecapabilityparser.extension.attachFile | ||
import it.smartphonecombo.uecapabilityparser.extension.bodyAsClassEfficient | ||
import it.smartphonecombo.uecapabilityparser.extension.custom | ||
import it.smartphonecombo.uecapabilityparser.extension.mutableListWithCapacity | ||
import it.smartphonecombo.uecapabilityparser.extension.notFound | ||
import it.smartphonecombo.uecapabilityparser.extension.toInputSource | ||
import it.smartphonecombo.uecapabilityparser.io.IOUtils | ||
import it.smartphonecombo.uecapabilityparser.model.Capabilities | ||
import it.smartphonecombo.uecapabilityparser.model.LogType | ||
import it.smartphonecombo.uecapabilityparser.model.MultiCapabilities | ||
import it.smartphonecombo.uecapabilityparser.model.index.LibraryIndex | ||
import it.smartphonecombo.uecapabilityparser.query.Query | ||
import it.smartphonecombo.uecapabilityparser.query.SearchableField | ||
import it.smartphonecombo.uecapabilityparser.util.Config | ||
import it.smartphonecombo.uecapabilityparser.util.MultiParsing | ||
import it.smartphonecombo.uecapabilityparser.util.Parsing | ||
import java.time.ZoneOffset | ||
import java.time.ZonedDateTime | ||
import java.time.format.DateTimeFormatter | ||
import kotlin.contracts.ExperimentalContracts | ||
import kotlinx.serialization.json.Json | ||
|
||
object Routes { | ||
private val dataFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd_HH-mm-ss") | ||
private val idRegex = "[a-f0-9-]{36}(?:-[0-9]+)?".toRegex() | ||
|
||
@OptIn(ExperimentalContracts::class) | ||
private fun validateId(id: String?) { | ||
kotlin.contracts.contract { returns() implies (id != null) } | ||
if (id?.matches(idRegex) != true) throw IllegalArgumentException("Wrong id") | ||
} | ||
|
||
fun parse(ctx: Context, store: String?, index: LibraryIndex, compression: Boolean) { | ||
val request = ctx.bodyAsClassEfficient<RequestParse>() | ||
val parsed = Parsing.fromRequest(request)!! | ||
ctx.json(parsed.capabilities) | ||
if (store != null) parsed.store(index, store, compression) | ||
} | ||
|
||
fun parseMultiPart(ctx: Context, store: String?, index: LibraryIndex, compression: Boolean) { | ||
val requestsStr = ctx.formParam("requests")!! | ||
val requestsJson = Json.custom().decodeFromString<List<RequestMultiPart>>(requestsStr) | ||
val files = ctx.uploadedFiles() | ||
val parsed = MultiParsing.fromRequest(requestsJson, files)!! | ||
ctx.json(parsed.getMultiCapabilities()) | ||
if (store != null) parsed.store(index, store, compression) | ||
} | ||
|
||
fun csv(ctx: Context) { | ||
val request = ctx.bodyAsClassEfficient<RequestCsv>() | ||
val comboList = request.input | ||
val type = request.type | ||
val date = dataFormatter.format(ZonedDateTime.now(ZoneOffset.UTC)) | ||
val newFmt = (request as? RequestCsv.LteCa)?.newCsvFormat ?: false | ||
ctx.attachFile( | ||
IOUtils.toCsv(comboList, newFmt).toInputSource(), | ||
"${type}-${date}.csv", | ||
ContentType.TEXT_CSV | ||
) | ||
} | ||
|
||
fun status(ctx: Context, maxRequestSize: Long, endpoints: List<String>) { | ||
val version = Config.getOrDefault("project.version", "") | ||
val logTypes = LogType.validEntries | ||
val status = | ||
ServerStatus( | ||
version, | ||
endpoints, | ||
logTypes, | ||
maxRequestSize, | ||
SearchableField.getAllSearchableFields() | ||
) | ||
ctx.json(status) | ||
} | ||
|
||
fun storeList(ctx: Context, index: LibraryIndex) { | ||
ctx.json(index) | ||
} | ||
|
||
fun storeGetItem(ctx: Context, index: LibraryIndex) { | ||
val id = ctx.queryParam("id") ?: throw IllegalArgumentException("Wrong id") | ||
val item = index.find(id) ?: return ctx.notFound() | ||
ctx.json(item) | ||
} | ||
|
||
fun storeGetMultiItem(ctx: Context, index: LibraryIndex) { | ||
val id = ctx.queryParam("id") ?: throw IllegalArgumentException("Wrong id") | ||
val item = index.findMulti(id) ?: return ctx.notFound() | ||
ctx.json(item) | ||
} | ||
|
||
fun storeGetOutput(ctx: Context, index: LibraryIndex, store: String) { | ||
val id = ctx.queryParam("id") | ||
validateId(id) | ||
|
||
val capabilities = index.getOutput(id, store) ?: return ctx.notFound() | ||
ctx.json(capabilities) | ||
} | ||
|
||
fun storeGetMultiOutput(ctx: Context, index: LibraryIndex, store: String) { | ||
val id = ctx.queryParam("id") | ||
validateId(id) | ||
|
||
val multiIndexLine = index.findMulti(id) ?: return ctx.notFound() | ||
val indexLineIds = multiIndexLine.indexLineIds | ||
val capabilitiesList = mutableListWithCapacity<Capabilities>(indexLineIds.size) | ||
for (indexId in indexLineIds) { | ||
val capabilities = index.getOutput(indexId, store) ?: continue | ||
capabilitiesList.add(capabilities) | ||
} | ||
|
||
val multiCapabilities = | ||
MultiCapabilities(capabilitiesList, multiIndexLine.description, multiIndexLine.id) | ||
ctx.json(multiCapabilities) | ||
} | ||
|
||
fun storeGetInput(ctx: Context, index: LibraryIndex, store: String) { | ||
val id = ctx.queryParam("id") | ||
validateId(id) | ||
|
||
val indexLine = index.findByInput(id) ?: return ctx.notFound() | ||
val compressed = indexLine.compressed | ||
val filePath = "$store/input/$id" | ||
|
||
val file = IOUtils.getInputSource(filePath, compressed) ?: return ctx.notFound() | ||
ctx.attachFile(file, id, ContentType.APPLICATION_OCTET_STREAM) | ||
} | ||
|
||
fun storeListFiltered(ctx: Context, index: LibraryIndex, store: String) { | ||
val request = ctx.bodyAsClassEfficient<Query>() | ||
val result = index.filterByQuery(request, store) | ||
ctx.json(result) | ||
} | ||
|
||
fun getOpenApi(ctx: Context) { | ||
val openapi = {}.javaClass.getResourceAsStream("/swagger/openapi.json") | ||
if (openapi != null) { | ||
val text = openapi.reader().readText() | ||
ctx.contentType(ContentType.JSON) | ||
ctx.result(text) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.