Microserviços em Kotlin com Dropwizard

Microserviços em Kotlin com Dropwizard

Apresentação para o Kotlin Meetup São Paulo em 25 de Julho de 2020

7fd4ba468da56bb5330a6352c1b54f52?s=128

felipecsl

June 25, 2020
Tweet

Transcript

  1. Microserviços em Kotlin com Dropwizard Felipe Lima Kotlin Meetup São

    Paulo 25 de Junho de 2020 felipecsl.com @felipecsl
  2. Introdução

  3. Um pouco de história…

  4. None
  5. None
  6. Dropwizard

  7. Dropwizard @ Airbnb

  8. Fonte: website oficial - dropwizard.io “Dropwizard is a Java framework

    for developing ops-friendly, high- performance, RESTful web services.”
  9. “Elefante na sala"

  10. “Tá, mas por que diabos eu deveria usar Dropwizard ao

    invés de <insert other framework name>”
  11. Fonte: https://blog.overops.com/java-bootstrap-dropwizard-vs-spring-boot Dropwizard vs. Spring Boot

  12. None
  13. Meu favorito

  14. • Criado em 2011 no Yammer • Arquitetura modular •

    Foco em produtividade, “get things done” • Java centric • Utiliza Jersey e Jetty Características
  15. Modularidade https://modules.dropwizard.io/official/

  16. Simplicidade companion object { @Throws(Exception::class) @JvmStatic fun main(args: Array<String>) {

    BrokerApplication().run(*args) } }
  17. Simplicidade class BrokerApplication : Application<BrokerConfiguration>() { override fun initialize(bootstrap: Bootstrap<BrokerConfiguration>)

    { bootstrap.apply { addBundle(webSocketBundle) addBundle(SslReloadBundle()) addBundle(RedirectBundle(HttpsRedirect())) } } override fun run(configuration: BrokerConfiguration, environment: Environment) { userDao = DaoFactory(environment, configuration).newDao(UserDao::class.java) sessionManager = SessionManagerFactory.newInstance( userDao, objectMapper, configuration ) environment.jersey().register(StatusResource(sessionManager)) environment.healthChecks().register("template", BrokerHealthCheck()) environment.jersey().register(UsersResource(userDao, sessionManager)) }
  18. None
  19. REST "Eclipse Jersey is a REST framework that provides a

    JAX-RS (JSR-370) implementation” https://eclipse-ee4j.github.io/jersey/
  20. REST https://github.com/jax-rs/spec/blob/master/spec.pdf

  21. REST @Path("/status") @Produces(MediaType.APPLICATION_JSON) class StatusResource(private val sessionManager: SessionManager) { @GET

    @Timed fun healthStatus(): HealthStatus { return HealthStatus(sessionManager.totalActiveSessions()) } }
  22. REST @Path("/users") @Produces(MediaType.APPLICATION_JSON) class UsersResource( private val userDao: UserDao, private

    val sessionManager: SessionManager ) { @POST @Timed @Consumes(MediaType.APPLICATION_JSON) fun create(user: User): Response { userDao.insert(user) return Response.ok().build() } @PUT @Timed @Consumes(MediaType.APPLICATION_JSON) fun update(user: User): Response { userDao.updateUserIdByFcmToken(user) return Response.ok().build() } }
  23. Configurações • Único arquivo YAML • Passado por parâmetro para

    o server via linha de comando • Pode ser utilizado para centralizar todas as configurações do servidor
  24. Configurações // build.gradle run { args 'server', 'src/dist/config/broker.dev.yml' }

  25. Configurações database: driverClass: org.postgresql.Driver user: felipecsl password: url: jdbc:postgresql://localhost/clairvoyance_dev properties:

    charSet: UTF-8 # the maximum amount of time to wait on an empty pool before throwing an exception maxWaitForConnection: 1s # the SQL query to run when validating a connection's liveness validationQuery: "/* MyService Health Check */ SELECT 1" # the minimum number of connections to keep open minSize: 8 logValidationErrors: true # the maximum number of connections to keep open maxSize: 32 # whether or not idle connections should be validated checkConnectionWhileIdle: false # the amount of time to sleep between runs of the idle connection validation, abandoned cleaner and idle pool resizing evictionInterval: 10s # the minimum amount of time an connection must sit idle in the pool before it is eligible for eviction minIdleTime: 1 minute server: applicationContextPath: / applicationConnectors: - type: http port: 8080
  26. Configurações class BrokerApplication : Application<BrokerConfiguration>() { // ... }

  27. Configurações class BrokerConfiguration : Configuration() { @JsonProperty var fcmCredentialJsonPath: String?

    = null @JsonProperty var iceConfigFilePath: String? = null @JsonProperty var database: DataSourceFactory = DataSourceFactory() }
  28. Database implementation "io.dropwizard:dropwizard-jdbi3:$dropwizardVersion"

  29. Database @RegisterRowMapper(UserMapper::class) interface UserDao { @SqlQuery("SELECT * FROM users") fun

    all(): List<User> @SqlQuery("SELECT * FROM users WHERE user_id = :user_id") fun findByUserId(@Bind("user_id") userId: String): User? @SqlUpdate("UPDATE users SET user_id = :user_id, fcm_token = :fcm_token WHERE ID = :id") fun updateById(@BindBean user: User): Int @SqlUpdate("INSERT INTO users (user_id, fcm_token) VALUES (:user_id, :fcm_token)") fun insert(@BindBean user: User): Int @SqlUpdate("DELETE FROM users") fun deleteAll(): Int }
  30. Database Migrations // build.gradle plugins { id "org.flywaydb.flyway" version "6.4.0"

    } flyway { url = 'jdbc:h2:file:./clairvoyance_test' user = ‘fulano_de_tal’ }
  31. Database Migrations private fun initFlyway(configuration: BrokerConfiguration) { val database =

    configuration.database Flyway.configure() .dataSource(database.url, database.user, database.password) .load() .migrate() }
  32. Database Migrations

  33. Frontend • Freemarker • Mustache

  34. Testing testImplementation "io.dropwizard:dropwizard-testing:$dropwizardVersion"

  35. Testing @ExtendWith(DropwizardExtensionsSupport::class) class BrokerApplicationTest { private val client = OkHttpClient.Builder().build()

    private val localPort = DROPWIZARD.localPort @Test fun status() { val client = JerseyClientBuilder().build() val result = client .target(“http://localhost:$localPort/status") .request() .get(String::class.java) assertThat(result).isEqualTo("""{"activeSessions":0}""") } companion object { private val DROPWIZARD = DropwizardAppExtension( BrokerApplication::class.java, ResourceHelpers.resourceFilePath("broker.yml") ) } }
  36. Perguntas?

  37. Obrigado!