akka.actor.Status.Failure Scala Examples

The following examples show how to use akka.actor.Status.Failure. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example.
Example 1
Source File: TAC.scala    From akka-tools   with MIT License 5 votes vote down vote up
package no.nextgentel.oss.akkatools.example2.trustaccountcreation

import java.util.concurrent.TimeUnit

import akka.actor.Status.Failure
import akka.actor.{ActorSystem, Props, ActorPath}
import no.nextgentel.oss.akkatools.aggregate._
import no.nextgentel.oss.akkatools.example2.other.{DoCreateTrustAccount, DoPerformESigning, DoSendEmailToCustomer}

import scala.concurrent.duration.FiniteDuration

class TACAggregate
(
  dmSelf:ActorPath,
  eSigningSystem:ActorPath,
  emailSystem:ActorPath,
  trustAccountSystem:ActorPath
) extends GeneralAggregateDMViaEvent[TACEvent, TACState](dmSelf) {

  override def persistenceIdBase() = TACAggregate.persistenceIdBase

  // Override this one to set different timeout
  override def idleTimeout() = FiniteDuration(60, TimeUnit.SECONDS)

  override var state = TACState.empty() // This is the state of our initial state (empty)

  // transform command to event
  override def cmdToEvent = {
    case c:CreateNewTACCmd        =>
      ResultingEvent( RegisteredEvent(c.info) )
        .onSuccess{ sender() ! "ok" }
        .onError{   (e) => sender() ! Failure(new Exception(s"Failed: $e"))}

    case c:ESigningFailedCmd      => ResultingEvent( ESigningFailedEvent() )
    case c:ESigningCompletedCmd   => ResultingEvent( ESigningCompletedEvent() )
    case c:CompletedCmd           => ResultingEvent( CreatedEvent(c.trustAccountId) )
    case c:DeclinedCmd            => ResultingEvent( DeclinedEvent(c.cause) )
  }

  override def generateDMs = {
    case e:RegisteredEvent  =>
      // We must send message to eSigningSystem
      val msg = DoPerformESigning(dispatchId, e.info.customerNo)
      ResultingDMs( msg, eSigningSystem)

    case e:ESigningCompletedEvent =>
      // ESigning is completed, so we should init creation of the TrustAccount
      val info = state.info.get
      val msg = DoCreateTrustAccount(dispatchId, info.customerNo, info.trustAccountType)
      ResultingDMs(msg, trustAccountSystem)


    case e:DeclinedEvent =>
      // The TrustAccountCreation-process failed - must notify customer
      val msg = DoSendEmailToCustomer(state.info.get.customerNo, s"Sorry.. TAC-failed: ${e.cause}")
      ResultingDMs(msg, emailSystem)

    case e:CreatedEvent =>
      // The TrustAccountCreation-process was success - must notify customer
      val msg = DoSendEmailToCustomer(state.info.get.customerNo, s"Your TrustAccount '${e.trustAccountId}' has been created!")
      ResultingDMs(msg, emailSystem)

  }
}

object TACAggregate {

  val persistenceIdBase = "TAC-"

  def props(dmSelf:ActorPath,
            eSigningSystem:ActorPath,
            emailSystem:ActorPath,
            trustAccountSystem:ActorPath) = Props(new TACAggregate(dmSelf, eSigningSystem, emailSystem ,trustAccountSystem))
}


class TACStarter(system:ActorSystem) extends AggregateStarter("tac", system) with AggregateViewStarter {

  def config(eSigningSystem:ActorPath,
             emailSystem:ActorPath,
             trustAccountSystem:ActorPath):TACStarter = {
    setAggregatePropsCreator{
      dmSelf =>
        TACAggregate.props(dmSelf, eSigningSystem, emailSystem, trustAccountSystem)
    }
    this
  }

  override def createViewProps(aggregateId: String): Props =
    Props( new GeneralAggregateView[TACEvent, TACState](TACAggregate.persistenceIdBase, aggregateId, TACState.empty(), true))
} 
Example 2
Source File: GeneralAggregateWithShardingTest.scala    From akka-tools   with MIT License 5 votes vote down vote up
package no.nextgentel.oss.akkatools.aggregate

import java.util.{Arrays, UUID}

import akka.actor.ActorSystem
import akka.actor.Status.Failure
import akka.testkit.{TestKit, TestProbe}
import com.typesafe.config.ConfigFactory
import no.nextgentel.oss.akkatools.aggregate.testAggregate.StateName._
import no.nextgentel.oss.akkatools.aggregate.testAggregate.{StateName, _}
import no.nextgentel.oss.akkatools.testing.AggregateTesting
import org.scalatest._
import org.slf4j.LoggerFactory

import scala.util.Random

object GeneralAggregateWithShardingTest {
  val port = 20000 + Random.nextInt(20000)
}


class GeneralAggregateWithShardingTest(_system:ActorSystem) extends TestKit(_system) with FunSuiteLike with Matchers with BeforeAndAfterAll with BeforeAndAfter {

  def this() = this(ActorSystem("test-actor-system", ConfigFactory.parseString(
    s"""akka.actor.provider = "akka.cluster.ClusterActorRefProvider"
        |akka.remote.enabled-transports = ["akka.remote.netty.tcp"]
        |akka.remote.netty.tcp.hostname="localhost"
        |akka.remote.netty.tcp.port=${GeneralAggregateWithShardingTest.port}
        |akka.cluster.seed-nodes = ["akka.tcp://test-actor-system@localhost:${GeneralAggregateWithShardingTest.port}"]
    """.stripMargin
  ).withFallback(ConfigFactory.load("application-test.conf"))))

  override def afterAll {
    TestKit.shutdownActorSystem(system)
  }

  val log = LoggerFactory.getLogger(getClass)
  private def generateId() = UUID.randomUUID().toString

  val seatIds = List("s1","id-used-in-Failed-in-onAfterValidationSuccess", "s2", "s3-This-id-is-going-to-be-discarded", "s4")

  trait TestEnv extends AggregateTesting[BookingState] {
    val id = generateId()
    val printShop = TestProbe()
    val cinema = TestProbe()
    val onSuccessDmForwardReceiver = TestProbe()

    val starter = new AggregateStarterSimple("booking", system).withAggregatePropsCreator {
      dmSelf =>
        BookingAggregate.props(dmSelf, dmForwardAndConfirm(printShop.ref).path, dmForwardAndConfirm(cinema.ref).path, seatIds, dmForwardAndConfirm(onSuccessDmForwardReceiver.ref).path)
    }

    val main = starter.dispatcher
    starter.start()

    def assertState(correctState:BookingState): Unit = {
      assert(getState(id) == correctState)
    }

  }




  test("normal flow") {

    new TestEnv {

      // Make sure we start with empty state
      assertState(BookingState.empty())

      val maxSeats = 2
      val sender = TestProbe()
      // Open the booking
      println("1")
      sendDMBlocking(main, OpenBookingCmd(id, maxSeats), sender.ref)
      println("2")
      assertState(BookingState(OPEN, maxSeats, Set()))

    }
  }
} 
Example 3
Source File: LoadBalancerActor.scala    From reactive-consul   with MIT License 5 votes vote down vote up
package stormlantern.consul.client.loadbalancers

import akka.actor.Status.Failure
import akka.actor.{ Props, Actor, ActorLogging }
import LoadBalancerActor._
import stormlantern.consul.client.discovery.{ ConnectionProvider, ConnectionHolder }
import stormlantern.consul.client.ServiceUnavailableException
import scala.concurrent.ExecutionContext.Implicits.global
import scala.collection.mutable

class LoadBalancerActor(loadBalancer: LoadBalancer, key: String) extends Actor with ActorLogging {

  import akka.pattern.pipe

  // Actor state
  val connectionProviders = mutable.Map.empty[String, ConnectionProvider]

  override def postStop(): Unit = {
    log.debug(s"LoadBalancerActor for $key stopped, destroying all connection providers")
    connectionProviders.values.foreach(_.destroy())
  }

  def receive: PartialFunction[Any, Unit] = {

    case GetConnection ⇒
      selectConnection match {
        case Some((id, connectionProvider)) ⇒ connectionProvider.getConnectionHolder(id, self) pipeTo sender
        case None                           ⇒ sender ! Failure(ServiceUnavailableException(key))
      }
    case ReturnConnection(connection)        ⇒ returnConnection(connection)
    case AddConnectionProvider(id, provider) ⇒ addConnectionProvider(id, provider)
    case RemoveConnectionProvider(id)        ⇒ removeConnectionProvider(id)
    case HasAvailableConnectionProvider      ⇒ sender ! connectionProviders.nonEmpty
  }

  def selectConnection: Option[(String, ConnectionProvider)] =
    loadBalancer.selectConnection.flatMap(id ⇒ connectionProviders.get(id).map(id → _))

  def returnConnection(connection: ConnectionHolder): Unit = {
    connectionProviders.get(connection.id).foreach(_.returnConnection(connection))
    loadBalancer.connectionReturned(connection.id)
  }

  def addConnectionProvider(id: String, provider: ConnectionProvider): Unit = {
    connectionProviders.put(id, provider)
    loadBalancer.connectionProviderAdded(id)
  }

  def removeConnectionProvider(id: String): Unit = {
    connectionProviders.remove(id).foreach(_.destroy())
    loadBalancer.connectionProviderRemoved(id)
  }
}

object LoadBalancerActor {
  // Props
  def props(loadBalancer: LoadBalancer, key: String) = Props(new LoadBalancerActor(loadBalancer, key))
  // Messsages
  case object GetConnection
  case class ReturnConnection(connection: ConnectionHolder)
  case class AddConnectionProvider(id: String, provider: ConnectionProvider)
  case class RemoveConnectionProvider(id: String)
  case object HasAvailableConnectionProvider
} 
Example 4
Source File: ServiceBrokerSpec.scala    From reactive-consul   with MIT License 5 votes vote down vote up
package stormlantern.consul.client

