Skip to content

Instantly share code, notes, and snippets.

@clonekim
Last active March 31, 2023 03:52
Show Gist options
  • Save clonekim/24a9e52b47e3d71a08df10c3d287d3ee to your computer and use it in GitHub Desktop.
Save clonekim/24a9e52b47e3d71a08df10c3d287d3ee to your computer and use it in GitHub Desktop.
Ktor+koin
import com.fasterxml.jackson.databind.SerializationFeature
import com.google.api.services.docs.v1.Docs
import com.google.api.services.drive.Drive
import io.ktor.application.Application
import io.ktor.application.call
import io.ktor.application.install
import io.ktor.features.*
import io.ktor.http.ContentType
import io.ktor.http.HttpStatusCode
import io.ktor.http.content.resources
import io.ktor.http.content.static
import io.ktor.jackson.jackson
import io.ktor.request.path
import io.ktor.response.respond
import io.ktor.response.respondText
import io.ktor.routing.get
import io.ktor.routing.routing
import io.ktor.server.engine.commandLineEnvironment
import io.ktor.server.engine.embeddedServer
import io.ktor.server.netty.Netty
import org.koin.dsl.module
import org.koin.ktor.ext.Koin
import org.koin.logger.SLF4JLogger
import org.slf4j.event.Level
fun main(args: Array<String>) {
embeddedServer(Netty, commandLineEnvironment(args)).start()
}
fun Application.main() {
install(CallLogging) {
level = Level.INFO
filter { call -> call.request.path().startsWith("/") }
}
install(DataConversion)
install(DefaultHeaders) {
header("X-Engine", "Ktor")
}
install(ContentNegotiation) {
jackson {
enable(SerializationFeature.INDENT_OUTPUT)
}
}
val (transport, jsonfactory,credential) = GoogleAuthenticate.install(this.environment.classLoader.getResourceAsStream("credentials.json"))
install(Koin) {
SLF4JLogger()
modules( module {
single { Docs.Builder(transport, jsonfactory,credentia).build().Documents()}
single { Drive.Builder(transport, jsonfactory,credentia).build() as Drive }
})
}
routing {
get("/") {
call.respondText("HELLO WORLD!", contentType = ContentType.Text.Plain)
}
drive()
docs()
static("/") {
resources("static")
}
install(StatusPages) {
exception<AuthenticationException> { cause ->
call.respond(HttpStatusCode.Unauthorized)
}
exception<AuthorizationException> { cause ->
call.respond(HttpStatusCode.Forbidden)
}
}
}
}
class AuthenticationException : RuntimeException()
class AuthorizationException : RuntimeException()
buildscript {
repositories {
jcenter()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
apply plugin: 'kotlin'
apply plugin: 'application'
group 'TODO'
version '0.0.1'
mainClassName = "ApplicationKt"
sourceSets {
main.kotlin.srcDirs = main.java.srcDirs = ['src']
test.kotlin.srcDirs = test.java.srcDirs = ['test']
main.resources.srcDirs = ['resources']
test.resources.srcDirs = ['testresources']
}
repositories {
mavenLocal()
jcenter()
maven { url 'https://kotlin.bintray.com/ktor' }
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
compile "io.ktor:ktor-server-netty:$ktor_version"
compile "ch.qos.logback:logback-classic:$logback_version"
compile "io.ktor:ktor-server-core:$ktor_version"
compile "io.ktor:ktor-server-host-common:$ktor_version"
compile "io.ktor:ktor-jackson:$ktor_version"
testImplementation "io.ktor:ktor-server-tests:$ktor_version"
//DI
compile "org.koin:koin-ktor:$koin_version"
compile "org.koin:koin-logger-slf4j:$koin_version"
//Google
compile ("com.google.auth:google-auth-library-oauth2-http:$google_oauth2_version") {
exclude group: 'com.google.code.findbugs'
}
compile ("com.google.apis:google-api-services-drive:$google_drive_version") {
exclude group: 'com.google.code.findbugs'
exclude module: 'oauth-client'
}
compile ("com.google.apis:google-api-services-docs:$google_docs_version") {
exclude group: 'com.google.code.findbugs'
}
compile ("com.google.apis:google-api-services-sheets:$google_sheets_version") {
exclude group: 'com.google.code.findbugs'
}
}
task fatjar(type: Jar) {
manifest {
attributes 'Implementation-Title': project.name, 'Main-Class': mainClassName
}
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
exclude 'META-INF/*.RSA', 'META-INF/*.SF', 'META-INF/*.DSA'
with jar
}
import com.google.api.client.http.javanet.NetHttpTransport
import com.google.api.client.json.jackson2.JacksonFactory
import com.google.api.services.docs.v1.DocsScopes
import com.google.api.services.drive.DriveScopes
import com.google.api.services.sheets.v4.SheetsScopes
import com.google.auth.http.HttpCredentialsAdapter
import com.google.auth.oauth2.GoogleCredentials
import java.io.InputStream
class GoogleAuthenticate {
companion object Factory {
private val scopes = listOf(
DriveScopes.DRIVE,
DriveScopes.DRIVE_FILE,
DriveScopes.DRIVE_SCRIPTS,
DriveScopes.DRIVE_APPDATA,
DriveScopes.DRIVE_METADATA,
DriveScopes.DRIVE_METADATA_READONLY,
DriveScopes.DRIVE_PHOTOS_READONLY,
DocsScopes.DOCUMENTS,
DocsScopes.DOCUMENTS_READONLY,
SheetsScopes.SPREADSHEETS,
SheetsScopes.SPREADSHEETS_READONLY
)
fun install(i: InputStream): Triple<NetHttpTransport, JacksonFactory, HttpCredentialsAdapter> {
val jsonFactory = JacksonFactory.getDefaultInstance()
val httpTransort = NetHttpTransport()
val googleCredentails = GoogleCredentials.fromStream(i)
.createScoped(scopes)
val httpInitializer = HttpCredentialsAdapter(googleCredentails)
return Triple(httpTransort, jsonFactory, httpInitializer)
}
}
}
import com.google.api.services.docs.v1.Docs
import io.ktor.routing.Route
import io.ktor.routing.get
import org.koin.ktor.ext.inject
fun Route.docs() {
val docsApi by inject<Docs.Documents>()
get ("/api/docs") {
//TODO
}
}
import com.google.api.services.drive.Drive
import io.ktor.application.call
import io.ktor.response.respond
import io.ktor.routing.Route
import io.ktor.routing.get
import io.ktor.routing.post
import org.koin.ktor.ext.inject
fun Route.drive() {
val driveApi by inject<Drive>()
get ("/api/drive") {
call.respond(driveApi.Files().list().setFields("files(id, name)").execute())
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment