67 lines
2.1 KiB
Scala
67 lines
2.1 KiB
Scala
package actors.auctions
|
|
|
|
import com.google.inject.Provides
|
|
import com.hivemq.client.mqtt.datatypes.MqttQos
|
|
import com.hivemq.client.mqtt.mqtt5.Mqtt5AsyncClient
|
|
import com.hivemq.client.mqtt.mqtt5.message.publish.Mqtt5Publish
|
|
import models.Auction
|
|
import mqttClient.MqttClientFactory
|
|
import org.apache.pekko.actor.typed.Behavior
|
|
import org.apache.pekko.actor.typed.scaladsl.Behaviors
|
|
import play.api.{Configuration, Logging}
|
|
import play.api.libs.concurrent.ActorModule
|
|
import play.api.libs.json.Json
|
|
|
|
import java.nio.charset.StandardCharsets
|
|
import javax.inject.Singleton
|
|
|
|
object AuctionPublisher extends ActorModule with Logging {
|
|
sealed trait Command
|
|
private case object Ready extends Command
|
|
case class Publish(auction: Auction) extends Command
|
|
|
|
private final val topic = "auctions/created"
|
|
|
|
override type Message = Command
|
|
|
|
@Provides
|
|
@Singleton
|
|
def apply(configuration: Configuration): Behavior[Message] = Behaviors.setup { context =>
|
|
val client = MqttClientFactory.createClient(configuration, "-auction-publisher")
|
|
client.connect().whenComplete { (_action, _throwable) =>
|
|
context.self ! Ready
|
|
}
|
|
|
|
idle(client)
|
|
}
|
|
|
|
private def idle(client: Mqtt5AsyncClient, waitingPublishes: Seq[Auction] = List()): Behaviors.Receive[Command] = Behaviors.receiveMessage[Command] {
|
|
case Publish(auction) =>
|
|
idle(client, waitingPublishes :+ auction)
|
|
case Ready =>
|
|
for { auction <- waitingPublishes } publishAuction(client, auction)
|
|
ready(client)
|
|
}
|
|
|
|
private def ready(client: Mqtt5AsyncClient): Behaviors.Receive[Command] = Behaviors.receiveMessage[Command] {
|
|
case Publish(auction) =>
|
|
publishAuction(client, auction)
|
|
ready(client)
|
|
case Ready =>
|
|
logger.warn("Message Ready received after ")
|
|
ready(client)
|
|
}
|
|
|
|
private def publishAuction(client: Mqtt5AsyncClient, auction: Auction): Unit = {
|
|
val payload = Json.toBytes(Json.toJson(auction))
|
|
|
|
val publish = Mqtt5Publish.builder()
|
|
.topic(topic)
|
|
.payload(payload)
|
|
.qos(MqttQos.EXACTLY_ONCE)
|
|
.build()
|
|
logger.info(s"Publishing auction ${auction.id.getOrElse(-1)}")
|
|
client.publish(publish)
|
|
}
|
|
}
|