import akka.actor.{ ActorRef, ActorSystem }
import akka.actor.Status.Failure
import akka.testkit.{ ImplicitSender, TestKit }
import org.scalamock.scalatest.MockFactory
import org.scalatest.concurrent.ScalaFutures
import org.scalatest.{ BeforeAndAfterAll, FlatSpecLike, Matchers }
import stormlantern.consul.client.dao.ConsulHttpClient
import stormlantern.consul.client.discovery.ConnectionHolder
import stormlantern.consul.client.helpers.CallingThreadExecutionContext
import stormlantern.consul.client.loadbalancers.LoadBalancerActor
import stormlantern.consul.client.util.Logging

import scala.concurrent.Future

class ServiceBrokerSpec(_system: ActorSystem) extends TestKit(_system) with ImplicitSender with FlatSpecLike
    with Matchers with ScalaFutures with BeforeAndAfterAll with MockFactory with Logging {

  implicit val ec = CallingThreadExecutionContext()
  def this() = this(ActorSystem("ServiceBrokerSpec"))

  override def afterAll() {
    TestKit.shutdownActorSystem(system)
  }

  trait TestScope {
    val connectionHolder: ConnectionHolder = mock[ConnectionHolder]
    val httpClient: ConsulHttpClient = mock[ConsulHttpClient]
    val loadBalancer: ActorRef = self
  }

  "The ServiceBroker" should "return a service connection when requested" in new TestScope {
    (connectionHolder.connection _).expects().returns(Future.successful(true))
    (connectionHolder.loadBalancer _).expects().returns(loadBalancer)
    val sut = new ServiceBroker(self, httpClient)
    val result: Future[Boolean] = sut.withService("service1") { service: Boolean ⇒
      Future.successful(service)
    }
    expectMsgPF() {
      case ServiceBrokerActor.GetServiceConnection("service1") ⇒
        lastSender ! connectionHolder
        result.map(_ shouldEqual true).futureValue
    }
    expectMsg(LoadBalancerActor.ReturnConnection(connectionHolder))
  }

  it should "return the connection when an error occurs" in new TestScope {
    (connectionHolder.connection _).expects().returns(Future.successful(true))
    (connectionHolder.loadBalancer _).expects().returns(loadBalancer)
    val sut = new ServiceBroker(self, httpClient)
    val result: Future[Boolean] = sut.withService[Boolean, Boolean]("service1") { service: Boolean ⇒
      throw new RuntimeException()
    }
    expectMsgPF() {
      case ServiceBrokerActor.GetServiceConnection("service1") ⇒
        lastSender ! connectionHolder
        an[RuntimeException] should be thrownBy result.futureValue
    }
    expectMsg(LoadBalancerActor.ReturnConnection(connectionHolder))
  }

  it should "throw an error when an excpetion is returned" in new TestScope {
    val sut = new ServiceBroker(self, httpClient)
    val result: Future[Boolean] = sut.withService("service1") { service: Boolean ⇒
      Future.successful(service)
    }
    expectMsgPF() {
      case ServiceBrokerActor.GetServiceConnection("service1") ⇒
        lastSender ! Failure(new RuntimeException())
        an[RuntimeException] should be thrownBy result.futureValue
    }
  }
} 
Example 5
Source File: Miner.scala    From scalachain   with MIT License 5 votes vote down vote up
package com.elleflorio.scalachain.actor

import akka.actor.Status.{Failure, Success}
import akka.actor.{Actor, ActorLogging, Props}
import com.elleflorio.scalachain.actor.Miner._
import com.elleflorio.scalachain.exception.{InvalidProofException, MinerBusyException}
import com.elleflorio.scalachain.proof.ProofOfWork

import scala.concurrent.Future

object Miner {

  sealed trait MinerMessage

  case class Validate(hash: String, proof: Long) extends MinerMessage

  case class Mine(hash: String) extends MinerMessage

  case object Ready extends MinerMessage

  val props: Props = Props(new Miner)
}

class Miner extends Actor with ActorLogging {

  import context._

  def validate: Receive = {
    case Validate(hash, proof) => {
      log.info(s"Validating proof $proof")
      if (ProofOfWork.validProof(hash, proof)) {
        log.info("proof is valid!")
        sender() ! Success
      }
      else {
        log.info("proof is not valid")
        sender() ! Failure(new InvalidProofException(hash, proof))
      }
    }
  }

  def ready: Receive = validate orElse {
    case Mine(hash) => {
      log.info(s"Mining hash $hash...")
      val proof = Future {
        ProofOfWork.proofOfWork(hash)
      }
      sender() ! proof
      become(busy)
    }
    case Ready => {
      log.info("I'm ready to mine!")
      sender() ! Success("OK")
    }
  }

  def busy: Receive = validate orElse {
    case Mine(_) => {
      log.info("I'm already mining")
      sender ! Failure(new MinerBusyException("Miner is busy"))
    }
    case Ready => {
      log.info("Ready to mine a new block")
      become(ready)
    }
  }


  override def receive: Receive = {
    case Ready => become(ready)
  }
} 
Example 6
Source File: PublishActor.scala    From sns   with Apache License 2.0 5 votes vote down vote up
package me.snov.sns.actor

import akka.actor.Status.{Failure, Success}
import akka.actor.{Actor, ActorLogging, ActorRef, Props}
import akka.pattern.ask
import akka.pattern.pipe
import akka.util.Timeout
import me.snov.sns.actor.SubscribeActor.CmdFanOut
import me.snov.sns.model.{Message, MessageAttribute}

import scala.concurrent.ExecutionContext
import scala.concurrent.duration._

object PublishActor {
  def props(actor: ActorRef) = Props(classOf[PublishActor], actor)

  case class CmdPublish(topicArn: String, bodies: Map[String, String], messageAttributes: Map[String, MessageAttribute])
}

class PublishActor(subscribeActor: ActorRef) extends Actor with ActorLogging {
  import me.snov.sns.actor.PublishActor._

  private implicit val timeout = Timeout(1.second)
  private implicit val ec = context.dispatcher

  private def publish(topicArn: String, bodies: Map[String, String], messageAttributes: Map[String, MessageAttribute])(implicit ec: ExecutionContext) = {
    val message = Message(bodies, messageAttributes = messageAttributes)

    (subscribeActor ? CmdFanOut(topicArn, message)).map {
      case Failure(e) => Failure(e)
      case Success => message
    }
  }

  override def receive = {
    case CmdPublish(topicArn, bodies, attributes) => publish(topicArn, bodies, attributes) pipeTo sender
  }
} 
Example 7
Source File: SubscribeApi.scala    From sns   with Apache License 2.0 5 votes vote down vote up
package me.snov.sns.api

import akka.actor.ActorRef
import akka.actor.Status.{Success, Failure}
import akka.http.scaladsl.model.HttpResponse
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.Route
import akka.pattern.ask
import akka.util.Timeout
import me.snov.sns.actor.SubscribeActor.{CmdListSubscriptions, CmdListSubscriptionsByTopic, CmdSubscribe, CmdUnsubscribe,CmdSetSubscriptionAttributes,CmdGetSubscriptionAttributes}
import me.snov.sns.model.Subscription
import me.snov.sns.response.SubscribeResponse

import scala.concurrent.ExecutionContext

object SubscribeApi {
  private val arnPattern = """([\w+_:-]{1,512})""".r

  def route(actorRef: ActorRef)(implicit timeout: Timeout, ec: ExecutionContext): Route = {
    pathSingleSlash {
      formField('Action ! "Subscribe") {
        formFields('Endpoint, 'Protocol, 'TopicArn) { (endpoint, protocol, topicArn) =>
          complete {
            (actorRef ? CmdSubscribe(topicArn, protocol, endpoint)).mapTo[Subscription] map {
              SubscribeResponse.subscribe
            }
          }
        } ~
          complete(HttpResponse(400, entity = "Endpoint, Protocol, TopicArn are required"))
      } ~
        formField('Action ! "ListSubscriptionsByTopic") {
          formField('TopicArn) {
            case arnPattern(topicArn) => complete {
              (actorRef ? CmdListSubscriptionsByTopic(topicArn)).mapTo[Iterable[Subscription]] map {
                SubscribeResponse.listByTopic
              }
            }
            case _ => complete(HttpResponse(400, entity = "Invalid topic ARN"))
          } ~
            complete(HttpResponse(400, entity = "TopicArn is missing"))
        } ~
        formField('Action ! "ListSubscriptions") {
          complete {
            (actorRef ? CmdListSubscriptions()).mapTo[Iterable[Subscription]] map {
              SubscribeResponse.list
            }
          }
        } ~
        formField('Action ! "Unsubscribe") {
          formField('SubscriptionArn) { (arn) =>
            complete {
              (actorRef ? CmdUnsubscribe(arn)).map {
                case Success => SubscribeResponse.unsubscribe
                case _ => HttpResponse(404, entity = "NotFound")
              }
            }
          } ~
          complete(HttpResponse(400, entity = "SubscriptionArn is missing"))
        } ~
        formField('Action ! "SetSubscriptionAttributes") {
          formField('SubscriptionArn, 'AttributeName, 'AttributeValue) { (arn, name, value) =>
            complete {
              (actorRef ? CmdSetSubscriptionAttributes(arn, name, value)).map {
                case Success => SubscribeResponse.setSubscriptionAttributes
                case Failure(ex) => HttpResponse(404, entity = "NotFound")
              }
            }
          } ~
          complete(HttpResponse(400, entity = "SubscriptionArn is missing"))
        } ~
        formField('Action ! "GetSubscriptionAttributes") {
          formField('SubscriptionArn) { (arn) =>
            complete {
              (actorRef ? CmdGetSubscriptionAttributes(arn)).mapTo[Option[Map[String,String]]] map { attributes =>
                attributes
                  .map(SubscribeResponse.getSubscriptionAttributes)
                  .getOrElse {
                    HttpResponse(404, entity = "Not Found")
                  }
              }
            }
          } ~
          complete(HttpResponse(400, entity = "SubscriptionArn is missing"))
        }
    }
  }
} 
Example 8
Source File: Register.scala    From eclair   with Apache License 2.0 5 votes vote down vote up
package fr.acinq.eclair.channel

