/kafkaStreamsModelServer/src/main/scala/com/lightbend/scala/kafkastreams/queriablestate/withstore/RestServiceStore.scala

https://github.com/lightbend/kafka-with-akka-streams-kafka-streams-tutorial · Scala · 75 lines · 60 code · 9 blank · 6 comment · 4 complexity · 45a8dd6bb39280fd07acdc0c12008fcc MD5 · raw file

  1. package com.lightbend.scala.kafkastreams.queriablestate.withstore
  2. import javax.ws.rs.NotFoundException
  3. import akka.actor.ActorSystem
  4. import akka.http.scaladsl.Http
  5. import akka.http.scaladsl.server.Directives._
  6. import akka.http.scaladsl.server.Route
  7. import akka.stream.ActorMaterializer
  8. import akka.util.Timeout
  9. import com.lightbend.scala.kafkastreams.queriablestate.MetadataService
  10. import com.lightbend.java.configuration.kafka.ApplicationKafkaParameters._
  11. import com.lightbend.scala.kafkastreams.store.StoreState
  12. import com.lightbend.scala.kafkastreams.store.store.custom.ModelStateStoreType
  13. import de.heikoseeberger.akkahttpjackson.JacksonSupport
  14. import org.apache.kafka.streams.KafkaStreams
  15. import org.apache.kafka.streams.state.QueryableStoreTypes
  16. import scala.concurrent.duration._
  17. /**
  18. * A simple REST proxy that runs embedded in the Model server. This is used to
  19. * demonstrate how a developer can use the Interactive Queries APIs exposed by Kafka Streams to
  20. * locate and query the State Stores within a Kafka Streams Application.
  21. * @see https://github.com/confluentinc/examples/blob/3.2.x/kafka-streams/src/main/java/io/confluent/examples/streams/interactivequeries/WordCountInteractiveQueriesRestService.java
  22. */
  23. object RestServiceStore {
  24. implicit val system = ActorSystem("ModelServing")
  25. implicit val materializer = ActorMaterializer()
  26. implicit val executionContext = system.dispatcher
  27. implicit val timeout = Timeout(10.seconds)
  28. val host = "127.0.0.1"
  29. val port = 8888
  30. def startRestProxy(streams: KafkaStreams, port: Int, storeType : String) = {
  31. val routes: Route = QueriesResource.storeRoutes(streams, port, storeType)
  32. Http().bindAndHandle(routes, host, port) map
  33. { binding => println(s"Starting models observer on port ${binding.localAddress}") } recover {
  34. case ex =>
  35. println(s"Models observer could not bind to $host:$port - ${ex.getMessage}")
  36. }
  37. }
  38. }
  39. object QueriesResource extends JacksonSupport {
  40. private val customStoreType = new ModelStateStoreType()
  41. private val standardStoreType = QueryableStoreTypes.keyValueStore[Integer,StoreState]
  42. def storeRoutes(streams: KafkaStreams, port : Int, storeType : String): Route = {
  43. val metadataService = new MetadataService(streams)
  44. get {
  45. pathPrefix("state") {
  46. path("instances") {
  47. complete(
  48. metadataService.streamsMetadataForStore(STORE_NAME, port)
  49. )
  50. } ~
  51. path("value") {
  52. storeType match {
  53. case "custom" =>
  54. val store = streams.store(STORE_NAME, customStoreType)
  55. if (store == null) throw new NotFoundException
  56. complete(store.getCurrentServingInfo)
  57. case _ =>
  58. val store = streams.store(STORE_NAME, standardStoreType)
  59. if (store == null) throw new NotFoundException
  60. complete(store.get(STORE_ID).currentState)
  61. }
  62. }
  63. }
  64. }
  65. }
  66. }