Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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


June 25, 2020

More Decks by felipecsl

Other Decks in Technology


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

    Paulo 25 de Junho de 2020 felipecsl.com @felipecsl
  2. Fonte: website oficial - dropwizard.io “Dropwizard is a Java framework

    for developing ops-friendly, high- performance, RESTful web services.”
  3. “Tá, mas por que diabos eu deveria usar Dropwizard ao

    invés de <insert other framework name>”
  4. • Criado em 2011 no Yammer • Arquitetura modular •

    Foco em produtividade, “get things done” • Java centric • Utiliza Jersey e Jetty Características
  5. 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)) }
  6. REST "Eclipse Jersey is a REST framework that provides a

    JAX-RS (JSR-370) implementation” https://eclipse-ee4j.github.io/jersey/
  7. REST @Path("/status") @Produces(MediaType.APPLICATION_JSON) class StatusResource(private val sessionManager: SessionManager) { @GET

    @Timed fun healthStatus(): HealthStatus { return HealthStatus(sessionManager.totalActiveSessions()) } }
  8. 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() } }
  9. 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
  10. 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
  11. Configurações class BrokerConfiguration : Configuration() { @JsonProperty var fcmCredentialJsonPath: String?

    = null @JsonProperty var iceConfigFilePath: String? = null @JsonProperty var database: DataSourceFactory = DataSourceFactory() }
  12. 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 }
  13. Database Migrations // build.gradle plugins { id "org.flywaydb.flyway" version "6.4.0"

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

    configuration.database Flyway.configure() .dataSource(database.url, database.user, database.password) .load() .migrate() }
  15. 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") ) } }