import akka.actor.Status.Failure
import akka.actor.{Actor, ActorLogging, ActorRef, Terminated}
import fr.acinq.bitcoin.ByteVector32
import fr.acinq.bitcoin.Crypto.PublicKey
import fr.acinq.eclair.ShortChannelId
import fr.acinq.eclair.channel.Register._



class Register extends Actor with ActorLogging {

  context.system.eventStream.subscribe(self, classOf[ChannelCreated])
  context.system.eventStream.subscribe(self, classOf[ChannelRestored])
  context.system.eventStream.subscribe(self, classOf[ChannelIdAssigned])
  context.system.eventStream.subscribe(self, classOf[ShortChannelIdAssigned])

  override def receive: Receive = main(Map.empty, Map.empty, Map.empty)

  def main(channels: Map[ByteVector32, ActorRef], shortIds: Map[ShortChannelId, ByteVector32], channelsTo: Map[ByteVector32, PublicKey]): Receive = {
    case ChannelCreated(channel, _, remoteNodeId, _, temporaryChannelId, _, _) =>
      context.watch(channel)
      context become main(channels + (temporaryChannelId -> channel), shortIds, channelsTo + (temporaryChannelId -> remoteNodeId))

    case ChannelRestored(channel, _, remoteNodeId, _, channelId, _) =>
      context.watch(channel)
      context become main(channels + (channelId -> channel), shortIds, channelsTo + (channelId -> remoteNodeId))

    case ChannelIdAssigned(channel, remoteNodeId, temporaryChannelId, channelId) =>
      context become main(channels + (channelId -> channel) - temporaryChannelId, shortIds, channelsTo + (channelId -> remoteNodeId) - temporaryChannelId)

    case ShortChannelIdAssigned(_, channelId, shortChannelId, _) =>
      context become main(channels, shortIds + (shortChannelId -> channelId), channelsTo)

    case Terminated(actor) if channels.values.toSet.contains(actor) =>
      val channelId = channels.find(_._2 == actor).get._1
      val shortChannelId = shortIds.find(_._2 == channelId).map(_._1).getOrElse(ShortChannelId(0L))
      context become main(channels - channelId, shortIds - shortChannelId, channelsTo - channelId)

    case Symbol("channels") => sender ! channels

    case Symbol("shortIds") => sender ! shortIds

    case Symbol("channelsTo") => sender ! channelsTo

    case fwd@Forward(channelId, msg) =>
      channels.get(channelId) match {
        case Some(channel) => channel forward msg
        case None => sender ! Failure(ForwardFailure(fwd))
      }

    case fwd@ForwardShortId(shortChannelId, msg) =>
      shortIds.get(shortChannelId).flatMap(channels.get) match {
        case Some(channel) => channel forward msg
        case None => sender ! Failure(ForwardShortIdFailure(fwd))
      }
  }
}

object Register {

  // @formatter:off
  case class Forward[T](channelId: ByteVector32, message: T)
  case class ForwardShortId[T](shortChannelId: ShortChannelId, message: T)

  case class ForwardFailure[T](fwd: Forward[T]) extends RuntimeException(s"channel ${fwd.channelId} not found")
  case class ForwardShortIdFailure[T](fwd: ForwardShortId[T]) extends RuntimeException(s"channel ${fwd.shortChannelId} not found")
  // @formatter:on
} 
Example 9
Source File: CheckpointTrackerActorSpec.scala    From kinesis-stream   with MIT License 5 votes vote down vote up
package px.kinesis.stream.consumer.checkpoint

import akka.actor.Status.Failure
import akka.actor.{ActorRef, ActorSystem}
import akka.testkit.{ImplicitSender, TestKit}
import org.scalamock.scalatest.MockFactory
import org.scalatest.funspec.AnyFunSpecLike
import org.scalatest.BeforeAndAfterAll
import org.scalatest.matchers.must.Matchers
import px.kinesis.stream.consumer.checkpoint.CheckpointTrackerActor._
import px.kinesis.stream.consumer.checkpoint.{ShardCheckpointTrackerActor => shard}
import software.amazon.kinesis.retrieval.kpl.ExtendedSequenceNumber

import scala.collection.immutable.Seq

class CheckpointTrackerActorSpec
    extends TestKit(ActorSystem("CheckpointTrackerActorSpec"))
    with ImplicitSender
    with AnyFunSpecLike
    with Matchers
    with BeforeAndAfterAll
    with MockFactory {
  override def afterAll: Unit = {
    TestKit.shutdownActorSystem(system)
  }

  val workerId = "123"

  def toSequenceNum(i: Int): ExtendedSequenceNumber =
    new ExtendedSequenceNumber(i.toString)

  def createTracker(): ActorRef =
    system.actorOf(
      CheckpointTrackerActor
        .props(workerId, 10, 10))

  describe("track") {
    it("should track successfully after creation of tracker") {
      val tracker = createTracker()
      val shardId = "01"
      tracker ! Command.Create(shardId)
      expectMsg(Response.Ack)

      tracker ! Command.Track(shardId, Seq(1).map(toSequenceNum))
      expectMsg(shard.Response.Ack)
    }

    it("should fail if tracker is not active") {
      val tracker = createTracker()
      val shardId = "01"
      // shard tracker for 01 does not exist
      tracker ! Command.Track(shardId, Seq(1).map(toSequenceNum))
      expectMsgPF() {
        case Failure(_) => true
      }
    }
  }

  describe("process") {
    it("should process successfully after creation of tracker") {
      val tracker = createTracker()
      val shardId = "01"
      tracker ! Command.Create(shardId)
      expectMsg(Response.Ack)

      tracker ! Command.Process(shardId, toSequenceNum(1))
      expectMsg(shard.Response.Ack)
    }

    it("should process successfully even after shard tracker is shutdown") {
      val tracker = createTracker()
      val shardId = "01"
      tracker ! Command.Create(shardId)
      expectMsg(Response.Ack)

      tracker ! Command.Process(shardId, toSequenceNum(1))
      expectMsg(shard.Response.Ack)

      tracker ! Command.ShutdownShard(shardId)
      expectMsg(Response.Ack)

      tracker ! Command.Process(shardId, toSequenceNum(2))
      expectMsg(shard.Response.Ack)

    }

  }
} 
Example 10
Source File: ConsumerCommitter.scala    From reactive-nakadi   with MIT License 5 votes vote down vote up
package org.zalando.react.nakadi.commit

import akka.actor._
import akka.actor.Status.Failure
import org.zalando.react.nakadi.properties.ConsumerProperties
import org.zalando.react.nakadi.NakadiActorPublisher.{CommitAck, CommitOffsets}
import org.zalando.react.nakadi.NakadiMessages.ConsumerMessage


object ConsumerCommitter {

  object Contract {
    object TheEnd
    object Flush
  }

  def props(consumerActor: ActorRef, consumerProperties: ConsumerProperties) = {
    Props(new ConsumerCommitter(consumerActor, consumerProperties))
  }
}

class ConsumerCommitter(consumerActor: ActorRef, consumerProperties: ConsumerProperties) extends Actor
  with ActorLogging {

  import ConsumerCommitter.Contract._

  val eventType = consumerProperties.eventType
  val commitInterval = consumerProperties.commitInterval
  var scheduledFlush: Option[Cancellable] = None
  var partitionOffsetMap = OffsetMap()
  var committedOffsetMap = OffsetMap()
  implicit val executionContext = context.dispatcher

  def scheduleFlush(): Unit = {
    if (scheduledFlush.isEmpty) {
      scheduledFlush = Option(context.system.scheduler.scheduleOnce(commitInterval, self, Flush))
    }
  }

  override def preStart(): Unit = {
    context.watch(consumerActor)
    super.preStart()
  }

  override def postStop(): Unit = {
    scheduledFlush.foreach(_.cancel())
    super.postStop()
  }

  override def receive: Receive = {
    case msg: ConsumerMessage => registerCommit(msg)
    case CommitAck(offsetMap) => handleAcknowledge(offsetMap)
    case Flush                => commitGatheredOffsets()
    case TheEnd =>
      log.debug("Closing Consumer connection")
      context.stop(self)
    case Failure =>
      log.error("Closing offset committer due to a failure")
      context.stop(self)
    case Terminated(_) =>
      log.warning("Terminating the consumer committer due to the death of the consumer actor.")
      context.stop(self)
  }

  def registerCommit(msg: ConsumerMessage): Unit = {
    log.debug(s"Received commit request for partition ${msg.cursor.partition} and offset ${msg.cursor.offset}")
    val eventTypePartition = EventTypePartition(msg.eventType, msg.cursor.partition)
    val last = partitionOffsetMap.lastOffset(eventTypePartition)
    updateOffsetIfLarger(msg, last)
  }

  def updateOffsetIfLarger(msg: ConsumerMessage, last: Long): Unit = {
    val msgOffset = msg.cursor.offset.toLong
    if (msgOffset > last) {
      log.debug(s"Registering commit for partition ${msg.cursor.partition} and offset ${msg.cursor.offset}, last registered = $last")
      val eventTypePartition = EventTypePartition(msg.eventType, msg.cursor.partition)
      partitionOffsetMap = partitionOffsetMap.plusOffset(eventTypePartition, msgOffset)
      scheduleFlush()
    } else {
      log.debug(s"Skipping commit for partition ${msg.cursor.partition} and offset ${msg.cursor.offset}, last registered is $last")
    }
  }

  def handleAcknowledge(offsetMap: OffsetMap) = committedOffsetMap = OffsetMap(offsetMap.map.mapValues(_ - 1))

  def commitGatheredOffsets() = {
    log.debug("Flushing offsets to commit")
    scheduledFlush = None
    val offsetMapToFlush = partitionOffsetMap diff committedOffsetMap
    if (offsetMapToFlush.nonEmpty) {
      consumerActor ! CommitOffsets(offsetMapToFlush)
    }
  }
} 
Example 11
Source File: TransactionalProducer.scala    From affinity   with Apache License 2.0 5 votes vote down vote up
package io.amient.affinity.kafka

import java.util.Properties

import akka.actor.Actor
import akka.actor.Status.{Failure, Success}
import akka.event.Logging
import com.typesafe.config.Config
import io.amient.affinity.Conf
import io.amient.affinity.core.actor.{TransactionAbort, TransactionBegin, TransactionCommit, TransactionalRecord}
import io.amient.affinity.core.config.CfgStruct
import io.amient.affinity.core.storage.StorageConf
import io.amient.affinity.kafka.KafkaStorage.{KafkaConsumerConf, KafkaProducerConf}
import org.apache.kafka.clients.producer.{Callback, KafkaProducer, ProducerRecord, RecordMetadata}
import org.apache.kafka.common.serialization.ByteArraySerializer

import scala.collection.JavaConverters._

object KafkaConf extends KafkaConf {
  override def apply(config: Config): KafkaConf = new KafkaConf().apply(config)
}

class KafkaConf extends CfgStruct[KafkaConf](classOf[StorageConf]) {
  val BootstrapServers = string("kafka.bootstrap.servers", true).doc("kafka connection string used for consumer and/or producer")
  val Producer = struct("kafka.producer", new KafkaProducerConf, false).doc("any settings that the underlying version of kafka producer client supports")
  val Consumer = struct("kafka.consumer", new KafkaConsumerConf, false).doc("any settings that the underlying version of kafka consumer client supports")
}

class TransactionalProducer extends Actor {

  val logger = Logging.getLogger(context.system, this)

  private[this] var producer: KafkaProducer[Array[Byte], Array[Byte]] = null

  val kafkaConf = KafkaConf(Conf(context.system.settings.config).Affi.Storage)
  val producerConfig = new Properties() {
    if (kafkaConf.Producer.isDefined) {
      val producerConfig = kafkaConf.Producer.toMap()
      if (producerConfig.containsKey("bootstrap.servers")) throw new IllegalArgumentException("bootstrap.servers cannot be overriden for KafkaStroage producer")
      if (producerConfig.containsKey("key.serializer")) throw new IllegalArgumentException("Binary kafka stream cannot use custom key.serializer")
      if (producerConfig.containsKey("value.serializer")) throw new IllegalArgumentException("Binary kafka stream cannot use custom value.serializer")
      producerConfig.entrySet.asScala.filter(_.getValue.isDefined).foreach { case (entry) =>
        put(entry.getKey, entry.getValue.apply.toString)
      }
    }
    put("bootstrap.servers", kafkaConf.BootstrapServers())
    put("value.serializer", classOf[ByteArraySerializer].getName)
    put("key.serializer", classOf[ByteArraySerializer].getName)
  }

  override def receive: Receive = {

    case req@TransactionBegin(transactionalId) => req(sender) ! {
      if (producer == null) {
        producerConfig.put("transactional.id", transactionalId)
        producer = new KafkaProducer[Array[Byte], Array[Byte]](producerConfig)
        logger.debug(s"Transactions.Init(transactional.id = $transactionalId)")
        producer.initTransactions()
      }
      logger.debug("Transactions.Begin()")
      producer.beginTransaction()
    }

    case TransactionalRecord(topic, key, value, timestamp, partition) =>
      val replyto = sender
      val producerRecord = new ProducerRecord(
        topic,
        partition.map(new Integer(_)).getOrElse(null),
        timestamp.map(new java.lang.Long(_)).getOrElse(null),
        key,
        value)
      logger.debug(s"Transactions.Append(topic=$topic)")
      producer.send(producerRecord, new Callback {
        override def onCompletion(metadata: RecordMetadata, exception: Exception): Unit = {
          if (exception != null) {
            replyto ! Failure(exception)
          } else {
            replyto ! Success(metadata.offset())
          }
        }
      })

    case req@TransactionCommit() => req(sender) ! {
      logger.debug("Transactions.Commit()")
      producer.commitTransaction()
    }

    case req@TransactionAbort() => req(sender) ! {
      logger.debug("Transactions.Abort()")
      producer.abortTransaction()
    }
  }
} 
Example 12
Source File: JobStatusActor.scala    From asura   with MIT License 5 votes vote down vote up
package asura.core.job.actor

import akka.actor.Status.Failure
import akka.actor.{ActorRef, Props}
import asura.common.actor._
import asura.common.model.Pagination
import asura.core.model.QueryJob
import asura.core.es.service.JobService
import asura.core.job.actor.JobStatusMonitorActor.JobStatusOperationMessage
import asura.core.job.eventbus.JobStatusBus.JobStatusNotificationMessage
import asura.core.job.{JobListItem, JobStates}
import asura.core.redis.RedisJobState
import asura.core.util.JacksonSupport
import com.typesafe.scalalogging.Logger

import scala.collection.mutable
import scala.collection.mutable.ArrayBuffer

class JobStatusActor() extends BaseActor {

  var query: QueryJob = null
  val watchIds = mutable.HashSet[String]()

  override def receive: Receive = {
    case SenderMessage(sender) =>
      context.become(query(sender))
  }

  def query(outSender: ActorRef): Receive = {
    case query: QueryJob =>
      this.query = query
      JobService.queryJob(query).map(esResponse =>
        if (esResponse.isSuccess) {
          val items = ArrayBuffer[JobListItem]()
          val jobsTable = mutable.HashMap[String, JobListItem]()
          val hits = esResponse.result.hits
          watchIds.clear()
          hits.hits.foreach(hit => {
            val jobId = hit.id
            watchIds.add(jobId)
            jobsTable += (jobId -> {
              val item = JacksonSupport.parse(hit.sourceAsString, classOf[JobListItem])
              item.state = JobStates.UNKNOWN
              items += item
              item._id = jobId
              item
            })
          })
          if (watchIds.nonEmpty) {
            RedisJobState.getJobState(watchIds.toSet).onComplete {
              case util.Success(statesMap) =>
                statesMap.forEach((jobKey, state) => jobsTable(jobKey).state = state)
                outSender ! ListActorEvent(Map("total" -> hits.total, "list" -> items))
              case util.Failure(_) =>
                outSender ! ListActorEvent(Map("total" -> hits.total, "list" -> items))
            }(context.system.dispatcher)
          } else {
            outSender ! ListActorEvent(Map("total" -> 0, "list" -> Nil))
          }
        } else {
          outSender ! ErrorActorEvent(esResponse.error.reason)
        })(context.system.dispatcher)
    case JobStatusNotificationMessage(_, operator, scheduler, group, name, data) =>
      if (watchIds.contains(name)) {
        outSender ! ItemActorEvent(JobStatusOperationMessage(operator, scheduler, group, name, data))
      }
    case eventMessage: ActorEvent =>
      outSender ! eventMessage
    case Failure(t) =>
      outSender ! ErrorActorEvent(t.getMessage)
  }

  override def postStop(): Unit = {
    import JobStatusActor.logger
    logger.debug(s"JobStatus for ${query} stopped")
  }
}

object JobStatusActor {

  val logger = Logger(classOf[JobStatusActor])

  def props() = Props(new JobStatusActor())

  case class JobQueryMessage(scheduler: String = null, group: String = null, text: String = null) extends Pagination

} 
Example 13
Source File: BankAccountTest.scala    From reactive-programming   with Apache License 2.0 5 votes vote down vote up
package com.test.week5

import akka.actor.Status.Failure
import akka.actor.{ Actor, ActorRef, Props }
import akka.event.LoggingReceive
import akka.pattern.ask
import com.test.TestSpec

class BankAccountTest extends TestSpec {

  "Actors" should "know itself" in {
    val ref: ActorRef = system.actorOf(Props(new Actor {
      override def receive: Receive = {
        case _ ⇒ sender() ! self
      }
    }))

    (ref ? "").futureValue shouldBe ref
    cleanup(ref)
  }

  it should "count" in {
    val ref: ActorRef = system.actorOf(Props(new Actor {
      def count(num: Int): Receive = LoggingReceive {
        case _ ⇒
          context.become(count(num + 1))
          sender() ! num
      }
      override def receive: Receive = LoggingReceive(count(0))
    }))
    (ref ? "").futureValue shouldBe 0
    (ref ? "").futureValue shouldBe 1
    (ref ? "").futureValue shouldBe 2
    (ref ? "").futureValue shouldBe 3
    cleanup(ref)
  }

  it should "be a BankAccount" in {
    object BankAccount {
      case class Transfer(from: ActorRef, to: ActorRef, amount: BigInt)
      case class Deposit(amount: BigInt)
      case class Withdraw(amount: BigInt)
      case object Info
      case class Done(amount: BigInt)
      case object Failed
    }
    class BankAccount extends Actor {
      import BankAccount._
      var balance: BigInt = BigInt(0)
      override def receive: Receive = LoggingReceive {
        case Deposit(amount) ⇒
          balance += amount
          sender() ! Done(balance)
        case Withdraw(amount) ⇒
          balance -= amount
          sender() ! Done(balance)
        case Info ⇒
          sender() ! Done(balance)
        case _ ⇒ sender() ! Failure
      }
    }

    import BankAccount._
    val account1 = system.actorOf(Props(new BankAccount))
    (account1 ? Info).futureValue shouldBe Done(0)
    (account1 ? Deposit(100)).futureValue shouldBe Done(100)
    (account1 ? Deposit(100)).futureValue shouldBe Done(200)

    val account2 = system.actorOf(Props(new BankAccount))

    val tom = system.actorOf(Props(new Actor {
      def awaitDeposit(client: ActorRef): Receive = LoggingReceive {
        case Done(amount) ⇒
          client ! Done(amount)
          context.stop(self)
      }
      def awaitWithdraw(to: ActorRef, amount: BigInt, client: ActorRef): Receive = LoggingReceive {
        case Done(_) ⇒
          to ! Deposit(amount)
          context.become(awaitDeposit(client))
        case Failed ⇒
          client ! Failed
          context.stop(self)
      }
      override def receive = {
        case Transfer(from, to, amount) ⇒
          from ! Withdraw(amount)
          context.become(awaitWithdraw(to, amount, sender()))
      }
    }))

    (tom ? Transfer(account1, account2, 50)).futureValue shouldBe Done(50)
    (account1 ? Info).futureValue shouldBe Done(150)
    (account2 ? Info).futureValue shouldBe Done(50)
    cleanup(account1, account2, tom)
  }
}