All Downloads are FREE. Search and download functionalities are using the official Maven repository.

daggerok.sample.H2FileApplication.kt Maven / Gradle / Ivy

package daggerok.sample

import java.time.Instant
import java.time.ZoneId
import java.time.ZoneOffset
import java.util.TimeZone
import org.apache.logging.log4j.kotlin.logger
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
import org.springframework.boot.web.error.ErrorAttributeOptions
import org.springframework.boot.web.error.ErrorAttributeOptions.Include
import org.springframework.boot.web.reactive.error.DefaultErrorAttributes
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.data.annotation.Id
import org.springframework.data.annotation.LastModifiedDate
import org.springframework.data.r2dbc.config.EnableR2dbcAuditing
import org.springframework.data.r2dbc.repository.R2dbcRepository
import org.springframework.data.relational.core.mapping.Table
import org.springframework.format.annotation.DateTimeFormat
import org.springframework.format.annotation.DateTimeFormat.ISO.DATE_TIME
import org.springframework.http.MediaType
import org.springframework.stereotype.Component
import org.springframework.web.reactive.function.server.ServerRequest
import org.springframework.web.reactive.function.server.ServerResponse
import org.springframework.web.reactive.function.server.body
import org.springframework.web.reactive.function.server.bodyToMono
import org.springframework.web.reactive.function.server.router
import reactor.core.publisher.Flux

/**
 * Liquibase R2DBC spring-boot starter sample
 * @since 0.0.1
 */
@EnableR2dbcAuditing
@SpringBootApplication
class H2FileApplication

fun main(args: Array) {
    runApplication(*args) {
        TimeZone.setDefault(TimeZone.getTimeZone(ZoneId.from(ZoneOffset.UTC)))
    }
}

@Table("messages", schema = "app")
data class Message(
    val body: String = "",
    val addressTo: String = "all",
    val addressFrom: String = "anonymous",
    @Id val id: Long? = null,
    @LastModifiedDate
    @DateTimeFormat(iso = DATE_TIME)
    val sentAt: Instant? = null,
)

interface Messages : R2dbcRepository {
    fun findAllByOrderByIdDesc(): Flux
}

@Configuration
class RoutesConfig(private val messages: Messages) {

    @Bean
    fun routes() = router {
        contentType(MediaType.APPLICATION_JSON)
        "/api".nest {
            GET("/messages") {
                ServerResponse.ok().body(
                    messages.findAllByOrderByIdDesc()
                        .doOnNext { log.info { "getting: $it" } }
                )
            }
            POST("/messages") {
                ServerResponse.ok().body(
                    it.bodyToMono()
                        .doOnNext { log.info { "posting: $it" } }
                        .flatMap(messages::save)
                        .doOnNext { log.info { "posted: $it" } }
                )
            }
            path("/**") {
                val baseUrl = it.uri().toURL().run { "$protocol://$authority" }
                ServerResponse.ok().bodyValue(
                    mapOf(
                        "Save messages => http POST " to "$baseUrl/api/messages",
                        "Get all messages => http GET " to "$baseUrl/api/messages",
                    )
                )
            }
        }
    }

    private companion object {
        val log = logger()
    }
}

/**
 * This component customizes error response.
 *
 * Adds `api` map with supported endpoints
 */
@Component
class RestApiErrorAttributes : DefaultErrorAttributes() {

    override fun getErrorAttributes(request: ServerRequest?, options: ErrorAttributeOptions): MutableMap =
        super.getErrorAttributes(request, options.including(Include.MESSAGE, Include.EXCEPTION)).apply {
            val baseUrl = request?.uri()?.let { "${it.scheme}://${it.authority}" } ?: ""
            val api = mapOf(
                "Save messages => http POST " to "$baseUrl/api/messages",
                "Get all messages => http GET " to "$baseUrl/api/messages",
            )
            put("api", api)
        }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy