Added OpenAPI doc page, as well as miscellaneous fixes

This commit is contained in:
Anthony Cicchetti 2019-08-29 18:50:15 -04:00
parent 02c29bfb1b
commit e75559e112
5 changed files with 101 additions and 16 deletions

View file

@ -19,6 +19,10 @@ dependencies {
implementation(Libs.javalin)
implementation(Libs.slf4j_simple)
implementation(Libs.jackson_databind)
implementation(Libs.jackson_module_kotlin)
implementation(Libs.swagger_core)
implementation(Libs.kotlin_openapi3_dsl)
implementation(Libs.swagger_ui)
testImplementation(Libs.junit_jupiter)
}

View file

@ -7,12 +7,24 @@ import kotlin.String
* `$ ./gradlew buildSrcVersions`
*/
object Libs {
/**
* https://github.com/derveloper/kotlin-openapi3-dsl
*/
const val kotlin_openapi3_dsl: String = "cc.vileda:kotlin-openapi3-dsl:" +
Versions.kotlin_openapi3_dsl
/**
* http://github.com/FasterXML/jackson
*/
const val jackson_databind: String = "com.fasterxml.jackson.core:jackson-databind:" +
Versions.jackson_databind
/**
* https://github.com/FasterXML/jackson-module-kotlin
*/
const val jackson_module_kotlin: String = "com.fasterxml.jackson.module:jackson-module-kotlin:" +
Versions.jackson_module_kotlin
const val com_github_johnrengelman_shadow_gradle_plugin: String =
"com.github.johnrengelman.shadow:com.github.johnrengelman.shadow.gradle.plugin:" +
Versions.com_github_johnrengelman_shadow_gradle_plugin
@ -26,6 +38,11 @@ object Libs {
*/
const val javalin: String = "io.javalin:javalin:" + Versions.javalin
/**
* https://github.com/swagger-api/swagger-core
*/
const val swagger_core: String = "io.swagger.core.v3:swagger-core:" + Versions.swagger_core
const val org_jetbrains_kotlin_jvm_gradle_plugin: String =
"org.jetbrains.kotlin.jvm:org.jetbrains.kotlin.jvm.gradle.plugin:" +
Versions.org_jetbrains_kotlin_jvm_gradle_plugin
@ -51,4 +68,9 @@ object Libs {
* http://www.slf4j.org
*/
const val slf4j_simple: String = "org.slf4j:slf4j-simple:" + Versions.slf4j_simple
/**
* http://webjars.org
*/
const val swagger_ui: String = "org.webjars:swagger-ui:" + Versions.swagger_ui
}

View file

@ -12,14 +12,20 @@ import org.gradle.plugin.use.PluginDependencySpec
* YOU are responsible for updating manually the dependency version.
*/
object Versions {
const val kotlin_openapi3_dsl: String = "0.20.2"
const val jackson_databind: String = "2.10.0.pr1"
const val jackson_module_kotlin: String = "2.10.0.pr1"
const val com_github_johnrengelman_shadow_gradle_plugin: String = "5.1.0"
const val de_fayard_buildsrcversions_gradle_plugin: String = "0.4.2"
const val javalin: String = "3.4.1"
const val swagger_core: String = "2.0.9"
const val org_jetbrains_kotlin_jvm_gradle_plugin: String = "1.3.50"
const val org_jetbrains_kotlin: String = "1.3.50"
@ -28,6 +34,8 @@ object Versions {
const val slf4j_simple: String = "1.7.28"
const val swagger_ui: String = "3.23.5"
/**
*
* See issue 19: How to update Gradle itself?

View file

@ -5,30 +5,68 @@ import com.anthonycicchetti.slackbot.utility.RespObj
import com.anthonycicchetti.slackbot.utility.TextResponse
import io.javalin.http.Context
import io.javalin.Javalin
import io.javalin.plugin.openapi.OpenApiOptions
import io.javalin.plugin.openapi.OpenApiPlugin
import io.javalin.plugin.openapi.dsl.document
import io.javalin.plugin.openapi.dsl.documented
import io.javalin.plugin.openapi.ui.SwaggerOptions
import io.swagger.v3.oas.models.OpenAPI
import io.swagger.v3.oas.models.info.Info
import io.swagger.v3.oas.models.servers.Server
import org.slf4j.LoggerFactory
import kotlin.math.roundToInt
fun main() {
val logger = LoggerFactory.getLogger("main")
val app = Javalin.create().start(7000)
val app = Javalin.create { config ->
config.registerPlugin(OpenApiPlugin(createOpenApiOptions()))
config.enableCorsForAllOrigins()
config.requestLogger {ctx, ms ->
logger.info("Took ${ms.roundToInt()} to process ${ctx.req.requestURL}")
}
}.start(7000)
with(app) {
get("/") { ctx -> ctx.result("Hello World") }
options("/*", documented(document().ignore()) {})
get("/", documented(document().ignore()) { ctx -> ctx.result("Hello World") })
post("/slack/receive") { ctx ->
post("/slack/receive", documented(document().operation {
it.description = "NOT DOCUMENTED. Required for slack usage"
it.summary = "NOT DOCUMENTED. Required for slack usage"
}.ignore()) { ctx ->
logger.info("Received request from ${ctx.req.requestURL}")
handleSlackEvent(ctx)
}
})
post("/api/v1/spongebob") { ctx ->
post("/api/v1/spongebob", documented(document().operation {
it.description = "Responds with the ${"spongemocked".toSpongemock()} version of the string posted"
it.summary = "POST for ${"spongemocking".toSpongemock()}"
}.body<String>().json<TextResponse>("200")) { ctx ->
logger.info("Spongemock: Received request from ${ctx.req.requestURL}")
ctx.json(TextResponse(200, ctx.body().toSpongemock()))
}
})
post("/api/v1/uppercase") { ctx ->
post("/api/v1/uppercase", documented(document().operation {
it.description = "Responds with the UPPERCASED version of the string posted"
it.summary = "POST for UPPERCASING"
}.body<String>().json<TextResponse>("200")) { ctx ->
logger.info("Uppercase: Received request from ${ctx.req.requestURL}")
ctx.json(TextResponse(200, ctx.body().toUpperCase()))
}
})
}
Runtime.getRuntime().addShutdownHook(Thread {
app.stop()
})
app.events { event ->
event.serverStopping { logger.info("Server stopping") }
event.serverStopped { logger.info("Server stopped") }
}
}
fun handleSlackEvent(ctx: Context) {
private fun handleSlackEvent(ctx: Context) {
// Short circuit for ssl check
if ((ctx.formParam("ssl_check") ?: "0") == "1") {
ctx.status(200)
@ -36,11 +74,11 @@ fun handleSlackEvent(ctx: Context) {
}
val responseObj = RespObj(
command = ctx.formParamMap().get("command")?.get(0).processToCommand(),
text = ctx.formParamMap().get("text")?.get(0) ?: "",
response_url = ctx.formParamMap().get("response_url")?.get(0) ?: "",
team_id = ctx.formParamMap().get("team_id")?.get(0) ?: "",
channel_id = ctx.formParamMap().get("channel_id")?.get(0) ?: ""
command = ctx.formParamMap()["command"]?.get(0).processToCommand(),
text = ctx.formParamMap()["text"]?.get(0) ?: "",
response_url = ctx.formParamMap()["response_url"]?.get(0) ?: "",
team_id = ctx.formParamMap()["team_id"]?.get(0) ?: "",
channel_id = ctx.formParamMap()["channel_id"]?.get(0) ?: ""
)
sendResponse(ctx, responseObj)
@ -54,7 +92,7 @@ private fun String?.processToCommand(): Commands {
}
}
fun sendResponse(ctx: Context, respObj: RespObj) {
private fun sendResponse(ctx: Context, respObj: RespObj) {
val returnMap = mutableMapOf<String, String>()
with(returnMap) {
when (respObj.command) {
@ -72,3 +110,16 @@ fun sendResponse(ctx: Context, respObj: RespObj) {
}
ctx.json(returnMap)
}
private fun createOpenApiOptions(): OpenApiOptions {
val o = {
OpenAPI()
.info(Info().version("0.1.2").description("Slackbot Open API documentation"))
.addServersItem(Server().url("https://acicchetti.dev/"))
.addServersItem(Server().url("http://localhost:7000/"))
}
return OpenApiOptions(o)
.path("/swagger-docs")
.swagger(SwaggerOptions("/swagger").title("Slackbot Swagger Docs"))
}

View file

@ -1,3 +1,3 @@
package com.anthonycicchetti.slackbot.utility
data class TextResponse(val status: Int, val response: String)
data class TextResponse(val status: Int = 200, val response: String)