Commit 791454af authored by Areum Kim's avatar Areum Kim
Browse files

[Issue, #36] implementation KTOR-Endpoints

parent c9730920
Pipeline #78208 failed with stages
in 3 minutes and 17 seconds
......@@ -7,23 +7,34 @@ import com.papsign.ktor.openapigen.route.apiRouting
import com.papsign.ktor.openapigen.route.tag
import com.papsign.ktor.openapigen.schema.namer.DefaultSchemaNamer
import com.papsign.ktor.openapigen.schema.namer.SchemaNamer
import com.squareup.moshi.JsonDataException
import de.h_da.fbi.smebt.intentfinder.server.nlp.PythonBridge
import de.h_da.fbi.smebt.intentfinder.server.routing.docx.docxRoutes
import de.h_da.fbi.smebt.intentfinder.server.routing.summarization.summarizationRoutes
import de.h_da.fbi.smebt.intentfinder.server.routing.tags.Tags
import de.h_da.fbi.smebt.intentfinder.server.routing.upload.uploadRoutes
import de.h_da.fbi.smebt.intentfinder.server.sources.FAQDataRepository
import de.h_da.fbi.smebt.intentfinder.server.sources.MoshiReader
import de.h_da.fbi.smebt.intentfinder.server.upload.registerApiRoutes
import io.ktor.application.*
import io.ktor.features.*
import io.ktor.gson.*
import io.ktor.http.*
import io.ktor.http.content.*
import io.ktor.request.*
import io.ktor.response.*
import io.ktor.routing.*
import io.ktor.serialization.*
import kotlinx.serialization.json.Json
import java.io.File
import kotlin.reflect.KType
fun main(args: Array<String>): Unit = io.ktor.server.netty.EngineMain.main(args)
fun Application.module() {
val data = FAQDataRepository()
install(OpenAPIGen) {
info {
version = "0.0.1"
......@@ -48,7 +59,14 @@ fun Application.module() {
}
install(ContentNegotiation) {
json()
gson {
setPrettyPrinting()
}
json(Json {
prettyPrint = true
})
}
install(StatusPages) {
......@@ -62,12 +80,104 @@ fun Application.module() {
}
routing {
get("/") {
call.respondRedirect("/swagger-ui/index.html?url=/openapi.json", true)
get("/summary") {
val response = PythonBridge().getSummary("test bridge",5)
call.respond(response)
}
// Definition eines Endpunkts zum Hochladen einer DOCX-Datei
post("/file/{chatbotId}") {
call.respondText("file was successful uploaded")
}
// Definition endpoint zur Änderung eine bereits existierende docx
put("/file/{chatbotId}/{id}/{filename}"){
}
get("/openapi.json") {
call.respond(GsonBuilder().create().toJson(application.openAPIGen.api.serialize()))
// Definition eines Endpunkts zur Definition einer FAQ-Webseite mit JSON-Konfiguration
post("/faqRessource/{chatbotId}/{jsonStructure}"){
try{
//parse file title
var title =call.parameters["jsonStructure"]
if (title != null) {
title= title!!.replace(".json", "", false)
}
//set file directory
val uploadDir = "tmp"
val multipart = call.receiveMultipart()
var file = File("")
multipart.forEachPart { part ->
when (part) {
is PartData.FormItem -> {
if (part.name == "title") {
title = part.value
}
}
is PartData.FileItem -> {
val ext = File(part.originalFileName).extension
//generate file title
file = File(uploadDir, "upload-${System.currentTimeMillis()}-${title.hashCode()}.$ext")
val fileBytes = part.streamProvider().readBytes()
File(uploadDir).mkdir()
file.writeBytes(fileBytes)
}
}
part.dispose()
}
//building json String from File
val stringList = file.readLines()
var json = ""
for(element in stringList){
json+=element
}
try{
//Generate DataObject from json string
val moshiReader = MoshiReader("url")
val jsonO = moshiReader.getObjectFromJson(json)
}
catch (exception: Exception){
when(exception) {
is JsonDataException -> {
val errorMessage = "The uploaded file doesn't match the predefined structure. The only valid structure is: \n" +
" {\n" +
" \"type\": \"url\",\n" +
" \"name\": \"https://your.url\",\n" +
" \"question\" : \n " +
" {\n" +
" \"type\": \"text\",\n" +
" \"css_selector\": \"table.category > tbody td.list-title > a\"\n" +
" },\n" +
" \"answer\": \n " +
" {\n" +
" \"type\": \"[text|href]\",\n" +
" \"css_selector\": \"div.item-page > div:nth-child(5)\"\n" +
" }\n" +
"} \n"+
"The following field is missing or couldn't be parsed: "
call.respondText(errorMessage+exception.message.toString())
}
else -> throw exception
}
}
}
catch (exception: Exception){
call.respondText("The uploaded File can not be parsed. Please choose another .json File")
println(exception.message.toString())
}
}
get("/files"){
var allFiles: MutableList<AllFiles> = mutableListOf()
data.getAllFaqData().forEach { faqData ->
if(faqData.type == "docx"){
allFiles.add(AllFiles(faqData.name, faqData.id.toString(), faqData.status))
}
}
call.respond(allFiles)
}
}
......@@ -87,4 +197,6 @@ fun Application.module() {
}
}
class InternalServerErrorException : RuntimeException()
\ No newline at end of file
class InternalServerErrorException : RuntimeException()
data class AllFiles(var filename:String, var id: String, var status: String)
package de.h_da.fbi.smebt.intentfinder.server.sources
import de.h_da.fbi.smebt.intentfinder.server.module
import io.ktor.http.*
import io.ktor.server.testing.*
import org.junit.jupiter.api.Test
import kotlin.test.assertEquals
import kotlin.test.assertTrue
class ApplicationTest {
private val data = FAQDataRepository()
@Test
fun testRoot() {
withTestApplication({ module() }) {
handleRequest(HttpMethod.Get, "/").apply {
assertEquals(HttpStatusCode.OK, response.status())
assertEquals("IntentFinder is available", response.content)
}
}
}
@Test
fun testDocxFiles() {
withTestApplication({ module() }) {
handleRequest(HttpMethod.Get, "/files").apply {
assertEquals(HttpStatusCode.OK, response.status())
data.getAllFaqData().forEach { faqData ->
if (faqData.type == "docx")
assertTrue { response.content!!.contains(faqData.name) }
}
}
}
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment