scala.collection.immutable.Seq Scala Examples

The following examples show how to use scala.collection.immutable.Seq. 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: DoobieRepository.scala    From pfhais   with Creative Commons Attribution Share Alike 4.0 International 5 votes vote down vote up
package com.wegtam.books.pfhais.tapir.db

import cats.effect.Sync
import com.wegtam.books.pfhais.tapir.models._
import doobie._
import doobie.implicits._
import doobie.postgres.implicits._
import doobie.refined.implicits._
import eu.timepit.refined.auto._
import fs2.Stream

import scala.collection.immutable.Seq


  override def updateProduct(p: Product): F[Int] = {
    val namesSql    = "INSERT INTO names (product_id, lang_code, name) VALUES (?, ?, ?)"
    val namesValues = p.names.toNonEmptyList.map(t => (p.id, t.lang, t.name))
    val program = for {
      dl <- sql"DELETE FROM names WHERE product_id = ${p.id}".update.run
      ts <- Update[(ProductId, LanguageCode, ProductName)](namesSql).updateMany(namesValues)
    } yield dl + ts
    program.transact(tx)
  }

} 
Example 2
Source File: FinatraRequestToRawBody.scala    From tapir   with Apache License 2.0 5 votes vote down vote up
package sttp.tapir.server.finatra

import java.io.ByteArrayInputStream
import java.nio.ByteBuffer
import java.nio.charset.Charset

import com.twitter.finagle.http.Request
import com.twitter.finatra.http.request.RequestUtils
import com.twitter.io.Buf
import com.twitter.util.Future
import org.apache.commons.fileupload.FileItemHeaders
import sttp.model.{Part, Header}
import sttp.tapir.{RawPart, RawBodyType}

import scala.collection.immutable.Seq
import scala.collection.JavaConverters._

class FinatraRequestToRawBody(serverOptions: FinatraServerOptions) {
  def apply[R](bodyType: RawBodyType[R], body: Buf, charset: Option[Charset], request: Request): Future[R] = {
    def asByteArray: Array[Byte] = {
      val array = new Array[Byte](body.length)
      body.write(array, 0)
      array
    }

    def asByteBuffer: ByteBuffer = {
      val buffer = ByteBuffer.allocate(body.length)
      body.write(buffer)
      buffer.flip()
      buffer
    }

    bodyType match {
      case RawBodyType.StringBody(defaultCharset) => Future.value[R](new String(asByteArray, charset.getOrElse(defaultCharset)))
      case RawBodyType.ByteArrayBody              => Future.value[R](asByteArray)
      case RawBodyType.ByteBufferBody             => Future.value[R](asByteBuffer)
      case RawBodyType.InputStreamBody            => Future.value[R](new ByteArrayInputStream(asByteArray))
      case RawBodyType.FileBody                   => serverOptions.createFile(asByteArray)
      case m: RawBodyType.MultipartBody           => multiPartRequestToRawBody(request, m)
    }
  }

  private def parseDispositionParams(headerValue: Option[String]): Map[String, String] =
    headerValue
      .map(
        _.split(";")
          .map(_.trim)
          .tail
          .map(_.split("="))
          .map(array => array(0) -> array(1))
          .toMap
      )
      .getOrElse(Map.empty)

  private def getCharset(contentType: Option[String]): Option[Charset] =
    contentType.flatMap(
      _.split(";")
        .map(_.trim)
        .tail
        .map(_.split("="))
        .map(array => array(0) -> array(1))
        .toMap
        .get("charset")
        .map(Charset.forName)
    )

  private def multiPartRequestToRawBody(request: Request, m: RawBodyType.MultipartBody): Future[Seq[RawPart]] = {
    def fileItemHeaders(headers: FileItemHeaders): Seq[Header] = {
      headers.getHeaderNames.asScala
        .flatMap { name => headers.getHeaders(name).asScala.map(name -> _) }
        .toSeq
        .filter(_._1.toLowerCase != "content-disposition")
        .map { case (k, v) => Header(k, v) }
        .toList
    }

    Future
      .collect(
        RequestUtils
          .multiParams(request)
          .flatMap {
            case (name, multiPartItem) =>
              val dispositionParams: Map[String, String] =
                parseDispositionParams(Option(multiPartItem.headers.getHeader("content-disposition")))
              val charset = getCharset(multiPartItem.contentType)

              for {
                partType <- m.partType(name)
                futureBody = apply(partType, Buf.ByteArray.Owned(multiPartItem.data), charset, request)
              } yield futureBody
                .map(body =>
                  Part(name, body, otherDispositionParams = dispositionParams - "name", headers = fileItemHeaders(multiPartItem.headers))
                    .asInstanceOf[RawPart]
                )
          }
          .toSeq
      )
      .map(_.toList)
  }
} 
Example 3
Source File: package.scala    From aloha   with MIT License 5 votes vote down vote up
package com.eharmony.aloha.factory

import spray.json._
import scala.collection.immutable.Seq

package object jsext {
  protected[aloha] implicit class JsValueExtensions(json: JsValue) {
    @inline def apply(fieldName: String): Option[JsValue] = json.asJsObject.getFields(fieldName).headOption
    @inline def sa(fieldName: String): Option[Seq[String]] = apply(fieldName) flatMap {
      case JsArray(a) =>
        val b = a collect {case JsString(s) => s}
        if (a.size == b.size) Some(b.toSeq) else None
      case _ => None
    }

    @inline def s(fieldName: String): Option[String] = apply(fieldName) collect {case JsString(s) => s}
    @inline def n(fieldName: String): Option[BigDecimal] = apply(fieldName) collect {case JsNumber(s) => s}
    @inline def b(fieldName: String): Option[Boolean] = apply(fieldName) collect {case JsBoolean(b) => b}
  }
} 
Example 4
Source File: FriendService.scala    From activator-lagom-scala-chirper   with Apache License 2.0 5 votes vote down vote up
package sample.chirper.friend.api

import akka.NotUsed
import com.lightbend.lagom.javadsl.api.Descriptor
import com.lightbend.lagom.javadsl.api.ScalaService._
import com.lightbend.lagom.javadsl.api.Service
import com.lightbend.lagom.javadsl.api.ServiceCall
import scala.collection.immutable.Seq



  def getFollowers(id: String): ServiceCall[NotUsed, Seq[String]]

  override def descriptor(): Descriptor = {
    // @formatter:off
    named("friendservice").withCalls(
        pathCall("/api/users/:id", getUser _),
        namedCall("/api/users", createUser _),
        pathCall("/api/users/:userId/friends", addFriend _),
        pathCall("/api/users/:id/followers", getFollowers _)
      ).withAutoAcl(true)
    // @formatter:on
  }
} 
Example 5
Source File: FriendServiceTest.scala    From activator-lagom-scala-chirper   with Apache License 2.0 5 votes vote down vote up
package sample.chirper.friend.impl

import java.util.concurrent.TimeUnit.SECONDS

import scala.collection.immutable.Seq
import scala.concurrent.duration.FiniteDuration

import org.junit.Assert.assertEquals
import org.junit.Test

import com.lightbend.lagom.javadsl.testkit.ServiceTest.defaultSetup
import com.lightbend.lagom.javadsl.testkit.ServiceTest.eventually
import com.lightbend.lagom.javadsl.testkit.ServiceTest.withServer

import akka.NotUsed
import sample.chirper.friend.api.FriendId
import sample.chirper.friend.api.FriendService
import sample.chirper.friend.api.User

class FriendServiceTest {


  @throws(classOf[Exception])
  @Test
  def shouldBeAbleToCreateUsersAndConnectFriends() {
    withServer(defaultSetup, server => {
      val friendService = server.client(classOf[FriendService])
      val usr1 = new User("usr1", "User 1");
      friendService.createUser().invoke(usr1).toCompletableFuture().get(10, SECONDS)
      val usr2 = new User("usr2", "User 2");
      friendService.createUser().invoke(usr2).toCompletableFuture().get(3, SECONDS)
      val usr3 = new User("usr3", "User 3");
      friendService.createUser().invoke(usr3).toCompletableFuture().get(3, SECONDS)

      friendService.addFriend("usr1").invoke(FriendId(usr2.userId)).toCompletableFuture().get(3, SECONDS)
      friendService.addFriend("usr1").invoke(FriendId(usr3.userId)).toCompletableFuture().get(3, SECONDS)

      val fetchedUsr1 = friendService.getUser("usr1").invoke(NotUsed).toCompletableFuture().get(3,
          SECONDS)
      assertEquals(usr1.userId, fetchedUsr1.userId)
      assertEquals(usr1.name, fetchedUsr1.name)
      assertEquals(Seq("usr2", "usr3"), fetchedUsr1.friends)

      eventually(FiniteDuration(10, SECONDS), () => {
        val followers = friendService.getFollowers("usr2").invoke()
            .toCompletableFuture().get(3, SECONDS)
        assertEquals(Seq("usr1"), followers)
      })

    })
  }

} 
Example 6
Source File: FriendEventProcessor.scala    From activator-lagom-scala-chirper   with Apache License 2.0 5 votes vote down vote up
package sample.chirper.friend.impl


import java.util.UUID

import scala.collection.JavaConverters._
import scala.collection.immutable.Seq
import scala.compat.java8.FutureConverters._
import scala.concurrent.ExecutionContext

import com.datastax.driver.core.PreparedStatement
import com.lightbend.lagom.javadsl.persistence.AggregateEventTag
import com.lightbend.lagom.javadsl.persistence.cassandra.CassandraReadSideProcessor
import com.lightbend.lagom.javadsl.persistence.cassandra.CassandraSession

import akka.Done
import javax.inject.Inject

class FriendEventProcessor @Inject()(implicit ec: ExecutionContext) extends CassandraReadSideProcessor[FriendEvent] {

  // Needed to convert some Scala types to Java
  import converter.CompletionStageConverters._

  @volatile private var writeFollowers: PreparedStatement = null // initialized in prepare
  @volatile private var writeOffset: PreparedStatement = null // initialized in prepare

  private def setWriteFollowers(writeFollowers: PreparedStatement): Unit =
    this.writeFollowers = writeFollowers

  private def setWriteOffset(writeOffset: PreparedStatement): Unit =
    this.writeOffset = writeOffset

  override def aggregateTag: AggregateEventTag[FriendEvent] = FriendEvent.Tag

  override def prepare(session: CassandraSession) = {
    // @formatter:off
    prepareCreateTables(session).thenCompose(a =>
    prepareWriteFollowers(session).thenCompose(b =>
    prepareWriteOffset(session).thenCompose(c =>
    selectOffset(session))))
    // @formatter:on
  }

  private def prepareCreateTables(session: CassandraSession) = {
    // @formatter:off
    session.executeCreateTable(
        "CREATE TABLE IF NOT EXISTS follower ("
          + "userId text, followedBy text, "
          + "PRIMARY KEY (userId, followedBy))")
      .thenCompose(a => session.executeCreateTable(
        "CREATE TABLE IF NOT EXISTS friend_offset ("
          + "partition int, offset timeuuid, "
          + "PRIMARY KEY (partition))"));
    // @formatter:on
  }

  private def prepareWriteFollowers(session: CassandraSession) = {
    val statement = session.prepare("INSERT INTO follower (userId, followedBy) VALUES (?, ?)")
    statement.map(ps => {
      setWriteFollowers(ps)
      Done
    })
  }

  private def prepareWriteOffset(session: CassandraSession) = {
    val statement = session.prepare("INSERT INTO friend_offset (partition, offset) VALUES (1, ?)")
    statement.map(ps => {
      setWriteOffset(ps)
      Done
    })
  }

  private def selectOffset(session: CassandraSession) = {
    val select = session.selectOne("SELECT offset FROM friend_offset WHERE partition=1")
    select.map { maybeRow => maybeRow.map[UUID](_.getUUID("offset")) }
  }

  override def defineEventHandlers(builder: EventHandlersBuilder): EventHandlers = {
    builder.setEventHandler(classOf[FriendAdded], processFriendChanged)
    builder.build()
  }

  private def processFriendChanged(event: FriendAdded, offset: UUID) = {
    val bindWriteFollowers = writeFollowers.bind()
    bindWriteFollowers.setString("userId", event.friendId)
    bindWriteFollowers.setString("followedBy", event.userId)
    val bindWriteOffset = writeOffset.bind(offset)
    completedStatements(Seq(bindWriteFollowers, bindWriteOffset).asJava)
  }

} 
Example 7
Source File: FriendServiceImpl.scala    From activator-lagom-scala-chirper   with Apache License 2.0 5 votes vote down vote up
package sample.chirper.friend.impl

import scala.collection.JavaConverters._
import scala.collection.immutable.Seq
import scala.compat.java8.FutureConverters._
import scala.concurrent.ExecutionContext

import com.lightbend.lagom.javadsl.api.ServiceCall
import com.lightbend.lagom.javadsl.api.transport.NotFound
import com.lightbend.lagom.javadsl.persistence.PersistentEntityRegistry
import com.lightbend.lagom.javadsl.persistence.cassandra.CassandraReadSide
import com.lightbend.lagom.javadsl.persistence.cassandra.CassandraSession

import akka.Done
import akka.NotUsed
import javax.inject.Inject
import sample.chirper.friend.api.FriendId
import sample.chirper.friend.api.FriendService
import sample.chirper.friend.api.User

class FriendServiceImpl @Inject() (
    persistentEntities: PersistentEntityRegistry,
    readSide: CassandraReadSide,
    db: CassandraSession)(implicit ec: ExecutionContext) extends FriendService {

  // Needed to convert some Scala types to Java
  import converter.ServiceCallConverter._
    
  persistentEntities.register(classOf[FriendEntity])
  readSide.register(classOf[FriendEventProcessor])

  override def getUser(id: String): ServiceCall[NotUsed, User] = {
    request =>
      friendEntityRef(id).ask[GetUserReply, GetUser](GetUser())
        .map(_.user.getOrElse(throw new NotFound(s"user $id not found")))
  }

  override def createUser(): ServiceCall[User, NotUsed] = {
    request =>
      friendEntityRef(request.userId).ask[Done, CreateUser](CreateUser(request))
  }

  override def addFriend(userId: String): ServiceCall[FriendId, NotUsed] = {
    request =>
      friendEntityRef(userId).ask[Done, AddFriend](AddFriend(request.friendId))
  }

  override def getFollowers(id: String): ServiceCall[NotUsed, Seq[String]] = {
    req =>
      {
        db.selectAll("SELECT * FROM follower WHERE userId = ?", id).map { jrows =>
          val rows = jrows.asScala.toVector
          rows.map(_.getString("followedBy"))
        }
      }
  }

  private def friendEntityRef(userId: String) =
    persistentEntities.refFor(classOf[FriendEntity], userId)
} 
Example 8
Source File: UpickleCustomizationSupport.scala    From akka-http-json   with Apache License 2.0 5 votes vote down vote up
package de.heikoseeberger.akkahttpupickle

import akka.http.javadsl.common.JsonEntityStreamingSupport
import akka.http.scaladsl.common.EntityStreamingSupport
import akka.http.scaladsl.marshalling.{ Marshaller, Marshalling, ToEntityMarshaller }
import akka.http.scaladsl.model.{ ContentTypeRange, HttpEntity, MediaType, MessageEntity }
import akka.http.scaladsl.model.MediaTypes.`application/json`
import akka.http.scaladsl.unmarshalling.{ FromEntityUnmarshaller, Unmarshal, Unmarshaller }
import akka.http.scaladsl.util.FastFuture
import akka.stream.scaladsl.{ Flow, Source }
import akka.util.ByteString
import UpickleCustomizationSupport._

import scala.collection.immutable.Seq
import scala.concurrent.Future
import scala.util.Try
import scala.util.control.NonFatal

// This companion object only exists for binary compatibility as adding methods with default implementations
// (including val's as they create synthetic methods) is not compatible.
private object UpickleCustomizationSupport {

  private def jsonStringUnmarshaller(support: UpickleCustomizationSupport) =
    Unmarshaller.byteStringUnmarshaller
      .forContentTypes(support.unmarshallerContentTypes: _*)
      .mapWithCharset {
        case (ByteString.empty, _) => throw Unmarshaller.NoContentException
        case (data, charset)       => data.decodeString(charset.nioCharset.name)
      }

  private def jsonSourceStringMarshaller(support: UpickleCustomizationSupport) =
    Marshaller.oneOf(support.mediaTypes: _*)(support.sourceByteStringMarshaller)

  private def jsonStringMarshaller(support: UpickleCustomizationSupport) =
    Marshaller.oneOf(support.mediaTypes: _*)(Marshaller.stringMarshaller)
}


  implicit def sourceMarshaller[A](implicit
      writes: apiInstance.Writer[A],
      support: JsonEntityStreamingSupport = EntityStreamingSupport.json()
  ): ToEntityMarshaller[SourceOf[A]] =
    jsonSourceStringMarshaller(this).compose(jsonSource[A])
} 
Example 9
Source File: GenCodecSupport.scala    From akka-http-json   with Apache License 2.0 5 votes vote down vote up
package de.heikoseeberger.akkahttpavsystemgencodec

import akka.http.scaladsl.marshalling.{ Marshaller, ToEntityMarshaller }
import akka.http.scaladsl.model.ContentTypeRange
import akka.http.scaladsl.model.MediaType
import akka.http.scaladsl.model.MediaTypes.`application/json`
import akka.http.scaladsl.unmarshalling.{ FromEntityUnmarshaller, Unmarshaller }
import akka.util.ByteString
import com.avsystem.commons.serialization.GenCodec
import com.avsystem.commons.serialization.json.{ JsonStringInput, JsonStringOutput }

import scala.collection.immutable.Seq

object GenCodecSupport extends GenCodecSupport {}

trait GenCodecSupport {

  def unmarshallerContentTypes: Seq[ContentTypeRange] =
    mediaTypes.map(ContentTypeRange.apply)

  def mediaTypes: Seq[MediaType.WithFixedCharset] =
    List(`application/json`)

  private val jsonStringUnmarshaller =
    Unmarshaller.byteStringUnmarshaller
      .forContentTypes(unmarshallerContentTypes: _*)
      .mapWithCharset {
        case (ByteString.empty, _) => throw Unmarshaller.NoContentException
        case (data, charset)       => data.decodeString(charset.nioCharset.name)
      }

  private val jsonStringMarshaller =
    Marshaller.oneOf(mediaTypes: _*)(Marshaller.stringMarshaller)

  
  implicit def marshaller[A: GenCodec]: ToEntityMarshaller[A] =
    jsonStringMarshaller.compose(JsonStringOutput.write(_))
} 
Example 10
Source File: Command.scala    From event-sourcing-kafka-streams   with MIT License 5 votes vote down vote up
package org.amitayh.invoices.common.domain

import java.time.{Instant, LocalDate}
import java.util.UUID

import scala.collection.immutable.Seq

case class Command(originId: UUID,
                   commandId: UUID,
                   expectedVersion: Option[Int],
                   payload: Command.Payload) {

  def apply(timestamp: Instant, snapshot: InvoiceSnapshot): CommandResult = {
    val outcome = snapshot
      .validateVersion(expectedVersion)
      .flatMap(payload(_))
      .fold(
        CommandResult.Failure,
        success(timestamp, snapshot, _))

    CommandResult(originId, commandId, outcome)
  }

  private def success(timestamp: Instant,
                      snapshot: InvoiceSnapshot,
                      payloads: Seq[Event.Payload]): CommandResult.Outcome = {
    payloads.foldLeft(CommandResult.Success(snapshot)) { (acc, payload) =>
      acc.update(timestamp, commandId, payload)
    }
  }

}

object Command {
  type Result = Either[InvoiceError, Seq[Event.Payload]]

  sealed trait Payload {
    def apply(invoice: Invoice): Result
  }

  case class CreateInvoice(customerName: String,
                           customerEmail: String,
                           issueDate: LocalDate,
                           dueDate: LocalDate,
                           lineItems: List[LineItem]) extends Payload {

    override def apply(invoice: Invoice): Result = {
      val createdEvent = Event.InvoiceCreated(customerName, customerEmail, issueDate, dueDate)
      val lineItemEvents = lineItems.map(toLineItemEvent)
      success(createdEvent :: lineItemEvents)
    }

    private def toLineItemEvent(lineItem: LineItem): Event.Payload =
      Event.LineItemAdded(
        description = lineItem.description,
        quantity = lineItem.quantity,
        price = lineItem.price)
  }

  case class AddLineItem(description: String,
                         quantity: Double,
                         price: Double) extends Payload {
    override def apply(invoice: Invoice): Result =
      success(Event.LineItemAdded(description, quantity, price))
  }

  case class RemoveLineItem(index: Int) extends Payload {
    override def apply(invoice: Invoice): Result = {
      if (invoice.hasLineItem(index)) success(Event.LineItemRemoved(index))
      else failure(LineItemDoesNotExist(index))
    }
  }

  case class PayInvoice() extends Payload {
    override def apply(invoice: Invoice): Result =
      success(Event.PaymentReceived(invoice.total))
  }

  case class DeleteInvoice() extends Payload {
    override def apply(invoice: Invoice): Result =
      success(Event.InvoiceDeleted())
  }

  private def success(events: Event.Payload*): Result = success(events.toList)

  private def success(events: List[Event.Payload]): Result = Right(events)

  private def failure(error: InvoiceError): Result = Left(error)
} 
Example 11
Source File: DoobieRepository.scala    From pfhais   with Creative Commons Attribution Share Alike 4.0 International 5 votes vote down vote up
package com.wegtam.books.pfhais.pure.db

import cats.effect.Sync
import com.wegtam.books.pfhais.pure.models._
import doobie._
import doobie.implicits._
import doobie.postgres.implicits._
import doobie.refined.implicits._
import eu.timepit.refined.auto._
import fs2.Stream

import scala.collection.immutable.Seq


  override def updateProduct(p: Product): F[Int] = {
    val namesSql    = "INSERT INTO names (product_id, lang_code, name) VALUES (?, ?, ?)"
    val namesValues = p.names.toNonEmptyList.map(t => (p.id, t.lang, t.name))
    val program = for {
      dl <- sql"DELETE FROM names WHERE product_id = ${p.id}".update.run
      ts <- Update[(ProductId, LanguageCode, ProductName)](namesSql).updateMany(namesValues)
    } yield dl + ts
    program.transact(tx)
  }

} 
Example 12
Source File: GaugeDoubleImpl.scala    From datadog4s   with MIT License 5 votes vote down vote up
package com.avast.datadog4s.statsd.metric

import cats.effect.Sync
import com.avast.datadog4s.api.Tag
import com.avast.datadog4s.api.metric.Gauge
import com.timgroup.statsd.StatsDClient
import scala.collection.immutable.Seq

class GaugeDoubleImpl[F[_]: Sync](
  statsDClient: StatsDClient,
  aspect: String,
  sampleRate: Double,
  defaultTags: Seq[Tag]
) extends Gauge[F, Double] {
  private[this] val F = Sync[F]

  override def set(value: Double, tags: Tag*): F[Unit] =
    F.delay {
      statsDClient.recordGaugeValue(aspect, value, sampleRate, (tags ++ defaultTags): _*)
    }
} 
Example 13
Source File: HistogramLongImpl.scala    From datadog4s   with MIT License 5 votes vote down vote up
package com.avast.datadog4s.statsd.metric

import cats.effect.Sync
import com.avast.datadog4s.api.Tag
import com.avast.datadog4s.api.metric.Histogram
import com.timgroup.statsd.StatsDClient
import scala.collection.immutable.Seq

class HistogramLongImpl[F[_]: Sync](
  statsDClient: StatsDClient,
  aspect: String,
  sampleRate: Double,
  defaultTags: Seq[Tag]
) extends Histogram[F, Long] {
  private[this] val F = Sync[F]

  override def record(value: Long, tags: Tag*): F[Unit] =
    F.delay {
      statsDClient.recordHistogramValue(aspect, value, sampleRate, (tags ++ defaultTags): _*)
    }
} 
Example 14
Source File: GaugeLongImpl.scala    From datadog4s   with MIT License 5 votes vote down vote up
package com.avast.datadog4s.statsd.metric

import cats.effect.Sync
import com.avast.datadog4s.api.Tag
import com.avast.datadog4s.api.metric.Gauge
import com.timgroup.statsd.StatsDClient

import scala.collection.immutable.Seq

class GaugeLongImpl[F[_]: Sync](
  statsDClient: StatsDClient,
  aspect: String,
  sampleRate: Double,
  defaultTags: Seq[Tag]
) extends Gauge[F, Long] {
  private[this] val F                                = Sync[F]
  override def set(value: Long, tags: Tag*): F[Unit] =
    F.delay {
      statsDClient.recordGaugeValue(aspect, value, sampleRate, (tags ++ defaultTags): _*)
    }
} 
Example 15
Source File: HistogramDoubleImpl.scala    From datadog4s   with MIT License 5 votes vote down vote up
package com.avast.datadog4s.statsd.metric

import cats.effect.Sync
import com.avast.datadog4s.api.Tag
import com.avast.datadog4s.api.metric.Histogram
import com.timgroup.statsd.StatsDClient
import scala.collection.immutable.Seq

class HistogramDoubleImpl[F[_]: Sync](
  statsDClient: StatsDClient,
  aspect: String,
  sampleRate: Double,
  defaultTags: Seq[Tag]
) extends Histogram[F, Double] {
  private[this] val F = Sync[F]

  override def record(value: Double, tags: Tag*): F[Unit] =
    F.delay {
      statsDClient.recordHistogramValue(aspect, value, sampleRate, (tags ++ defaultTags): _*)
    }
} 
Example 16
Source File: TimerImpl.scala    From datadog4s   with MIT License 5 votes vote down vote up
package com.avast.datadog4s.statsd.metric

import java.time.Duration
import java.util.concurrent.TimeUnit

import cats.effect.{ Clock, Sync }
import cats.syntax.flatMap._
import cats.syntax.functor._
import com.avast.datadog4s.api.Tag
import com.avast.datadog4s.api.metric.Timer
import com.avast.datadog4s.api.tag.Tagger
import com.timgroup.statsd.StatsDClient

import scala.collection.immutable.Seq

class TimerImpl[F[_]: Sync](
  clock: Clock[F],
  statsDClient: StatsDClient,
  aspect: String,
  sampleRate: Double,
  defaultTags: Seq[Tag]
) extends Timer[F] {
  private[this] val F                                  = Sync[F]
  private[this] val successTagger: Tagger[Boolean]     = Tagger.make("success")
  private[this] val failedTag: Tag                     = successTagger.tag(false)
  private[this] val succeededTag: Tag                  = successTagger.tag(true)
  private[this] val exceptionTagger: Tagger[Throwable] = Tagger.make("exception")

  override def time[A](value: F[A], tags: Tag*): F[A] =
    for {
      start <- clock.monotonic(TimeUnit.NANOSECONDS)
      a     <- F.recoverWith(value)(measureFailed(start))
      stop  <- clock.monotonic(TimeUnit.NANOSECONDS)
      _     <- record(Duration.ofNanos(stop - start), (tags :+ succeededTag): _*)
    } yield a

  private def measureFailed[A](startTime: Long, tags: Tag*): PartialFunction[Throwable, F[A]] = {
    case thr: Throwable =>
      val finalTags   = tags :+ exceptionTagger.tag(thr) :+ failedTag
      val computation = for {
        stop <- clock.monotonic(TimeUnit.NANOSECONDS)
        _    <- record(Duration.ofNanos(stop - startTime), finalTags: _*)
      } yield ()
      computation >> F.raiseError(thr)
  }

  override def record(duration: Duration, tags: Tag*): F[Unit] =
    F.delay {
      statsDClient.recordExecutionTime(aspect, duration.toMillis, sampleRate, (tags ++ defaultTags): _*)
    }
} 
Example 17
Source File: Prod.scala    From scalaz-deriving   with GNU Lesser General Public License v3.0 5 votes vote down vote up
// Copyright: 2017 - 2020 Sam Halliday
// License: https://opensource.org/licenses/BSD-3-Clause

// Derived from https://github.com/frees-io/iota
//
// Copyright (C) 2017-2018 Andy Scott.
// Copyright (c) 2017-2018 47 Degrees. <http://47deg.com>
// All rights reserved.
//
// https://github.com/frees-io/iota/blob/v0.3.10/LICENSE
// https://github.com/frees-io/iota/blob/v0.3.10/NOTICE

package scalaz.iotaz

import scala._, Predef._
import scala.collection.immutable.Seq


final class Prod[LL <: TList] private (
  val values: Seq[Any]
) {
  type L = LL

  override def equals(anyOther: Any): Boolean =
    anyOther match {
      case other: Prod[LL] => values == other.values
      case _               => false
    }

  override def hashCode(): Int =
    values.hashCode()

  override def toString: String =
    s"""Prod(${values.mkString(", ")})"""
}

object Prod {

  import scalaz.Isomorphism._
  def gen[A, R <: TList]: A <=> Prod[R] =
    macro internal.ProductMacros.prodGen[A, R]

  def apply[L <: TList](args: Any*): Prod[L] =
    macro internal.ProductMacros.prodApply[L]

  def unsafeApply[L <: TList](values: Seq[Any]): Prod[L] =
    new Prod[L](values)

} 
Example 18
Source File: ChirpRepository.scala    From lagom-scala-chirper   with Apache License 2.0 5 votes vote down vote up
package sample.chirper.chirp.impl

import java.time.Instant

import akka.NotUsed
import akka.stream.scaladsl.Source
import com.datastax.driver.core.Row
import com.lightbend.lagom.scaladsl.persistence.cassandra.CassandraSession
import sample.chirper.chirp.api.Chirp

import scala.collection.immutable.Seq
import scala.concurrent.{ExecutionContext, Future}


trait ChirpRepository {

  def getHistoricalChirps(userIds: Seq[String], timestamp: Long): Source[Chirp, NotUsed]

  def getRecentChirps(userIds: Seq[String]): Future[Seq[Chirp]]

}

class ChirpRepositoryImpl(
                           db: CassandraSession
                         )(implicit val ec: ExecutionContext) extends ChirpRepository {

  private val NumRecentChirps = 10
  private val SelectHistoricalChirps = "SELECT * FROM chirp WHERE userId = ? AND timestamp >= ? ORDER BY timestamp ASC"
  private val SelectRecentChirps = "SELECT * FROM chirp WHERE userId = ? ORDER BY timestamp DESC LIMIT ?"

  override def getHistoricalChirps(userIds: Seq[String], timestamp: Long): Source[Chirp, NotUsed] = {
    val sources = userIds.map(getHistoricalChirps(_, timestamp))
    // Chirps from one user are ordered by timestamp, but chirps from different
    // users are not ordered. That can be improved by implementing a smarter
    // merge that takes the timestamps into account.
    Source(sources).flatMapMerge(sources.size, identity)
  }

  override def getRecentChirps(userIds: Seq[String]): Future[Seq[Chirp]] =
    Future
    .sequence(userIds.map(getRecentChirps))
    .map(_.flatten)
    .map(limitRecentChirps)

  // Helpers -----------------------------------------------------------------------------------------------------------

  private def getHistoricalChirps(userId: String, timestamp: Long): Source[Chirp, NotUsed] =
    db.select(
      SelectHistoricalChirps,
      userId,
      Long.box(timestamp)
    ).map(mapChirp)

  private def getRecentChirps(userId: String) =
    db.selectAll(
      SelectRecentChirps,
      userId,
      Int.box(NumRecentChirps)
    ).map(_.map(mapChirp))

  private def mapChirp(row: Row): Chirp = Chirp(
    row.getString("userId"),
    row.getString("message"),
    Instant.ofEpochMilli(row.getLong("timestamp")),
    row.getString("uuid")
  )

  private def limitRecentChirps(all: Seq[Chirp]): Seq[Chirp] = {
    // FIXME: this can be streamed
    val limited = all
      .sortWith(_.timestamp.toEpochMilli < _.timestamp.toEpochMilli)
      .take(NumRecentChirps)
    limited.reverse
  }

} 
Example 19
Source File: SealedValues.scala    From flamy   with Apache License 2.0 5 votes vote down vote up
package com.flaminem.flamy.utils.macros

import scala.collection.immutable.Seq
import scala.language.experimental.macros
import scala.reflect.macros.blackbox

//scalastyle:off

object SealedValues {

  def values[A]: Seq[A] = macro values_impl[A]

  def values_impl[A: c.WeakTypeTag](c: blackbox.Context) : c.Expr[Seq[A]] = {
    import c.universe._

    val symbol = weakTypeOf[A].typeSymbol

    if (!symbol.isClass)  { c.abort(
      c.enclosingPosition,
      "Can only enumerate values of a sealed trait or class."
    )}
    else if (!symbol.asClass.isSealed) {
      c.abort(
        c.enclosingPosition,
        "Can only enumerate values of a sealed trait or class."
      )
    } else {
      val siblingSubclasses: List[Symbol] = scala.util.Try {
        val enclosingModule = c.macroApplication
        enclosingModule.filter { x =>
          scala.util.Try(x.symbol.asModule.moduleClass.asClass.baseClasses.contains(symbol))
            .getOrElse(false)
        }.map(_.symbol)
      } getOrElse {
        Nil
      }

      val children = symbol.asClass.knownDirectSubclasses.toList.sortBy{_.pos.start} ::: siblingSubclasses
      if (!children.forall(x => x.isModuleClass || x.isModule)) {
        c.abort(
          c.enclosingPosition,
          "All children must be objects."
        )
      } else c.Expr[Seq[A]] {
        def sourceModuleRef(sym: Symbol) = Ident(
          if (sym.isModule) {
            sym
          }
          else {
            sym.asInstanceOf[
              scala.reflect.internal.Symbols#Symbol
              ].sourceModule.asInstanceOf[Symbol]
          }
        )

        Apply(
          Select(
            reify(Seq).tree,
            TermName("apply")
          ),
          children.map(sourceModuleRef(_))
        )
      }
    }
  }
}

//scalastyle:on 
Example 20
Source File: PartitionWaiter.scala    From flamy   with Apache License 2.0 5 votes vote down vote up
package com.flaminem.flamy.exec.hive

import com.flaminem.flamy.conf.FlamyContext
import com.flaminem.flamy.exec.utils.{ReturnFailure, ReturnStatus, ReturnSuccess, Waiter}
import com.flaminem.flamy.model.names.{ItemName, TablePartitionName}
import com.flaminem.flamy.utils.logging.Logging
import com.flaminem.flamy.utils.time.TimeUtils

import scala.collection.immutable.Seq


  private def waitForPartition(partitions: Seq[TablePartitionName], timeout: Long, after: Option[Long], retryInterval: Long): ReturnStatus = {
    Waiter.waitForEvent(partitionsExist(partitions, after), timeout, retryInterval) match {
      case true => ReturnSuccess
      case false => ReturnFailure
    }
  }

  override def close(): Unit = {
    this.fetcher.close()
  }

} 
Example 21
Source File: TraversableLikeExtensionTest.scala    From flamy   with Apache License 2.0 5 votes vote down vote up
package com.flaminem.flamy.utils.collection

import org.scalatest.FreeSpec

import scala.collection.immutable.Seq


class TraversableLikeExtensionTest extends FreeSpec {

  "splitBy should correctly work with sorted groups" in {
    val l: Seq[Int] = 1 to 10
    val res = l.splitBy{x => x / 6}

    assert(res===Seq((0,Vector(1, 2, 3, 4, 5)), (1, Vector(6, 7, 8, 9, 10))))
  }

  "splitBy should correctly work with unsorted groups" in {
    val l: Seq[Int] = 1 to 10
    val res = l.splitBy{x => x % 2}

    assert(res ===
      Seq(
        (1, Vector(1)),
        (0, Vector(2)),
        (1, Vector(3)),
        (0, Vector(4)),
        (1, Vector(5)),
        (0, Vector(6)),
        (1, Vector(7)),
        (0, Vector(8)),
        (1, Vector(9)),
        (0, Vector(10))
      )
    )
  }

} 
Example 22
Source File: GrpcServerModule.scala    From scala-server-toolkit   with MIT License 5 votes vote down vote up
package com.avast.sst.grpc.server

import java.util.concurrent.TimeUnit

import cats.effect.{Resource, Sync}
import io.grpc.{Server, ServerBuilder, ServerInterceptor, ServerServiceDefinition}

import scala.collection.immutable.Seq
import scala.concurrent.ExecutionContext

object GrpcServerModule {

  
  def make[F[_]: Sync](
      config: GrpcServerConfig,
      services: Seq[ServerServiceDefinition],
      executionContext: ExecutionContext,
      interceptors: Seq[ServerInterceptor] = List.empty
  ): Resource[F, Server] =
    Resource.make {
      Sync[F].delay {
        val builder = ServerBuilder
          .forPort(config.port)
          .handshakeTimeout(config.handshakeTimeout.toMillis, TimeUnit.MILLISECONDS)
          .maxInboundMessageSize(config.maxInboundMessageSize)
          .maxInboundMetadataSize(config.maxInboundMetadataSize)
          .executor(executionContext.execute)

        services.foreach(builder.addService)
        interceptors.foreach(builder.intercept)

        builder.build.start()
      }
    } { s =>
      Sync[F].delay {
        s.shutdown().awaitTermination(config.serverShutdownTimeout.toMillis, TimeUnit.MILLISECONDS)
        ()
      }
    }

} 
Example 23
Source File: SparkProductJoinerKitSpec.scala    From pipelines-examples   with Apache License 2.0 5 votes vote down vote up
package pipelines.example.warez

import scala.collection.immutable.Seq
import scala.concurrent.duration._

import pipelines.spark.testkit._
import pipelines.spark.sql.SQLImplicits._
import TestUtils._
import warez._

class SparkProductJoinerKitSpec extends SparkScalaTestSupport {

  val testKit = SparkStreamletTestkit(session)

  "SparkJoin3" should {
    "process streaming data" in {
      // create spark streamlet
      val join3 = new SparkProductJoiner()

      // setup inlet tap on inlet port
      val in0: SparkInletTap[Product] = testKit.inletAsTap[Product](join3.in0)
      val in1: SparkInletTap[StockUpdate] = testKit.inletAsTap[StockUpdate](join3.in1)
      val in2: SparkInletTap[PriceUpdate] = testKit.inletAsTap[PriceUpdate](join3.in2)

      // setup outlet tap on outlet port
      val out: SparkOutletTap[Product] = testKit.outletAsTap[Product](join3.out)

      val socksId = uuid
      val pantsId = uuid
      val socksSkus = genSkus()
      val pantsSkus = genSkus()
      val socks = Product(socksId, "Socks", "Warm in winter", Seq("clothing", "sock", "socks"), socksSkus)
      val pants = Product(pantsId, "Pants", "Denim for the masses", Seq("clothing", "pants"), pantsSkus)

      val stockUpdate = StockUpdate(socksId, socksSkus.head.id, 1)
      val priceUpdate = PriceUpdate(pantsId, pantsSkus.head.id, 100)

      // build data and send to inlet tap
      val data0 = List(socks, pants)
      in0.addData(data0)
      // try multiple updates
      val data1 = (1 to 100).map(_ ⇒ stockUpdate)
      in1.addData(data1)
      val data2 = List(priceUpdate)
      in2.addData(data2)

      testKit.run(join3, Seq(in0, in1, in2), Seq(out), 60.seconds)

      // get data from outlet tap
      val results = out.asCollection(session)

      results.foreach(println)

      // assert
      results must have length 2
      results.exists { p ⇒ p.name == "Socks" && p.skus.head.stock.contains(100) }
    }
  }
} 
Example 24
Source File: SparkProductOperationsSpec.scala    From pipelines-examples   with Apache License 2.0 5 votes vote down vote up
package pipelines.example.warez

import org.scalatest.{ Matchers, WordSpec }
import org.scalatest.OptionValues._

import scala.collection.immutable.Seq
import warez.{ PriceUpdate, Product, Sku, StockUpdate }

class SparkProductOperationsSpec extends WordSpec with Matchers {

  "A Product" should {
    "be updated correctly" in {
      val skus = Array(
        Sku("1", "Small Hole", Some(10), Some(5)),
        Sku("2", "Medium Hole", Some(10), Some(10)),
        Sku("3", "Large Hole", Some(15), Some(20))
      )
      val description = "A cartoon hole that can be applied to any surface."
      val keywords = Array("black", "hole", "gag", "plot device", "roger rabbit")

      val p = new Product(
        "123456789",
        "Acme Portable Hole",
        description,
        keywords,
        skus
      )

      val priceUpdate = PriceUpdate(
        "123456789",
        "1",
        10
      )
      val stockUpdate = StockUpdate(
        "123456789",
        "1",
        10
      )
      val zero = SparkProductJoiner.emptyProduct
      val p1 = SparkProductJoiner.updateProduct(zero, Seq(p).toIterator)
      p1 == p should equal(true)
      val prodPrice = SparkProductJoiner.priceUpdate2Products(priceUpdate)
      val p2 = SparkProductJoiner.updateProduct(p1, Seq(prodPrice).toIterator)
      p2.skus.find(_.id == "1").value.price should equal(Some(10))
      val prodStock = SparkProductJoiner.stockUpdate2Product(stockUpdate)
      val p3 = SparkProductJoiner.updateProduct(p2, Seq(prodStock).toIterator)
      p3.skus.find(_.id == "1").value.stock should equal(Some(20))
      // the same price update should cause no change here
      val p4 = SparkProductJoiner.updateProduct(p3, Seq(prodPrice).toIterator)
      p4.skus.find(_.id == "1").value.price should equal(Some(10))
      p4.skus.find(_.id == "1").value.stock should equal(Some(20))
      p4.description should be(description)
      p4.keywords should be(keywords)
    }
  }
} 
Example 25
Source File: SparkSequenceGeneratorIngressTest.scala    From pipelines-examples   with Apache License 2.0 5 votes vote down vote up
package pipelines.example

import scala.collection.immutable.Seq
import scala.concurrent.duration._

import pipelines.spark.testkit._
import pipelines.spark.sql.SQLImplicits._

class SparkSequenceGeneratorIngressTest extends SparkScalaTestSupport {

  val streamlet = new SparkSequenceGeneratorIngress()
  val testKit = SparkStreamletTestkit(session).withConfigParameterValues(ConfigParameterValue(streamlet.RecordsPerSecond, "50"))

  "SparkSequenceGeneratorIngress" should {
    "produce data " in {

      // setup inlet tap on inlet(s) port(s)
      val out: SparkOutletTap[Data] = testKit.outletAsTap[Data](streamlet.out)

      // Run the streamlet using the testkit and the setup inlet taps and outlet probes
      testKit.run(streamlet, Seq.empty, Seq(out), 10.seconds)

      // get data from outlet tap
      val results = out.asCollection(session)
      val ordered = results.map(data ⇒ data.value).sorted
      ordered.size mustBe >(SequenceSettings.RecordsPerSecond) // at least one second of data
      assert((ordered zip ordered.tail).forall { case (i, j) ⇒ j == (i + 1) }, "produced list missed elements")

    }
  }
} 
Example 26
Source File: JSDependencyManifest.scala    From jsdependencies   with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
package org.scalajs.jsdependencies.core

import scala.collection.immutable.{Seq, Traversable}

import java.io._
import java.nio.charset.StandardCharsets
import java.nio.file.{Path, Files}

import org.scalajs.jsdependencies.core.json._


final class JSDependencyManifest(
    val origin: Origin,
    val libDeps: List[JSDependency]) {

  import JSDependencyManifest._

  override def equals(that: Any): Boolean = that match {
    case that: JSDependencyManifest =>
      this.origin == that.origin &&
      this.libDeps == that.libDeps
    case _ =>
      false
  }

  override def hashCode(): Int = {
    import scala.util.hashing.MurmurHash3._
    var acc = HashSeed
    acc = mix(acc, origin.##)
    acc = mixLast(acc, libDeps.##)
    finalizeHash(acc, 2)
  }

  override def toString(): String = {
    val b = new StringBuilder
    b ++= s"JSDependencyManifest(origin=$origin"
    if (libDeps.nonEmpty)
      b ++= s", libDeps=$libDeps"
    b ++= ")"
    b.result()
  }
}

object JSDependencyManifest {

  // "org.scalajs.jsdependencies.core.JSDependencyManifest".##
  private final val HashSeed = -902988673

  final val ManifestFileName = "JS_DEPENDENCIES"

  implicit object JSDepManJSONSerializer extends JSONSerializer[JSDependencyManifest] {
    @inline def optList[T](x: List[T]): Option[List[T]] =
      if (x.nonEmpty) Some(x) else None

    def serialize(x: JSDependencyManifest): JSON = {
      new JSONObjBuilder()
        .fld("origin", x.origin)
        .opt("libDeps", optList(x.libDeps))
        .toJSON
    }
  }

  implicit object JSDepManJSONDeserializer extends JSONDeserializer[JSDependencyManifest] {
    def deserialize(x: JSON): JSDependencyManifest = {
      val obj = new JSONObjExtractor(x)
      new JSDependencyManifest(
          obj.fld[Origin]("origin"),
          obj.opt[List[JSDependency]]("libDeps").getOrElse(Nil))
    }
  }

  def write(dep: JSDependencyManifest, output: Path): Unit = {
    val writer = Files.newBufferedWriter(output, StandardCharsets.UTF_8)
    try {
      write(dep, writer)
    } finally {
      writer.close()
    }
  }

  def write(dep: JSDependencyManifest, writer: Writer): Unit =
    writeJSON(dep.toJSON, writer)

  def read(file: Path): JSDependencyManifest = {
    val reader = Files.newBufferedReader(file, StandardCharsets.UTF_8)
    try {
      read(reader)
    } finally {
      reader.close()
    }
  }

  def read(reader: Reader): JSDependencyManifest =
    fromJSON[JSDependencyManifest](readJSON(reader))

} 
Example 27
Source File: CommandArgs.scala    From reactive-cli   with Apache License 2.0 5 votes vote down vote up
package com.lightbend.rp.reactivecli.argparse

import scala.collection.immutable.Seq
import GenerateDeploymentArgs.{ DockerRegistryUseHttpsDefault, DockerRegistryValidateTlsDefault, DockerRegistryUseLocalDefault }


case class GenerateDeploymentArgs(
  application: Option[String] = None,
  akkaClusterJoinExisting: Boolean = false,
  akkaClusterSkipValidation: Boolean = false,
  deploymentType: DeploymentType = CanaryDeploymentType,
  discoveryMethod: DiscoveryMethod = DiscoveryMethod.KubernetesApi,
  dockerImages: Seq[String] = Seq.empty,
  name: Option[String] = None,
  version: Option[String] = None,
  environmentVariables: Map[String, String] = Map.empty,
  cpu: Option[Double] = None,
  memory: Option[Long] = None,
  diskSpace: Option[Long] = None,
  targetRuntimeArgs: Option[TargetRuntimeArgs] = None,
  registryUsername: Option[String] = None,
  registryPassword: Option[String] = None,
  registryUseHttps: Boolean = DockerRegistryUseHttpsDefault,
  registryValidateTls: Boolean = DockerRegistryValidateTlsDefault,
  registryUseLocal: Boolean = DockerRegistryUseLocalDefault,
  externalServices: Map[String, Seq[String]] = Map.empty) extends CommandArgs 
Example 28
Source File: MarathonArgs.scala    From reactive-cli   with Apache License 2.0 5 votes vote down vote up
package com.lightbend.rp.reactivecli.argparse.marathon

import com.lightbend.rp.reactivecli.argparse.{ GenerateDeploymentArgs, InputArgs, TargetRuntimeArgs }
import com.lightbend.rp.reactivecli.json.JsonTransformExpression
import java.io.PrintStream
import scala.collection.immutable.Seq

object MarathonArgs {
  object Output {
    
case class MarathonArgs(
  instances: Int = 1,
  marathonLbHaproxyGroup: String = "external",
  marathonLbHaproxyHosts: Seq[String] = Seq.empty,
  namespace: Option[String] = None,
  output: MarathonArgs.Output = MarathonArgs.Output.PipeToStream(System.out),
  registryForcePull: Boolean = false,
  transformOutput: Option[JsonTransformExpression] = None) extends TargetRuntimeArgs 
Example 29
Source File: PodControllerArgs.scala    From reactive-cli   with Apache License 2.0 5 votes vote down vote up
package com.lightbend.rp.reactivecli.argparse.kubernetes

import com.lightbend.rp.reactivecli.argparse.InputArgs
import com.lightbend.rp.reactivecli.runtime.kubernetes.PodTemplate
import scala.collection.immutable.Seq
import scala.concurrent.Future

object PodControllerArgs {
  sealed trait ControllerType {
    def arg: String
  }

  object ControllerType {
    case object Deployment extends ControllerType {
      val arg: String = "deployment"
    }

    case object Job extends ControllerType {
      val arg: String = "job"
    }

    val All: Seq[ControllerType] = Seq(Deployment, Job)
    val Default: ControllerType = Deployment
  }

  
case class PodControllerArgs(
  appsApiVersion: Future[String] = KubernetesArgs.DefaultAppsApiVersion,
  batchApiVersion: Future[String] = KubernetesArgs.DefaultBatchApiVersion,
  controllerType: PodControllerArgs.ControllerType = PodControllerArgs.ControllerType.Deployment,
  numberOfReplicas: Int = KubernetesArgs.DefaultNumberOfReplicas,
  imagePullPolicy: PodTemplate.ImagePullPolicy.Value = KubernetesArgs.DefaultImagePullPolicy,
  restartPolicy: PodTemplate.RestartPolicy.Value = PodTemplate.RestartPolicy.Default) 
Example 30
Source File: kubectl.scala    From reactive-cli   with Apache License 2.0 5 votes vote down vote up
package com.lightbend.rp.reactivecli.process

import com.lightbend.rp.reactivecli.concurrent._
import scala.collection.immutable.Seq
import scala.concurrent.Future
import slogging._

object kubectl extends LazyLogging {
  lazy val apiVersions: Future[Seq[String]] =
    for {
      (code, output) <- exec("kubectl", "api-versions", "--request-timeout=1s")
    } yield {
      if (code == 0) {
        output
          .replaceAllLiterally("\r\n", "\n")
          .split('\n')
          .map(_.trim)
          .filter(_.nonEmpty)
          .toVector
      } else {
        logger.debug(s"kubectl version exited with $code")

        Seq.empty
      }
    }

  def findApi(preferred: String, other: String*): Future[String] = {
    apiVersions.map { versions =>
      (preferred +: other)
        .find(versions.contains)
        .getOrElse(preferred)
    }
  }
} 
Example 31
Source File: Ingress.scala    From reactive-cli   with Apache License 2.0 5 votes vote down vote up
package com.lightbend.rp.reactivecli.runtime.kubernetes

import argonaut._
import com.lightbend.rp.reactivecli.annotations._
import com.lightbend.rp.reactivecli.json.{ JsonTransform, JsonTransformExpression }
import com.lightbend.rp.reactivecli.runtime._
import scala.collection.immutable.Seq
import scalaz._
import Argonaut._
import Scalaz._

object Ingress {
  case class EncodedEndpoint(serviceName: String, servicePort: Int, paths: Seq[String], host: Option[String])

  def encodeEndpoints(
    appName: String,
    endpoints: Map[String, Endpoint],
    pathAppend: Option[String],
    hostsOverride: Option[Seq[String]]): List[EncodedEndpoint] = {

    val ports = AssignedPort.assignPorts(endpoints)

    val httpEndpoints =
      endpoints
        .collect {
          case (_, httpEndpoint: HttpEndpoint) => httpEndpoint
        }
        .toList

    val append = pathAppend.getOrElse("")

    for {
      endpoint <- httpEndpoints
      port <- ports.find(_.endpoint == endpoint).toVector
      ingress <- endpoint.ingress
      host <- hostsOverride.getOrElse(if (ingress.hosts.isEmpty) Seq("") else ingress.hosts)
      paths = if (ingress.paths.isEmpty) Seq("") else ingress.paths
    } yield {
      val pathEntries =
        for {
          path <- paths
        } yield if (path.isEmpty)
          ""
        else
          path + (if (path.endsWith("/") && append.startsWith("/")) append.drop(1) else append)

      EncodedEndpoint(appName, port.port, pathEntries, if (host.isEmpty) None else Some(host))
    }
  }

  def renderEndpoints(endpoints: Seq[EncodedEndpoint]): Json = {
    case class Path(serviceName: String, servicePort: Int, path: String) {
      def depthAndLength: (Int, Int) = pathDepthAndLength(path)
    }

    val byHost =
      endpoints
        .groupBy(_.host)
        .toVector
        .sortBy(_._1)
        .map {
          case (host, endpoints) =>
            val paths =
              endpoints
                .foldLeft(Seq.empty[Path]) {
                  case (ac, e) =>
                    ac ++ e.paths.map(p => Path(e.serviceName, e.servicePort, p))
                }
                .distinct
                .sortBy(_.depthAndLength)
                .reverse

            host -> paths
        }

    jArray(
      byHost.toList.map {
        case (host, paths) =>
          host
            .fold(jEmptyObject)(h => jObjectFields("host" -> jString(h)))
            .deepmerge(
              jObjectFields("http" ->
                jObjectFields(
                  "paths" -> jArray(
                    paths.toList.map(p =>
                      (if (p.path.nonEmpty) jObjectFields("path" -> jString(p.path)) else jEmptyObject)
                        .deepmerge(
                          jObjectFields(
                            "backend" -> jObjectFields(
                              "serviceName" -> jString(p.serviceName),
                              "servicePort" -> jNumber(p.servicePort)))))))))
      })
  }

  
case class Ingress(name: String, endpoints: List[Ingress.EncodedEndpoint], json: Json, jsonTransform: JsonTransform) extends GeneratedKubernetesResource {
  val resourceType = "ingress"
} 
Example 32
Source File: DockerCredentialsTest.scala    From reactive-cli   with Apache License 2.0 5 votes vote down vote up
package com.lightbend.rp.reactivecli.docker
import scala.collection.immutable.Seq
import utest._

object DockerCredentialsTest extends TestSuite {
  val tests = this{
    "Parse Credentials" - {
      val result = DockerCredentials.decodeCreds(
        """|registry = lightbend-docker-registry.bintray.io
           |username=hello
           |password =      there
           |
           |reg=what
           |
           |registry= registry.hub.docker.com
           |password = bar
           |username    = foo
           |
           |registry= 1.hub.docker.com
           |password = what
           |registry = 2.hub.docker.com
           |username = ok
           |""".stripMargin)

      val expected = Seq(
        DockerCredentials("lightbend-docker-registry.bintray.io", Right("hello", "there")),
        DockerCredentials("registry.hub.docker.com", Right("foo", "bar")),
        DockerCredentials("2.hub.docker.com", Right("ok", "what")))

      assert(result == expected)
    }
    "Parse Docker Config" - {
      val resultEmpty = DockerCredentials.decodeConfig("""{"auths": {} }""")
      val result = DockerCredentials.decodeConfig(
        """
          |{
          |   "auths": {
          |       "https://index.docker.io/v1/": {
          |         "auth": "0123abcdef="
          |       },
          |       "lightbend-docker-registry.bintray.io": {
          |         "auth": "xzyw="
          |       }
          |   }
          |}
        """.stripMargin)

      val expected = Seq(
        DockerCredentials("https://index.docker.io/v1/", Left("0123abcdef=")),
        DockerCredentials("lightbend-docker-registry.bintray.io", Left("xzyw=")))

      assert(resultEmpty == Seq.empty)
      assert(result == expected)
    }
  }
} 
Example 33
Source File: NamespaceJsonTest.scala    From reactive-cli   with Apache License 2.0 5 votes vote down vote up
package com.lightbend.rp.reactivecli.runtime.kubernetes

import argonaut._
import scala.collection.immutable.Seq
import com.lightbend.rp.reactivecli.annotations.Annotations
import com.lightbend.rp.reactivecli.concurrent._
import com.lightbend.rp.reactivecli.json.{ JsonTransform, JsonTransformExpression }
import com.lightbend.rp.reactivecli.process.jq
import utest._

import Argonaut._

object NamespaceJsonTest extends TestSuite {

  val tests = this{
    "json serialization" - {
      val annotations = Annotations(
        namespace = None,
        applications = Vector.empty,
        appName = None,
        appType = None,
        configResource = None,
        diskSpace = None,
        memory = None,
        cpu = None,
        endpoints = Map.empty,
        managementEndpointName = None,
        remotingEndpointName = None,
        secrets = Seq.empty,
        privileged = false,
        environmentVariables = Map.empty,
        version = None,
        modules = Set.empty,
        akkaClusterBootstrapSystemName = None)

      "namespace present" - {
        val result = Namespace.generate(annotations.copy(namespace = Some("chirper")), "v1", JsonTransform.noop)

        assert(result.isSuccess)

        val expectedJson =
          """
            |{
            |  "apiVersion": "v1",
            |  "kind": "Namespace",
            |  "metadata": {
            |    "name": "chirper",
            |    "labels": {
            |      "name": "chirper"
            |    }
            |  }
            |}
          """.stripMargin.parse.right.get
        assert(result.toOption.get.get == Namespace("chirper", expectedJson, JsonTransform.noop))
      }

      "namespace not present" - {
        val result = Namespace.generate(annotations.copy(namespace = None), "v1", JsonTransform.noop)

        assert(result.isSuccess)
        assert(result.toOption.get.isEmpty)
      }

      "jq works" - {
        val result = Namespace.generate(annotations.copy(namespace = Some("chirper")), "v1", JsonTransform.jq(JsonTransformExpression(".jq=\"testing\"")))

        assert(result.isSuccess)

        val expectedJson =
          """
            |{
            |  "apiVersion": "v1",
            |  "kind": "Namespace",
            |  "metadata": {
            |    "name": "chirper",
            |    "labels": {
            |      "name": "chirper"
            |    }
            |  },
            |  "jq": "testing"
            |}
          """.stripMargin.parse.right.get

        result.toOption.get.get.payload.map { generatedJson =>
          assert(expectedJson == generatedJson)
        }
      }
    }
  }
} 
Example 34
Source File: GraphQLRequestUnmarshaller.scala    From graphql-gateway   with Apache License 2.0 5 votes vote down vote up
package sangria.gateway.http

import java.nio.charset.Charset

import akka.http.scaladsl.marshalling.{Marshaller, ToEntityMarshaller}
import akka.http.scaladsl.model._
import akka.http.scaladsl.model.headers.Accept
import akka.http.scaladsl.server.Directive0
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.unmarshalling.{FromEntityUnmarshaller, Unmarshaller}
import akka.util.ByteString
import sangria.ast.Document
import sangria.parser.QueryParser
import sangria.renderer.{QueryRenderer, QueryRendererConfig}

import scala.collection.immutable.Seq

object GraphQLRequestUnmarshaller {
  val `application/graphql` = MediaType.applicationWithFixedCharset("graphql", HttpCharsets.`UTF-8`, "graphql")

  def explicitlyAccepts(mediaType: MediaType): Directive0 =
    headerValuePF {
      case Accept(ranges) if ranges.exists(range ⇒ !range.isWildcard && range.matches(mediaType)) ⇒ ranges
    }.flatMap(_ ⇒ pass)

  def includeIf(include: Boolean): Directive0 =
    if (include) pass
    else reject

  def unmarshallerContentTypes: Seq[ContentTypeRange] =
    mediaTypes.map(ContentTypeRange.apply)

  def mediaTypes: Seq[MediaType.WithFixedCharset] =
    List(`application/graphql`)

  implicit final def documentMarshaller(implicit config: QueryRendererConfig = QueryRenderer.Compact): ToEntityMarshaller[Document] =
    Marshaller.oneOf(mediaTypes: _*) { mediaType ⇒
      Marshaller.withFixedContentType(ContentType(mediaType)) { json ⇒
        HttpEntity(mediaType, QueryRenderer.render(json, config))
      }
    }

  
  implicit final val documentUnmarshaller: FromEntityUnmarshaller[Document] =
    Unmarshaller.byteStringUnmarshaller
      .forContentTypes(unmarshallerContentTypes: _*)
      .map {
        case ByteString.empty ⇒ throw Unmarshaller.NoContentException
        case data ⇒
          import sangria.parser.DeliveryScheme.Throw

          QueryParser.parse(data.decodeString(Charset.forName("UTF-8")))
      }
} 
Example 35
Source File: AlienExchangeImpl.scala    From c4proto   with Apache License 2.0 5 votes vote down vote up
package ee.cone.c4ui

import java.net.URL
import java.util.UUID

import ee.cone.c4actor_branch.BranchTypes.BranchKey
import ee.cone.c4actor.LEvent.{delete, update}
import ee.cone.c4actor.Types.SrcId
import ee.cone.c4actor._
import ee.cone.c4actor_branch._
import ee.cone.c4assemble.Types.{Each, Values}
import ee.cone.c4assemble.{Assemble, assemble, c4assemble}
import ee.cone.c4gate.AlienProtocol.{U_FromAlienState, U_ToAlienWrite}
import ee.cone.c4gate.HttpProtocol.S_HttpRequest
import ee.cone.c4gate.LocalHttpConsumer
import ee.cone.c4di.c4
import okio.ByteString

import scala.collection.immutable.Seq

case object ToAlienPriorityKey extends TransientLens[java.lang.Long](0L)

@c4("AlienExchangeCompApp") final class ToAlienSenderImpl(
  txAdd: LTxAdd,
) extends ToAlienSender {
  def send(sessionKeys: Seq[String], evType: String, data: String): Context => Context = local => if(sessionKeys.isEmpty) local else {
    val priority = ToAlienPriorityKey.of(local)
    val messages = sessionKeys.zipWithIndex.flatMap{
      case (sessionKey,i) =>
        val id = UUID.randomUUID.toString
        update(U_ToAlienWrite(id,sessionKey,evType,data,priority+i))
    }
    //println(s"messages: $messages")
    ToAlienPriorityKey.modify(_+sessionKeys.size).andThen(txAdd.add(messages))(local)
  }
}

case class MessageFromAlienImpl(
  srcId: String,
  headers: Map[String,String],
  request: S_HttpRequest
) extends BranchMessage {
  def method: String = request.method match { case "" => "POST" case m => m }
  def header: String => String = k => headers.getOrElse(k,"")
  def body: ByteString = request.body
  def deletes: Seq[LEvent[Product]] = delete(request)
}

@c4assemble("AlienExchangeCompApp") class MessageFromAlienAssembleBase   {
  def mapHttpReqByBranch(
    key: SrcId,
    req: Each[S_HttpRequest]
  ): Values[(BranchKey, BranchMessage)] = if(req.path != "/connection") Nil else for(
    headers <- List(req.headers.flatMap(h =>
      if(h.key.startsWith("x-r-")) List(h.key->h.value) else Nil
    ).toMap);
    branchKey <- headers.get("x-r-branch");
    index <- headers.get("x-r-index").map(_.toLong)
  ) yield branchKey -> MessageFromAlienImpl(req.srcId,headers,req)


  def consumersForHandlers(
    key: SrcId,
    h: Each[BranchHandler]
  ): Values[(SrcId,LocalHttpConsumer)] =
    List(WithPK(LocalHttpConsumer(h.branchKey)))

}

@c4assemble("AlienExchangeCompApp") class FromAlienBranchAssembleBase(operations: BranchOperations)   {
  // more rich session may be joined
  def fromAliensToSeeds(
    key: SrcId,
    fromAlien: Each[U_FromAlienState]
  ): Values[(BranchKey, BranchRel)] = {
    val child = operations.toSeed(fromAlien)
    List(operations.toRel(child, fromAlien.sessionKey, parentIsSession = true))
  }
}

@assemble class FromAlienTaskAssembleBase(file: String) {
  def mapBranchTaskByLocationHash(
    key: SrcId,
    task: Each[BranchTask]
  ): Values[(SrcId, FromAlienTask)] =
    for (
      fromAlien <- List(task.product).collect { case s: U_FromAlienState => s };
      url <- Option(new URL(fromAlien.location))
        if  url.getFile == file || url.getPath == file
    ) yield task.branchKey -> FromAlienTask(
      task.branchKey,
      task,
      fromAlien,
      Option(url.getQuery).getOrElse(""),
      Option(url.getRef).getOrElse("")
    )
} 
Example 36
Source File: IndexUpdaterImpl.scala    From c4proto   with Apache License 2.0 5 votes vote down vote up
package ee.cone.c4assemble

import ee.cone.c4assemble.Types.{DMap, Index, emptyIndex}
import ee.cone.c4di.c4

import scala.collection.immutable.Seq
import scala.concurrent.{ExecutionContext, Future}

@c4("AssembleApp") final class IndexUpdaterImpl(readModelUtil: ReadModelUtil) extends IndexUpdater {
  def setPart(worldKeys: Seq[AssembledKey], update: Future[IndexUpdates], logTask: Boolean): WorldTransition=>WorldTransition = transition => {
    implicit val ec: ExecutionContext = transition.executionContext.value
    val diff = readModelUtil.updated(worldKeys,update.map(_.diffs))(ec)(transition.diff)
    val next = readModelUtil.updated(worldKeys,update.map(_.results))(ec)(transition.result)
    val log = for {
      log <- transition.log
      u <- update
    } yield u.log ::: log
    val nTaskLog = if(logTask) worldKeys.toList ::: transition.taskLog else transition.taskLog
    transition.copy(diff=diff,result=next,log=log,taskLog=nTaskLog)
  }
}

@c4("AssembleApp") final class ReadModelUtilImpl(indexUtil: IndexUtil) extends ReadModelUtil {
  def create(inner: MMap): ReadModel =
    new ReadModelImpl(inner)
  def updated(worldKeys: Seq[AssembledKey], values: Future[Seq[Index]])(implicit ec: ExecutionContext): ReadModel=>ReadModel = {
    case from: ReadModelImpl =>
      val cValues = values.map{l=>assert(l.size==worldKeys.size);l}
      new ReadModelImpl(from.inner ++ worldKeys.zipWithIndex.map{ case (k,i) => k -> cValues.map(_(i)) })
  }

  def isEmpty(implicit executionContext: ExecutionContext): ReadModel=>Future[Boolean] = {
    case model: ReadModelImpl =>
      Future.sequence(model.inner.values).map(_.forall(indexUtil.isEmpty))
  }
  def op(op: (MMap,MMap)=>MMap): (ReadModel,ReadModel)=>ReadModel = Function.untupled({
    case (a: ReadModelImpl, b: ReadModelImpl) => new ReadModelImpl(op(a.inner,b.inner))
    case (_,_) =>  throw new Exception("ReadModel op")
  })
  def toMap: ReadModel=>Map[AssembledKey,Index] = {
    case model: ReadModelImpl => model.inner.transform((k,f) => indexUtil.getInstantly(f)) // .getOrElse(throw new Exception(s"index failure: $k"))
  }
  def ready(implicit executionContext: ExecutionContext): ReadModel=>Future[ReadModel] = {
    case model: ReadModelImpl =>
      for {
        ready <- Future.sequence(model.inner.values)
      } yield model
  }
}

class ReadModelImpl(val inner: DMap[AssembledKey,Future[Index]]) extends ReadModel {
  def getFuture(key: AssembledKey): Option[Future[Index]] = inner.get(key)
} 
Example 37
Source File: AssembleSeqOptimizerImpl.scala    From c4proto   with Apache License 2.0 5 votes vote down vote up
package ee.cone.c4assemble

import ee.cone.c4assemble.Types._
import ee.cone.c4di.{c4, c4multi}

import scala.annotation.tailrec
import scala.collection.immutable.{Map, Seq}
import scala.concurrent.{ExecutionContext, Future}

@c4multi("AssembleApp") final class LoopExpression[MapKey, Value](
  outputWorldKeys: Seq[AssembledKey],
  loopOutputIndex: Int,
  wasOutputWorldKey: AssembledKey,
  main: WorldPartExpression, // with DataDependencyTo[Index[MapKey, Value]],
  continue: List[WorldPartExpression],
)(
  updater: IndexUpdater,
  composes: IndexUtil,
  //val outputWorldKey: AssembledKey[Index[MapKey, Value]] = main.outputWorldKey,
  continueF: WorldTransition=>WorldTransition = Function.chain(continue.map(h=>h.transform(_)))
) extends WorldPartExpression {
  private def inner(
    left: Int,
    transition: WorldTransition,
    wasSumDiffs: Option[Seq[Index]], //do not inclide transition.diff-s
  ): Future[(IndexUpdates,IndexUpdates)] = {
    implicit val executionContext: ExecutionContext = transition.executionContext.value
    for {
      diffParts <- Future.sequence(outputWorldKeys.map(_.of(transition.diff)))
      sumDiffs = wasSumDiffs.fold(diffParts)(composes.zipMergeIndex(diffParts))
      res <- if(composes.isEmpty(diffParts(loopOutputIndex))){
        for {
          results <- Future.sequence(outputWorldKeys.map(_.of(transition.result)))
        } yield (
          new IndexUpdates(sumDiffs, results, Nil),
          new IndexUpdates(Seq(emptyIndex),Seq(results(loopOutputIndex)),Nil)
        )
      } else {
        assert(left > 0, s"unstable local assemble $diffParts")
        inner(left - 1, main.transform(continueF(transition)), Option(sumDiffs))
      }
    } yield res
  }
  def transform(transition: WorldTransition): WorldTransition = {
    val transitionA = main.transform(transition)
    if(transition eq transitionA) transition
    else finishTransform(transition, inner(1000, transitionA, None))
  }
  def finishTransform(transition: WorldTransition, next: Future[(IndexUpdates,IndexUpdates)]): WorldTransition = {
    implicit val executionContext: ExecutionContext = transition.executionContext.value
    Function.chain(Seq(
      updater.setPart(outputWorldKeys,next.map(_._1),logTask = true),
      updater.setPart(Seq(wasOutputWorldKey),next.map(_._2),logTask = false)
    ))(transition)
  }
}

@c4("AssembleApp") final class ShortAssembleSeqOptimizer(
  backStageFactory: BackStageFactory,
  loopExpressionFactory: LoopExpressionFactory
) extends AssembleSeqOptimizer {
  private def getSingleKeys[K]: Seq[K] => Set[K] = _.groupBy(i=>i).collect{ case (k,Seq(_)) => k }.toSet
  def optimize: List[Expr]=>List[WorldPartExpression] = expressionsByPriority => {
    val singleOutputKeys: Set[AssembledKey] = getSingleKeys(expressionsByPriority.flatMap(_.outputWorldKeys))
    val singleInputKeys = getSingleKeys(expressionsByPriority.flatMap(_.inputWorldKeys))
    expressionsByPriority.map{ e =>
      Single.option(e.outputWorldKeys.map{ case k:JoinKey => k }.zipWithIndex.flatMap{ case (key,i) =>
        val wKey = key.withWas(was=true)
        if(
          singleOutputKeys(key) && singleInputKeys(wKey) &&
            e.inputWorldKeys.contains(wKey)
        ) loopExpressionFactory.create[Any,Any](
          e.outputWorldKeys, i, wKey, e, backStageFactory.create(List(e))
        ) :: Nil
        else Nil
      }).getOrElse(e)
    }
  }
}

class NoAssembleSeqOptimizer() extends AssembleSeqOptimizer {
  def optimize: List[Expr]=>List[WorldPartExpression] = l=>l
} 
Example 38
Source File: AssemblerApi.scala    From c4proto   with Apache License 2.0 5 votes vote down vote up
package ee.cone.c4assemble

import ee.cone.c4assemble.Types._

import scala.collection.immutable.Seq
import scala.concurrent.Future

object Single {
  def apply[C](l: Seq[C]): C =
    if(l.nonEmpty && l.tail.isEmpty) l.head else throw defException(l)
  def apply[C](l: Seq[C], exception: Seq[C]=>Exception): C =
    if(l.nonEmpty && l.tail.isEmpty) l.head else throw exception(l)
  def option[C](l: Seq[C]): Option[C] = if(l.isEmpty) None else Option(apply(l))
  private def defException[C]: Seq[C]=>Exception = l => new Exception(
    if(l.isEmpty) "empty" else s"non-single: \n${l.head}, \n${l.tail.head} ..."
  )
}

object ToPrimaryKey {
  def apply(node: Product): String =
    if(node.productArity > 0) node.productElement(0) match {
      case s: String => s
      case p: Product => ToPrimaryKey(p)
      case _ => throw new Exception(s"1st field of ${node.getClass.getName} should be primary key")
    } else ""
}

trait WorldPartRule

class OriginalWorldPart[A<:Object](val outputWorldKeys: Seq[AssembledKey]) extends WorldPartRule with DataDependencyTo[A]

trait Replace {
  def active: List[WorldPartRule]
  def replace(
    prevWorld: ReadModel, diff: ReadModel, profiler: JoiningProfiling,
    executionContext: OuterExecutionContext
  ): Future[WorldTransition]
}

trait TreeAssembler {
  def create(rules: List[WorldPartRule], isTarget: WorldPartRule=>Boolean): Replace
}

trait ByPriority {
  def byPriority[K,V](uses: K=>(List[K],List[V]=>V)): List[K] => List[V]
}

////
// moment -> mod/index -> key/srcId -> value -> count

class IndexUpdates(val diffs: Seq[Index], val results: Seq[Index], val log: ProfilingLog)

trait IndexUpdater {
  def setPart(worldKeys: Seq[AssembledKey], update: Future[IndexUpdates], logTask: Boolean): WorldTransition=>WorldTransition
  //def setPart(worldKey: AssembledKey, update: Future[IndexUpdate], logTask: Boolean): WorldTransition=>WorldTransition
}

trait AssembleSeqOptimizer {
  type Expr = WorldPartExpression with DataDependencyFrom[_] with DataDependencyTo[_]
  def optimize: List[Expr]=>List[WorldPartExpression]
}

trait BackStageFactory {
  def create(l: List[DataDependencyFrom[_]]): List[WorldPartExpression]
}

trait AssembleDataDependencyFactory {
  def create(assembles: List[Assemble]): List[WorldPartRule]
} 
Example 39
Source File: BranchApi.scala    From c4proto   with Apache License 2.0 5 votes vote down vote up
package ee.cone.c4actor_branch

import ee.cone.c4actor.ArgTypes.LazyList
import ee.cone.c4actor._

import scala.collection.immutable.Seq
import ee.cone.c4actor_branch.BranchProtocol.S_BranchResult
import ee.cone.c4actor.Types.SrcId
import ee.cone.c4proto._

object BranchTypes {
  type BranchKey = SrcId
}

trait BranchMessage extends Product {
  def method: String
  def header: String=>String
  def body: okio.ByteString
  def deletes: Seq[LEvent[Product]]
}

trait BranchHandler extends Product {
  def branchKey: SrcId
  def exchange: BranchMessage => Context => Context
  def seeds: Context => List[S_BranchResult]
}

trait BranchTask extends Product {
  def branchKey: SrcId
  def product: Product
  def sessionKeys: Context => Set[BranchRel]
  type Send = Option[(String,String) => Context => Context]
  def sending: Context => (Send,Send)
  def relocate(to: String): Context => Context
}

trait BranchOperations {
  def toSeed(value: Product): S_BranchResult
  def toRel(seed: S_BranchResult, parentSrcId: SrcId, parentIsSession: Boolean): (SrcId,BranchRel)
}

case class BranchRel(srcId: SrcId, seed: S_BranchResult, parentSrcId: SrcId, parentIsSession: Boolean)



@protocol("BranchApp") object BranchProtocol   {
  @Id(0x0040) case class S_BranchResult(
    @Id(0x0041) hash: String,
    @Id(0x0042) valueTypeId: Long,
    @Id(0x0043) value: okio.ByteString,
    @Id(0x0044) children: LazyList[S_BranchResult],
    @Id(0x0045) position: String
  )

    @Id(0x0046) case class U_SessionFailure(
    @Id(0x0047) srcId: String,
    @Id(0x0048) text: String,
    @Id(0x0049) time: Long,
    @Id(0x004A) sessionKeys: List[String]
    //retry: List[S_HttpRequest]
  )

  @Id(0x004B) case class U_Redraw(
    @Id(0x004C) srcId: String,
    @Id(0x004D) branchKey: String
  )
}

trait ToAlienSender {
  def send(sessionKeys: Seq[String], evType: String, data: String): Context=>Context
}

trait BranchError {
  def message: String
} 
Example 40
Source File: KafkaLatTestApp.scala    From c4proto   with Apache License 2.0 5 votes vote down vote up
package ee.cone.c4gate

import com.typesafe.scalalogging.LazyLogging
import ee.cone.c4actor.{RawQSender, _}
import ee.cone.c4assemble.Single
import ee.cone.c4di.c4

import scala.annotation.tailrec
import scala.collection.immutable.Seq


class TestQRecordImpl(val topic: TopicName, val value: Array[Byte], val headers: Seq[RawHeader]) extends QRecord
@c4("KafkaLatTestApp") final class TestRootProducerImpl(rawQSender: RawQSender, toUpdate: ToUpdate) extends Executable with LazyLogging {
  def run(): Unit = {
    iteration()
  }
  @tailrec private def iteration(): Unit = {
    val updates = Nil //LEvent.update(S_Firstborn(actorName,offset)).toList.map(toUpdate.toUpdate)
    val (bytes, headers) = toUpdate.toBytes(updates)
    val offset = Single(rawQSender.send(List(new TestQRecordImpl(InboxTopicName(),bytes,headers))))
    logger.info(s"pushed $offset")
    Thread.sleep(1000)
    iteration()
  }
}


@c4("KafkaLatTestApp") final class TestRootConsumerImpl(consuming: Consuming) extends Executable with LazyLogging {
  def run(): Unit = {
    consuming.process("0" * OffsetHexSize(), consumer => iteration(consumer))
  }
  @tailrec private def iteration(consumer: Consumer): Unit = {
    val events = consumer.poll()
    logger.info(s"poll-ed ${events.size}")
    iteration(consumer)
  }
} 
Example 41
Source File: SnapshotPutImpl.scala    From c4proto   with Apache License 2.0 5 votes vote down vote up
package ee.cone.c4gate_server

import com.typesafe.scalalogging.LazyLogging
import ee.cone.c4actor.QProtocol.S_Firstborn
import ee.cone.c4actor._
import ee.cone.c4actor.Types.SrcId
import ee.cone.c4assemble.Types.{Each, Values}
import ee.cone.c4assemble.{assemble, by, c4assemble}
import ee.cone.c4gate.HttpProtocol.{N_Header, S_HttpRequest}
import ee.cone.c4di.c4
import ee.cone.c4gate._
import okio.ByteString

import scala.collection.immutable.Seq

class MemRawSnapshotLoader(relativePath: String, bytes: ByteString) extends RawSnapshotLoader {
  def load(snapshot: RawSnapshot): ByteString = {
    assert(snapshot.relativePath==relativePath)
    bytes
  }
}

@c4("SnapshotPutApp") final class SnapshotPutter(
  snapshotLoaderFactory: SnapshotLoaderFactory,
  snapshotDiffer: SnapshotDiffer
) extends LazyLogging {
  val url = "/put-snapshot"
  def merge(relativePath: String, data: ByteString): Context=>Context = local => {
    val rawSnapshotLoader = new MemRawSnapshotLoader(relativePath,data)
    val snapshotLoader = snapshotLoaderFactory.create(rawSnapshotLoader)
    val Some(targetFullSnapshot) = snapshotLoader.load(RawSnapshot(relativePath))
    val currentSnapshot = snapshotDiffer.needCurrentSnapshot(local)
    val diffUpdates = snapshotDiffer.diff(currentSnapshot,targetFullSnapshot)
    logger.info(s"put-snapshot activated, ${diffUpdates.size} updates")
    WriteModelKey.modify(_.enqueueAll(diffUpdates))(local)
  }
}

case class SnapshotPutTx(srcId: SrcId, requests: List[S_HttpRequest])(
  putter: SnapshotPutter, signatureChecker: Signer[List[String]], signedPostUtil: SignedReqUtil
) extends TxTransform {
  import signedPostUtil._
  def transform(local: Context): Context = catchNonFatal {
    val request = requests.head
    assert(request.method == "POST")
    val Some(Seq(putter.`url`,relativePath)) =
      signatureChecker.retrieve(check=true)(signed(request.headers))
    Function.chain(Seq(
      putter.merge(relativePath, request.body),
      respond(List(request->Nil),requests.tail.map(_->"Ignored"))
    ))(local)
  }("put-snapshot"){ e =>
    respond(Nil,List(requests.head -> e.getMessage))(local)
  }
}

@c4assemble("SnapshotPutApp") class SnapshotPutAssembleBase(putter: SnapshotPutter, signatureChecker: SimpleSigner, signedPostUtil: SignedReqUtil) {
  type PuttingId = SrcId

  def needConsumer(
    key: SrcId,
    first: Each[S_Firstborn]
  ): Values[(SrcId,LocalHttpConsumer)] =
    List(WithPK(LocalHttpConsumer(putter.url)))

  def mapAll(
    key: SrcId,
    req: Each[S_HttpRequest]
  ): Values[(PuttingId,S_HttpRequest)] =
    if(req.path == putter.url) List("snapshotPut"->req) else Nil

  def mapTx(
    key: SrcId,
    @by[PuttingId] requests: Values[S_HttpRequest]
  ): Values[(SrcId,TxTransform)] =
    List(WithPK(SnapshotPutTx(key,requests.toList.sortBy(_.srcId))(putter,signatureChecker,signedPostUtil)))
}

// how to know if post failed? 
Example 42
Source File: ContextMarker.scala    From tofu   with Apache License 2.0 5 votes vote down vote up
package tofu.logging
package impl

import java.util

import org.slf4j.Marker

import scala.collection.immutable.{List, Seq}

final case class ContextMarker(ctx: LoggedValue, referenceList: Seq[Marker] = List.empty) extends Marker {
  import scala.jdk.CollectionConverters._

  override def getName: String                    = "Context"
  override def add(reference: Marker): Unit = {}
  override def remove(reference: Marker): Boolean = false
  override def hasChildren: Boolean               = referenceList.nonEmpty
  override def hasReferences: Boolean             = referenceList.nonEmpty
  override def iterator(): util.Iterator[Marker]  = referenceList.iterator.asJava
  override def contains(other: Marker): Boolean   = referenceList.contains(other)
  override def contains(name: String): Boolean    = referenceList.map(_.getName).contains(name)

  def +(marker: Marker)         = copy(ctx, marker +: referenceList)
  def addMarker(marker: Marker) = this + marker
} 
Example 43
Source File: AssemblerProfiler.scala    From c4proto   with Apache License 2.0 5 votes vote down vote up
package ee.cone.c4actor

import java.util.UUID

import com.typesafe.scalalogging.LazyLogging
import ee.cone.c4actor.NoJoiningProfiling.Res
import ee.cone.c4actor.QProtocol.{N_TxRef, N_Update}
import ee.cone.c4actor.SimpleAssembleProfilerProtocol.{D_LogEntry, D_TxAddMeta}
import ee.cone.c4assemble.Types.DPIterable
import ee.cone.c4assemble._
import ee.cone.c4assemble.Types._
import ee.cone.c4di.{c4, provide}
import ee.cone.c4proto.{Id, protocol}

import scala.collection.immutable.Seq
import scala.concurrent.{ExecutionContext, Future}

@c4("NoAssembleProfilerCompApp") final class NoAssembleProfilerProvider {
  @provide def get: Seq[AssembleProfiler] = List(NoAssembleProfiler)
}

case object NoAssembleProfiler extends AssembleProfiler {
  def createJoiningProfiling(localOpt: Option[Context]): JoiningProfiling =
    NoJoiningProfiling
  def addMeta(transition: WorldTransition, updates: Seq[N_Update]): Future[Seq[N_Update]] =
    Future.successful(updates)
}

case object NoJoiningProfiling extends JoiningProfiling {
  def time: Long = 0L
  def handle(join: Join, result: Seq[AggrDOut], wasLog: ProfilingLog): ProfilingLog = wasLog
  def handle(join: Join, stage: Res, start: Res, wasLog: ProfilingLog): ProfilingLog = wasLog
}

////

@protocol("SimpleAssembleProfilerCompApp") object SimpleAssembleProfilerProtocol   {
  @Id(0x0073) case class D_TxAddMeta(
    @Id(0x0074) srcId: String,
    @Id(0x0075) startedAt: Long,
    @Id(0x0076) finishedAt: Long,
    @Id(0x0077) log: List[D_LogEntry],
    @Id(0x007B) updObjCount: Long,
    @Id(0x007C) updByteCount: Long,
    @Id(0x007D) updValueTypeIds: List[Long]
  )
  @Id(0x0078) case class D_LogEntry(
    @Id(0x0079) name: String,
    @Id(0x007E) stage: Long,
    @Id(0x007A) value: Long
  )
}

@c4("SimpleAssembleProfilerCompApp") final case class SimpleAssembleProfiler(idGenUtil: IdGenUtil)(toUpdate: ToUpdate) extends AssembleProfiler {
  def createJoiningProfiling(localOpt: Option[Context]) =
    if(localOpt.isEmpty) SimpleConsoleSerialJoiningProfiling
    else SimpleSerialJoiningProfiling(System.nanoTime)
  def addMeta(transition: WorldTransition, updates: Seq[N_Update]): Future[Seq[N_Update]] = transition.profiling match {
    case SimpleSerialJoiningProfiling(startedAt) =>
    implicit val executionContext: ExecutionContext = transition.executionContext.value
    //val meta = transition.profiling.result.toList.flatMap(LEvent.update).map(toUpdate.toUpdate)
    val finishedAt = System.nanoTime
    val size = updates.map(_.value.size).sum
    val types = updates.map(_.valueTypeId).distinct.toList
    val id = idGenUtil.srcIdFromStrings(UUID.randomUUID.toString)
    for {
      logAll <- transition.log
    } yield {
      val log = logAll.collect{ case l: D_LogEntry => l }
      val meta = List(
        N_TxRef(id,""),
        D_TxAddMeta(id,startedAt,finishedAt,log,updates.size,size,types)
      )
      val metaUpdates = meta.flatMap(LEvent.update).map(toUpdate.toUpdate)
      val metaTypeIds = metaUpdates.map(_.valueTypeId).toSet
      if(updates.map(_.valueTypeId).forall(metaTypeIds)) updates
      else metaUpdates ++ updates
    }
  }
}

case class SimpleSerialJoiningProfiling(startedAt: Long) extends JoiningProfiling {
  def time: Long = System.nanoTime
  def handle(join: Join, stage: Long, start: Long, wasLog: ProfilingLog): ProfilingLog = {
    val period = (System.nanoTime - start) / 1000
    D_LogEntry(join.name,stage,period) :: wasLog
  }
  def handle(join: Join, result: Seq[AggrDOut], wasLog: ProfilingLog): ProfilingLog = wasLog
}

case object SimpleConsoleSerialJoiningProfiling extends JoiningProfiling with LazyLogging {
  def time: Long = System.nanoTime
  def handle(join: Join, stage: Long, start: Long, wasLog: ProfilingLog): ProfilingLog = {
    val period = (System.nanoTime - start) / 1000000
    if(period > 50)
      logger.debug(s"$period ms for ${join.name}-$stage") // "${joinRes.size} items"
    wasLog
  }
  def handle(join: Join, result: Seq[AggrDOut], wasLog: ProfilingLog): ProfilingLog = wasLog
} 
Example 44
Source File: instances.scala    From nexus-iam   with Apache License 2.0 5 votes vote down vote up
package ch.epfl.bluebrain.nexus.iam.marshallers

import akka.http.scaladsl.marshalling.GenericMarshallers.eitherMarshaller
import akka.http.scaladsl.marshalling._
import akka.http.scaladsl.model.MediaTypes.`application/json`
import akka.http.scaladsl.model._
import ch.epfl.bluebrain.nexus.commons.circe.syntax._
import ch.epfl.bluebrain.nexus.commons.http.JsonLdCirceSupport.OrderedKeys
import ch.epfl.bluebrain.nexus.commons.http.RdfMediaTypes._
import ch.epfl.bluebrain.nexus.commons.http.directives.StatusFrom
import ch.epfl.bluebrain.nexus.iam.acls.AclRejection
import ch.epfl.bluebrain.nexus.iam.config.AppConfig._
import ch.epfl.bluebrain.nexus.iam.permissions.PermissionsRejection
import ch.epfl.bluebrain.nexus.iam.realms.RealmRejection
import ch.epfl.bluebrain.nexus.iam.types.IamError.InternalError
import ch.epfl.bluebrain.nexus.iam.types.{IamError, ResourceRejection}
import de.heikoseeberger.akkahttpcirce.FailFastCirceSupport
import io.circe._
import io.circe.syntax._
import monix.eval.Task
import monix.execution.Scheduler

import scala.collection.immutable.Seq
import scala.concurrent.Future
import scala.concurrent.duration.FiniteDuration

object instances extends FailFastCirceSupport {

  implicit val finiteDurationEncoder: Encoder[FiniteDuration] =
    Encoder.encodeString.contramap(fd => s"${fd.toMillis} ms")

  implicit val resourceRejectionEncoder: Encoder[ResourceRejection] =
    Encoder.instance {
      case r: AclRejection         => Encoder[AclRejection].apply(r)
      case r: RealmRejection       => Encoder[RealmRejection].apply(r)
      case r: PermissionsRejection => Encoder[PermissionsRejection].apply(r)
      case _                       => Encoder[IamError].apply(InternalError("unspecified"))
    }

  implicit val resourceRejectionStatusFrom: StatusFrom[ResourceRejection] =
    StatusFrom {
      case r: AclRejection         => AclRejection.aclRejectionStatusFrom(r)
      case r: RealmRejection       => RealmRejection.realmRejectionStatusFrom(r)
      case r: PermissionsRejection => PermissionsRejection.permissionsRejectionStatusFrom(r)
    }

  override def unmarshallerContentTypes: Seq[ContentTypeRange] =
    List(`application/json`, `application/ld+json`, `application/sparql-results+json`)

  
  implicit final def rejection[A <: ResourceRejection: Encoder](
      implicit statusFrom: StatusFrom[A],
      printer: Printer = Printer.noSpaces.copy(dropNullValues = true),
      ordered: OrderedKeys = orderedKeys
  ): ToResponseMarshaller[A] = {
    val marshallers = Seq(`application/ld+json`, `application/json`).map { contentType =>
      Marshaller.withFixedContentType[A, HttpResponse](contentType) { rejection =>
        HttpResponse(
          status = statusFrom(rejection),
          entity = HttpEntity(contentType, printer.print(rejection.asJson.sortKeys))
        )
      }
    }
    Marshaller.oneOf(marshallers: _*)
  }

  implicit class EitherTask[R <: ResourceRejection, A](task: Task[Either[R, A]])(implicit s: Scheduler) {
    def runWithStatus(code: StatusCode): Future[Either[R, (StatusCode, A)]] =
      task.map(_.map(code -> _)).runToFuture
  }

  implicit class OptionTask[A](task: Task[Option[A]])(implicit s: Scheduler) {
    def runNotFound: Future[A] =
      task.flatMap {
        case Some(a) => Task.pure(a)
        case None    => Task.raiseError(IamError.NotFound)
      }.runToFuture
  }
} 
Example 45
Source File: TestRunner.scala    From banditsbook-scala   with MIT License 5 votes vote down vote up
package com.github.everpeace.banditsbook.testing_framework

import java.io.File

import breeze.linalg.Vector._
import breeze.linalg._
import breeze.stats.MeanAndVariance
import breeze.storage.Zero
import com.github.everpeace.banditsbook.algorithm.{Algorithm, TracedAlgorithmDriver}
import com.github.everpeace.banditsbook.arm._
import com.typesafe.config.Config

import scala.collection.immutable.Seq
import scala.reflect.ClassTag

object TestRunner {
  def toString(mv: MeanAndVariance) = s"(μ = ${mv.mean}, σ^2 = ${mv.variance})"

  def readConfig(conf: Config, baseKey: String, hyper_parameters_name: Option[String] = None) = {
    import scala.collection.convert.decorateAsScala._
    val means = Array(
      conf.getDoubleList(s"$baseKey.arm-means").asScala.map(_.toDouble): _*
    )
    val hyper_parameters = hyper_parameters_name.map(name =>
      conf.getDoubleList(s"$baseKey.$name").asScala.map(_.toDouble).toSeq
    )
    val horizon = conf.getInt(s"$baseKey.horizon")
    val nSims = conf.getInt(s"$baseKey.n-sims")
    val outDir = new File(conf.getString(s"banditsbook.algorithm.test-common.out-dir"))

    (means, hyper_parameters, horizon, nSims, outDir)
  }

  case class TestRunnerResult(
    arms: Seq[Arm[Double]],
    numSims: Int,
    horizon: Int,
    simNums: Vector[Int],
    stepNums: Vector[Int],
    chosenArms: Vector[Int],
    rewards: Vector[Double],
    cumRewards: Vector[Double],
    // raw data format:
    // simNum, step, chosenArm, rewards, cumRewards
    rawResults: Vector[(Int, Int, Int, Double, Double)]
  )

  def run[AlgState](alg: Algorithm[Double, AlgState], arms: Seq[Arm[Double]], nSims: Int, horizon: Int)
                   (implicit zeroDouble: Zero[Double], zero:Zero[Int], classTag: ClassTag[Double] )
  = {
    val simNums = zeros[Int](nSims * horizon)
    val stepNums = zeros[Int](nSims * horizon)
    val chosenArms = zeros[Int](nSims * horizon)
    val rewards = zeros[Double](nSims * horizon)
    val cumRewards = zeros[Double](nSims * horizon)
    val rawResults = fill(nSims * horizon)((0, 0, 0, 0.0d, 0.0d))

    for { sim <- 0 until nSims }{
      val st = horizon * sim
      val end = (horizon * (sim + 1)) - 1

      val driver = TracedAlgorithmDriver(alg)
      val res = driver.run(arms, horizon)

      val cums = Vector(
        res.trace.rewards.valuesIterator.foldLeft(Array.empty[Double])((cum, r) => cum ++ Array(cum.lastOption.getOrElse(0d) + r))
      )
      simNums(st to end) := fill(horizon)(sim)
      stepNums(st to end) := tabulate(horizon)(identity)
      chosenArms(st to end) := res.trace.chosenArms
      rewards(st to end) := res.trace.rewards
      cumRewards(st to end) := cums
      rawResults(st to end) := tabulate(horizon)(i =>
        (sim, i, res.trace.chosenArms(i), res.trace.rewards(i), cums(i))
      )
      print((if (sim % 10 == 9) "." else "") + (if (sim % 1000 == 999 || sim == nSims - 1) s"[${sim + 1}]\n" else ""))
    }

    TestRunnerResult(
      arms, nSims, horizon, simNums, stepNums,
      chosenArms, rewards, cumRewards,
      rawResults
    )
  }

} 
Example 46
Source File: Standard.scala    From banditsbook-scala   with MIT License 5 votes vote down vote up
package com.github.everpeace.banditsbook.algorithm.softmax

import breeze.linalg.Vector._
import breeze.linalg._
import breeze.numerics.exp
import breeze.stats.distributions.{Rand, RandBasis}
import breeze.storage.Zero
import com.github.everpeace.banditsbook.algorithm._
import com.github.everpeace.banditsbook.arm.Arm

import scala.collection.immutable.Seq
import scala.reflect.ClassTag


object Standard {

  case class State(τ: Double, counts: Vector[Int], expectations: Vector[Double])


  def Algorithm(τ: Double)(implicit zeroReward: Zero[Double], zeroInt: Zero[Int], tag: ClassTag[Double], rand: RandBasis = Rand)
  = {
    require(τ > 0, "τ must be positive.")
    new Algorithm[Double, State] {

      override def initialState(arms: Seq[Arm[Double]]): State = State(
        τ, zeros(arms.size), zeros(arms.size)
      )

      override def selectArm(arms: Seq[Arm[Double]], state: State): Int = {
        val expectations = state.expectations
        val τ = state.τ
        val p = exp(expectations / τ) / sum(exp(expectations / τ))
        CategoricalDistribution(p).draw
      }

      override def updateState(arms: Seq[Arm[Double]], state: State, chosen: Int, reward: Double): State = {
        val counts = state.counts
        val expectations = state.expectations

        val count = counts(chosen) + 1
        counts.update(chosen, count)

        val expectation = (((count - 1) / count.toDouble) * expectations(chosen)) + ((1 / count.toDouble) * reward)
        expectations.update(chosen, expectation)

        state.copy(counts = counts, expectations = expectations)
      }
    }
  }
} 
Example 47
Source File: TestStandard.scala    From banditsbook-scala   with MIT License 5 votes vote down vote up
package com.github.everpeace.banditsbook.algorithm.softmax

import java.io.{File, PrintWriter}

import breeze.linalg._
import breeze.stats.MeanAndVariance
import com.github.everpeace.banditsbook.arm._
import com.github.everpeace.banditsbook.testing_framework.TestRunner
import com.github.everpeace.banditsbook.testing_framework.TestRunner._
import com.typesafe.config.ConfigFactory

import scala.collection.immutable.Seq

object TestStandard extends _TestStandard with App {
  run()
}

trait _TestStandard {
  def run() = {
//    implicit val randBasis = RandBasis.mt0

    val conf = ConfigFactory.load()
    val baseKey = "banditsbook.algorithm.softmax.test-standard"
    val (_means, Some(τs), horizon, nSims, outDir) = readConfig(conf, baseKey, Some("τs"))
    val means = shuffle(_means)
    val arms = Seq(means:_*).map(μ => BernoulliArm(μ))

    val outputPath = new File(outDir, "test-standard-softmax-results.csv")
    val file = new PrintWriter(outputPath.toString)
    file.write("tau, sim_num, step, chosen_arm, reward, cumulative_reward\n")
    try {
      println("-------------------------------")
      println("Standard Softmax Algorithm")
      println("-------------------------------")
      println(s"   arms = ${means.map("(μ="+_+")").mkString(", ")} (Best Arm = ${argmax(means)})")
      println(s"horizon = $horizon")
      println(s"  nSims = $nSims")
      println(s"      τ = (${τs.mkString(",")})")
      println("")

      val meanOfFinalRewards = scala.collection.mutable.Map.empty[Double, MeanAndVariance]
      val res = for {
        τ <- τs
      } yield {
        println(s"starts simulation on τ=$τ.")

        val algo = Standard.Algorithm(τ)
        val res = TestRunner.run(algo, arms, nSims, horizon)

        for {
          sim <- 0 until nSims
        } {
          val st = sim * horizon
          val end = ((sim + 1) * horizon) - 1
        }
        val finalRewards = res.cumRewards((horizon-1) until (nSims * horizon, horizon))
        import breeze.stats._
        val meanAndVar = meanAndVariance(finalRewards)
        meanOfFinalRewards += τ -> meanAndVar
        println(s"reward stats: ${TestRunner.toString(meanAndVar)}")

        res.rawResults.valuesIterator.foreach{ v =>
          file.write(s"${Seq(τ, v._1, v._2, v._3, v._4, v._5).mkString(",")}\n")
        }
        println(s"finished simulation on τ=$τ.")
      }
      println("")
      println(s"reward stats summary")
      println(s"${meanOfFinalRewards.iterator.toSeq.sortBy(_._1).map(p => (s"τ=${p._1}", TestRunner.toString(p._2))).mkString("\n")}")
    } finally {
      file.close()
      println("")
      println(s"results are written to ${outputPath}")
    }
  }
} 
Example 48
Source File: Exp3.scala    From banditsbook-scala   with MIT License 5 votes vote down vote up
package com.github.everpeace.banditsbook.algorithm.exp3

import breeze.linalg.Vector._
import breeze.linalg._
import breeze.numerics.exp
import breeze.stats.distributions.{Rand, RandBasis}
import breeze.storage.Zero
import com.github.everpeace.banditsbook.algorithm._
import com.github.everpeace.banditsbook.arm.Arm

import scala.collection.immutable.Seq
import scala.reflect.ClassTag


object Exp3 {

  case class State(γ: Double, weights: Vector[Double], counts: Vector[Int])

  def Algorithm(γ: Double)(implicit zeroReward: Zero[Double], zeroInt: Zero[Int], tag: ClassTag[Double], rand: RandBasis = Rand)
  = {
    require(0< γ && γ <= 1, "γ must be in (0,1]")

    new Algorithm[Double, State] {

      override def initialState(arms: Seq[Arm[Double]]): State = State(
        γ, fill(arms.size)(1.0d), zeros[Int](arms.size)
      )

      override def selectArm(arms: Seq[Arm[Double]], state: State): Int =
        CategoricalDistribution(probs(state.γ, state.weights)).draw()

      override def updateState(arms: Seq[Arm[Double]], state: State, chosen: Int, reward: Double): State = {
        val counts = state.counts
        val weights = state.weights

        val count = counts(chosen) + 1
        counts.update(chosen, count)

        val K = weights.size
        val p = probs(state.γ, weights)
        val x = zeros[Double](K)
        x.update(chosen, reward/p(chosen))
        weights *= exp((state.γ * x) / K.toDouble)

        state.copy(weights = weights, counts = counts)
      }

      private def probs(γ: Double, weights: Vector[Double]): Vector[Double] = {
        val K = weights.size  // #arms
        ((1 - γ) * (weights / sum(weights))) + (γ / K)
      }
    }
  }
} 
Example 49
Source File: TestExp3.scala    From banditsbook-scala   with MIT License 5 votes vote down vote up
package com.github.everpeace.banditsbook.algorithm.exp3

import java.io.{File, PrintWriter}

import breeze.linalg._
import breeze.stats.MeanAndVariance
import com.github.everpeace.banditsbook.arm._
import com.github.everpeace.banditsbook.testing_framework.TestRunner
import com.github.everpeace.banditsbook.testing_framework.TestRunner._
import com.typesafe.config.ConfigFactory

import scala.collection.immutable.Seq

object TestExp3 extends _TestExp3 with App {
  run()
}

trait _TestExp3{
  def run() = {
//    implicit val randBasis = RandBasis.mt0

    val conf = ConfigFactory.load()
    val baseKey = "banditsbook.algorithm.exp3.test-exp3"
    val (_means, Some(γs), horizon, nSims, outDir) = readConfig(conf, baseKey, Some("γs"))
    val means = shuffle(_means)
    val arms = Seq(means:_*).map(μ => BernoulliArm(μ))

    val outputPath = new File(outDir, "test-exp3-results.csv")
    val file = new PrintWriter(outputPath.toString)
    file.write("gamma, sim_num, step, chosen_arm, reward, cumulative_reward\n")
    try {
      println("-------------------------------")
      println("EXP3 Algorithm")
      println("-------------------------------")
      println(s"   arms = ${means.map("(μ="+_+")").mkString(", ")} (Best Arm = ${argmax(means)})")
      println(s"horizon = $horizon")
      println(s"  nSims = $nSims")
      println(s"      γ = (${γs.mkString(",")})")
      println("")

      val meanOfFinalRewards = scala.collection.mutable.Map.empty[Double, MeanAndVariance]
      val res = for {
        γ <- γs
      } yield {
        println(s"starts simulation on γ=$γ.")

        val algo = Exp3.Algorithm(γ)
        val res = TestRunner.run(algo, arms, nSims, horizon)

        for {
          sim <- 0 until nSims
        } {
          val st = sim * horizon
          val end = ((sim + 1) * horizon) - 1
        }
        val finalRewards = res.cumRewards((horizon-1) until (nSims * horizon, horizon))
        import breeze.stats._
        val meanAndVar = meanAndVariance(finalRewards)
        meanOfFinalRewards += γ -> meanAndVar
        println(s"reward stats: ${TestRunner.toString(meanAndVar)}")

        res.rawResults.valuesIterator.foreach{ v =>
          file.write(s"${Seq(γ, v._1, v._2, v._3, v._4, v._5).mkString(",")}\n")
        }
        println(s"finished simulation on γ=$γ.")
      }
      println("")
      println(s"reward stats summary")
      println(s"${meanOfFinalRewards.iterator.toSeq.sortBy(_._1).toSeq.sortBy(_._1).map(p => (s"γ=${p._1}", TestRunner.toString(p._2))).mkString("\n")}")
    } finally {
      file.close()
      println("")
      println(s"results are written to ${outputPath}")
    }
  }
} 
Example 50
Source File: TestUCB1.scala    From banditsbook-scala   with MIT License 5 votes vote down vote up
package com.github.everpeace.banditsbook.algorithm.ucb

import java.io.{File, PrintWriter}

import breeze.linalg._
import com.github.everpeace.banditsbook.arm._
import com.github.everpeace.banditsbook.testing_framework.TestRunner
import com.github.everpeace.banditsbook.testing_framework.TestRunner._
import com.typesafe.config.ConfigFactory

import scala.collection.immutable.Seq

object TestUCB1 extends _TestUCB1 with App{
  run()
}

trait _TestUCB1 {
  def run() = {
//    implicit val randBasis = RandBasis.mt0

    val conf = ConfigFactory.load()
    val baseKey = "banditsbook.algorithm.ucb.test-ucb1"
    val (_means, _, horizon, nSims, outDir) = readConfig(conf, baseKey)
    val means = shuffle(_means)
    val arms = Seq(means:_*).map(μ => BernoulliArm(μ))


    val outputPath = new File(outDir, "test-ucb1-results.csv")
    val file = new PrintWriter(outputPath.toString)
    file.write("sim_num, step, chosen_arm, reward, cumulative_reward\n")
    try {
      println("-------------------------------")
      println("UCB1 Algorithm")
      println("-------------------------------")
      println(s"   arms = ${means.map("(μ="+_+")").mkString(", ")} (Best Arm = ${argmax(means)})")
      println(s"horizon = $horizon")
      println(s"  nSims = $nSims")
      println( "The algorithm has no hyper parameters.")
      println("")

      println(s"starts simulation.")

      val algo = UCB1.Algorithm
      val res = TestRunner.run(algo, arms, nSims, horizon)

      for {sim <- 0 until nSims} {
        val st = sim * horizon
        val end = ((sim + 1) * horizon) - 1
      }
      val finalRewards = res.cumRewards((horizon-1) until (nSims * horizon, horizon))
      import breeze.stats._
      val meanAndVar = meanAndVariance(finalRewards)
      println(s"reward stats: ${TestRunner.toString(meanAndVar)}")

      res.rawResults.valuesIterator.foreach{ v =>
        file.write(s"${Seq(v._1, v._2, v._3, v._4, v._5).mkString(",")}\n")
      }
      println(s"finished simulation.")
    } finally {
      file.close()
      println("")
      println(s"results are written to ${outputPath}")
    }
  }
} 
Example 51
Source File: UCB1.scala    From banditsbook-scala   with MIT License 5 votes vote down vote up
package com.github.everpeace.banditsbook.algorithm.ucb

import breeze.numerics.sqrt
import breeze.stats.distributions.{Rand, RandBasis}
import breeze.storage.Zero
import com.github.everpeace.banditsbook.algorithm.Algorithm
import com.github.everpeace.banditsbook.arm.Arm

import scala.collection.immutable.Seq
import scala.reflect.ClassTag


object UCB1 {

  import breeze.linalg._
  import Vector._

  case class State(counts: Vector[Int], expectations: Vector[Double])

  def Algorithm(implicit zeroReward: Zero[Double], zeroInt: Zero[Int], tag: ClassTag[Double], rand: RandBasis = Rand)
  = {
    new Algorithm[Double, State] {

      override def initialState(arms: Seq[Arm[Double]]): State = State(
        zeros(arms.size), zeros(arms.size)
      )

      override def selectArm(arms: Seq[Arm[Double]], state: State): Int = {
        val counts = state.counts
        val expectations = state.expectations
        val step = sum(counts)
        val factor = fill(counts.size)(2 * scala.math.log(step))
        val bonus = sqrt(factor / counts.map(_.toDouble))
        val score = expectations + bonus
        argmax(score)
      }

      override def updateState(arms: Seq[Arm[Double]], state: State, chosen: Int, reward: Double): State = {
        val counts = state.counts
        val expectations = state.expectations
        val count = counts(chosen) + 1
        counts.update(chosen, count)

        val expectation = (((count - 1) / count.toDouble) * expectations(chosen)) + ((1 / count.toDouble) * reward)
        expectations.update(chosen, expectation)

        state.copy(counts = counts, expectations = expectations)
      }
    }
  }
} 
Example 52
Source File: ComponentApi.scala    From c4proto   with Apache License 2.0 5 votes vote down vote up
package ee.cone.c4actor

import ee.cone.c4assemble.Single
import ee.cone.c4di.{AbstractComponents, Component, TypeKey}

import scala.collection.immutable.Seq

object ComponentRegistry {
  def isRegistry: Component=>Boolean = {
    val clName = classOf[AbstractComponents].getName
    c => c.in match {
      case Seq(inKey) if inKey.clName == clName => true
      case _ => false
    }
  }
  def apply(app: AbstractComponents): ComponentRegistry =
    Single(Single(app.components.filter(isRegistry).distinct).create(Seq(app)))
      .asInstanceOf[ComponentRegistry]
}

trait ComponentRegistry {
  def resolveKey(key: TypeKey): DeferredSeq[Any]
  def resolve[T](cl: Class[T], args: Seq[TypeKey]): DeferredSeq[T]
  def components: Seq[Component]
}

trait DeferredSeq[+T] {
  def value: Seq[T]
}

case class StrictTypeKey[T](value: TypeKey) 
Example 53
Source File: ComponentImpl.scala    From c4proto   with Apache License 2.0 5 votes vote down vote up
package ee.cone.c4actor

import com.typesafe.scalalogging.LazyLogging
import ee.cone.c4assemble.Single
import ee.cone.c4di._
import ee.cone.c4di.Types._

import scala.collection.immutable.Seq

class SimpleDeferredSeq[T](get: ()=>Seq[T]) extends DeferredSeq[T] {
  lazy val value: Seq[T] = get()
}
object EmptyDeferredSeq extends DeferredSeq[Nothing] {
  def value: Seq[Nothing] = Nil
}

@c4("BaseApp") final class ComponentRegistryImpl(app: AbstractComponents)(
  debug: Boolean = Option(System.getenv("C4DEBUG_COMPONENTS")).nonEmpty
) extends ComponentRegistry {
  def toTypeKey[T](cl: Class[T], args: Seq[TypeKey]): TypeKey =
    CreateTypeKey(cl,cl.getSimpleName,args.toList)
  lazy val components: Seq[Component] = fixNonFinal(app.components.distinct)
  lazy val reg: Map[TypeKey,DeferredSeq[Object]] =
    components.map(toCached).groupBy(_.out)
      .transform((k,v)=>new SimpleDeferredSeq(()=>v.flatMap(_.deferredSeq.value)))
  // def toNonFinal(k: TypeKey): TypeKey = k.copy(alias = s"NonFinal#${k.alias}")
  def fixNonFinal(components: Seq[Component]): Seq[Component] = {
    if(debug) components.foreach(c=>println(s"component (out: ${c.out}) (in: ${c.in})"))
    val toNonFinal = components.flatMap(c => c.nonFinalOut.map(nOut=>c.out->nOut)).toMap
    components.map{ c =>
      if(c.nonFinalOut.nonEmpty) c
      else toNonFinal.get(c.out).fold(c)(nOut=>new Component(nOut, c.nonFinalOut, c.in, c.create))
    }
  }
  class Cached(val out: TypeKey, val deferredSeq: DeferredSeq[Object])
  def toCached(component: Component): Cached = {
    val values = if(ComponentRegistry.isRegistry(component)) ()=>Seq(this)
      else () => component.create(component.in.map(resolveSingle(component.out)))
    new Cached(component.out, new SimpleDeferredSeq[Object](values))
  }
  def resolveSingle: TypeKey => TypeKey => Object = outKey => inKey => resolveKey(inKey).value match {
    case Seq(r:Object) =>
      r
    case r => throw new Exception(s"resolution of $inKey for $outKey fails with $r")
  }
  def resolveKey(key: TypeKey): DeferredSeq[Any] =
    new SimpleDeferredSeq[Any](()=>
      if(!debug) resolveKeyDo(key) else try resolveKeyDo(key) catch{
        case e: StackOverflowError =>
          throw new ResolveKeyError(Set(key),s"${e.getMessage} with suggested dep loop:\n-- $key")
        case e: ResolveKeyError if e.keys.isEmpty || e.keys(key) =>
          throw new ResolveKeyError(Set.empty, e.message)
        case e: ResolveKeyError =>
          throw new ResolveKeyError(e.keys ++ Set(key),s"${e.message}\n-- $key")
      }
    )
  def resolveKeyDo(key: TypeKey): Seq[Any] = {
    val directRes: DeferredSeq[Any] = reg.getOrElse(key,EmptyDeferredSeq)
    val factoryKey = CreateTypeKey(classOf[ComponentFactory[_]],"ComponentFactory",List(key.copy(args=Nil)))
    val factories = reg.getOrElse(factoryKey,EmptyDeferredSeq).asInstanceOf[DeferredSeq[ComponentFactory[_]]]
    directRes.value ++ factories.value.flatMap(_(key.args))
  }
  def resolve[T](cl: Class[T], args: Seq[TypeKey]): DeferredSeq[T] =
    resolveKey(toTypeKey(cl,args)).asInstanceOf[DeferredSeq[T]]
}

class ResolveKeyError(
  val keys: Set[TypeKey], val message: String
) extends Exception(message)

@c4("BaseApp") final class DefComponentFactoryProvider(
  componentRegistry: ComponentRegistry
) {
  @provide def getDeferredSeq: Seq[ComponentFactory[DeferredSeq[_]]] =
    List(args=>Seq(componentRegistry.resolveKey(Single(args))))
  @provide def getList: Seq[ComponentFactory[List[_]]] =
    List(args=>Seq(componentRegistry.resolveKey(Single(args)).value.toList))
  @provide def getOption: Seq[ComponentFactory[Option[_]]] =
    List(args=>Seq(Single.option(componentRegistry.resolveKey(Single(args)).value)))
  @provide def getTypeKey: Seq[ComponentFactory[StrictTypeKey[_]]] =
    List(args=>Seq(StrictTypeKey(Single(args))))
} 
Example 54
Source File: ComponentApi.scala    From c4proto   with Apache License 2.0 5 votes vote down vote up
package ee.cone.c4di

import scala.annotation.StaticAnnotation
import scala.collection.immutable.Seq

object Types {
  type ComponentFactory[T] = Seq[TypeKey]=>Seq[T]
}

object CreateTypeKey { // to use mostly from generated code
  def apply(cl: Class[_], alias: String, args: List[TypeKey]): TypeKey =
    Value(cl.getName, alias, args)(cl)
  private case class Value(clName: String, alias: String, args: List[TypeKey])(val cl: Class[_]) extends TypeKey {
    def copy(alias: String, args: List[TypeKey]): TypeKey =
      Value(clName,alias,args)(cl)
  }
}
trait TypeKey extends Product {
  def cl: Class[_]
  def clName: String
  def args: List[TypeKey]
  def alias: String
  def copy(alias: String = alias, args: List[TypeKey] = args): TypeKey
}

class c4(apps: String*) extends StaticAnnotation
class provide extends StaticAnnotation
class c4multi(apps: String*) extends StaticAnnotation

trait AbstractComponents {
  def components: Seq[Component]
}
class Component(val out: TypeKey, val nonFinalOut: Option[TypeKey], val in: Seq[TypeKey], val create: Seq[Object]=>Seq[Object]) extends AbstractComponents {
  def components: Seq[Component] = Seq(this)
}


abstract class AutoMixer(val components: List[Component], val dependencies: List[AutoMixer])

trait GeneralC4Factory0
trait GeneralC4Factory1
trait GeneralC4Factory2
trait C4Factory0[+Out] { def create(): Out }
trait C4Factory1[In,+Out] { def create(in: In): Out }
trait C4Factory2[In1,In2,+Out] { def create(in1: In1, in2: In2): Out } 
Example 55
Source File: ScalametaTest.scala    From c4proto   with Apache License 2.0 5 votes vote down vote up
package ee.cone.c4actor.tests

import scala.collection.immutable.Seq
import scala.meta.Term.Name
import scala.meta._

object ScalametaTest {
  def main(args: Array[String]): Unit = {
    val s = "override val test: List[Int] = 1 ::: super.test".parse[Stat].get

    def parseType(t: Type): String = {
      t match {
        case t"$tpe[..$tpesnel]" => s"""ee.cone.c4proto.TypeProp(classOf[$tpe[${tpesnel.map(_ => "_").mkString(", ")}]].getName, "$tpe", ${tpesnel.map(parseType)})"""
        case t"$tpe" => s"""ee.cone.c4proto.TypeProp(classOf[$tpe].getName, "$tpe", Nil)"""
      }
    }
    //println(parseType(s))
    //println(s)
    println(s match {
      case q"override val ..$vname: $tpe = $expr" =>
        expr.collect({
          case q"super.test" => 1
          case _ => 0
        })
      case _ => 666 :: Nil
    })

    val defenition = "@ignore def test(arg: Int): LUL = {val a = 3}".parse[Stat].get
    defenition match {
      case q"@ignore def $ename[..$tparams](...$paramss): $tpeopt = $expr" => println("def ok")
      case _ => println("not ok")
    }

    def parseArgs: Seq[Seq[Term]] => List[String] =
      _.flatMap(_.map(_.toString())).toList

    val text = "@Meta(Atata, ee.cone.ee.Totoot(1,1,1)) val a = 1".parse[Stat].get
    text match {
      case q"@Meta(...$exprss) val a = 1" => println(parseArgs(exprss))
      case _ => ()
    }
  }
} 
Example 56
Source File: UIExtraMix.scala    From c4proto   with Apache License 2.0 5 votes vote down vote up
package ee.cone.c4ui

import ee.cone.c4actor._
import ee.cone.c4actor_branch.{BranchOperations, ToAlienSender}
import ee.cone.c4di.c4
import ee.cone.c4vdom.{ChildPairFactory, TagJsonUtils, TagStyles, Tags, VDomResolver}

import scala.collection.immutable.Seq

trait VDomApp extends ComponentProviderApp {
  lazy val childPairFactory: ChildPairFactory = resolveSingle(classOf[ChildPairFactory])
  lazy val tagJsonUtils: TagJsonUtils = resolveSingle(classOf[TagJsonUtils])
  lazy val tags: Tags = resolveSingle(classOf[Tags])
  lazy val tagStyles: TagStyles = resolveSingle(classOf[TagStyles])
  lazy val vDomResolver: VDomResolver = resolveSingle(classOf[VDomResolver])
}

trait UIApp extends UICompApp with VDomApp with AlienExchangeApp {
  lazy val branchOperations: BranchOperations = resolveSingle(classOf[BranchOperations])
  lazy val untilPolicy: UntilPolicy = resolveSingle(classOf[UntilPolicy])
}

////

trait AlienExchangeAppBase extends AlienExchangeCompApp
@c4("AlienExchangeApp") final class SendToAlienInit(
  toAlienSender: ToAlienSender,
) extends ToInject {
  def toInject: List[Injectable] = SendToAlienKey.set(toAlienSender.send)
} 
Example 57
Source File: LEventTransform.scala    From c4proto   with Apache License 2.0 5 votes vote down vote up
package ee.cone.c4actor

import ee.cone.c4actor.CollectiveTransformProtocol.D_CollectiveTransformMeta
import ee.cone.c4assemble.Types.Values
import ee.cone.c4di.c4multi
import ee.cone.c4proto.{Id, protocol}

import scala.collection.immutable.Seq

trait LEventTransform extends Product {
  def lEvents(local: Context): Seq[LEvent[Product]]

  def leventsDescription: String = this.getClass.getName
}

trait CollectiveTransformAppBase
@c4multi("CollectiveTransformApp") final case class CollectiveTransform(srcId: String, events: Values[LEventTransform])(
  txAdd: LTxAdd,
) extends TxTransform {
  def transform(local: Context): Context =
    txAdd.add(events.flatMap(_.lEvents(local)))(InsertOrigMeta(D_CollectiveTransformMeta(events.map(_.leventsDescription).toList) :: Nil)(local))
}

object InsertOrigMeta {
  def apply(origs: List[Product]): Context => Context =
    TxTransformOrigMetaKey.set(origs.map(MetaAttr))
}

trait CollectiveTransformProtocolAppBase
@protocol("CollectiveTransformProtocolApp") object CollectiveTransformProtocol   {

  @Id(0x0ab0) case class D_CollectiveTransformMeta(
    @Id(0x0ab1) transforms: List[String]
  )

} 
Example 58
Source File: ConsoleAssembleProfiler.scala    From c4proto   with Apache License 2.0 5 votes vote down vote up
package ee.cone.c4actor

import com.typesafe.scalalogging.LazyLogging
import ee.cone.c4actor.QProtocol.N_Update
import ee.cone.c4assemble.{AggrDOut, Join, JoiningProfiling, WorldTransition}
import ee.cone.c4assemble.Types.{DPIterable, Index, ProfilingLog}

import scala.collection.immutable.Seq
import scala.concurrent.Future

case object ConsoleAssembleProfiler extends AssembleProfiler {
  def createJoiningProfiling(localOpt: Option[Context]): JoiningProfiling = ConsoleProfiling

  def addMeta(transition: WorldTransition, updates: Seq[QProtocol.N_Update]): Future[Seq[N_Update]] = Future.successful(updates)
}

case object ConsoleProfiling extends JoiningProfiling with LazyLogging {
  def time: Long = System.nanoTime

  def handle(join: Join, stage: Long, start: Long, wasLog: ProfilingLog): ProfilingLog = {
    val timeNano: Long = (System.nanoTime - start) / 10000
    val timeFront: Double = timeNano / 100.0
    logger.debug(s"rule ${join.assembleName}-${join.name}-$stage for ${getColoredPeriod(timeFront)} ms")
    wasLog
  }

  def getColoredPeriod: Double => String = {
    case i if i < 200 => PrintColored.makeColored("g")(i.toString)
    case i if i >= 200 && i < 500 => PrintColored.makeColored("y")(i.toString)
    case i if i >= 500 => PrintColored.makeColored("r")(i.toString)
  }

//  def getColoredCount: Long => String = {
//    case i if i < 100 => PrintColored.makeColored("g")(i.toString)
//    case i if i >= 100 && i < 1000 => PrintColored.makeColored("y")(i.toString)
//    case i if i >= 1000 => PrintColored.makeColored("r")(i.toString)
//  }
  def handle(join: Join, result: Seq[AggrDOut], wasLog: ProfilingLog): ProfilingLog = wasLog
} 
Example 59
Source File: Container.scala    From metronome   with Apache License 2.0 5 votes vote down vote up
package dcos.metronome
package model

import mesosphere.marathon.state.Parameter
import scala.collection.immutable.Seq

trait Container

case class DockerSpec(
    image: String,
    privileged: Boolean = false,
    parameters: Seq[Parameter] = Nil,
    forcePullImage: Boolean = false
) extends Container

object DockerSpec {
  val DefaultParameters = Seq.empty[Parameter]
}

case class ImageSpec(id: String, kind: String = ImageSpec.DefaultKind, forcePull: Boolean = false)

object ImageSpec {
  val DefaultKind = "docker"
}

case class UcrSpec(image: ImageSpec, privileged: Boolean = false) extends Container 
Example 60
Source File: LandmarkIOTests.scala    From scalismo   with Apache License 2.0 5 votes vote down vote up
package scalismo.io

import java.io.{ByteArrayOutputStream, File, InputStream}
import java.net.URLDecoder

import breeze.linalg.DenseVector
import scalismo.ScalismoTestSuite
import scalismo.geometry._
import scalismo.statisticalmodel.MultivariateNormalDistribution

import scala.io.Source
import scala.language.implicitConversions
import scala.collection.immutable.Seq

class LandmarkIOTests extends ScalismoTestSuite {

  implicit def doubleToFloat(d: Double): Float = d.toFloat

  implicit def inputStreamToSource(s: InputStream): Source = Source.fromInputStream(s)

  describe("Spray LandmarkIO") {

    val csvName = "/landmarks.csv"
    def csvStream() = getClass.getResourceAsStream(csvName)

    val jsonName = "/landmarks.json"
    def jsonStream() = getClass.getResourceAsStream(jsonName)

    

    def distWithDefaultVectors(d1: Double, d2: Double, d3: Double): MultivariateNormalDistribution = {
      val axes = List(DenseVector[Double](1, 0, 0), DenseVector[Double](0, 1, 0), DenseVector[Double](0, 0, 1))
      val devs = List(d1, d2, d3)
      val data = axes zip devs
      MultivariateNormalDistribution(DenseVector[Double](0, 0, 0), data)
    }

    val jsonLm1 = Landmark("one", Point(1, 2, 3))
    val jsonLm2 = Landmark("two", Point(2, 3, 4), Some("Landmark two"), Some(distWithDefaultVectors(1, 4, 9)))
    val jsonLms = List(jsonLm1, jsonLm2)

    it("can serialize and deserialize simple landmarks using JSON") {
      val out = new ByteArrayOutputStream()
      LandmarkIO.writeLandmarksJsonToStream(jsonLms, out)
      val written = new String(out.toByteArray)
      val read = LandmarkIO.readLandmarksJsonFromSource[_3D](Source.fromString(written)).get
      read should equal(jsonLms)
    }

    it("can read simple landmarks from a JSON Stream") {
      val read = LandmarkIO.readLandmarksJsonFromSource[_3D](jsonStream()).get
      read should equal(jsonLms)
    }

  }
} 
Example 61
Source File: TaxiData.scala    From cloudflow   with Apache License 2.0 5 votes vote down vote up
package cloudflow.flink

import scala.collection.immutable.Seq
import scala.collection.JavaConverters._

import org.joda.time.DateTime
import cloudflow.flink.avro._

object TaxiData {
  def testRide(rideId: Long): TaxiRide =
    new TaxiRide(rideId, true, 0, 1, rideId, 0f, 0f, 0f, 0f, new DateTime(0).getMillis, new DateTime(0).getMillis)

  def testFare(rideId: Long): TaxiFare =
    new TaxiFare(rideId, 0, "", new DateTime(0).getMillis, 1, 0f, 0f, 0f)

  val ride1 = testRide(1)
  val ride2 = testRide(2)
  val fare1 = testFare(1)
  val fare2 = testFare(2)

  val rideFare1 = new TaxiRideFare(ride1.rideId, fare1.totalFare)
  val rideFare2 = new TaxiRideFare(ride2.rideId, fare2.totalFare)
  val expected  = Seq(rideFare1.toString(), rideFare2.toString()).asJava
} 
Example 62
Source File: SparkIngressSpec.scala    From cloudflow   with Apache License 2.0 5 votes vote down vote up
package cloudflow.spark

import scala.collection.immutable.Seq
import org.apache.spark.sql.Dataset
import org.apache.spark.sql.streaming.OutputMode
import org.apache.spark.sql.execution.streaming.MemoryStream
import cloudflow.streamlets.StreamletShape
import cloudflow.streamlets.avro._
import cloudflow.spark.avro._
import cloudflow.spark.testkit._
import cloudflow.spark.sql.SQLImplicits._

class SparkIngressSpec extends SparkScalaTestSupport {

  "SparkIngress" should {
    "produce elements to its outlet" in {

      val testKit  = SparkStreamletTestkit(session)
      val instance = new MySparkIngress()

      // setup outlet tap on outlet port
      val out: SparkOutletTap[Data] = testKit.outletAsTap[Data](instance.out)

      val run = testKit.run(instance, Seq.empty, Seq(out))

      // get processed rows from the run
      run.totalRows must be(10)

      // get data from outlet tap
      val results = out.asCollection(session)

      // assert
      results must contain(Data(1, "name1"))
    }
  }
}
// create sparkStreamlet
class MySparkIngress extends SparkStreamlet {
  val out   = AvroOutlet[Data]("out", d ⇒ d.id.toString)
  val shape = StreamletShape(out)

  override def createLogic() = new SparkStreamletLogic {
    private def process: Dataset[Data] = {
      implicit val sqlCtx = session.sqlContext
      val data            = (1 to 10).map(i ⇒ Data(i, s"name$i"))
      val m               = MemoryStream[Data]
      m.addData(data)
      m.toDF.as[Data]
    }
    override def buildStreamingQueries = {
      val outStream: Dataset[Data] = process
      require(outStream.isStreaming, "The Dataset created by an Ingress must be a Streaming Dataset")
      val query = writeStream(outStream, out, OutputMode.Append)
      StreamletQueryExecution(query)
    }
  }
} 
Example 63
Source File: SparkProcessorSpec.scala    From cloudflow   with Apache License 2.0 5 votes vote down vote up
package cloudflow.spark

import scala.collection.immutable.Seq
import org.apache.spark.sql.streaming.OutputMode
import cloudflow.streamlets.StreamletShape
import cloudflow.streamlets.avro._
import cloudflow.spark.avro._
import cloudflow.spark.testkit._
import cloudflow.spark.sql.SQLImplicits._

class SparkProcessorSpec extends SparkScalaTestSupport {

  "SparkProcessor" should {
    "process streaming data" in {

      val testKit = SparkStreamletTestkit(session)

      // create an instance of the streamlet under test
      val instance = new TestSparkProcessor()

      // setup inlet tap on inlet port
      val in: SparkInletTap[Data] = testKit.inletAsTap[Data](instance.in)

      // setup outlet tap on outlet port
      val out: SparkOutletTap[Simple] = testKit.outletAsTap[Simple](instance.out)

      // build data and send to inlet tap
      val data = (1 to 10).map(i ⇒ Data(i, s"name$i"))
      in.addData(data)

      val run = testKit.run(instance, Seq(in), Seq(out))
      run.totalRows must be(10)

      // get data from outlet tap
      val results = out.asCollection(session)

      // assert
      results must contain(Simple("name1"))
    }
  }
}
// Test sparkStreamlet
class TestSparkProcessor extends SparkStreamlet {
  val in    = AvroInlet[Data]("in")
  val out   = AvroOutlet[Simple]("out", _.name)
  val shape = StreamletShape(in, out)

  override def createLogic() = new SparkStreamletLogic {
    override def buildStreamingQueries = {
      val dataset   = readStream(in)
      val outStream = dataset.select($"name").as[Simple]
      val query     = writeStream(outStream, out, OutputMode.Append)
      StreamletQueryExecution(query)
    }
  }
} 
Example 64
Source File: ResponseMetadata.scala    From sttp   with Apache License 2.0 5 votes vote down vote up
package sttp.client

import sttp.model._
import sttp.model.{Header, StatusCode}

import scala.collection.immutable.Seq

trait ResponseMetadata extends HasHeaders {
  def code: StatusCode
  def statusText: String
  def is200: Boolean = code == StatusCode.Ok
  def isSuccess: Boolean = code.isSuccess
  def isRedirect: Boolean = code.isRedirect
  def isClientError: Boolean = code.isClientError
  def isServerError: Boolean = code.isServerError

  override def toString: String = s"ResponseMetadata(code=$code, statusText=$statusText, headers=$headersToStringSafe)"

  private def headersToStringSafe: Seq[String] = headers.map(_.toStringSafe)
}

object ResponseMetadata {
  def apply(h: Seq[Header], c: StatusCode, st: String): ResponseMetadata =
    new ResponseMetadata {
      override def headers: Seq[Header] = h
      override def code: StatusCode = c
      override def statusText: String = st
    }
} 
Example 65
Source File: RequestBody.scala    From sttp   with Apache License 2.0 5 votes vote down vote up
package sttp.client

import java.io.InputStream
import java.nio.ByteBuffer

import sttp.model._
import sttp.client.internal.SttpFile
import sttp.model.internal.UriCompatibility

import scala.collection.immutable.Seq

sealed trait RequestBody[+S]
case object NoBody extends RequestBody[Nothing]

sealed trait BasicRequestBody extends RequestBody[Nothing] {
  def defaultContentType: Option[MediaType]
}

case class StringBody(
    s: String,
    encoding: String,
    defaultContentType: Option[MediaType] = Some(MediaType.TextPlain)
) extends BasicRequestBody

case class ByteArrayBody(
    b: Array[Byte],
    defaultContentType: Option[MediaType] = Some(MediaType.ApplicationOctetStream)
) extends BasicRequestBody

case class ByteBufferBody(
    b: ByteBuffer,
    defaultContentType: Option[MediaType] = Some(MediaType.ApplicationOctetStream)
) extends BasicRequestBody

case class InputStreamBody(
    b: InputStream,
    defaultContentType: Option[MediaType] = Some(MediaType.ApplicationOctetStream)
) extends BasicRequestBody

case class FileBody(
    f: SttpFile,
    defaultContentType: Option[MediaType] = Some(MediaType.ApplicationOctetStream)
) extends BasicRequestBody

case class StreamBody[S](s: S) extends RequestBody[S]

case class MultipartBody(parts: Seq[Part[BasicRequestBody]]) extends RequestBody[Nothing]

object RequestBody {
  private[client] def paramsToStringBody(fs: Seq[(String, String)], encoding: String): StringBody = {
    val b = fs
      .map {
        case (key, value) =>
          UriCompatibility.encodeQuery(key, encoding) + "=" +
            UriCompatibility.encodeQuery(value, encoding)
      }
      .mkString("&")

    StringBody(b, encoding)
  }
} 
Example 66
Source File: CorsSettingsImpl.scala    From akka-http-cors   with Apache License 2.0 5 votes vote down vote up
package ch.megard.akka.http.cors.scaladsl.settings

import akka.http.scaladsl.model.{HttpHeader, HttpMethod}
import akka.http.scaladsl.model.headers._
import ch.megard.akka.http.cors.scaladsl.model.{HttpHeaderRange, HttpOriginMatcher}

import scala.collection.immutable.Seq


final private[akka] case class CorsSettingsImpl(
    allowGenericHttpRequests: Boolean,
    allowCredentials: Boolean,
    allowedOrigins: HttpOriginMatcher,
    allowedHeaders: HttpHeaderRange,
    allowedMethods: Seq[HttpMethod],
    exposedHeaders: Seq[String],
    maxAge: Option[Long]
) extends CorsSettings {
  override def productPrefix = "CorsSettings"

  private def accessControlExposeHeaders: Option[`Access-Control-Expose-Headers`] =
    if (exposedHeaders.nonEmpty)
      Some(`Access-Control-Expose-Headers`(exposedHeaders))
    else
      None

  private def accessControlAllowCredentials: Option[`Access-Control-Allow-Credentials`] =
    if (allowCredentials)
      Some(`Access-Control-Allow-Credentials`(true))
    else
      None

  private def accessControlMaxAge: Option[`Access-Control-Max-Age`] =
    maxAge.map(`Access-Control-Max-Age`.apply)

  private def accessControlAllowMethods: `Access-Control-Allow-Methods` =
    `Access-Control-Allow-Methods`(allowedMethods)

  private def accessControlAllowHeaders(requestHeaders: Seq[String]): Option[`Access-Control-Allow-Headers`] =
    allowedHeaders match {
      case HttpHeaderRange.Default(headers)             => Some(`Access-Control-Allow-Headers`(headers))
      case HttpHeaderRange.* if requestHeaders.nonEmpty => Some(`Access-Control-Allow-Headers`(requestHeaders))
      case _                                            => None
    }

  private def accessControlAllowOrigin(origins: Seq[HttpOrigin]): `Access-Control-Allow-Origin` =
    if (allowedOrigins == HttpOriginMatcher.* && !allowCredentials)
      `Access-Control-Allow-Origin`.*
    else
      `Access-Control-Allow-Origin`.forRange(HttpOriginRange.Default(origins))

  // Cache headers that are always included in a preflight response
  private val basePreflightResponseHeaders: List[HttpHeader] =
    List(accessControlAllowMethods) ++ accessControlMaxAge ++ accessControlAllowCredentials

  // Cache headers that are always included in an actual response
  private val baseActualResponseHeaders: List[HttpHeader] =
    accessControlExposeHeaders.toList ++ accessControlAllowCredentials

  def preflightResponseHeaders(origins: Seq[HttpOrigin], requestHeaders: Seq[String]): List[HttpHeader] =
    accessControlAllowHeaders(requestHeaders) match {
      case Some(h) => h :: accessControlAllowOrigin(origins) :: basePreflightResponseHeaders
      case None    => accessControlAllowOrigin(origins) :: basePreflightResponseHeaders
    }

  def actualResponseHeaders(origins: Seq[HttpOrigin]): List[HttpHeader] =
    accessControlAllowOrigin(origins) :: baseActualResponseHeaders
} 
Example 67
Source File: EventDecoderApi.scala    From daml   with Apache License 2.0 5 votes vote down vote up
// Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

package com.daml.ledger.client.binding

import com.daml.ledger.api.refinements.ApiTypes

import scala.collection.immutable.{Map, Seq}
import scalaz.Id.Id
import com.daml.ledger.api.v1.{event => rpcevent, value => rpcvalue}

abstract class EventDecoderApi(val templateTypes: Seq[TemplateCompanion[_]]) {

  @SuppressWarnings(Array("org.wartremover.warts.Any"))
  val decoderTable: Map[ApiTypes.TemplateId, rpcevent.CreatedEvent => Option[Template[_]]] =
    templateTypes.map(_.decoderEntry).toMap

  private[this] val dtl = {
    type F[A] = A => Option[rpcevent.CreatedEvent => Option[Template[_]]]
    ApiTypes.TemplateId.unsubst[F, rpcvalue.Identifier](decoderTable.lift)
  }

  @SuppressWarnings(Array("org.wartremover.warts.Any"))
  final def createdEventToContractRef(
      createdEvent: rpcevent.CreatedEvent): Either[EventDecoderError, Contract.OfAny] = {
    for {
      templateToContract <- createdEvent.templateId flatMap dtl toRight DecoderTableLookupFailure
      tadt <- templateToContract(createdEvent).toRight(
        CreateEventToContractMappingError: EventDecoderError)
    } yield
      Contract(
        Primitive.substContractId[Id, Nothing](ApiTypes.ContractId(createdEvent.contractId)),
        tadt,
        createdEvent.agreementText,
        createdEvent.signatories,
        createdEvent.observers,
        createdEvent.contractKey
      )
  }
} 
Example 68
Source File: ChaosCommands.scala    From eventuate-chaos   with Apache License 2.0 5 votes vote down vote up
package com.rbmhtechnology.eventuate.chaos

import java.net.InetAddress

import scala.collection.immutable.Seq
import scala.sys.process._
import scala.util.Try

trait ChaosCommands {
  private lazy val environment: Array[(String, String)] =
    Seq("boot2docker", "shellinit").lineStream
      .map(_.trim)
      .filter(_.startsWith("export "))
      .map(_.substring(7))
      .map(_.split("="))
      .foldLeft(Seq[(String, String)]()) { case (acc, kv) => acc :+ (kv(0) -> kv(1)) }.toArray

  def seedAddress(): Try[InetAddress] =
    runCommand(Seq("docker", "inspect", "--format='{{ .NetworkSettings.IPAddress }}'", "cassandra-1"), _.!!.trim).map(InetAddress.getByName)

  private def runCommand[A](command: Seq[String], f: ProcessBuilder => A): Try[A] =
    Try(f(Process(command, None, environment: _*)))

} 
Example 69
Source File: AkkaStreamUtils.scala    From akka-serialization-test   with Apache License 2.0 5 votes vote down vote up
package com.github.dnvriend

import akka.NotUsed
import akka.stream.scaladsl.Source
import akka.stream.testkit.TestSubscriber
import akka.stream.testkit.scaladsl.TestSink
import scala.collection.immutable.Seq
import scala.concurrent.duration._

trait AkkaStreamUtils { _: TestSpec ⇒
  implicit class SourceOps[A, M](src: Source[A, M]) {
    def testProbe(f: TestSubscriber.Probe[A] ⇒ Unit): Unit = {
      val tp = src.runWith(TestSink.probe(system))
      tp.within(10.seconds)(f(tp))
    }
  }

  def withIteratorSrc[T](start: Int = 0)(f: Source[Int, NotUsed] ⇒ Unit): Unit =
    f(Source.fromIterator(() ⇒ Iterator from start))

  def fromCollectionProbe[A](xs: Seq[A])(f: TestSubscriber.Probe[A] ⇒ Unit): Unit =
    f(Source(xs).runWith(TestSink.probe(system)))
} 
Example 70
Source File: SbtSlamDataPlugin.scala    From sbt-slamdata   with Apache License 2.0 5 votes vote down vote up
package slamdata

import sbt._, Keys._

import bintray.{BintrayKeys, BintrayPlugin}, BintrayKeys._

import sbtghactions.GitHubActionsPlugin, GitHubActionsPlugin.autoImport._

import scala.{sys, Some}
import scala.collection.immutable.Seq

object SbtSlamDataPlugin extends SbtSlamDataBase {

  override def requires = super.requires && BintrayPlugin

  object autoImport extends autoImport {

    lazy val noPublishSettings = Seq(
      publish := {},
      publishLocal := {},
      bintrayRelease := {},
      publishArtifact := false,
      skip in publish := true,
      bintrayEnsureBintrayPackageExists := {})
  }

  import autoImport._

  override def projectSettings =
    super.projectSettings ++
    addCommandAlias("releaseSnapshot", "; project /; reload; checkLocalEvictions; bintrayEnsureBintrayPackageExists; publish; bintrayRelease") ++
    Seq(
      sbtPlugin := true,

      bintrayOrganization := Some("slamdata-inc"),
      bintrayRepository := "sbt-plugins",
      bintrayReleaseOnPublish := false,

      publishMavenStyle := false,

      // it's annoying that sbt-bintray doesn't do this for us
      credentials ++= {
        if (githubIsWorkflowBuild.value) {
          val creds = for {
            user <- sys.env.get("BINTRAY_USER")
            pass <- sys.env.get("BINTRAY_PASS")
          } yield Credentials("Bintray API Realm", "api.bintray.com", user, pass)

          creds.toSeq
        } else {
          Seq()
        }
      })

  override def buildSettings =
    super.buildSettings ++
    Seq(
      secrets += file("credentials.yml.enc"),

      transferPublishAndTagResources := {
        transferToBaseDir("plugin", (ThisBuild / baseDirectory).value, "credentials.yml.enc")
        transferPublishAndTagResources.value
      })

  protected val autoImporter = autoImport
} 
Example 71
Source File: SbtSlamDataPlugin.scala    From sbt-slamdata   with Apache License 2.0 5 votes vote down vote up
package slamdata

import sbt._, Keys._

import bintray.{BintrayKeys, BintrayPlugin}, BintrayKeys._

import sbtghactions.GitHubActionsPlugin, GitHubActionsPlugin.autoImport._

import scala.{sys, Some}
import scala.collection.immutable.Seq

object SbtSlamDataPlugin extends SbtSlamDataBase {

  override def requires = super.requires && BintrayPlugin

  object autoImport extends autoImport {

    lazy val noPublishSettings = Seq(
      publish := {},
      publishLocal := {},
      bintrayRelease := {},
      publishArtifact := false,
      skip in publish := true,
      bintrayEnsureBintrayPackageExists := {})
  }

  import autoImport._

  override def projectSettings =
    super.projectSettings ++
    addCommandAlias("releaseSnapshot", "; project /; reload; checkLocalEvictions; bintrayEnsureBintrayPackageExists; publish; bintrayRelease") ++
    Seq(
      sbtPlugin := true,

      bintrayOrganization := Some("slamdata-inc"),
      bintrayRepository := "sbt-plugins",
      bintrayReleaseOnPublish := false,

      publishMavenStyle := false,

      // it's annoying that sbt-bintray doesn't do this for us
      credentials ++= {
        if (githubIsWorkflowBuild.value) {
          val creds = for {
            user <- sys.env.get("BINTRAY_USER")
            pass <- sys.env.get("BINTRAY_PASS")
          } yield Credentials("Bintray API Realm", "api.bintray.com", user, pass)

          creds.toSeq
        } else {
          Seq()
        }
      })

  override def buildSettings =
    super.buildSettings ++
    Seq(
      secrets += file("credentials.yml.enc"),

      transferPublishAndTagResources := {
        transferToBaseDir("plugin", (ThisBuild / baseDirectory).value, "credentials.yml.enc")
        transferPublishAndTagResources.value
      })

  protected val autoImporter = autoImport
} 
Example 72
Source File: SbtSlamData.scala    From sbt-slamdata   with Apache License 2.0 5 votes vote down vote up
package slamdata

import sbt._, Keys._

import sbtghpackages.GitHubPackagesPlugin

import scala.collection.immutable.Seq

object SbtSlamData extends SbtSlamDataBase {

  override def requires = super.requires && GitHubPackagesPlugin

  object autoImport extends autoImport {

    lazy val noPublishSettings = Seq(
      publish := {},
      publishLocal := {},
      publishArtifact := false,
      skip in publish := true)
  }

  import autoImport._
  import GitHubPackagesPlugin.autoImport._

  override def projectSettings =
    super.projectSettings ++
    addCommandAlias("releaseSnapshot", "; project /; reload; checkLocalEvictions; +publish") ++
    Seq(
      githubOwner := "slamdata",
      githubRepository := { if (publishAsOSSProject.value) "public" else "private" },
      githubTokenSource := TokenSource.Environment("GITHUB_TOKEN") || githubTokenSource.value,

      resolvers += Resolver.githubPackages("slamdata", "public"),
      resolvers += Resolver.githubPackages("slamdata", "tectonic"),   // don't ask...

      resolvers ++= {
        if (!publishAsOSSProject.value)
          Seq(Resolver.githubPackages("slamdata", "private"))
        else
          Seq.empty
      })

  protected val autoImporter = autoImport
} 
Example 73
Source File: DilateProtocol.scala    From dilate   with Apache License 2.0 5 votes vote down vote up
package com.vitorsvieira.dilate

import scala.annotation.StaticAnnotation
import scala.collection.immutable.Seq
import scala.meta._

sealed trait ClassParamAnnotation extends StaticAnnotation
final class hold extends ClassParamAnnotation

final private[dilate] case class ExtractionResult(
    template: CompanionObjectTemplate,
    domain:   OwnerClassArgs)

final private[dilate] case class CompanionObjectTemplate(
    valueclasses:    Seq[Defn.Class] = Seq.empty,
    traits:          Seq[Defn.Trait] = Seq.empty,
    types:           Seq[Defn.Type]  = Seq.empty,
    implicitClasses: Seq[Defn.Class] = Seq.empty,
    implicitDefs:    Seq[Defn.Def]   = Seq.empty
)

final private[dilate] case class OwnerClassArgs(finalArgs: Seq[Seq[Term.Param]] = Seq.empty)

final private[dilate] case class OwnerClassArgsSplitted(
    nonImplicitArgs: Seq[Term.Param],
    implicitArgs:    Seq[Term.Param])

final private[dilate] case class ExtractionPreResult(
    extraction: Seq[Extraction],
    newArgs:    OwnerClassArgs)

final private[dilate] case class Extraction(
    newArgs:     Term.Param,
    valueclass:  Option[Defn.Class]    = None,
    traitT:      Option[Defn.Trait]    = None,
    typeT:       Option[Defn.Type]     = None,
    implicitDef: Seq[Option[Defn.Def]] = Seq.empty
) 
Example 74
Source File: newtype.scala    From dilate   with Apache License 2.0 5 votes vote down vote up
package com.vitorsvieira.dilate

import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.collection.immutable.Seq
import scala.meta._
import scala.util.Try

@compileTimeOnly("@newtype macro expands only in compile time.")
final class newtype extends StaticAnnotation {
  inline def apply(defn: Any): Any = meta {
    defn match {
      case Term.Block(Seq([email protected](_, name, _, ctor, _), companion: Defn.Object)) =>
        val result = Dilate.newtypeApply(name, ctor.paramss)
        val newClass: Defn.Class = cls.copy(
          ctor = Ctor.Primary.apply(ctor.mods, ctor.name, result.domain.finalArgs)
        )

        val templateStats: Option[Seq[Stat]] = Try(
          result.template.traits ++:
            result.template.types ++:
            result.template.implicitClasses ++:
            companion.templ.stats.getOrElse(Nil)
        ).toOption
        val newCompanion: Defn.Object = companion.copy(templ = companion.templ.copy(stats = templateStats))

        Term.Block(Seq(newClass, newCompanion))
      case [email protected](_, name, _, ctor, _) =>
        val result: ExtractionResult = Dilate.newtypeApply(name, ctor.paramss)
        val newClass: Defn.Class = cls.copy(
          ctor = Ctor.Primary.apply(ctor.mods, ctor.name, result.domain.finalArgs)
        )

        val newCompanion: Defn.Object =
          q"""object ${Term.Name(name.value)} {
            ..${result.template.traits}
            ..${result.template.types}
            ..${result.template.implicitClasses}
          }"""

        Term.Block(Seq(newClass, newCompanion))
      case _ =>
        println(defn.structure)
        abort("@newtype must annotate a class.")
    }
  }
} 
Example 75
Source File: valueclass.scala    From dilate   with Apache License 2.0 5 votes vote down vote up
package com.vitorsvieira.dilate

import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.collection.immutable.Seq
import scala.meta._
import scala.util.Try

@compileTimeOnly("@valueclass macro expands only in compile time.")
final class valueclass extends StaticAnnotation {
  inline def apply(defn: Any): Any = meta {
    defn match {
      case Term.Block(Seq([email protected](_, name, _, ctor, _), companion: Defn.Object)) =>
        val result = Dilate.valueclassApply(name, ctor.paramss)
        val newClass: Defn.Class = cls.copy(
          ctor = Ctor.Primary.apply(ctor.mods, ctor.name, result.domain.finalArgs)
        )

        val templateStats: Option[Seq[Stat]] = Try(
          result.template.valueclasses ++:
            result.template.implicitDefs ++:
            companion.templ.stats.getOrElse(Nil)
        ).toOption
        val newCompanion: Defn.Object = companion.copy(templ = companion.templ.copy(stats = templateStats))

        Term.Block(Seq(newClass, newCompanion))
      case [email protected](_, name, _, ctor, _)                                          =>
        val result: ExtractionResult = Dilate.valueclassApply(name, ctor.paramss)
        val newClass: Defn.Class = cls.copy(
          ctor = Ctor.Primary.apply(ctor.mods, ctor.name, result.domain.finalArgs)
        )

        val newCompanion: Defn.Object =
          q"""object ${Term.Name(name.value)} {
            ..${result.template.valueclasses}
            ..${result.template.implicitDefs}
          }"""

        Term.Block(Seq(newClass, newCompanion))
      case _ =>
        println(defn.structure)
        abort("@valueclass must annotate a class.")
    }
  }
} 
Example 76
Source File: Endpoint.scala    From sbt-reactive-app   with Apache License 2.0 5 votes vote down vote up
package com.lightbend.rp.sbtreactiveapp

import scala.collection.immutable.Seq

sealed trait Endpoint {
  def name: String
  def port: Int
  def protocol: String

  def withName(s: String): Endpoint
}

case class HttpEndpoint(name: String, port: Int, ingress: Seq[HttpIngress]) extends Endpoint {
  val protocol: String = "http"

  def withName(n: String): Endpoint = copy(name = n)
}

object HttpEndpoint {
  def apply(name: String): HttpEndpoint = new HttpEndpoint(name, 0, Vector.empty)
  def apply(name: String, ingress: HttpIngress*): HttpEndpoint = new HttpEndpoint(name, 0, ingress.toVector)
  def apply(name: String, port: Int): HttpEndpoint = new HttpEndpoint(name, port, Vector.empty)
  def apply(name: String, port: Int, ingress: HttpIngress*): HttpEndpoint = new HttpEndpoint(name, port, ingress.toVector)
}

case class TcpEndpoint(name: String, port: Int, ingress: Option[PortIngress]) extends Endpoint {
  val protocol: String = "tcp"

  def withName(n: String): Endpoint = copy(name = n)
}

object TcpEndpoint {
  def apply(name: String): TcpEndpoint = new TcpEndpoint(name, 0, None)
  def apply(name: String, ingress: PortIngress): TcpEndpoint = new TcpEndpoint(name, 0, Some(ingress))
  def apply(name: String, port: Int): TcpEndpoint = new TcpEndpoint(name, port, None)
  def apply(name: String, port: Int, ingress: PortIngress): TcpEndpoint = new TcpEndpoint(name, port, Some(ingress))
}

case class UdpEndpoint(name: String, port: Int, ingress: Option[PortIngress]) extends Endpoint {
  val protocol: String = "udp"

  def withName(n: String): Endpoint = copy(name = n)
}

object UdpEndpoint {
  def apply(name: String): UdpEndpoint = new UdpEndpoint(name, 0, None)
  def apply(name: String, ingress: PortIngress): UdpEndpoint = new UdpEndpoint(name, 0, Some(ingress))
  def apply(name: String, port: Int): UdpEndpoint = new UdpEndpoint(name, port, None)
  def apply(name: String, port: Int, ingress: PortIngress): UdpEndpoint = new UdpEndpoint(name, port, Some(ingress))
} 
Example 77
Source File: Ingress.scala    From sbt-reactive-app   with Apache License 2.0 5 votes vote down vote up
package com.lightbend.rp.sbtreactiveapp

import scala.collection.{ Seq => DefaultSeq }
import scala.collection.immutable.Seq

sealed trait Ingress {
  def ingressPorts: Seq[Int]
}

case class PortIngress(ingressPorts: Seq[Int]) extends Ingress

object PortIngress {
  def apply(ports: Int*): PortIngress = new PortIngress(ports.toVector)
}

case class HttpIngress(ingressPorts: Seq[Int], hosts: Seq[String], paths: Seq[String]) extends Ingress {
  def ++(that: HttpIngress): HttpIngress =
    HttpIngress(ingressPorts ++ that.ingressPorts, hosts = hosts ++ that.hosts, paths = paths ++ that.paths)
}

object HttpIngress {
  def apply(paths: DefaultSeq[String]): HttpIngress =
    new HttpIngress(Vector.empty, Vector.empty, paths.toVector)

  def apply(hosts: DefaultSeq[String], paths: DefaultSeq[String]): HttpIngress =
    new HttpIngress(Vector.empty, hosts.toVector, paths.toVector)

  def apply(ingressPorts: DefaultSeq[Int], hosts: DefaultSeq[String], paths: DefaultSeq[String]): HttpIngress =
    new HttpIngress(ingressPorts.toVector, hosts.toVector, paths.toVector)
} 
Example 78
Source File: helm.scala    From sbt-reactive-app   with Apache License 2.0 5 votes vote down vote up
package com.lightbend.rp.sbtreactiveapp.cmd

import sbt.Logger
import scala.collection.immutable.Seq

object helm {
  def assert(): Unit =
    runSuccess("helm is not installed")(run()("helm", "--help"))

  def init(logger: Logger, serviceAccount: String): Unit = {
    runSuccess("helm init failed")(
      run(logStdErr = Some(logger), logStdOut = Some(logger))("helm", "init", "--service-account", serviceAccount))

    runSuccess("helm repo add failed")(
      run(logStdErr = Some(logger), logStdOut = Some(logger))("helm", "repo", "add", "lightbend-helm-charts", "https://repo.lightbend.com/helm-charts"))

    runSuccess("helm repo update")(
      run(logStdErr = Some(logger), logStdOut = Some(logger))("helm", "repo", "update"))
  }

  def installReactiveSandbox(logger: Logger): Unit =
    runSuccess("helm failed to install reactive sandbox")(
      run(logStdErr = Some(logger), logStdOut = Some(logger))("helm", "install", "lightbend-helm-charts/reactive-sandbox", "--name", "reactive-sandbox"))

  def invoke(logger: Logger, args: Seq[String]): Unit =
    runSuccess("helm failed")(run(logStdErr = Some(logger), logStdOut = Some(logger))("helm" +: args: _*))
} 
Example 79
Source File: rp.scala    From sbt-reactive-app   with Apache License 2.0 5 votes vote down vote up
package com.lightbend.rp.sbtreactiveapp.cmd

import com.lightbend.rp.sbtreactiveapp._;
import sbt.Logger
import scala.collection.immutable.Seq

object rp {
  def assert(): Unit = runSuccess("reactive-cli is not installed")(run()("rp", "version"))

  def generateKubernetesResources(wrapper: String, logger: Logger, additionalArgs: Seq[String]): String = {
    val rpCommand =
      (if (isWindows) Vector("powershell.exe", wrapper, "rp.exe") else Vector(wrapper, "rp")) ++
        Vector("generate-kubernetes-resources", "--generate-all") ++
        additionalArgs

    val (code, stdout, _) = run(logStdErr = Some(logger))(rpCommand: _*)

    if (code != 0) {
      sys.error(s"rp generate-kubernetes-resources failed [$code]")
    }

    stdout.mkString("\n")
  }
} 
Example 80
Source File: minikube.scala    From sbt-reactive-app   with Apache License 2.0 5 votes vote down vote up
package com.lightbend.rp.sbtreactiveapp.cmd

import sbt.Logger
import scala.collection.immutable.Seq

object minikube {
  def assert(): Unit = {
    val minMajor = 0
    val minMinor = 25

    val (code, out, _) = run()("minikube", "version")

    if (code != 0) {
      sys.error(s"minikube is not installed [$code]")
    } else {
      val version = out.headOption.getOrElse("")

      parseVersion(version) match {
        case Some((major, minor, _)) if major > minMajor || (major == minMajor && minor >= minMinor) =>
          val minikubeRunning = run()("minikube", "status")._1 == 0

          if (!minikubeRunning) {
            sys.error(s"minikube is not running; start it with `minikube start`; enable ingress with `minikube addons enable ingress`")
          }

          if (!enabledAddons().contains("ingress")) {
            sys.error(s"minikube ingress addon is not enabled; enable it with `minikube addons enable ingress`")
          }
        case None =>
          sys.error(s"minikube version unparseable [$version]")
        case Some(_) =>
          sys.error(s"minikube version too old, required $minMajor.$minMinor.0 or newer [$version]")
      }
    }
  }

  def invoke(logger: Logger, args: Seq[String]): Unit =
    runSuccess("minikube failed")(run(logStdErr = Some(logger), logStdOut = Some(logger))("minikube" +: args: _*))

  def ip(): String = {
    val (code, out, _) = run()("minikube", "ip")

    if (code != 0 || out.isEmpty) {
      sys.error(s"minikube ip failed [$code]")
    }

    out.head.trim
  }

  private def enabledAddons(): Seq[String] = {
    val (code, out, _) = run()("minikube", "addons", "list")
    if (code != 0) {
      Seq.empty
    } else {
      out.flatMap { line =>
        "- ((?:\\w|-)+): (enabled|disabled)".r.findFirstMatchIn(line).flatMap { matches =>
          if (matches.group(2) == "enabled")
            Some(matches.group(1))
          else
            None
        }
      }
    }
  }

  private[cmd] def parseVersion(version: String): Option[(Int, Int, Int)] =
    "v([0-9]+)[.]([0-9]+)[.]([0-9]+).*"
      .r
      .findFirstMatchIn(version)
      .map { matches =>
        (matches.group(1).toInt, matches.group(2).toInt, matches.group(3).toInt)
      }
} 
Example 81
Source File: package.scala    From sbt-reactive-app   with Apache License 2.0 5 votes vote down vote up
package com.lightbend.rp.sbtreactiveapp

import java.io.File
import java.nio.file.Paths
import org.apache.tools.ant.filters.StringInputStream
import sbt.Logger
import scala.collection.immutable.Seq
import scala.sys.process.{ Process, ProcessLogger }

package object cmd {
  
  private[cmd] def run(
    cwd: File = Paths.get(".").toRealPath().toFile,
    env: Map[String, String] = Map.empty,
    input: Option[String] = None,
    logStdErr: Option[Logger] = None,
    logStdOut: Option[Logger] = None)(args: String*): (Int, Seq[String], Seq[String]) = {
    var outList = List.empty[String]
    var errList = List.empty[String]

    val stringLogger = ProcessLogger(
      { s =>
        outList = s :: outList

        logStdOut.foreach(_.info(s))
      },
      { s =>
        errList = s :: errList

        logStdErr.foreach(_.error(s))
      })

    val exitCode =
      input
        .map(new StringInputStream(_))
        .foldLeft(Process(args, cwd = cwd, env.toVector: _*))(_ #< _)
        .run(stringLogger)
        .exitValue()

    (exitCode, outList.reverse, errList.reverse)
  }

  private[cmd] def runSuccess(failMsg: String)(result: (Int, Seq[String], Seq[String])): Unit = {
    if (result._1 != 0) {
      sys.error(s"$failMsg [${result._1}]")
    }
  }
} 
Example 82
Source File: AppSpec.scala    From sbt-reactive-app   with Apache License 2.0 5 votes vote down vote up
package com.lightbend.rp.sbtreactiveapp

import com.typesafe.sbt.packager.docker
import scala.collection.immutable.Seq

class AppSpec extends UnitSpec {
  "normalizeName" should {
    Seq(
      "hello" -> "hello",
      "hello there" -> "hello-there",
      "?? hello?there++=))" -> "hello-there").foreach { x =>
        val (input, expectedResult) = x
        s"normalize [$input] to [$expectedResult]" in {
          App.normalizeName(input) shouldBe expectedResult
        }
      }
  }

  "labelCommand" should {
    "work for empty" in {
      BasicApp.labelCommand(Seq.empty) shouldBe Seq.empty
    }

    "work for single" in {
      BasicApp.labelCommand(Seq("a" -> "test")) shouldBe Seq(docker.Cmd("LABEL", "a=\"test\""))
    }

    "work for multiple" in {
      BasicApp.labelCommand(
        Seq("a" -> "test", "b" -> "test2", "c" -> "test3")) shouldBe Seq(docker.Cmd("LABEL", "a=\"test\" \\\nb=\"test2\" \\\nc=\"test3\""))
    }
  }
} 
Example 83
Source File: CouchbaseStatements.scala    From akka-persistence-couchbase   with Apache License 2.0 5 votes vote down vote up
package akka.persistence.couchbase.journal

import java.util.concurrent.TimeUnit

import akka.actor.{Actor, ActorLogging}
import akka.persistence.couchbase.CouchbaseJournalConfig
import com.couchbase.client.java.Bucket
import com.couchbase.client.java.document.JsonDocument
import com.couchbase.client.java.document.json.JsonArray
import com.couchbase.client.java.view._
import rx.Observable
import rx.functions.Func1

import scala.collection.immutable.Seq
import scala.concurrent.ExecutionContext
import scala.util.{Failure, Try}

trait CouchbaseStatements extends Actor with ActorLogging {

  def config: CouchbaseJournalConfig

  def bucket: Bucket

  implicit def executionContext: ExecutionContext

  def bySequenceNr(persistenceId: String, from: Long, to: Long): ViewQuery = {
    ViewQuery
      .from("journal", "by_sequenceNr")
      .stale(config.stale)
      .startKey(JsonArray.from(persistenceId, from.asInstanceOf[AnyRef]))
      .endKey(JsonArray.from(persistenceId, to.asInstanceOf[AnyRef]))
  }

  
  def nextKey(name: String): Try[String] = {
    Try {
      val counterKey = s"counter::$name"
      val counter = bucket.counter(counterKey, 1L, 0L).content()
      s"$name-$counter"
    }
  }
} 
Example 84
Source File: DurableEventWriterIntegrationSpec.scala    From eventuate   with Apache License 2.0 5 votes vote down vote up
package com.rbmhtechnology.eventuate.adapter.stream

import akka.actor._
import akka.stream._
import akka.stream.scaladsl._
import akka.stream.testkit.scaladsl._
import akka.testkit.TestKit

import com.rbmhtechnology.eventuate._
import com.rbmhtechnology.eventuate.utilities._

import org.scalatest._

import scala.collection.immutable.Seq

class DurableEventWriterIntegrationSpec extends TestKit(ActorSystem("test")) with WordSpecLike with Matchers with SingleLocationSpecLeveldb {
  implicit val materializer: Materializer = ActorMaterializer()

  val SrcEmitterId = "src-emitter"
  val SrcLogId = "src-log"
  val WriterId = "writer"

  "An emission writer" must {
    "write a DurableEvent stream to a log (with an emission-write strategy) and continue the stream with the logged events" in {
      val writerId = "w1"

      val (src, snk) = TestSource.probe[DurableEvent]
        .via(DurableEventWriter.emissionWriter(WriterId, log))
        .toMat(TestSink.probe[DurableEvent])(Keep.both)
        .run()

      val expected = Seq(
        ("a", WriterId, logId, logId, 1L, VectorTime(logId -> 1L)),
        ("b", WriterId, logId, logId, 2L, VectorTime(logId -> 2L)),
        ("c", WriterId, logId, logId, 3L, VectorTime(logId -> 3L)))

      def extract(e: DurableEvent) =
        (e.payload, e.emitterId, e.processId, e.localLogId, e.localSequenceNr, e.vectorTimestamp)

      snk.request(3)

      src.sendNext(DurableEvent("a"))
      src.sendNext(DurableEvent("b"))
      src.sendNext(DurableEvent("c"))

      snk.expectNextN(3).map(extract) should be(expected)
      snk.cancel()

      Source.fromGraph(DurableEventSource(log)).map(extract).take(3).toMat(Sink.seq)(Keep.right).run().await should be(expected)
    }
  }

  "A replication writer" must {
    "write a Seq[DurableEvent] stream to a log (with a replication-write strategy) and continue the stream with the logged events" in {
      val writerId = "w2"

      val (src, snk) = TestSource.probe[Seq[DurableEvent]]
        .via(DurableEventWriter.replicationWriter(WriterId, log))
        .toMat(TestSink.probe[DurableEvent])(Keep.both)
        .run()

      val expected = Seq(
        ("a", WriterId, logId, logId, 1L, VectorTime(SrcLogId -> 11L, logId -> 1L)),
        ("b", WriterId, logId, logId, 2L, VectorTime(SrcLogId -> 12L, logId -> 2L)),
        ("c", WriterId, logId, logId, 3L, VectorTime(SrcLogId -> 13L, logId -> 3L)))

      def extract(e: DurableEvent) =
        (e.payload, e.emitterId, e.processId, e.localLogId, e.localSequenceNr, e.vectorTimestamp)

      def durableEvent(payload: String, sequenceNr: Long): DurableEvent =
        DurableEvent(payload, SrcEmitterId, processId = SrcLogId, localLogId = SrcLogId, localSequenceNr = sequenceNr, vectorTimestamp = VectorTime(SrcLogId -> sequenceNr))

      snk.request(3)

      src.sendNext(Seq(durableEvent("a", 11)))
      src.sendNext(Seq(durableEvent("b", 12), durableEvent("c", 13)))

      snk.expectNextN(3).map(extract) should be(expected)
      snk.cancel()

      Source.fromGraph(DurableEventSource(log)).map(extract).take(3).toMat(Sink.seq)(Keep.right).run().await should be(expected)
    }
  }
} 
Example 85
Source File: DurableEventProcessorIntegrationSpec.scala    From eventuate   with Apache License 2.0 5 votes vote down vote up
package com.rbmhtechnology.eventuate.adapter.stream

import akka.actor._
import akka.stream._
import akka.stream.scaladsl._
import akka.stream.testkit.scaladsl._
import akka.testkit.TestKit

import com.rbmhtechnology.eventuate._

import org.scalatest._

import scala.collection.immutable.Seq

class DurableEventProcessorIntegrationSpec extends TestKit(ActorSystem("test")) with WordSpecLike with Matchers with SingleLocationSpecLeveldb {
  implicit val materializer: Materializer = ActorMaterializer()

  val SrcEmitterId = "src-emitter"
  val SrcLogId = "src-log"
  val ProcessorId = "processor"

  def durableEvent(payload: String, sequenceNr: Long): DurableEvent =
    DurableEvent(payload, SrcEmitterId, processId = SrcLogId, localLogId = SrcLogId, localSequenceNr = sequenceNr, vectorTimestamp = VectorTime(SrcLogId -> sequenceNr))

  "A DurableEventProcessor" must {
    "support stateless DurableEvent payload stream processing" in {
      def logic(event: DurableEvent): Seq[String] = {
        val common = Seq("1", "2").map(s => s"${event.payload}$s")

        event.payload match {
          case "c" => common.filter(_.startsWith("a"))
          case _   => common.filterNot(_ == "b1")
        }
      }

      val (src, snk) = TestSource.probe[DurableEvent]
        .via(DurableEventProcessor.statelessProcessor(ProcessorId, log)(logic))
        .toMat(TestSink.probe[DurableEvent])(Keep.both)
        .run()

      snk.request(3)

      src.sendNext(durableEvent("a", 11))
      src.sendNext(durableEvent("b", 12))
      src.sendNext(durableEvent("c", 13))

      snk.expectNextN(3).map(_.payload) should be(Seq("a1", "a2", "b2"))
      snk.cancel()
    }
    "support stateful DurableEvent payload stream processing" in {
      def logic(s: Int, event: DurableEvent): (Int, Seq[String]) = {
        val payload = event.payload.toString
        val counter = if (payload.contains("b")) s + 1 else s
        (counter, Seq(s"${payload}1($counter)", s"${payload}2($counter)"))
      }

      val (src, snk) = TestSource.probe[DurableEvent]
        .via(DurableEventProcessor.statefulProcessor(ProcessorId, log)(0)(logic))
        .toMat(TestSink.probe[DurableEvent])(Keep.both)
        .run()

      snk.request(6)

      src.sendNext(durableEvent("a", 11))
      src.sendNext(durableEvent("b", 12))
      src.sendNext(durableEvent("c", 13))

      snk.expectNextN(6).map(_.payload) should be(Seq("a1(0)", "a2(0)", "b1(1)", "b2(1)", "c1(1)", "c2(1)"))
      snk.cancel()
    }
  }
  "support idempotent stream processing" in {
    def logic(event: DurableEvent) =
      Seq(s"${event.payload}-${event.localSequenceNr}")

    val graph = TestSource.probe[DurableEvent]
      .via(DurableEventProcessor.statelessProcessor(ProcessorId, log)(logic))
      .toMat(TestSink.probe[DurableEvent])(Keep.both)

    val (src1, snk1) = graph.run()

    snk1.request(2)
    src1.sendNext(durableEvent("a", 11))
    src1.sendNext(durableEvent("b", 12))
    snk1.expectNextN(2).map(_.payload) should be(Seq("a-11", "b-12"))
    snk1.cancel()

    val (src2, snk2) = graph.run()

    snk2.request(1)
    src2.sendNext(durableEvent("a", 11))
    src2.sendNext(durableEvent("b", 12))
    src2.sendNext(durableEvent("c", 13))
    snk2.expectNextN(1).map(_.payload) should be(Seq("c-13"))
    snk2.cancel()
  }
} 
Example 86
Source File: DurableEventJunctionIntegrationSpec.scala    From eventuate   with Apache License 2.0 5 votes vote down vote up
package com.rbmhtechnology.eventuate.adapter.stream

import akka.NotUsed
import akka.actor._
import akka.stream._
import akka.stream.scaladsl._

import com.rbmhtechnology.eventuate._
import com.rbmhtechnology.eventuate.log.EventLogWriter
import com.rbmhtechnology.eventuate.utilities._

import org.scalatest._

import scala.collection.immutable.Seq

class DurableEventJunctionIntegrationSpec extends WordSpec with Matchers with MultiLocationSpecLeveldb {
  var logA: ActorRef = _
  var logB: ActorRef = _
  var logC: ActorRef = _

  implicit var system: ActorSystem = _
  implicit var materializer: ActorMaterializer = _

  override def beforeEach(): Unit = {
    super.beforeEach()

    val location1 = location("1")
    val endpoint1 = location1.endpoint(Set("A", "B", "C"), Set())

    logA = endpoint1.logs("A")
    logB = endpoint1.logs("B")
    logC = endpoint1.logs("C")

    system = location1.system
    materializer = ActorMaterializer()
  }

  "A DurableEventProcessor" must {
    "be able to process a DurableEvent stream merged from multiple sources" in {
      val emittedA = Seq("a", "b", "c", "d", "e", "f")
      val emittedB = Seq("u", "v", "w", "x", "y", "z")

      val emitterA = new EventLogWriter("e1", logA)
      val emitterB = new EventLogWriter("e2", logB)

      val sourceA = Source.fromGraph(DurableEventSource(logA))
      val sourceB = Source.fromGraph(DurableEventSource(logB))

      val processorC = DurableEventProcessor.statefulProcessor[Int, String]("p1", logC)(0) {
        case (ctr, evt) => (ctr + 1, Seq(s"${evt.payload}-$ctr"))
      }

      emitterA.write(emittedA)
      emitterB.write(emittedB)

      val processedC = sourceA.merge(sourceB).via(processorC).map(_.payload.toString).take(12).toMat(Sink.seq[String])(Keep.right).run().await

      // test total order from stateful processing
      processedC.map(_.substring(2).toInt) should be(0 to 11)
      // test partial order from merging
      processedC.map(_.substring(0, 1)).partition(emittedA.contains) should be((emittedA, emittedB))
    }
    "be able to process a DurableEvent stream broadcast from a shared source" in {
      val emittedA = Seq("a", "b", "c")
      val emitterA = new EventLogWriter("e1", logA)

      val sourceA = Source.fromGraph(DurableEventSource(logA))

      val processorB = DurableEventProcessor.statefulProcessor[Int, String]("p1", logB)(0) {
        case (ctr, evt) => (ctr + 1, Seq(s"${evt.payload}-$ctr"))
      }

      val processorC = DurableEventProcessor.statefulProcessor[Int, String]("p2", logC)(0) {
        case (ctr, evt) => (ctr + 2, Seq(s"${evt.payload}-$ctr"))
      }

      def sink(processor: Graph[FlowShape[DurableEvent, DurableEvent], NotUsed]) =
        Flow.fromGraph(processor).map(_.payload.toString).take(3).toMat(Sink.seq[String])(Keep.right)

      val graph = RunnableGraph.fromGraph(GraphDSL.create(sink(processorB), sink(processorC))(Keep.both) { implicit b => (sink1, sink2) =>
        import GraphDSL.Implicits._

        val bcast = b.add(Broadcast[DurableEvent](2))

        sourceA ~> bcast
        bcast ~> sink1
        bcast ~> sink2

        ClosedShape
      })

      emitterA.write(emittedA)

      val (processedB, processedC) = graph.run()

      processedB.await should be(Seq("a-0", "b-1", "c-2"))
      processedC.await should be(Seq("a-0", "b-2", "c-4"))
    }
  }
} 
Example 87
Source File: BatchWriteStageSpec.scala    From eventuate   with Apache License 2.0 5 votes vote down vote up
package com.rbmhtechnology.eventuate.adapter.stream

import akka.actor._
import akka.stream._
import akka.stream.scaladsl.Keep
import akka.stream.testkit._
import akka.stream.testkit.scaladsl.{ TestSink, TestSource }
import akka.pattern
import akka.testkit._

import com.rbmhtechnology.eventuate.DurableEvent

import org.scalatest._

import scala.collection.immutable.Seq
import scala.concurrent._
import scala.concurrent.duration._
import scala.util.Random

class BatchWriteStageSpec extends TestKit(ActorSystem("test")) with WordSpecLike with Matchers with BeforeAndAfterAll with BeforeAndAfterEach {
  import BatchWriteStage.BatchWriter

  private val settings: DurableEventWriterSettings =
    new DurableEventWriterSettings(system.settings.config)

  implicit val materializer: Materializer =
    ActorMaterializer()

  private var src: TestPublisher.Probe[Seq[DurableEvent]] = _
  private var snk: TestSubscriber.Probe[Seq[DurableEvent]] = _

  override def beforeEach(): Unit = {
    val probes = TestSource.probe[Seq[DurableEvent]]
      .via(new BatchWriteStage(ec => writer(ec)))
      .toMat(TestSink.probe[Seq[DurableEvent]])(Keep.both)
      .run()

    src = probes._1
    snk = probes._2
  }

  override def afterEach(): Unit = {
    snk.cancel()
  }

  override def afterAll(): Unit = {
    TestKit.shutdownActorSystem(system)
    super.afterAll()
  }

  private def random: Int =
    Random.nextInt(100)

  private def writer(implicit ec: ExecutionContext): BatchWriter = events =>
    if (events.exists(_.payload == "boom")) Future(throw TestException)
    else pattern.after(random.millis, system.scheduler)(Future(events))

  "A BatchWriterStage" must {
    "write batches sequentially" in {
      val b1 = Seq("a", "b", "c").map(DurableEvent(_))
      val b2 = Seq("d", "e", "f").map(DurableEvent(_))
      val b3 = Seq("g", "h", "i").map(DurableEvent(_))

      snk.request(3)
      src.sendNext(b1)
      src.sendNext(b2)
      src.sendNext(b3)
      snk.expectNext() should be(b1)
      snk.expectNext() should be(b2)
      snk.expectNext() should be(b3)
    }
    "fail if the batch writer fails" in {
      val b = Seq("a", "boom", "c").map(DurableEvent(_))

      snk.request(3)
      src.sendNext(b)
      snk.expectError(TestException)
    }
  }
} 
Example 88
Source File: NotificationChannel.scala    From eventuate   with Apache License 2.0 5 votes vote down vote up
package com.rbmhtechnology.eventuate.log

import java.util.concurrent.TimeUnit

import akka.actor.Actor
import akka.actor.ActorRef
import com.rbmhtechnology.eventuate._
import com.rbmhtechnology.eventuate.ReplicationProtocol._
import com.typesafe.config.Config

import scala.collection.immutable.Seq
import scala.concurrent.duration.DurationLong
import scala.concurrent.duration.FiniteDuration

class NotificationChannelSettings(config: Config) {
  val registrationExpirationDuration: FiniteDuration =
    config.getDuration("eventuate.log.replication.retry-delay", TimeUnit.MILLISECONDS).millis
}

object NotificationChannel {
  case class Updated(events: Seq[DurableEvent])

  private case class Registration(replicator: ActorRef, currentTargetVersionVector: VectorTime, filter: ReplicationFilter, registrationTime: Long)

  private object Registration {
    def apply(read: ReplicationRead): Registration =
      new Registration(read.replicator, read.currentTargetVersionVector, read.filter, System.nanoTime())
  }
}


class NotificationChannel(logId: String) extends Actor {
  import NotificationChannel._

  private val settings = new NotificationChannelSettings(context.system.settings.config)

  // targetLogId -> subscription
  private var registry: Map[String, Registration] = Map.empty

  // targetLogIds for which a read operation is in progress
  private var reading: Set[String] = Set.empty

  def receive = {
    case Updated(events) =>
      val currentTime = System.nanoTime()
      registry.foreach {
        case (targetLogId, reg) =>
          if (!reading.contains(targetLogId)
            && events.exists(_.replicable(reg.currentTargetVersionVector, reg.filter))
            && currentTime - reg.registrationTime <= settings.registrationExpirationDuration.toNanos)
            reg.replicator ! ReplicationDue
      }
    case r: ReplicationRead =>
      registry += (r.targetLogId -> Registration(r))
      reading += r.targetLogId
    case r: ReplicationReadSuccess =>
      reading -= r.targetLogId
    case r: ReplicationReadFailure =>
      reading -= r.targetLogId
    case w: ReplicationWrite =>
      for {
        id <- w.sourceLogIds
        rr <- registry.get(id)
      } registry += (id -> rr.copy(currentTargetVersionVector = w.metadata(id).currentVersionVector))
  }
} 
Example 89
Source File: SubscriberRegistry.scala    From eventuate   with Apache License 2.0 5 votes vote down vote up
package com.rbmhtechnology.eventuate.log

import akka.actor.ActorRef
import com.rbmhtechnology.eventuate.DurableEvent
import com.rbmhtechnology.eventuate.EventsourcingProtocol._

import scala.collection.immutable.Seq

private case class SubscriberRegistry(
  aggregateRegistry: AggregateRegistry = AggregateRegistry(),
  defaultRegistry: Set[ActorRef] = Set.empty) {

  def registerDefaultSubscriber(subscriber: ActorRef): SubscriberRegistry =
    copy(defaultRegistry = defaultRegistry + subscriber)

  def registerAggregateSubscriber(subscriber: ActorRef, aggregateId: String): SubscriberRegistry =
    copy(aggregateRegistry = aggregateRegistry.add(subscriber, aggregateId))

  def unregisterSubscriber(subscriber: ActorRef): SubscriberRegistry =
    aggregateRegistry.aggregateId(subscriber) match {
      case Some(aggregateId) => copy(aggregateRegistry = aggregateRegistry.remove(subscriber, aggregateId))
      case None              => copy(defaultRegistry = defaultRegistry - subscriber)
    }

  def notifySubscribers(events: Seq[DurableEvent], condition: ActorRef => Boolean = _ => true): Unit =
    events.foreach { event =>
      val written = Written(event)
      // in any case, notify all default subscribers
      // for which condition evaluates to true
      defaultRegistry.foreach(r => if (condition(r)) r ! written)
      // notify subscribers with matching aggregate id
      for {
        aggregateId <- event.destinationAggregateIds
        aggregate <- aggregateRegistry(aggregateId) if condition(aggregate)
      } aggregate ! written
    }
}

private case class AggregateRegistry(
  aggregateRegistry: Map[String, Set[ActorRef]] = Map.empty,
  aggregateRegistryIndex: Map[ActorRef, String] = Map.empty) {

  def apply(aggregateId: String): Set[ActorRef] =
    aggregateRegistry.getOrElse(aggregateId, Set.empty)

  def aggregateId(aggregate: ActorRef): Option[String] =
    aggregateRegistryIndex.get(aggregate)

  def add(aggregate: ActorRef, aggregateId: String): AggregateRegistry = {
    val aggregates = aggregateRegistry.get(aggregateId) match {
      case Some(as) => as + aggregate
      case None     => Set(aggregate)
    }
    copy(
      aggregateRegistry + (aggregateId -> aggregates),
      aggregateRegistryIndex + (aggregate -> aggregateId))
  }

  def remove(aggregate: ActorRef, aggregateId: String): AggregateRegistry = {
    val aggregates = aggregateRegistry.get(aggregateId) match {
      case Some(as) => as - aggregate
      case None     => Set(aggregate)
    }
    copy(
      aggregateRegistry + (aggregateId -> aggregates),
      aggregateRegistryIndex - aggregate)
  }
} 
Example 90
Source File: EventLogWriter.scala    From eventuate   with Apache License 2.0 5 votes vote down vote up
package com.rbmhtechnology.eventuate.log

import akka.actor._

import com.rbmhtechnology.eventuate._

import scala.collection.immutable.Seq
import scala.concurrent.Future
import scala.concurrent.duration._
import scala.util._

private object EventLogWriter {
  class EventLogWriterActor(val id: String, val eventLog: ActorRef, override val aggregateId: Option[String]) extends EventsourcedActor {
    override def onCommand: Receive = {
      case event => persist(event) {
        case Success(r) => sender() ! lastHandledEvent
        case Failure(e) => sender() ! Status.Failure(e)
      }
    }

    override def onEvent: Receive = {
      case event =>
    }
  }
}


  def stop(): Unit =
    system.stop(actor)
} 
Example 91
Source File: FilesystemSnapshotStore.scala    From eventuate   with Apache License 2.0 5 votes vote down vote up
package com.rbmhtechnology.eventuate.snapshot.filesystem

import java.io._
import java.net.URLEncoder

import akka.event.{ LogSource, Logging }
import com.rbmhtechnology.eventuate._
import com.rbmhtechnology.eventuate.snapshot.SnapshotStore
import org.apache.commons.io.IOUtils

import scala.concurrent.Future
import scala.collection.immutable.Seq
import scala.util._

object FilesystemSnapshotStore {
  implicit val logSource = LogSource.fromAnyClass[FilesystemSnapshotStore]
}


class FilesystemSnapshotStore(settings: FilesystemSnapshotStoreSettings, logId: String) extends SnapshotStore {
  private val log = Logging(settings.system, classOf[FilesystemSnapshotStore])
  private val rootDir = new File(settings.rootDir, URLEncoder.encode(logId, "UTF-8"))

  rootDir.mkdirs()

  override def deleteAsync(lowerSequenceNr: Long): Future[Unit] = {
    import settings.writeDispatcher
    Future(delete(lowerSequenceNr))
  }

  override def saveAsync(snapshot: Snapshot): Future[Unit] = {
    import settings.writeDispatcher
    Future(withOutputStream(dstDir(snapshot.metadata.emitterId), snapshot.metadata.sequenceNr)(serialize(_, snapshot)))
  }

  override def loadAsync(emitterId: String): Future[Option[Snapshot]] = {
    import settings.readDispatcher
    Future(load(dstDir(emitterId)))
  }

  def delete(lowerSequenceNr: Long): Unit = for {
    emitterId <- rootDir.listFiles
    emitterDir = dstDir(emitterId.getName)
    sequenceNr <- decreasingSequenceNrs(emitterDir) if sequenceNr >= lowerSequenceNr
  } dstFile(emitterDir, sequenceNr).delete()

  def load(dir: File): Option[Snapshot] = {
    @annotation.tailrec
    def go(snrs: Seq[Long]): Option[Snapshot] = snrs.headOption match {
      case None => None
      case Some(snr) => Try(withInputStream(dir, snr)(deserialize)) match {
        case Success(s) => Some(s)
        case Failure(e) =>
          log.error(e, s"error loading snapshot ${dstFile(dir, snr)}")
          go(snrs.tail)
      }
    }
    go(decreasingSequenceNrs(dir))
  }

  private def serialize(outputStream: OutputStream, snapshot: Snapshot): Unit =
    outputStream.write(settings.serialization.serialize(snapshot).get)

  private def deserialize(inputStream: InputStream): Snapshot =
    settings.serialization.deserialize(IOUtils.toByteArray(inputStream), classOf[Snapshot]).get

  private def withOutputStream(dir: File, snr: Long)(body: OutputStream => Unit): Unit = {
    val dst = dstFile(dir, snr)
    val tmp = tmpFile(dir, snr)

    dir.mkdirs()
    withStream(new BufferedOutputStream(new FileOutputStream(tmp)), body)
    tmp.renameTo(dst)

    // do not keep more than the configured maximum number of snapshot files
    decreasingSequenceNrs(dir).drop(settings.snapshotsPerEmitterMax).foreach { snr =>
      dstFile(dir, snr).delete()
    }
  }

  private def withInputStream[A](dir: File, snr: Long)(body: InputStream => A): A =
    withStream(new BufferedInputStream(new FileInputStream(dstFile(dir, snr))), body)

  private def withStream[A <: Closeable, B](stream: A, p: A => B): B =
    try { p(stream) } finally { stream.close() }

  private val DstFilenamePattern =
    """^snr-(\d+)""".r

  private[eventuate] def dstDir(emitterId: String): File =
    new File(rootDir, URLEncoder.encode(emitterId, "UTF-8"))

  private[eventuate] def dstFile(dstDir: File, sequenceNr: Long): File =
    new File(dstDir, s"snr-${sequenceNr}")

  private[eventuate] def tmpFile(dstDir: File, sequenceNr: Long): File =
    new File(dstDir, s"tmp-${sequenceNr}")

  private[eventuate] def decreasingSequenceNrs(dir: File): Seq[Long] =
    if (!dir.exists) Nil else dir.listFiles.map(_.getName).collect { case DstFilenamePattern(snr) => snr.toLong }.toList.sorted.reverse
} 
Example 92
Source File: BasicReplicationSpec.scala    From eventuate   with Apache License 2.0 5 votes vote down vote up
package com.rbmhtechnology.eventuate

import akka.actor._
import akka.remote.testkit._
import akka.testkit.TestProbe

import com.typesafe.config.Config

import scala.collection.immutable.Seq
import scala.util._

class BasicReplicationConfig(providerConfig: Config) extends MultiNodeReplicationConfig {
  val nodeA = role("nodeA")
  val nodeB = role("nodeB")
  val nodeC = role("nodeC")

  setConfig(providerConfig)
}

object BasicReplicationSpec {
  class ReplicatedActor(val id: String, val eventLog: ActorRef, probe: ActorRef) extends EventsourcedActor {
    def onCommand = {
      case s: String => persist(s) {
        case Success(e) =>
        case Failure(e) => throw e
      }
    }

    def onEvent = {
      case s: String => probe ! s
    }
  }
}

abstract class BasicReplicationSpec(config: BasicReplicationConfig) extends MultiNodeSpec(config) with MultiNodeWordSpec with MultiNodeReplicationEndpoint {
  import BasicReplicationSpec._
  import config._

  def initialParticipants: Int =
    roles.size

  def assertPartialOrder[A](events: Seq[A], sample: A*): Unit = {
    val indices = sample.map(events.indexOf)
    assert(indices == indices.sorted)
  }

  muteDeadLetters(classOf[AnyRef])(system)

  "Event log replication" must {
    "replicate all events by default" in {
      val probe = TestProbe()

      runOn(nodeA) {
        val endpoint = createEndpoint(nodeA.name, Set(node(nodeB).address.toReplicationConnection))
        val actor = system.actorOf(Props(new ReplicatedActor("pa", endpoint.log, probe.ref)))

        actor ! "A1"
        actor ! "A2"
      }

      runOn(nodeB) {
        val endpoint = createEndpoint(nodeB.name, Set(
          node(nodeA).address.toReplicationConnection,
          node(nodeC).address.toReplicationConnection))
        val actor = system.actorOf(Props(new ReplicatedActor("pb", endpoint.log, probe.ref)))

        actor ! "B1"
        actor ! "B2"
      }

      runOn(nodeC) {
        val endpoint = createEndpoint(nodeC.name, Set(node(nodeB).address.toReplicationConnection))
        val actor = system.actorOf(Props(new ReplicatedActor("pc", endpoint.log, probe.ref)))

        actor ! "C1"
        actor ! "C2"
      }

      val actual = probe.expectMsgAllOf("A1", "A2", "B1", "B2", "C1", "C2")

      assertPartialOrder(actual, "A1", "A2")
      assertPartialOrder(actual, "B1", "B2")
      assertPartialOrder(actual, "C1", "C2")

      enterBarrier("finish")
    }
  }
} 
Example 93
Source File: SerializationContext.scala    From eventuate   with Apache License 2.0 5 votes vote down vote up
package com.rbmhtechnology.eventuate.serializer

import akka.actor._
import akka.serialization.Serialization
import akka.serialization.SerializationExtension

import com.typesafe.config.Config

import scala.collection.immutable.Seq
import scala.concurrent.Await
import scala.concurrent.duration._

object SerializationContext {
  class SenderActor(receiver: ActorSelection) extends Actor {
    def receive = {
      case msg => receiver ! msg
    }
  }

  class ReceiverActor(probe: ActorRef) extends Actor {
    def receive = {
      case msg => probe ! msg
    }
  }
}

class SerializationContext(configs: Config*) {
  val systems: Seq[ActorSystem] = configs.toList.zipWithIndex.map {
    case (config, idx) => ActorSystem(s"test-system-${idx + 1}", config)
  }

  val serializations: Seq[Serialization] =
    systems.map(SerializationExtension(_))

  val ports: Seq[Int] =
    systems.map(port)

  def port(system: ActorSystem): Int =
    system.asInstanceOf[ExtendedActorSystem].provider.getDefaultAddress.port.get

  def shutdown(): Unit =
    systems.foreach(system => Await.result(system.terminate(), 10.seconds))
} 
Example 94
Source File: EventsourcedActorCausalitySpec.scala    From eventuate   with Apache License 2.0 5 votes vote down vote up
package com.rbmhtechnology.eventuate

import akka.actor._
import akka.testkit.TestProbe

import org.scalatest._

import scala.collection.immutable.Seq
import scala.util._

object EventsourcedActorCausalitySpec {
  class Collaborator(val id: String, val eventLog: ActorRef, handles: Set[String], probe: ActorRef) extends EventsourcedActor {
    def onCommand = {
      case s: String => persist(s) {
        case Success(e) =>
        case Failure(e) => throw e
      }
    }

    def onEvent = {
      case s: String if handles.contains(s) =>
        probe ! ((s, lastVectorTimestamp, currentVersion))
    }
  }
}

trait EventsourcedActorCausalitySpec extends WordSpec with Matchers with MultiLocationSpec {
  import ReplicationIntegrationSpec.replicationConnection
  import EventsourcedActorCausalitySpec._

  def assertPartialOrder[A](events: Seq[A], sample: A*): Unit = {
    val indices = sample.map(events.indexOf)
    assert(indices == indices.sorted)
  }

  "Event-sourced actors" when {
    "located at different locations" can {
      "track causality" in {
        val logName = "L1"

        val locationA = location("A")
        val locationB = location("B")

        val endpointA = locationA.endpoint(Set(logName), Set(replicationConnection(locationB.port)))
        val endpointB = locationB.endpoint(Set(logName), Set(replicationConnection(locationA.port)))

        val logA = endpointA.logs(logName)
        val logB = endpointB.logs(logName)

        val logIdA = endpointA.logId(logName)
        val logIdB = endpointB.logId(logName)

        val probeA1 = new TestProbe(locationA.system)
        val probeA2 = new TestProbe(locationA.system)
        val probeA3 = new TestProbe(locationA.system)
        val probeB = new TestProbe(locationB.system)

        val actorA1 = locationA.system.actorOf(Props(new Collaborator("pa1", logA, Set("e1", "e2", "e5"), probeA1.ref)))
        val actorA2 = locationA.system.actorOf(Props(new Collaborator("pa2", logA, Set("e3", "e5", "e6"), probeA2.ref)))
        val actorA3 = locationA.system.actorOf(Props(new Collaborator("pa3", logA, Set("e4"), probeA3.ref)))
        val actorB = locationB.system.actorOf(Props(new Collaborator("pb", logB, Set("e1", "e6"), probeB.ref)))

        def vectorTime(a: Long, b: Long) = (a, b) match {
          case (0L, 0L) => VectorTime()
          case (a, 0L)  => VectorTime(logIdA -> a)
          case (0L, b)  => VectorTime(logIdB -> b)
          case (a, b)   => VectorTime(logIdA -> a, logIdB -> b)
        }

        actorB ! "e1"
        probeA1.expectMsg(("e1", vectorTime(0, 1), vectorTime(0, 1)))
        probeB.expectMsg(("e1", vectorTime(0, 1), vectorTime(0, 1)))

        actorA1 ! "e2"
        probeA1.expectMsg(("e2", vectorTime(2, 1), vectorTime(2, 1)))

        actorA2 ! "e3"
        probeA2.expectMsg(("e3", vectorTime(3, 0), vectorTime(3, 0)))

        actorA3 ! "e4"
        probeA3.expectMsg(("e4", vectorTime(4, 0), vectorTime(4, 0)))

        actorA1 ! "e5"
        probeA1.expectMsg(("e5", vectorTime(5, 1), vectorTime(5, 1)))
        probeA2.expectMsg(("e5", vectorTime(5, 1), vectorTime(5, 1)))

        actorA2 ! "e6"
        probeA2.expectMsg(("e6", vectorTime(6, 1), vectorTime(6, 1)))
        probeB.expectMsg(("e6", vectorTime(6, 1), vectorTime(6, 1)))

        // -----------------------------------------------------------
        //  Please note:
        //  - e2 <-> e3 (because e1 -> e2 and e1 <-> e3)
        //  - e3 <-> e4 (but plausible clocks reports e3 -> e4)
        // -----------------------------------------------------------
      }
    }
  }
} 
Example 95
Source File: package.scala    From eventuate   with Apache License 2.0 5 votes vote down vote up
package com.rbmhtechnology.eventuate

import akka.pattern.ask
import akka.testkit.TestProbe
import akka.util.Timeout

import com.rbmhtechnology.eventuate.EventsourcingProtocol._
import com.rbmhtechnology.eventuate.ReplicationFilter.NoFilter
import com.rbmhtechnology.eventuate.ReplicationProtocol._

import scala.collection.immutable.Seq
import scala.concurrent._
import scala.concurrent.duration._

package object utilities {
  val timeoutDuration = 20.seconds

  implicit class AwaitHelper[T](awaitable: Awaitable[T]) {
    def await: T = Await.result(awaitable, timeoutDuration)
  }

  def write(target: ReplicationTarget, events: Seq[String], aggregateId: Option[String] = None): Unit = {
    val system = target.endpoint.system
    val probe = TestProbe()(system)
    target.log ! Write(events.map(DurableEvent(_, target.logId, emitterAggregateId = aggregateId)), system.deadLetters, probe.ref, 0, 0)
    probe.expectMsgClass(classOf[WriteSuccess])
  }

  def read(target: ReplicationTarget): Seq[String] = {
    import target.endpoint.system.dispatcher
    implicit val timeout = Timeout(3.seconds)

    def readEvents: Future[ReplicationReadSuccess] =
      target.log.ask(ReplicationRead(1L, Int.MaxValue, Int.MaxValue, NoFilter, DurableEvent.UndefinedLogId, target.endpoint.system.deadLetters, VectorTime())).mapTo[ReplicationReadSuccess]

    val reading = for {
      res <- readEvents
    } yield res.events.map(_.payload.asInstanceOf[String])

    reading.await
  }

  def replicate(from: ReplicationTarget, to: ReplicationTarget, num: Int = Int.MaxValue): Int = {
    import to.endpoint.system.dispatcher
    implicit val timeout = Timeout(3.seconds)

    def readProgress: Future[GetReplicationProgressSuccess] =
      to.log.ask(GetReplicationProgress(from.logId)).mapTo[GetReplicationProgressSuccess]

    def readEvents(reply: GetReplicationProgressSuccess): Future[ReplicationReadSuccess] =
      from.log.ask(ReplicationRead(reply.storedReplicationProgress + 1, num, Int.MaxValue, NoFilter, to.logId, to.endpoint.system.deadLetters, reply.currentTargetVersionVector)).mapTo[ReplicationReadSuccess]

    def writeEvents(reply: ReplicationReadSuccess): Future[ReplicationWriteSuccess] =
      to.log.ask(ReplicationWrite(reply.events, Map(from.logId -> ReplicationMetadata(reply.replicationProgress, VectorTime.Zero)))).mapTo[ReplicationWriteSuccess]

    val replication = for {
      rps <- readProgress
      res <- readEvents(rps)
      wes <- writeEvents(res)
    } yield wes.events.size

    replication.await
  }
} 
Example 96
Source File: FailureDetectorSpec.scala    From eventuate   with Apache License 2.0 5 votes vote down vote up
package com.rbmhtechnology.eventuate

import akka.actor._
import akka.testkit._

import org.scalatest._

import scala.collection.immutable.Seq
import scala.concurrent.duration._

class FailureDetectorSpec extends TestKit(ActorSystem("test")) with WordSpecLike with Matchers with BeforeAndAfterEach with BeforeAndAfterAll {
  import ReplicationEndpoint._
  import FailureDetector._

  var failureDetector: ActorRef = _

  override def beforeEach(): Unit = {
    failureDetector = system.actorOf(Props(new FailureDetector("A", "L1", 500.millis)))
  }

  override def afterEach(): Unit = {
    system.stop(failureDetector)
  }

  override def afterAll(): Unit = {
    TestKit.shutdownActorSystem(system)
  }

  "A replication failure detector" must {
    "publish availability events to the actor system's event stream" in {
      val probe = TestProbe()

      val cause1 = new Exception("1")
      val cause2 = new Exception("2")

      system.eventStream.subscribe(probe.ref, classOf[Available])
      system.eventStream.subscribe(probe.ref, classOf[Unavailable])

      failureDetector ! AvailabilityDetected
      probe.expectMsg(Available("A", "L1"))
      failureDetector ! FailureDetected(cause1)
      // time passes ...
      probe.expectMsg(Unavailable("A", "L1", Seq(cause1)))
      failureDetector ! AvailabilityDetected
      failureDetector ! AvailabilityDetected // second AvailabilityDetected within limit doesn't publish another Available
      probe.expectMsg(Available("A", "L1"))
      failureDetector ! FailureDetected(cause2)
      // time passes ...
      probe.expectMsg(Unavailable("A", "L1", Seq(cause2)))
      // time passes ...
      probe.expectMsg(Unavailable("A", "L1", Nil))
    }
  }
} 
Example 97
Source File: CassandraEventLogStore.scala    From eventuate   with Apache License 2.0 5 votes vote down vote up
package com.rbmhtechnology.eventuate.log.cassandra

import java.io.Closeable
import java.lang.{ Long => JLong }

import com.datastax.driver.core._
import com.rbmhtechnology.eventuate._
import com.rbmhtechnology.eventuate.log._

import scala.collection.JavaConverters._
import scala.collection.immutable.{ VectorBuilder, Seq }
import scala.concurrent.{ ExecutionContext, Future }

private[eventuate] class CassandraEventLogStore(cassandra: Cassandra, logId: String) {
  val preparedWriteEventStatement: PreparedStatement =
    cassandra.prepareWriteEvent(logId)

  val preparedReadEventsStatement: PreparedStatement =
    cassandra.prepareReadEvents(logId)

  def write(events: Seq[DurableEvent], partition: Long) =
    cassandra.executeBatch { batch =>
      events.foreach { event =>
        batch.add(preparedWriteEventStatement.bind(partition: JLong, event.localSequenceNr: JLong, cassandra.eventToByteBuffer(event)))
      }
    }

  def readAsync(fromSequenceNr: Long, toSequenceNr: Long, max: Int, fetchSize: Int)(implicit executor: ExecutionContext): Future[BatchReadResult] =
    readAsync(fromSequenceNr, toSequenceNr, max, fetchSize, Int.MaxValue, _ => true)

  def readAsync(fromSequenceNr: Long, toSequenceNr: Long, max: Int, scanLimit: Int, fetchSize: Int, filter: DurableEvent => Boolean)(implicit executor: ExecutionContext): Future[BatchReadResult] =
    Future(read(fromSequenceNr, toSequenceNr, max, scanLimit, fetchSize, filter))

  def read(fromSequenceNr: Long, toSequenceNr: Long, max: Int, scanLimit: Int, fetchSize: Int, filter: DurableEvent => Boolean): BatchReadResult = {
    val iter = eventIterator(fromSequenceNr, toSequenceNr, fetchSize)
    val builder = new VectorBuilder[DurableEvent]

    var lastSequenceNr = fromSequenceNr - 1L
    var scanned = 0
    var filtered = 0

    while (iter.hasNext && filtered < max && scanned < scanLimit) {
      val event = iter.next()
      if (filter(event)) {
        builder += event
        filtered += 1
      }
      scanned += 1
      lastSequenceNr = event.localSequenceNr
    }
    BatchReadResult(builder.result(), lastSequenceNr)
  }

  def eventIterator(fromSequenceNr: Long, toSequenceNr: Long, fetchSize: Int): Iterator[DurableEvent] with Closeable =
    new EventIterator(fromSequenceNr, toSequenceNr, fetchSize)

  private class EventIterator(fromSequenceNr: Long, toSequenceNr: Long, fetchSize: Int) extends Iterator[DurableEvent] with Closeable {
    import cassandra.settings._
    import EventLog._

    var currentSequenceNr = math.max(fromSequenceNr, 1L)
    var currentPartition = partitionOf(currentSequenceNr, partitionSize)

    var currentIter = newIter()
    var read = currentSequenceNr != firstSequenceNr(currentPartition, partitionSize)

    def newIter(): Iterator[Row] =
      if (currentSequenceNr > toSequenceNr) Iterator.empty else read(lastSequenceNr(currentPartition, partitionSize) min toSequenceNr).iterator.asScala

    def read(upperSequenceNr: Long): ResultSet =
      cassandra.session.execute(preparedReadEventsStatement.bind(currentPartition: JLong, currentSequenceNr: JLong, upperSequenceNr: JLong).setFetchSize(fetchSize))

    @annotation.tailrec
    final def hasNext: Boolean = {
      if (currentIter.hasNext) {
        true
      } else if (read) {
        // some events read from current partition, try next partition
        currentPartition += 1
        currentSequenceNr = firstSequenceNr(currentPartition, partitionSize)
        currentIter = newIter()
        read = false
        hasNext
      } else  {
        // no events read from current partition, we're done
        false
      }
    }

    def next(): DurableEvent = {
      val row = currentIter.next()
      currentSequenceNr = row.getLong("sequence_nr")
      read = true
      cassandra.eventFromByteBuffer(row.getBytes("event"))
    }

    override def close(): Unit =
      ()
  }
} 
Example 98
Source File: CassandraIndexStore.scala    From eventuate   with Apache License 2.0 5 votes vote down vote up
package com.rbmhtechnology.eventuate.log.cassandra

import java.lang.{ Long => JLong }

import com.datastax.driver.core._

import com.rbmhtechnology.eventuate.DurableEvent
import com.rbmhtechnology.eventuate.log.EventLogClock

import scala.collection.JavaConverters._
import scala.collection.immutable.Seq
import scala.concurrent._

private[eventuate] class CassandraIndexStore(cassandra: Cassandra, logId: String) {
  import CassandraIndex._

  private val preparedReadAggregateEventStatement: PreparedStatement = cassandra.prepareReadAggregateEvents(logId)
  private val preparedWriteAggregateEventStatement: PreparedStatement = cassandra.prepareWriteAggregateEvent(logId)

  def readEventLogClockSnapshotAsync(implicit executor: ExecutionContext): Future[EventLogClock] =
    cassandra.session.executeAsync(cassandra.preparedReadEventLogClockStatement.bind(logId)).map { resultSet =>
      if (resultSet.isExhausted) EventLogClock() else cassandra.clockFromByteBuffer(resultSet.one().getBytes("clock"))
    }

  def writeEventLogClockSnapshotAsync(clock: EventLogClock)(implicit executor: ExecutionContext): Future[EventLogClock] =
    cassandra.session.executeAsync(cassandra.preparedWriteEventLogClockStatement.bind(logId, cassandra.clockToByteBuffer(clock))).map(_ => clock)

  def writeAsync(aggregateEvents: AggregateEvents, clock: EventLogClock)(implicit executor: ExecutionContext): Future[EventLogClock] = {
    for {
      _ <- writeAggregateEventsAsync(aggregateEvents)
      t <- writeEventLogClockSnapshotAsync(clock) // must be after other writes
    } yield t
  }

  def writeAggregateEventsAsync(aggregateEvents: AggregateEvents)(implicit executor: ExecutionContext): Future[Unit] =
    Future.sequence(aggregateEvents.events.map {
      case (aggregateId, events) => writeAggregateEventsAsync(aggregateId, events)
    }).map(_ => ())

  def writeAggregateEventsAsync(aggregateId: String, events: Seq[DurableEvent])(implicit executor: ExecutionContext): Future[Unit] = cassandra.executeBatchAsync { batch =>
    events.foreach(event => batch.add(preparedWriteAggregateEventStatement.bind(aggregateId, event.localSequenceNr: JLong, cassandra.eventToByteBuffer(event))))
  }

  def aggregateEventIterator(aggregateId: String, fromSequenceNr: Long, toSequenceNr: Long, fetchSize: Int): Iterator[DurableEvent] =
    new AggregateEventIterator(aggregateId, fromSequenceNr, toSequenceNr, fetchSize)

  private class AggregateEventIterator(aggregateId: String, fromSequenceNr: Long, toSequenceNr: Long, fetchSize: Int) extends Iterator[DurableEvent] {
    var currentSequenceNr = fromSequenceNr
    var currentIter = newIter()
    var rowCount = 0

    def newIter(): Iterator[Row] =
      if (currentSequenceNr > toSequenceNr) Iterator.empty else read().iterator.asScala

    def read(): ResultSet =
      cassandra.session.execute(preparedReadAggregateEventStatement.bind(aggregateId, currentSequenceNr: JLong, toSequenceNr: JLong).setFetchSize(fetchSize))

    @annotation.tailrec
    final def hasNext: Boolean = {
      if (currentIter.hasNext) {
        true
      } else if (rowCount < cassandra.settings.partitionSize) {
        // all events consumed
        false
      } else {
        // max result set size reached, fetch again
        currentSequenceNr += 1L
        currentIter = newIter()
        rowCount = 0
        hasNext
      }
    }

    def next(): DurableEvent = {
      val row = currentIter.next()
      currentSequenceNr = row.getLong("sequence_nr")
      rowCount += 1
      cassandra.eventFromByteBuffer(row.getBytes("event"))
    }
  }
} 
Example 99
Source File: EventLogPartitioningSpecCassandra.scala    From eventuate   with Apache License 2.0 5 votes vote down vote up
package com.rbmhtechnology.eventuate.log

import akka.actor.ActorSystem
import akka.testkit.{ TestKit, TestProbe }

import com.rbmhtechnology.eventuate.EventsourcingProtocol._
import com.rbmhtechnology.eventuate.SingleLocationSpecCassandra
import com.typesafe.config._

import scala.collection.immutable.Seq

object EventLogPartitioningSpecCassandra {
  val config: Config = ConfigFactory.parseString(
    """
      |akka.loglevel = "ERROR"
      |akka.test.single-expect-default = 20s
      |
      |eventuate.snapshot.filesystem.dir = target/test-snapshot
      |
      |eventuate.log.write-batch-size = 3
      |eventuate.log.cassandra.partition-size = 5
      |eventuate.log.cassandra.default-port = 9142
    """.stripMargin)
}

class EventLogPartitioningSpecCassandra extends TestKit(ActorSystem("test", EventLogPartitioningSpecCassandra.config)) with EventLogSpecSupport with SingleLocationSpecCassandra {
  import EventLogSpec._

  def replay(fromSequenceNr: Long): Seq[(Any, Long)] = {
    val probe = TestProbe()
    log.tell(Replay(fromSequenceNr, None, 0), replyToProbe.ref)
    replyToProbe.expectMsgClass(classOf[ReplaySuccess]).events.map { event =>
      (event.payload, event.localSequenceNr)
    }
  }

  "A Cassandra event log" must {
    "fill a partition with a single batch" in {
      writeEmittedEvents(List(event("a"), event("b"), event("c"), event("d"), event("e")))
      replay(1L) should be(List(("a", 1L), ("b", 2L), ("c", 3L), ("d", 4L), ("e", 5L)))
      replay(4L) should be(List(("d", 4L), ("e", 5L)))
      replay(5L) should be(List(("e", 5L)))
      replay(6L) should be(List())
    }
    "fill a partition with more than one batch" in {
      writeEmittedEvents(List(event("a"), event("b"), event("c")))
      writeEmittedEvents(List(event("d"), event("e")))
      replay(1L) should be(List(("a", 1L), ("b", 2L), ("c", 3L), ("d", 4L), ("e", 5L)))
      replay(5L) should be(List(("e", 5L)))
      replay(6L) should be(List())
    }
    "switch to the next partition if the current partition is full" in {
      writeEmittedEvents(List(event("a"), event("b"), event("c"), event("d"), event("e")))
      writeEmittedEvents(List(event("f"), event("g")))
      replay(1L) should be(List(("a", 1L), ("b", 2L), ("c", 3L), ("d", 4L), ("e", 5L), ("f", 6L), ("g", 7L)))
      replay(5L) should be(List(("e", 5L), ("f", 6L), ("g", 7L)))
      replay(6L) should be(List(("f", 6L), ("g", 7L)))
    }
    "switch to the next partition if the current partition isn't full but doesn't provide enough remaining space for a batch" in {
      val eventsA = List(event("a"), event("b"), event("c"), event("d"))
      val eventsB = List(event("f"), event("g"))

      log ! Write(eventsA, system.deadLetters, replyToProbe.ref, 0, 0)
      log ! Write(eventsB, system.deadLetters, replyToProbe.ref, 0, 0)

      val expectedA = eventsA.zipWithIndex.map {
        case (event, idx) => event.copy(vectorTimestamp = timestamp(1L + idx), processId = logId, localLogId = logId, localSequenceNr = 1L + idx)
      }

      val expectedB = eventsB.zipWithIndex.map {
        case (event, idx) => event.copy(vectorTimestamp = timestamp(6L + idx), processId = logId, localLogId = logId, localSequenceNr = 6L + idx)
      }

      replyToProbe.expectMsg(WriteSuccess(expectedA, 0, 0))
      replyToProbe.expectMsg(WriteSuccess(expectedB, 0, 0))

      replay(1L) should be(List(("a", 1L), ("b", 2L), ("c", 3L), ("d", 4L), ("f", 6L), ("g", 7L)))
      replay(5L) should be(List(("f", 6L), ("g", 7L)))
      replay(6L) should be(List(("f", 6L), ("g", 7L)))
    }
    "reject batches larger than the maximum partition size" in {
      val events = Vector(event("a"), event("b"), event("c"), event("d"), event("e"), event("f"))
      log ! Write(events, system.deadLetters, replyToProbe.ref, 0, 0)
      replyToProbe.expectMsgClass(classOf[WriteFailure])
    }
  }
} 
Example 100
Source File: VertxEventDispatcher.scala    From eventuate   with Apache License 2.0 5 votes vote down vote up
package com.rbmhtechnology.eventuate.adapter.vertx

import com.rbmhtechnology.eventuate.{ DurableEvent, EventsourcedWriter }
import com.rbmhtechnology.eventuate.adapter.vertx.api.EndpointRouter

import scala.collection.immutable.Seq
import scala.concurrent.{ ExecutionContext, Future }

case class EventEnvelope(address: String, evt: DurableEvent)

trait VertxEventDispatcher[R, W] extends EventsourcedWriter[R, W] with ProgressStore[R, W] {
  import context.dispatcher

  def endpointRouter: EndpointRouter

  def dispatch(events: Seq[EventEnvelope])(implicit ec: ExecutionContext): Future[Unit]

  var events: Vector[EventEnvelope] = Vector.empty

  override def onCommand: Receive = {
    case _ =>
  }

  override def onEvent: Receive = {
    case ev =>
      events = endpointRouter.endpoint(ev) match {
        case Some(endpoint) => events :+ EventEnvelope(endpoint, lastHandledEvent)
        case None           => events
      }
  }

  override def write(): Future[W] = {
    val snr = lastSequenceNr
    val ft = dispatch(events).flatMap(x => writeProgress(id, snr))

    events = Vector.empty
    ft
  }

  override def read(): Future[R] =
    readProgress(id)

  override def readSuccess(result: R): Option[Long] =
    Some(progress(result) + 1L)
} 
Example 101
Source File: VertxNoConfirmationSender.scala    From eventuate   with Apache License 2.0 5 votes vote down vote up
package com.rbmhtechnology.eventuate.adapter.vertx

import akka.actor.{ ActorRef, Props }
import com.rbmhtechnology.eventuate.adapter.vertx.api.{ EndpointRouter, StorageProvider }
import io.vertx.core.Vertx

import scala.collection.immutable.Seq
import scala.concurrent.{ ExecutionContext, Future }

private[eventuate] object VertxNoConfirmationSender {
  def props(id: String, eventLog: ActorRef, endpointRouter: EndpointRouter, vertx: Vertx, storageProvider: StorageProvider): Props =
    Props(new VertxNoConfirmationSender(id, eventLog, endpointRouter, vertx, storageProvider))
      .withDispatcher("eventuate.log.dispatchers.write-dispatcher")
}

private[eventuate] class VertxNoConfirmationSender(val id: String, val eventLog: ActorRef, val endpointRouter: EndpointRouter, val vertx: Vertx, val storageProvider: StorageProvider)
  extends VertxEventDispatcher[Long, Long] with VertxSender with SequenceNumberProgressStore {

  override def dispatch(events: Seq[EventEnvelope])(implicit ec: ExecutionContext): Future[Unit] =
    Future(events.foreach(e => send(e.address, e.evt)))
} 
Example 102
Source File: VertxNoConfirmationPublisher.scala    From eventuate   with Apache License 2.0 5 votes vote down vote up
package com.rbmhtechnology.eventuate.adapter.vertx

import akka.actor.{ ActorRef, Props }
import com.rbmhtechnology.eventuate.adapter.vertx.api.{ EndpointRouter, StorageProvider }
import io.vertx.core.Vertx

import scala.collection.immutable.Seq
import scala.concurrent.{ ExecutionContext, Future }

private[eventuate] object VertxNoConfirmationPublisher {
  def props(id: String, eventLog: ActorRef, endpointRouter: EndpointRouter, vertx: Vertx, storageProvider: StorageProvider): Props =
    Props(new VertxNoConfirmationPublisher(id, eventLog, endpointRouter, vertx, storageProvider))
      .withDispatcher("eventuate.log.dispatchers.write-dispatcher")
}

private[eventuate] class VertxNoConfirmationPublisher(val id: String, val eventLog: ActorRef, val endpointRouter: EndpointRouter, val vertx: Vertx, val storageProvider: StorageProvider)
  extends VertxEventDispatcher[Long, Long] with VertxPublisher with SequenceNumberProgressStore {

  override def dispatch(events: Seq[EventEnvelope])(implicit ec: ExecutionContext): Future[Unit] =
    Future(events.foreach(e => publish(e.address, e.evt)))
} 
Example 103
Source File: VertxAdapterSpec.scala    From eventuate   with Apache License 2.0 5 votes vote down vote up
package com.rbmhtechnology.eventuate.adapter.vertx

import akka.actor.ActorSystem
import akka.testkit.TestKit
import com.rbmhtechnology.eventuate.adapter.vertx.api.{ EventProducer, VertxAdapterConfig }
import com.rbmhtechnology.eventuate.log.EventLogWriter
import com.rbmhtechnology.eventuate.log.leveldb.LeveldbEventLog
import com.rbmhtechnology.eventuate.utilities._
import com.rbmhtechnology.eventuate.{ LocationCleanupLeveldb, ReplicationEndpoint }
import com.typesafe.config.Config
import org.scalatest.{ BeforeAndAfterAll, MustMatchers, WordSpecLike }

import scala.collection.immutable.Seq

object VertxAdapterSpec {
  case class Event(id: String)

  val Config = TestConfig.withReplayBatchSize(10)
}

class VertxAdapterSpec extends TestKit(ActorSystem("test", VertxAdapterSpec.Config))
  with WordSpecLike with MustMatchers with BeforeAndAfterAll with StopSystemAfterAll with LocationCleanupLeveldb
  with VertxEnvironment with VertxEventBusProbes {

  import VertxAdapterSpec._
  import utilities._

  val logName = "logA"
  val adapterId = "adapter1"
  var storage: ActorStorageProvider = _
  var endpoint: ReplicationEndpoint = _

  override def config: Config = VertxAdapterSpec.Config

  override def beforeAll(): Unit = {
    super.beforeAll()
    storage = new ActorStorageProvider(adapterId)
    endpoint = new ReplicationEndpoint(id = "1", logNames = Set(logName), logFactory = logId => LeveldbEventLog.props(logId), connections = Set())
  }

  "A VertxAdapter" must {
    "read events from an inbound log and deliver them to the Vert.x eventbus" in {
      val log = endpoint.logs(logName)
      val adapterConfig = VertxAdapterConfig()
        .addProducer(EventProducer.fromLog(log)
          .publishTo {
            case _ => endpoint1.address
          }
          .as("adapter1"))
        .registerDefaultCodecFor(classOf[Event])

      val vertxAdapter = VertxAdapter(adapterConfig, vertx, storage)
      val logWriter = new EventLogWriter("w1", endpoint.logs(logName))

      endpoint.activate()
      vertxAdapter.start()

      logWriter.write(Seq(Event("1"))).await.head

      storage.expectRead(replySequenceNr = 0)
      storage.expectWrite(sequenceNr = 1)

      endpoint1.probe.expectVertxMsg(body = Event("1"))

      logWriter.write(Seq(Event("2"))).await

      storage.expectWrite(sequenceNr = 2)

      endpoint1.probe.expectVertxMsg(body = Event("2"))

      logWriter.write(Seq(Event("3"), Event("4"))).await

      storage.expectWriteAnyOf(sequenceNrs = Seq(3, 4))

      endpoint1.probe.expectVertxMsg(body = Event("3"))
      endpoint1.probe.expectVertxMsg(body = Event("4"))
    }
  }
} 
Example 104
Source File: ImapResponses.scala    From gatling-imap   with GNU Affero General Public License v3.0 5 votes vote down vote up
package com.linagora.gatling.imap.protocol

import java.util.regex.Pattern

import com.sun.mail.imap.protocol.IMAPResponse

import scala.collection.immutable.Seq

case class ImapResponses(responses: Seq[IMAPResponse]) {

  import ImapResponses._

  def mkString(separator: String = ",") = {
    responses.mkString(separator)
  }

  def isBad = responses.lastOption.exists(_.isBAD)

  def isOk = responses.lastOption.exists(_.isOK)

  def isNo = responses.lastOption.exists(_.isNO)

  def countRecent: Option[Int] = {
    responses.map(_.toString).find(_.matches(Recent.regex))
      .map {
        case Recent(actual) => actual.toInt
      }
  }

  def folderList: Seq[String] = {
    responses.map(_.toString).filter(_.matches(List.regex))
      .map {
        case List(name, null) => name
        case List(null, quotedName) => quotedName
      }
  }

  def uidList: Seq[Uid] = {
    responses.map(_.toString).filter(_.matches(UidRegex.regex))
      .map {
        case UidRegex(uid) => Uid(uid.toInt)
      }
  }

  def contains(content: String): Boolean =
    responses.map(_.toString).exists(_.contains(content))
}

object ImapResponses {
  val empty = ImapResponses(Seq.empty)

  private[this] val dotAllFlag = """(?s)"""
  private[this] val startWithStar = """^(?:(?:, )?\*)"""
  private[this] val mailboxName = """(?:"([^"]*)"|([^"\s]*))"""

  private val Recent = (dotAllFlag + startWithStar + """ (\d+) RECENT\s*$""").r
  private val List = ("""^\* LIST .*? """ + mailboxName + """\s*$""").r
  private val UidRegex = (dotAllFlag + startWithStar + """ .*UID (\d+).*$""").r
} 
Example 105
Source File: ImapSessionExecutor.scala    From gatling-imap   with GNU Affero General Public License v3.0 5 votes vote down vote up
package com.linagora.gatling.imap.protocol.command

import akka.actor.ActorRef
import com.linagora.gatling.imap.protocol.{ImapResponses, Response, UserId}
import com.typesafe.scalalogging.Logger
import com.yahoo.imapnio.async.client.ImapFuture
import com.yahoo.imapnio.async.response.ImapAsyncResponse

import scala.collection.immutable.Seq
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global

private[command] object ImapSessionExecutor {
  def listen(self: ActorRef, userId: UserId, getResponse: ImapResponses => Response)(logger: Logger)(response: ImapFuture[ImapAsyncResponse]): Unit = {
    listenWithHandler(self, userId, getResponse, _ => ())(logger)(response)
  }

  def listenWithHandler[T](self: ActorRef, userId: UserId, getResponse: ImapResponses => Response, callback: Future[ImapAsyncResponse] => T)(logger: Logger)(response: ImapFuture[ImapAsyncResponse]): T = {
    import collection.JavaConverters._

    callback(Future {
      val responses = response.get()
      val responsesList = ImapResponses(responses.getResponseLines.asScala.to[Seq])
      logger.trace(s"On response for $userId :\n ${responsesList.mkString("\n")}")
      self ! getResponse(responsesList)
      responses
    })
  }
} 
Example 106
Source File: ImapExpungeScenario.scala    From gatling-imap   with GNU Affero General Public License v3.0 5 votes vote down vote up
package com.linagora.gatling.imap.scenario

import java.util.Calendar

import com.linagora.gatling.imap.PreDef._
import com.typesafe.scalalogging.LazyLogging
import io.gatling.core.Predef._
import io.gatling.core.feeder.FeederBuilder
import io.gatling.core.scenario.Simulation
import io.gatling.core.session.{Expression, _}
import io.gatling.core.structure.ScenarioBuilder

import scala.collection.immutable.Seq
import scala.concurrent.duration._
import scala.util.Random

object ImapExpungeScenario extends Simulation with LazyLogging {
  private val numberOfMailInInbox = Integer.getInteger("numberOfMailInInbox", 1000).intValue()
  private val percentageOfMailToExpunge = Integer.getInteger("percentageOfMailToExpunge", 20).toFloat
  private val maxDurationInMinutes = Integer.getInteger("maxDuration", 15).toFloat minutes

  logger.trace(s"numberOfMailInInbox $numberOfMailInInbox")
  logger.trace(s"percentageOfMailToExpunge $percentageOfMailToExpunge")

  private def getRandomDeleted(): Boolean = Random.nextFloat() < (percentageOfMailToExpunge/ 100.0)

  def flagsWithRandomDeletion: Expression[Session] = (session: Session) => {
    session.set("flags",
      if (getRandomDeleted())
        Some(Seq("\\Flagged", "\\Deleted"))
      else
        Some(Seq("\\Flagged"))
    )
  }

  private val populateMailbox = exec(imap("append").append("INBOX", "${flags}", Option.empty[Calendar],
    """From: [email protected]
      |To: [email protected]
      |Subject: test subject
      |
      |Test content
      |abcdefghijklmnopqrstuvwxyz
      |0123456789""".stripMargin).check(ok))

  private val populateInbox = repeat(numberOfMailInInbox)(exec(flagsWithRandomDeletion).pause(5 millisecond).exec(populateMailbox))

  def apply(feeder: FeederBuilder): ScenarioBuilder = scenario("Imap")
    .feed(feeder)
    .pause(1 second)
    .exec(imap("Connect").connect()).exitHereIfFailed
    .exec(imap("login").login("${username}", "${password}").check(ok))
    .exec(imap("select").select("INBOX").check(ok))
    .exec(populateInbox)
    .exec(imap("expunge").expunge().check(ok))

} 
Example 107
Source File: ImapUIDFetchScenario.scala    From gatling-imap   with GNU Affero General Public License v3.0 5 votes vote down vote up
package com.linagora.gatling.imap.scenario

import java.util.Calendar

import com.linagora.gatling.imap.PreDef._
import com.linagora.gatling.imap.protocol.command.FetchAttributes.AttributeList
import com.linagora.gatling.imap.protocol.command.MessageRange._
import com.linagora.gatling.imap.protocol.command.MessageRanges
import io.gatling.core.Predef._
import io.gatling.core.feeder.FeederBuilder
import io.gatling.core.structure.ScenarioBuilder

import scala.collection.immutable.Seq
import scala.concurrent.duration._

object ImapUIDFetchScenario {
  val numberOfMailInInbox = 1000
  private val appendGracePeriod = 5 milliseconds

  private val populateMailbox = exec(imap("append").append("INBOX", Option.empty[Seq[String]], Option.empty[Calendar],
    """From: [email protected]
      |To: [email protected]
      |Subject: test subject
      |
      |Test content
      |abcdefghijklmnopqrstuvwxyz
      |0123456789""".stripMargin).check(ok))

  private val populateInbox = repeat(numberOfMailInInbox)(pause(appendGracePeriod).exec(populateMailbox))

  private val uidFetch = exec(imap("uidFetch").uidFetch(MessageRanges(Range(1, numberOfMailInInbox)), AttributeList("UID")).check(ok))
  
  def apply(feeder: FeederBuilder): ScenarioBuilder =
    scenario("Imap")
      .feed(feeder)
      .exec(imap("Connect").connect()).exitHereIfFailed
      .exec(imap("login").login("${username}", "${password}").check(ok))
      .exec(imap("select").select("INBOX").check(ok))
      .exec(populateInbox)
      .pause(1 second)
      .exec(repeat(100)(uidFetch))

} 
Example 108
Source File: ImapSimpleScenario.scala    From gatling-imap   with GNU Affero General Public License v3.0 5 votes vote down vote up
package com.linagora.gatling.imap.scenario

import java.util.Calendar

import com.linagora.gatling.imap.PreDef._
import com.linagora.gatling.imap.protocol.command.FetchAttributes.AttributeList
import com.linagora.gatling.imap.protocol.command.MessageRange._
import com.linagora.gatling.imap.protocol.command.{MessageRanges, Silent, StoreFlags}
import io.gatling.core.Predef._
import io.gatling.core.feeder.FeederBuilder
import io.gatling.core.scenario.Simulation
import io.gatling.core.structure.ScenarioBuilder

import scala.collection.immutable.Seq
import scala.concurrent.duration._

object ImapSimpleScenario extends Simulation {
  private val receiveEmail = exec(imap("append").append("INBOX", Some(Seq("\\Flagged")), Option.empty[Calendar],
    """From: [email protected]
      |To: [email protected]
      |Subject: test subject
      |
      |Test content
      |abcdefghijklmnopqrstuvwxyz
      |0123456789""".stripMargin).check(ok))

  def apply(feeder: FeederBuilder): ScenarioBuilder = scenario("Imap")
    .feed(feeder)
    .pause(1 second)
    .exec(imap("Connect").connect()).exitHereIfFailed
    .exec(imap("login").login("${username}", "${password}").check(ok))
    .during(1 minute) {
        exec(imap("list").list("", "*").check(ok, hasFolder("INBOX")))
        .pause(200 milli)
        .exec(imap("select").select("INBOX").check(ok))
        .pause(200 milli)
        .exec(receiveEmail)
        .pause(200 milli)
        .exec(imap("fetch").fetch(MessageRanges(Last()), AttributeList("BODY[HEADER]", "UID", "BODY[TEXT]")).check(ok))
        .pause(200 milli)
        .exec(imap("store").store(MessageRanges(Last()), StoreFlags.add(Silent.Disable(), "\\Deleted")).check(ok))
        .pause(200 milli)
        .exec(imap("expunge").expunge().check(ok))
        .pause(200 milli)
        .exec(imap("fetch").fetch(MessageRanges(Last()), AttributeList("BODY[HEADER]", "UID", "BODY[TEXT]")).check(no))
    }

} 
Example 109
Source File: ImapAuthenticationScenario.scala    From gatling-imap   with GNU Affero General Public License v3.0 5 votes vote down vote up
package com.linagora.gatling.imap.scenario

import com.linagora.gatling.imap.PreDef.{contains, hasFolder, hasRecent, hasUid, imap, ok}
import com.linagora.gatling.imap.protocol.Uid
import com.linagora.gatling.imap.protocol.command.FetchAttributes.AttributeList
import com.linagora.gatling.imap.protocol.command.MessageRange.{From, One, Range, To}
import com.linagora.gatling.imap.protocol.command.MessageRanges
import io.gatling.core.Predef.{scenario, _}
import io.gatling.core.feeder.FeederBuilder
import io.gatling.core.structure.ScenarioBuilder

import scala.collection.immutable.Seq

object ImapAuthenticationScenario {

  def apply(feeder: FeederBuilder): ScenarioBuilder = scenario("ImapAuthentication")
    .feed(feeder)
    .exec(imap("Connect").connect()).exitHereIfFailed
    .exec(imap("login").login("${username}", "${password}").check(ok))
    .exec(imap("list").list("", "*").check(ok, hasFolder("INBOX")))
    .exec(imap("select").select("INBOX").check(ok, hasRecent(0)))
    .exec(imap("append").append(mailbox = "INBOX", flags = Some(Seq("\\Flagged")), date = None,
      content =
        """From: [email protected]
        |To: [email protected]
        |Subject: test subject
        |
        |Test content""".stripMargin).check(ok))
    .exec(imap("fetch").fetch(MessageRanges(One(1), One(2), Range(3,5), From(3), One(8)), AttributeList("BODY", "UID")).check(ok, hasUid(Uid(1)), contains("TEXT")))

} 
Example 110
Source File: StoreAction.scala    From gatling-imap   with GNU Affero General Public License v3.0 5 votes vote down vote up
package com.linagora.gatling.imap.action

import akka.actor.Props
import com.linagora.gatling.imap.check.ImapCheck
import com.linagora.gatling.imap.protocol.{Command, UserId}
import com.linagora.gatling.imap.protocol.command.{MessageRanges, StoreFlags}
import io.gatling.commons.validation.Validation
import io.gatling.core.action.ValidatedActionActor
import io.gatling.core.session._

import scala.collection.immutable.Seq

object StoreAction {
  def props(imapContext: ImapActionContext, requestname: String, checks: Seq[ImapCheck], sequence: Expression[MessageRanges], flags: Expression[StoreFlags]) =
    Props(new StoreAction(imapContext, requestname, checks, sequence, flags))
}

class StoreAction(val imapContext: ImapActionContext, val requestName: String, override val checks: Seq[ImapCheck], sequence: Expression[MessageRanges], flags: Expression[StoreFlags]) extends ValidatedActionActor with ImapActionActor {

  override protected def executeOrFail(session: Session): Validation[_] = {
    for {
      sequence <- sequence(session)
      flags <- flags(session)
    } yield {
      val id: Long = session.userId
      val handler = handleResponse(session, imapContext.clock.nowMillis)
      sessions.tell(Command.Store(UserId(id), sequence, flags), handler)
    }
  }
} 
Example 111
Source File: FetchAction.scala    From gatling-imap   with GNU Affero General Public License v3.0 5 votes vote down vote up
package com.linagora.gatling.imap.action

import akka.actor.Props
import com.linagora.gatling.imap.check.ImapCheck
import com.linagora.gatling.imap.protocol.{Command, UserId}
import com.linagora.gatling.imap.protocol.command.{FetchAttributes, MessageRanges}
import io.gatling.commons.validation.Validation
import io.gatling.core.action.ValidatedActionActor
import io.gatling.core.session._

import scala.collection.immutable.Seq

object FetchAction {
  def props(imapContext: ImapActionContext, requestname: String, checks: Seq[ImapCheck], sequence: Expression[MessageRanges], attributes: Expression[FetchAttributes]) =
    Props(new FetchAction(imapContext, requestname, checks, sequence, attributes))
}

class FetchAction(val imapContext: ImapActionContext, val requestName: String, override val checks: Seq[ImapCheck], sequence: Expression[MessageRanges], attributes: Expression[FetchAttributes]) extends ValidatedActionActor with ImapActionActor {

  override protected def executeOrFail(session: Session): Validation[_] = {
    for {
      sequence <- sequence(session)
      attributes <- attributes(session)
    } yield {
      val id: Long = session.userId
      val handler = handleResponse(session, imapContext.clock.nowMillis)
      sessions.tell(Command.Fetch(UserId(id), sequence, attributes), handler)
    }
  }
} 
Example 112
Source File: UIDFetchAction.scala    From gatling-imap   with GNU Affero General Public License v3.0 5 votes vote down vote up
package com.linagora.gatling.imap.action

import akka.actor.Props
import com.linagora.gatling.imap.check.ImapCheck
import com.linagora.gatling.imap.protocol.{Command, UserId}
import com.linagora.gatling.imap.protocol.command.{FetchAttributes, MessageRanges}
import io.gatling.commons.validation.Validation
import io.gatling.core.action.ValidatedActionActor
import io.gatling.core.session._

import scala.collection.immutable.Seq

object UIDFetchAction {
  def props(imapContext: ImapActionContext, requestname: String, checks: Seq[ImapCheck], sequence: Expression[MessageRanges], attributes: Expression[FetchAttributes]) =
    Props(new UIDFetchAction(imapContext, requestname, checks, sequence, attributes))
}

class UIDFetchAction(val imapContext: ImapActionContext, val requestName: String, override val checks: Seq[ImapCheck], sequence: Expression[MessageRanges], attributes: Expression[FetchAttributes]) extends ValidatedActionActor with ImapActionActor {

  override protected def executeOrFail(session: Session): Validation[_] = {
    for {
      sequence <- sequence(session)
      attributes <- attributes(session)
    } yield {
      val id: Long = session.userId
      val handler = handleResponse(session, imapContext.clock.nowMillis)
      sessions.tell(Command.UIDFetch(UserId(id), sequence, attributes), handler)
    }
  }
} 
Example 113
Source File: AppendAction.scala    From gatling-imap   with GNU Affero General Public License v3.0 5 votes vote down vote up
package com.linagora.gatling.imap.action

import java.util.Calendar

import akka.actor.Props
import com.linagora.gatling.imap.check.ImapCheck
import com.linagora.gatling.imap.protocol.{Command, UserId}
import io.gatling.commons.validation.Validation
import io.gatling.core.action.ValidatedActionActor
import io.gatling.core.session._

import scala.collection.immutable.Seq

object AppendAction {
  def props(imapContext: ImapActionContext, requestname: String, checks: Seq[ImapCheck], mailbox: Expression[String], flags: Expression[Option[Seq[String]]], date: Expression[Option[Calendar]], content: Expression[String]) =
    Props(new AppendAction(imapContext, requestname, checks, mailbox, flags, date, content))
}

class AppendAction(val imapContext: ImapActionContext, val requestName: String, override val checks: Seq[ImapCheck], mailbox: Expression[String], flags: Expression[Option[Seq[String]]], date: Expression[Option[Calendar]], content: Expression[String]) extends ValidatedActionActor with ImapActionActor {

  override protected def executeOrFail(session: Session): Validation[_] = {
    for {
      mailbox <- mailbox(session)
      flags <- flags(session)
      date <- date(session)
      content <- content(session)
    } yield {
      val id: Long = session.userId
      val handler = handleResponse(session, imapContext.clock.nowMillis)
      sessions.tell(Command.Append(UserId(id), mailbox, flags, date, content), handler)
    }
  }
} 
Example 114
Source File: LoginAction.scala    From gatling-imap   with GNU Affero General Public License v3.0 5 votes vote down vote up
package com.linagora.gatling.imap.action

import akka.actor.Props
import com.linagora.gatling.imap.check.ImapCheck
import com.linagora.gatling.imap.protocol.{Command, UserId}
import io.gatling.commons.validation.Validation
import io.gatling.core.action.ValidatedActionActor
import io.gatling.core.session._

import scala.collection.immutable.Seq

object LoginAction {
  def props(imapContext: ImapActionContext, requestName: String, checks: Seq[ImapCheck], username: Expression[String], password: Expression[String]) =
    Props(new LoginAction(imapContext, requestName, checks, username, password))
}

class LoginAction(val imapContext: ImapActionContext,
                  val requestName: String,
                  override val checks: Seq[ImapCheck],
                  username: Expression[String],
                  password: Expression[String]) extends ValidatedActionActor with ImapActionActor {

  override protected def executeOrFail(session: Session): Validation[_] = {
    for {
      user <- username(session)
      pass <- password(session)
    } yield {
      val id: Long = session.userId
      val handler = handleResponse(session, imapContext.clock.nowMillis)
      sessions.tell(Command.Login(UserId(id), user, pass), handler)
    }
  }
} 
Example 115
Source File: SelectAction.scala    From gatling-imap   with GNU Affero General Public License v3.0 5 votes vote down vote up
package com.linagora.gatling.imap.action

import akka.actor.Props
import com.linagora.gatling.imap.check.ImapCheck
import com.linagora.gatling.imap.protocol.{Command, UserId}
import io.gatling.commons.validation.Validation
import io.gatling.core.action.ValidatedActionActor
import io.gatling.core.session._

import scala.collection.immutable.Seq

object SelectAction {
  def props(imapContext: ImapActionContext, requestname: String, checks: Seq[ImapCheck], mailbox: Expression[String]) =
    Props(new SelectAction(imapContext, requestname, checks, mailbox))
}

class SelectAction(val imapContext: ImapActionContext, val requestName: String, override val checks: Seq[ImapCheck], mailbox: Expression[String]) extends ValidatedActionActor with ImapActionActor {

  override protected def executeOrFail(session: Session): Validation[_] = {
    for {
      mailbox <- mailbox(session)
    } yield {
      val id: Long = session.userId
      val handler = handleResponse(session, imapContext.clock.nowMillis)
      sessions.tell(Command.Select(UserId(id), mailbox), handler)
    }
  }
} 
Example 116
Source File: ImapResponseHandler.scala    From gatling-imap   with GNU Affero General Public License v3.0 5 votes vote down vote up
package com.linagora.gatling.imap.action

import akka.actor.Props
import com.linagora.gatling.imap.protocol.Response.Disconnected
import com.linagora.gatling.imap.protocol.{ImapResponses, Response}
import io.gatling.commons.stats.{KO, OK}
import io.gatling.commons.validation.Failure
import io.gatling.core.akka.BaseActor
import io.gatling.core.check.Check
import io.gatling.core.session.Session

import scala.collection.immutable.Seq

object ImapResponseHandler {
  def props(imapActionContext: ImapActionContext, requestName: String, session: Session, start: Long, checks: Seq[Check[ImapResponses]]): Props = {
    Props(new ImapResponseHandler(imapActionContext, requestName, session, start, checks))
  }
}

class ImapResponseHandler(imapActionContext: ImapActionContext, requestName: String, session: Session, start: Long, checks: Seq[Check[ImapResponses]]) extends BaseActor {
  private val statsEngine = imapActionContext.statsEngine
  private val next = imapActionContext.next

  override def receive: Receive = {
    case Response(responses) =>
      val (newSession, error) = Check.check(responses, session, checks.toList)
      error.fold(ok(newSession, start))(ko(session, start))
    case e: Exception =>
      ko(session, start)(Failure(e.getMessage))
    case Disconnected(e) =>
      ko(session, start)(Failure(e.getMessage))
    case msg =>
      logger.error(s"received unexpected message $msg")
  }

  def ko(session: Session, start: Long)(failure: Failure) = {
    statsEngine.logResponse(session, requestName, start, imapActionContext.clock.nowMillis, KO, None, Some(failure.message))
    next ! session.markAsFailed
    context.stop(self)
  }

  def ok(session: Session, start: Long) = {
    statsEngine.logResponse(session, requestName, start, imapActionContext.clock.nowMillis, OK, None, None)
    next ! session
    context.stop(self)
  }
} 
Example 117
Source File: ListAction.scala    From gatling-imap   with GNU Affero General Public License v3.0 5 votes vote down vote up
package com.linagora.gatling.imap.action

import akka.actor.Props
import com.linagora.gatling.imap.check.ImapCheck
import com.linagora.gatling.imap.protocol.{Command, UserId}
import io.gatling.commons.validation.Validation
import io.gatling.core.action.ValidatedActionActor
import io.gatling.core.session._

import scala.collection.immutable.Seq

object ListAction {
  def props(imapContext: ImapActionContext, requestname: String, checks: Seq[ImapCheck], reference: Expression[String], name: Expression[String]) =
    Props(new ListAction(imapContext, requestname, checks, reference, name))
}

class ListAction(val imapContext: ImapActionContext, val requestName: String, override val checks: Seq[ImapCheck], reference: Expression[String], name: Expression[String]) extends ValidatedActionActor with ImapActionActor {

  override protected def executeOrFail(session: Session): Validation[_] = {
    for {
      reference <- reference(session)
      name <- name(session)
    } yield {
      val id: Long = session.userId
      val handler = handleResponse(session, imapContext.clock.nowMillis)
      sessions.tell(Command.List(UserId(id), reference, name), handler)
    }
  }
} 
Example 118
Source File: ExpungeAction.scala    From gatling-imap   with GNU Affero General Public License v3.0 5 votes vote down vote up
package com.linagora.gatling.imap.action

import akka.actor.Props
import com.linagora.gatling.imap.check.ImapCheck
import com.linagora.gatling.imap.protocol.{Command, UserId}
import io.gatling.commons.validation.{Success, Validation}
import io.gatling.core.action.ValidatedActionActor
import io.gatling.core.session._

import scala.collection.immutable.Seq

object ExpungeAction {
  def props(imapContext: ImapActionContext, requestname: String, checks: Seq[ImapCheck]) =
    Props(new ExpungeAction(imapContext, requestname, checks))
}

class ExpungeAction(val imapContext: ImapActionContext, val requestName: String, override val checks: Seq[ImapCheck]) extends ValidatedActionActor with ImapActionActor {

  override protected def executeOrFail(session: Session): Validation[_] = {
    val id: Long = session.userId
    val handler = handleResponse(session, imapContext.clock.nowMillis)
    sessions.tell(Command.Expunge(UserId(id)), handler)

    Success("ok")
  }
} 
Example 119
Source File: Prod.scala    From iota   with Apache License 2.0 5 votes vote down vote up
package iota  //#=cats
package iotaz //#=scalaz

import scala.collection.immutable.Seq


final class Prod[LL <: TList] private(
  val values: Seq[Any]
) {
  type L = LL

  override def equals(anyOther: Any): Boolean = anyOther match {
    case other: Prod[LL] => values == other.values
    case _               => false
  }

  override def hashCode(): Int = {
    values.hashCode()
  }

  override def toString: String =
    s"""Prod(${values.mkString(", ")})"""
}

object Prod {

  //#+scalaz
  import scalaz.Isomorphism._
  def gen[A, R <: TList]: A <=> Prod[R] = macro internal.ProductMacros.prodGen[A, R]
  //#-scalaz

  def apply[L <: TList](args: Any*): Prod[L] =
    macro internal.ProductMacros.prodApply[L]

  def unsafeApply[L <: TList](values: Seq[Any]): Prod[L] =
    new Prod[L](values)

} 
Example 120
Source File: SeqPromisesTest.scala    From reactive-activemq   with Apache License 2.0 5 votes vote down vote up
package akka.stream.integration
package promise

import scala.collection.immutable.Seq
import scala.concurrent.{ Future, Promise }
import scala.util.Try

class SeqPromisesTest extends TestSpec {
  def withPromise[T, U](complete: Try[T] => U, failure: PartialFunction[Throwable, U]): (Promise[T], Future[T]) = {
    val p = Promise[T]()
    val f = p.future
    f.onComplete(complete)
    f.onFailure(failure)
    p -> f
  }

  def withPromises()(f: Seq[(Promise[Unit], Future[Unit])] => Unit): Unit = f(Seq(
    withPromise((_: Try[Unit]) => (), PartialFunction.empty),
    withPromise((_: Try[Unit]) => (), PartialFunction.empty),
    withPromise((_: Try[Unit]) => (), PartialFunction.empty)
  ))

  it should "complete a promise" in withPromises() { xs =>
    xs.head._1.success(())
    xs.head._2.futureValue shouldBe ()
    xs.filterNot(_._1.isCompleted).size shouldBe 2
  }

  it should "complete multiple promises" in withPromises() { xs =>
    xs.zipWithIndex.foreach {
      case ((p, f), 0) =>
        p success (); f.futureValue shouldBe ()
      case ((p, f), 1) =>
        p success (); f.futureValue shouldBe ()
      case ((p, f), 2) =>
        p success (); f.futureValue shouldBe ()
    }
  }
} 
Example 121
Source File: WhiskChangeEventObserverTests.scala    From openwhisk   with Apache License 2.0 5 votes vote down vote up
package org.apache.openwhisk.core.database.cosmosdb.cache
import com.azure.data.cosmos.CosmosItemProperties
import common.StreamLogging
import org.apache.openwhisk.core.database.CacheInvalidationMessage
import org.apache.openwhisk.core.entity.CacheKey
import org.junit.runner.RunWith
import org.scalatest.junit.JUnitRunner
import org.scalatest.{FlatSpec, Matchers}
import spray.json.DefaultJsonProtocol

import scala.collection.immutable.Seq

@RunWith(classOf[JUnitRunner])
class WhiskChangeEventObserverTests extends FlatSpec with Matchers with StreamLogging {
  import WhiskChangeEventObserver.instanceId

  behavior of "CosmosDB extract LSN from Session token"

  it should "parse old session token" in {
    WhiskChangeEventObserver.getSessionLsn("0:12345") shouldBe 12345
  }

  it should "parse new session token" in {
    WhiskChangeEventObserver.getSessionLsn("0:-1#12345") shouldBe 12345
  }

  it should "parse new session token with multiple regional lsn" in {
    WhiskChangeEventObserver.getSessionLsn("0:-1#12345#Region1=1#Region2=2") shouldBe 12345
  }

  behavior of "CosmosDB feed events"

  it should "generate cache events" in {
    val config = InvalidatorConfig(8080, None)
    val docs = Seq(createDoc("foo"), createDoc("bar"))
    val processedDocs = WhiskChangeEventObserver.processDocs(docs, config)

    processedDocs.map(CacheInvalidationMessage.parse(_).get) shouldBe Seq(
      CacheInvalidationMessage(CacheKey("foo"), instanceId),
      CacheInvalidationMessage(CacheKey("bar"), instanceId))
  }

  it should "filter clusterId" in {
    val config = InvalidatorConfig(8080, Some("cid1"))
    val docs = Seq(createDoc("foo", Some("cid2")), createDoc("bar", Some("cid1")), createDoc("baz"))
    val processedDocs = WhiskChangeEventObserver.processDocs(docs, config)

    //Should not include bar as the clusterId matches
    processedDocs.map(CacheInvalidationMessage.parse(_).get) shouldBe Seq(
      CacheInvalidationMessage(CacheKey("foo"), instanceId),
      CacheInvalidationMessage(CacheKey("baz"), instanceId))
  }

  private def createDoc(id: String, clusterId: Option[String] = None): CosmosItemProperties = {
    val cdoc = CosmosDBDoc(id, clusterId)
    val json = CosmosDBDoc.seredes.write(cdoc).compactPrint
    new CosmosItemProperties(json)
  }

  case class CosmosDBDoc(id: String, _clusterId: Option[String], _lsn: Int = 42)

  object CosmosDBDoc extends DefaultJsonProtocol {
    implicit val seredes = jsonFormat3(CosmosDBDoc.apply)
  }

} 
Example 122
Source File: KafkaEventProducer.scala    From openwhisk   with Apache License 2.0 5 votes vote down vote up
package org.apache.openwhisk.core.database.cosmosdb.cache

import akka.Done
import akka.actor.ActorSystem
import akka.kafka.scaladsl.Producer
import akka.kafka.{ProducerMessage, ProducerSettings}
import akka.stream.scaladsl.{Keep, Sink, Source}
import akka.stream.{ActorMaterializer, OverflowStrategy, QueueOfferResult}
import org.apache.kafka.clients.consumer.ConsumerConfig
import org.apache.kafka.clients.producer.ProducerRecord
import org.apache.openwhisk.connector.kafka.KamonMetricsReporter

import scala.collection.immutable.Seq
import scala.concurrent.{ExecutionContext, Future, Promise}

case class KafkaEventProducer(
  settings: ProducerSettings[String, String],
  topic: String,
  eventProducerConfig: EventProducerConfig)(implicit system: ActorSystem, materializer: ActorMaterializer)
    extends EventProducer {
  private implicit val executionContext: ExecutionContext = system.dispatcher

  private val queue = Source
    .queue[(Seq[String], Promise[Done])](eventProducerConfig.bufferSize, OverflowStrategy.dropNew) //TODO Use backpressure
    .map {
      case (msgs, p) =>
        ProducerMessage.multi(msgs.map(newRecord), p)
    }
    .via(Producer.flexiFlow(producerSettings))
    .map {
      case ProducerMessage.MultiResult(_, passThrough) =>
        passThrough.success(Done)
      case _ => //As we use multi mode only other modes need not be handled
    }
    .toMat(Sink.ignore)(Keep.left)
    .run

  override def send(msg: Seq[String]): Future[Done] = {
    val promise = Promise[Done]
    queue.offer(msg -> promise).flatMap {
      case QueueOfferResult.Enqueued    => promise.future
      case QueueOfferResult.Dropped     => Future.failed(new Exception("Kafka request queue is full."))
      case QueueOfferResult.QueueClosed => Future.failed(new Exception("Kafka request queue was closed."))
      case QueueOfferResult.Failure(f)  => Future.failed(f)
    }
  }

  def close(): Future[Done] = {
    queue.complete()
    queue.watchCompletion()
  }

  private def newRecord(msg: String) = new ProducerRecord[String, String](topic, "messages", msg)

  private def producerSettings =
    settings.withProperty(ConsumerConfig.METRIC_REPORTER_CLASSES_CONFIG, KamonMetricsReporter.name)
} 
Example 123
Source File: WhiskChangeEventObserver.scala    From openwhisk   with Apache License 2.0 5 votes vote down vote up
package org.apache.openwhisk.core.database.cosmosdb.cache

import akka.Done
import com.azure.data.cosmos.CosmosItemProperties
import com.azure.data.cosmos.internal.changefeed.ChangeFeedObserverContext
import com.google.common.base.Throwables
import kamon.metric.MeasurementUnit
import org.apache.openwhisk.common.{LogMarkerToken, Logging, MetricEmitter}
import org.apache.openwhisk.core.database.CacheInvalidationMessage
import org.apache.openwhisk.core.database.cosmosdb.CosmosDBConstants
import org.apache.openwhisk.core.database.cosmosdb.CosmosDBUtil.unescapeId
import org.apache.openwhisk.core.entity.CacheKey

import scala.collection.concurrent.TrieMap
import scala.collection.immutable.Seq
import scala.concurrent.{ExecutionContext, Future}
import scala.util.{Failure, Success}

class WhiskChangeEventObserver(config: InvalidatorConfig, eventProducer: EventProducer)(implicit ec: ExecutionContext,
                                                                                        log: Logging)
    extends ChangeFeedObserver {
  import WhiskChangeEventObserver._

  override def process(context: ChangeFeedObserverContext, docs: Seq[CosmosItemProperties]): Future[Done] = {
    //Each observer is called from a pool managed by CosmosDB ChangeFeedProcessor
    //So its fine to have a blocking wait. If this fails then batch would be reread and
    //retried thus ensuring at-least-once semantics
    val f = eventProducer.send(processDocs(docs, config))
    f.andThen {
      case Success(_) =>
        MetricEmitter.emitCounterMetric(feedCounter, docs.size)
        recordLag(context, docs.last)
      case Failure(t) =>
        log.warn(this, "Error occurred while sending cache invalidation message " + Throwables.getStackTraceAsString(t))
    }
  }
}

trait EventProducer {
  def send(msg: Seq[String]): Future[Done]
}

object WhiskChangeEventObserver {
  val instanceId = "cache-invalidator"
  private val feedCounter =
    LogMarkerToken("cosmosdb", "change_feed", "count", tags = Map("collection" -> "whisks"))(MeasurementUnit.none)
  private val lags = new TrieMap[String, LogMarkerToken]

  
  def recordLag(context: ChangeFeedObserverContext, lastDoc: CosmosItemProperties): Unit = {
    val sessionToken = context.getFeedResponse.sessionToken()
    val lsnRef = lastDoc.get("_lsn")
    require(lsnRef != null, s"Non lsn defined in document $lastDoc")

    val lsn = lsnRef.toString.toLong
    val sessionLsn = getSessionLsn(sessionToken)
    val lag = sessionLsn - lsn
    val partitionKey = context.getPartitionKeyRangeId
    val gaugeToken = lags.getOrElseUpdate(partitionKey, createLagToken(partitionKey))
    MetricEmitter.emitGaugeMetric(gaugeToken, lag)
  }

  private def createLagToken(partitionKey: String) = {
    LogMarkerToken("cosmosdb", "change_feed", "lag", tags = Map("collection" -> "whisks", "pk" -> partitionKey))(
      MeasurementUnit.none)
  }

  def getSessionLsn(token: String): Long = {
    // Session Token can be in two formats. Either {PartitionKeyRangeId}:{LSN}
    // or {PartitionKeyRangeId}:{Version}#{GlobalLSN}
    // See https://github.com/Azure/azure-documentdb-changefeedprocessor-dotnet/pull/113/files#diff-54cbd8ddcc33cab4120c8af04869f881
    val parsedSessionToken = token.substring(token.indexOf(":") + 1)
    val segments = parsedSessionToken.split("#")
    val lsn = if (segments.size < 2) segments(0) else segments(1)
    lsn.toLong
  }

  def processDocs(docs: Seq[CosmosItemProperties], config: InvalidatorConfig)(implicit log: Logging): Seq[String] = {
    docs
      .filter { doc =>
        val cid = Option(doc.getString(CosmosDBConstants.clusterId))
        val currentCid = config.clusterId

        //only if current clusterId is configured do a check
        currentCid match {
          case Some(_) => cid != currentCid
          case None    => true
        }
      }
      .map { doc =>
        val id = unescapeId(doc.id())
        log.info(this, s"Changed doc [$id]")
        val event = CacheInvalidationMessage(CacheKey(id), instanceId)
        event.serialize
      }
  }

} 
Example 124
Source File: ChartJson.scala    From temperature-machine   with Apache License 2.0 5 votes vote down vote up
package bad.robot.temperature.rrd

import bad.robot.temperature.rrd.ChartJson._
import io.circe._

import scala.collection.immutable.Seq
import scala.xml.Elem

object ChartJson {

  type Time = String
  type Sensor = String
  type Celsius = String

  def parse(rdd: Elem): List[Series] = {
    val series = (rdd \\ "datasources" \ "name").map(_.text)
    val rows = rdd \\ "data" \ "row"
    val data = rows.map { row =>
      val time = row \ "timestamp"
      val values = row \ "values" \ "v"
      (time.text, values.map(_.text))
    }

    val measurements = data.flatMap { case (time, temperatures) =>
      series.zip(temperatures).map { case (label, temperature) => (time, label, temperature) }
    }

    val bySeries: PartialFunction[(Time, Sensor, Celsius), Sensor] = {
      case (_, sensor, _) => sensor
    }

    val toSeries: PartialFunction[(Sensor, Seq[(Time, Sensor, Celsius)]), Series] = {
      case series => Series(series._1, series._2.map { case (time, _, celsius) => (time, celsius) }.toList)
    }

    measurements
      .groupBy(bySeries)
      .map(toSeries)
      .toList
      .sortBy(_.name)
  }
}

case class Series(name: Sensor, data: List[(Time, Celsius)])

object Series {

  implicit def seriesEncoder: Encoder[Series] = new Encoder[Series] {
    def apply(series: Series): Json = Json.obj(
      ("label", Json.fromString(series.name)),
      ("data" -> data(series.data))
    )
  }

  private def data(measurements: List[(Time, Celsius)]): Json = {
    Json.arr(measurements.map(point): _*)
  }

  private def point(measurement: (Time, Celsius)): Json = {
    Json.obj(
      "x" -> Json.fromLong(Seconds.secondsToDuration(Seconds(measurement._1.toLong)).toMillis),
      "y" -> Json.fromString(measurement._2)
    )
  }

} 
Example 125
Source File: free.scala    From liberator   with MIT License 5 votes vote down vote up
package io.aecor.liberator.macros

import scala.collection.immutable.Seq
import scala.meta._

class free extends scala.annotation.StaticAnnotation {
  inline def apply(defn: Any): Any = meta {
    defn match {
      case Term.Block(Seq(t: Defn.Trait, companion: Defn.Object)) =>
        FreeMacro(t, Some(companion))
      case t: Defn.Trait =>
        FreeMacro(t, None)
    }
  }
}

object FreeMacro {
  def apply(base: Defn.Trait, companion: Option[Defn.Object]): Term.Block = {
    val baseName = base.name
    val abstractParams = base.tparams.dropRight(1)
    val abstractTypes = abstractParams.map(_.name.value).map(Type.Name(_))

    val appliedBase =
      if (abstractTypes.isEmpty) {
        base.name
      } else {
        t"({ type Out[F[_]] = $baseName[..$abstractTypes, F] })#Out"
      }

    val applyWithImplicit = {
      val types = base.tparams.map(_.name.value).map(Type.Name(_))
      q"def apply[..${base.tparams}](implicit instance: $baseName[..$types]): $baseName[..$types] = instance"
    }

    val hasDefinedApplyWithImplicit = companion.flatMap(_.templ.stats).exists(_.exists {
      case q"def apply[..$_](implicit instance: $_[..$_]): $_[..$_] = instance" => true
      case _ => false
    })

    val applyWithImplicitStats = if (hasDefinedApplyWithImplicit) Seq.empty else Seq(applyWithImplicit)

    val companionStats: Seq[Stat] = applyWithImplicitStats ++ Seq(
      q"""
       implicit def freeInstance[..$abstractParams, Alg[_], F[_]](
         implicit algebra: _root_.io.aecor.liberator.Algebra.Aux[$appliedBase, Alg],
         inject: _root_.cats.InjectK[Alg, F]
       ): $baseName[..$abstractTypes, ({type Out[A] = _root_.cats.free.Free[F, A]})#Out] =
         algebra.fromFunctionK(new _root_.cats.arrow.FunctionK[Alg, ({type Out[A] = _root_.cats.free.Free[F, A]})#Out] {
          def apply[A](op: Alg[A]): _root_.cats.free.Free[F, A] = _root_.cats.free.Free.inject(op)
         })
     """
    )

    val newCompanion = companion match {
      case Some(c) =>
        val oldTemplStats = c.templ.stats.getOrElse(Nil)
        c.copy(templ = c.templ.copy(stats = Some(companionStats ++ oldTemplStats)))
      case None =>
        q"object ${Term.Name(baseName.value)} { ..$companionStats }"

    }

    Term.Block(Seq(base, newCompanion))
  }
} 
Example 126
Source File: functorK.scala    From liberator   with MIT License 5 votes vote down vote up
package io.aecor.liberator.macros

import scala.collection.immutable.Seq
import scala.meta._

class functorK(commonFields: scala.Symbol*) extends scala.annotation.StaticAnnotation {
  inline def apply(defn: Any): Any = meta {
    val commonFields = this match {
      case q"new $_(..$xs)" => xs.map { case ctor"$_(${Lit(x: String)})" => x }.toList
      case _ => Nil
    }
    defn match {
      case Term.Block(Seq(t: Defn.Trait, companion: Defn.Object)) =>
        FunctorKMacro(commonFields, t, Some(companion))
      case t: Defn.Trait =>
        FunctorKMacro(commonFields, t, None)
      case other =>
        defn
    }
  }
}

object FunctorKMacro {

  def apply(commonFields: List[String], base: Defn.Trait, companion: Option[Defn.Object]): Term.Block = {
    val typeName = base.name
    val traitStats = base.templ.stats.get
    val (theF, abstractParams) = (base.tparams.last.name, base.tparams.dropRight(1))
    val abstractTypes = abstractParams.map(_.name.value).map(Type.Name(_))

    val unifiedBase =
      if (abstractTypes.isEmpty) {
        base.name
      } else {
        t"({type X[F[_]] = $typeName[..$abstractTypes, F]})#X"
      }

    val companionStats: Seq[Stat] = Seq(
      q"""
        implicit def liberatorFunctorKInstance[..$abstractParams]: io.aecor.liberator.FunctorK[$unifiedBase] =
          new io.aecor.liberator.FunctorK[$unifiedBase] {
            final def mapK[F[_], G[_]](mf: $typeName[..$abstractTypes, F], fg: _root_.cats.arrow.FunctionK[F, G]): $typeName[..$abstractTypes, G] =
              new ${Ctor.Name(typeName.value)}[..$abstractTypes, G] {
                ..${
                  traitStats.map {
                    case q"def $name[..$tps](..$params): ${someF: Type.Name}[$out]" if someF.value == theF.value =>
                      q"final def $name[..$tps](..$params): G[$out] = fg(mf.$name(..${params.map(_.name.value).map(Term.Name(_))}))"
                    case q"def $name: ${someF: Type.Name}[$out]" if someF.value == theF.value =>
                      q"final def $name: G[$out] = fg(mf.$name)"
                    case other =>
                      abort(s"Illegal method [$other]")
                  }
                }
              }
          }
    """
    )

    val newCompanion = companion match {
      case Some(c) =>
        val oldTemplStats = c.templ.stats.getOrElse(Nil)
        c.copy(templ = c.templ.copy(stats = Some(companionStats ++ oldTemplStats)))
      case None =>
        q"object ${Term.Name(typeName.value)} { ..$companionStats }"

    }

    Term.Block(Seq(base, newCompanion))
  }
} 
Example 127
Source File: reifyInvocations.scala    From liberator   with MIT License 5 votes vote down vote up
package io.aecor.liberator.macros

import scala.annotation.compileTimeOnly
import scala.collection.immutable.Seq
import scala.meta._
import Common._

@compileTimeOnly("Cannot expand @reifyInvocations")
class reifyInvocations extends scala.annotation.StaticAnnotation {
  inline def apply(defn: Any): Any = meta {
    Common.parseTraitAndCompanion(defn) match {
      case Some((t, c)) =>
        ReifiedInvocationsMacro(t, c)
      case None =>
        defn
    }
  }
}

object ReifiedInvocationsMacro {

  def apply(base: Defn.Trait, companion: Defn.Object): Term.Block = {
    val t = Common.Trait.fromDefn(base)

    val unifiedInvocation = t"({type X[A] = _root_.io.aecor.liberator.Invocation[${t.unified}, A]})#X"

    val generatedStats: Seq[Stat] = Seq(
      q"""
        implicit def aecorLiberatorReifiedInvocations[..${t.params}]: _root_.io.aecor.liberator.ReifiedInvocations[${t.unified}] =
          new _root_.io.aecor.liberator.ReifiedInvocations[${t.unified}] {
            final def mapK[F[_], G[_]](mf: ${t.name}[..${t.paramTypes}, F], fg: _root_.cats.arrow.FunctionK[F, G]): ${t.name}[..${t.paramTypes}, G] =
               new ${Ctor.Name(t.name.value)}[..${t.paramTypes}, G] {
                 ..${
                   t.methods.map {
                     case Method(name, tps, params, out) =>
                       if (params.nonEmpty)
                         q"final def $name[..$tps](..$params): G[$out] = fg(mf.$name(..${params.map(_.name.value).map(Term.Name(_))}))"
                       else
                         q"final def $name[..$tps]: G[$out] = fg(mf.$name)"
                   }
                 }
               }

            final val invocations: ${t.name}[..${t.paramTypes}, $unifiedInvocation] = new ${Ctor.Name(t.name.value)}[..${t.paramTypes}, $unifiedInvocation] {
              ..${
                t.methods.map {
                  case Method(name, tps, params, out) =>
                    if (params.nonEmpty)
                      q"""final def $name[..$tps](..$params): _root_.io.aecor.liberator.Invocation[${t.unified}, $out] =
                         new _root_.io.aecor.liberator.Invocation[${t.unified}, $out] {
                           final def invoke[F[_]](mf: ${t.name}[..${t.paramTypes}, F]): F[$out] =
                             mf.$name(..${params.map(_.name.value).map(Term.Name(_))})
                         }
                       """
                    else
                      q"""final def $name[..$tps]: _root_.io.aecor.liberator.Invocation[${t.unified}, $out] =
                         new _root_.io.aecor.liberator.Invocation[${t.unified}, $out] {
                           final def invoke[F[_]](mf: ${t.name}[..${t.paramTypes}, F]): F[$out] =
                             mf.$name
                         }
                       """
                }
              }
            }

          }
    """
    )

    val newCompanion = {
      val currentStats = companion.templ.stats.getOrElse(Nil)
      companion.copy(templ = companion.templ.copy(stats = Some(currentStats ++ generatedStats)))
    }

    Term.Block(Seq(base, newCompanion))
  }
} 
Example 128
Source File: term.scala    From liberator   with MIT License 5 votes vote down vote up
package io.aecor.liberator.macros

import scala.collection.immutable.Seq
import scala.meta._

class term extends scala.annotation.StaticAnnotation {
  inline def apply(defn: Any): Any = meta {
    defn match {
      case Term.Block(Seq(t: Defn.Trait, companion: Defn.Object)) =>
        TermMacro(t, Some(companion))
      case t: Defn.Trait =>
        TermMacro(t, None)
    }
  }
}

object TermMacro {
  def apply(base: Defn.Trait, companion: Option[Defn.Object]): Term.Block = {
    val baseName = base.name
    val abstractParams  = base.tparams.dropRight(1)
    val abstractTypes = abstractParams.map(_.name.value).map(Type.Name(_))

    val appliedBase =
      if (abstractTypes.isEmpty) {
        base.name
      } else {
        t"({ type Out[F[_]] = $baseName[..$abstractTypes, F] })#Out"
      }

    val applyWithImplicit = {
      val types = base.tparams.map(_.name.value).map(Type.Name(_))
      q"def apply[..${base.tparams}](implicit instance: $baseName[..$types]): $baseName[..$types] = instance"
    }

    val hasDefinedApplyWithImplicit = companion.flatMap(_.templ.stats).exists(_.exists {
      case q"def apply[..$_](implicit instance: $_[..$_]): $_[..$_] = instance" => true
      case _ => false
    })

    val applyWithImplicitStats = if (hasDefinedApplyWithImplicit) Seq.empty else Seq(applyWithImplicit)

    val companionStats: Seq[Stat] = applyWithImplicitStats ++ Seq(
      q"""
         implicit def termInstance[..$abstractParams, Alg[_], M[_[_]]](
           implicit algebra: _root_.io.aecor.liberator.Algebra.Aux[$appliedBase, Alg],
           extract: _root_.io.aecor.liberator.Extract[M, $appliedBase]
         ): $baseName[..$abstractTypes, ({type Out[A] = _root_.io.aecor.liberator.Term[M, A]})#Out] =
          algebra.fromFunctionK(new _root_.cats.arrow.FunctionK[Alg, ({type Out[A] = _root_.io.aecor.liberator.Term[M, A]})#Out] {
            def apply[A](op: Alg[A]): _root_.io.aecor.liberator.Term[M, A] =
              _root_.io.aecor.liberator.Term.lift(new _root_.io.aecor.liberator.Term.Invocation[M, A] {
                override def invoke[F[_]](mf: M[F]): F[A] =
                  algebra.toFunctionK(extract(mf))(op)
              })
          })
        """
    )

    val newCompanion = companion match {
      case Some(c) =>
        val existingStats = c.templ.stats.getOrElse(Nil)
        c.copy(templ = c.templ.copy(stats = Some(companionStats ++ existingStats)))
      case None =>
        q"object ${Term.Name(baseName.value)} { ..$companionStats }"

    }

    Term.Block(Seq(base, newCompanion))
  }
} 
Example 129
Source File: ClientSerializerRegistry.scala    From Akka-Cookbook   with MIT License 5 votes vote down vote up
package com.packt.chapter11.trip.impl

import com.lightbend.lagom.scaladsl.playjson.{JsonSerializer, JsonSerializerRegistry}
import scala.collection.immutable.Seq

object ClientSerializerRegistry extends JsonSerializerRegistry {
  override def serializers: Seq[JsonSerializer[_]] = Seq(
    JsonSerializer[Location],
    JsonSerializer[ClientState],
    JsonSerializer[TripStarted],
    JsonSerializer[TripEnded],
    JsonSerializer[LocationAdded],
    JsonSerializer[AddLocation]
  )
} 
Example 130
Source File: HelloWorldEntity.scala    From lagom   with Apache License 2.0 5 votes vote down vote up
package com.example.helloworld.impl

import java.time.LocalDateTime

import akka.Done
import com.lightbend.lagom.scaladsl.persistence.AggregateEventShards
import com.lightbend.lagom.scaladsl.persistence.{ PersistentEntity, AggregateEventTag, AggregateEvent }
import com.lightbend.lagom.scaladsl.persistence.PersistentEntity.ReplyType
import com.lightbend.lagom.scaladsl.playjson.{ JsonSerializer, JsonSerializerRegistry }
import play.api.libs.json.{ Format, Json }

import scala.collection.immutable.Seq

class HelloWorldEntity extends PersistentEntity {

  override type Command = HelloWorldCommand[_]
  override type Event = HelloWorldEvent
  override type State = HelloWorldState

  override def initialState: HelloWorldState = HelloWorldState("Hello", LocalDateTime.now.toString)

  override def behavior: Behavior = {
    case HelloWorldState(message, _) => Actions().onCommand[UseGreetingMessage, Done] {
      case (UseGreetingMessage(newMessage), ctx, state) =>
        ctx.thenPersist(
          GreetingMessageChanged(entityId, newMessage)
        ) { _ =>
          ctx.reply(Done)
        }
    }.onReadOnlyCommand[Hello, String] {
      case (Hello(name), ctx, state) =>
        ctx.reply(s"$message, $name!")
    }.onEvent {
      case (GreetingMessageChanged(_, newMessage), state) =>
        HelloWorldState(newMessage, LocalDateTime.now().toString)
    }
  }
}

case class HelloWorldState(message: String, timestamp: String)
object HelloWorldState {
  implicit val format: Format[HelloWorldState] = Json.format
}

sealed trait HelloWorldEvent extends AggregateEvent[HelloWorldEvent] {
  override def aggregateTag: AggregateEventShards[HelloWorldEvent] = HelloWorldEvent.Tag
}
object HelloWorldEvent {
  val NumShards = 4
  val Tag = AggregateEventTag.sharded[HelloWorldEvent](NumShards)
}

case class GreetingMessageChanged(id:String, message: String) extends HelloWorldEvent
object GreetingMessageChanged {
  implicit val format: Format[GreetingMessageChanged] = Json.format
}

sealed trait HelloWorldCommand[R] extends ReplyType[R]

case class UseGreetingMessage(message: String) extends HelloWorldCommand[Done]
object UseGreetingMessage {
  implicit val format: Format[UseGreetingMessage] = Json.format
}

case class Hello(name: String) extends HelloWorldCommand[String]
object Hello {
  implicit val format: Format[Hello] = Json.format
}

object HelloWorldSerializerRegistry extends JsonSerializerRegistry {
  override def serializers: Seq[JsonSerializer[_]] = Seq(
    JsonSerializer[UseGreetingMessage],
    JsonSerializer[Hello],
    JsonSerializer[GreetingMessageChanged],
    JsonSerializer[HelloWorldState]
  )
} 
Example 131
Source File: LagomDevModeServiceRegistry.scala    From lagom   with Apache License 2.0 5 votes vote down vote up
package com.lightbend.lagom.devmode.internal.scaladsl.registry

import java.net.URI

import akka.NotUsed
import akka.util.ByteString
import com.lightbend.lagom.devmode.internal.registry.ServiceRegistryClient
import com.lightbend.lagom.scaladsl.api.deser.MessageSerializer.NegotiatedDeserializer
import com.lightbend.lagom.scaladsl.api.deser.MessageSerializer.NegotiatedSerializer
import com.lightbend.lagom.scaladsl.api.deser.MessageSerializer
import com.lightbend.lagom.scaladsl.api.deser.StrictMessageSerializer
import com.lightbend.lagom.scaladsl.api.transport.MessageProtocol
import com.lightbend.lagom.scaladsl.api.transport.Method
import com.lightbend.lagom.scaladsl.api.Descriptor
import com.lightbend.lagom.scaladsl.api.Service
import com.lightbend.lagom.scaladsl.api.ServiceAcl
import com.lightbend.lagom.scaladsl.api.ServiceCall
import play.api.libs.functional.syntax._
import play.api.libs.json._

import scala.collection.immutable
import scala.collection.immutable.Seq


trait ServiceRegistry extends Service {
  def register(name: String): ServiceCall[ServiceRegistryService, NotUsed]
  def unregister(name: String): ServiceCall[NotUsed, NotUsed]
  def lookup(name: String, portName: Option[String]): ServiceCall[NotUsed, URI]
  def registeredServices: ServiceCall[NotUsed, immutable.Seq[RegisteredService]]

  import Service._
  import ServiceRegistry._

  def descriptor: Descriptor = {
    named(ServiceRegistryClient.ServiceName)
      .withCalls(
        restCall(Method.PUT, "/services/:id", register _),
        restCall(Method.DELETE, "/services/:id", this.unregister _),
        restCall(Method.GET, "/services/:id?portName", lookup _),
        pathCall("/services", registeredServices)
      )
      .withLocatableService(false)
  }
}

object ServiceRegistry {
  implicit val uriMessageSerializer: MessageSerializer[URI, ByteString] = new StrictMessageSerializer[URI] {
    private val serializer = new NegotiatedSerializer[URI, ByteString] {
      override def serialize(message: URI): ByteString = ByteString.fromString(message.toString, "utf-8")
      override val protocol: MessageProtocol           = MessageProtocol.empty.withContentType("text/plain").withCharset("utf-8")
    }
    override def serializerForRequest                                                  = serializer
    override def serializerForResponse(acceptedMessageProtocols: Seq[MessageProtocol]) = serializer

    override def deserializer(protocol: MessageProtocol): NegotiatedDeserializer[URI, ByteString] =
      new NegotiatedDeserializer[URI, ByteString] {
        override def deserialize(wire: ByteString) =
          URI.create(wire.decodeString(protocol.charset.getOrElse("utf-8")))
      }
  }
}

case class RegisteredService(name: String, url: URI, portName: Option[String])

object RegisteredService {
  import UriFormat.uriFormat
  implicit val format: Format[RegisteredService] = Json.format[RegisteredService]
}

case class ServiceRegistryService(uris: immutable.Seq[URI], acls: immutable.Seq[ServiceAcl])

object ServiceRegistryService {
  def apply(uri: URI, acls: immutable.Seq[ServiceAcl]): ServiceRegistryService = ServiceRegistryService(Seq(uri), acls)

  import UriFormat.uriFormat

  implicit val methodFormat: Format[Method] =
    (__ \ "name").format[String].inmap(new Method(_), _.name)

  implicit val serviceAclFormat: Format[ServiceAcl] =
    (__ \ "method")
      .formatNullable[Method]
      .and((__ \ "pathRegex").formatNullable[String])
      .apply(ServiceAcl.apply, acl => (acl.method, acl.pathRegex))

  implicit val format: Format[ServiceRegistryService] = Json.format[ServiceRegistryService]
}

object UriFormat {
  implicit val uriFormat: Format[URI] =
    implicitly[Format[String]].inmap(URI.create, _.toString)
} 
Example 132
Source File: HelloEntity.scala    From lagom   with Apache License 2.0 5 votes vote down vote up
package docs.scaladsl.mb

import java.time.LocalDateTime

import akka.Done
import com.lightbend.lagom.scaladsl.persistence.AggregateEvent
import com.lightbend.lagom.scaladsl.persistence.AggregateEventTag
import com.lightbend.lagom.scaladsl.persistence.AggregateEventTagger
import com.lightbend.lagom.scaladsl.persistence.PersistentEntity
import com.lightbend.lagom.scaladsl.persistence.PersistentEntity.ReplyType
import com.lightbend.lagom.scaladsl.playjson.JsonSerializerRegistry
import com.lightbend.lagom.scaladsl.playjson.JsonSerializer
import play.api.libs.json.Format
import play.api.libs.json.Json

import scala.collection.immutable.Seq

class HelloEntity extends PersistentEntity {
  override type Command = HelloCommand[_]
  override type Event   = HelloEvent
  override type State   = HelloState

  override def initialState: HelloState = HelloState("Hello", LocalDateTime.now.toString)

  override def behavior: Behavior = {
    case HelloState(message, _) =>
      Actions()
        .onCommand[UseGreetingMessage, Done] {
          // Command handler for the UseGreetingMessage command
          case (UseGreetingMessage(newMessage), ctx, state) =>
            // In response to this command, we want to first persist it as a
            // GreetingMessageChanged event
            ctx.thenPersist(GreetingMessageChanged(newMessage)) {
              // Then once the event is successfully persisted, we respond with done.
              _ =>
                ctx.reply(Done)
            }
        }
        .onReadOnlyCommand[Hello, String] {
          // Command handler for the Hello command
          case (Hello(name, organization), ctx, state) =>
            // Reply with a message built from the current message, and the name of
            // the person we're meant to say hello to.
            ctx.reply(s"$message, $name!")
        }
        .onEvent {
          // Event handler for the GreetingMessageChanged event
          case (GreetingMessageChanged(newMessage), state) =>
            // We simply update the current state to use the greeting message from
            // the event.
            HelloState(newMessage, LocalDateTime.now().toString)
        }
  }
}

case class HelloState(message: String, timestamp: String)

object HelloState {
  implicit val format: Format[HelloState] = Json.format
}

object HelloEventTag {
  val INSTANCE: AggregateEventTag[HelloEvent] = AggregateEventTag[HelloEvent]()
}

sealed trait HelloEvent extends AggregateEvent[HelloEvent] {
  override def aggregateTag: AggregateEventTagger[HelloEvent] = HelloEventTag.INSTANCE
}

case class GreetingMessageChanged(message: String) extends HelloEvent

object GreetingMessageChanged {
  implicit val format: Format[GreetingMessageChanged] = Json.format
}
sealed trait HelloCommand[R] extends ReplyType[R]

case class UseGreetingMessage(message: String) extends HelloCommand[Done]

object UseGreetingMessage {
  implicit val format: Format[UseGreetingMessage] = Json.format
}

case class Hello(name: String, organization: Option[String]) extends HelloCommand[String]

object Hello {
  implicit val format: Format[Hello] = Json.format
}

object HelloSerializerRegistry extends JsonSerializerRegistry {
  override def serializers: Seq[JsonSerializer[_]] = Seq(
    JsonSerializer[UseGreetingMessage],
    JsonSerializer[Hello],
    JsonSerializer[GreetingMessageChanged],
    JsonSerializer[HelloState]
  )
} 
Example 133
Source File: BlogPostService.scala    From lagom   with Apache License 2.0 5 votes vote down vote up
package docs.scaladsl.mb

import com.lightbend.lagom.scaladsl.api.broker.Topic
import com.lightbend.lagom.scaladsl.api.broker.kafka.KafkaProperties
import com.lightbend.lagom.scaladsl.api.broker.kafka.PartitionKeyStrategy
import com.lightbend.lagom.scaladsl.api.Descriptor
import com.lightbend.lagom.scaladsl.api.Service
import play.api.libs.json._

import scala.collection.immutable.Seq


trait BlogPostService extends Service {
  final override def descriptor: Descriptor = {
    import Service._

    //#withTopics
    named("blogpostservice")
      .withTopics(
        topic("blogposts", blogPostEvents)
          .addProperty(
            KafkaProperties.partitionKeyStrategy,
            PartitionKeyStrategy[BlogPostEvent](_.postId)
          )
      )
    //#withTopics
  }

  def blogPostEvents: Topic[BlogPostEvent]
}

//#content
sealed trait BlogPostEvent {
  def postId: String
}

case class BlogPostCreated(postId: String, title: String) extends BlogPostEvent

case class BlogPostPublished(postId: String) extends BlogPostEvent
//#content

//#content-formatters
case object BlogPostCreated {
  implicit val blogPostCreatedFormat: Format[BlogPostCreated] = Json.format
}

case object BlogPostPublished {
  implicit val blogPostPublishedFormat: Format[BlogPostPublished] = Json.format
}
//#content-formatters

//#polymorphic-play-json
object BlogPostEvent {
  implicit val reads: Reads[BlogPostEvent] = {
    (__ \ "event_type").read[String].flatMap {
      case "postCreated"   => implicitly[Reads[BlogPostCreated]].map(identity)
      case "postPublished" => implicitly[Reads[BlogPostPublished]].map(identity)
      case other           => Reads(_ => JsError(s"Unknown event type $other"))
    }
  }
  implicit val writes: Writes[BlogPostEvent] = Writes { event =>
    val (jsValue, eventType) = event match {
      case m: BlogPostCreated   => (Json.toJson(m)(BlogPostCreated.blogPostCreatedFormat), "postCreated")
      case m: BlogPostPublished => (Json.toJson(m)(BlogPostPublished.blogPostPublishedFormat), "postPublished")
    }
    jsValue.transform(__.json.update((__ \ 'event_type).json.put(JsString(eventType)))).get
  }
}

//#polymorphic-play-json 
Example 134
Source File: Customer.scala    From lagom   with Apache License 2.0 5 votes vote down vote up
package docs.home.scaladsl.serialization.v2a

import com.lightbend.lagom.scaladsl.playjson.JsonMigration
import com.lightbend.lagom.scaladsl.playjson.JsonSerializerRegistry
import play.api.libs.json.JsObject
import play.api.libs.json.JsPath
import play.api.libs.json.Json
import play.api.libs.json.Reads

import scala.collection.immutable.Seq

//#structural
case class Address(street: String, city: String, zipCode: String, country: String)

case class Customer(name: String, address: Address, shippingAddress: Option[Address])
//#structural

object Customer {
  implicit val addressFormat = Json.format[Address]
  val customerFormat         = Json.format[Customer]
}

class CustomerMigration extends JsonSerializerRegistry {
  override def serializers = Seq.empty

  // format: off
  //#structural-migration
  import play.api.libs.json._
  import play.api.libs.functional.syntax._

  val customerMigration = new JsonMigration(2) {

    // use arbitrary logic to parse an Address
    // out of the old schema
    val readOldAddress: Reads[Address] = {
      (JsPath \ "street")
        .read[String]
        .and(
          (JsPath \ "city").read[String])
        .and(
          (JsPath \ "zipCode").read[String])
        .and(
          (JsPath \ "country").read[String])(Address)
    }

    override def transform(fromVersion: Int, json: JsObject): JsObject = {
      if (fromVersion < 2) {
        val address           = readOldAddress.reads(json).get
        val withoutOldAddress = json - "street" - "city" - "zipCode" - "country"

        // use existing formatter to write the address in the new schema
        withoutOldAddress + ("address" -> Customer.addressFormat.writes(address))
      } else {
        json
      }
    }
  }

  override def migrations: Map[String, JsonMigration] = Map(
    classOf[Customer].getName -> customerMigration
  )
  //#structural-migration
  // format: on
} 
Example 135
Source File: MessageSerializerSpec.scala    From lagom   with Apache License 2.0 5 votes vote down vote up
package com.lightbend.lagom.scaladsl.api.deser

import akka.util.ByteString
import com.lightbend.lagom.scaladsl.api.deser.MessageSerializer._
import com.lightbend.lagom.scaladsl.api.transport.DeserializationException
import com.lightbend.lagom.scaladsl.api.transport.MessageProtocol
import play.api.libs.json._
import scala.collection.immutable.Seq
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec

class MessageSerializerSpec extends AnyWordSpec with Matchers {
  case class Dummy(prop: Option[String])

  "ByteString-to-PlayJson (via JsValueMessageSerializer)" should {
    "deserialize empty ByteString as JSON null" in {
      val deserializer = JsValueMessageSerializer.deserializer(MessageProtocol.empty)
      deserializer.deserialize(ByteString.empty) shouldBe JsNull
    }
  }

  implicit def optionFormat[T: Format]: Format[Option[T]] = new Format[Option[T]] {
    override def reads(json: JsValue): JsResult[Option[T]] = json.validateOpt[T]
    override def writes(o: Option[T]): JsValue = o match {
      case Some(t) => implicitly[Writes[T]].writes(t)
      case None    => JsNull
    }
  }

  "PlayJson-to-RequestPayload formatters" should {
    implicit val format: Format[Dummy] = Json.format

    "fail when converting JSNull into T." in {
      intercept[JsResultException] {
        JsNull.as[Dummy]
      }
    }

    "convert JS null to None by default" in {
      val dummy = JsNull.as[Option[Dummy]]
      dummy shouldBe None
    }
  }

  "ByteString-to-RequestPayload (for JSON payloads, using jsValueFormatMessageSerializer)" should {
    "deserialize empty ByteString's to Option[T] as None" in {
      val serializer = jsValueFormatMessageSerializer(JsValueMessageSerializer, optionFormat[String])
      val out        = serializer.deserializer(MessageProtocol.empty).deserialize(ByteString.empty)
      out shouldBe None
    }

    "fail to deserialize empty ByteString to Dummy(prop: Option[T])" in {
      val format: Format[Dummy] = Json.format
      val serializer            = jsValueFormatMessageSerializer(JsValueMessageSerializer, format)

      intercept[DeserializationException] {
        serializer.deserializer(MessageProtocol.empty).deserialize(ByteString.empty)
      }
    }
  }

  "ByteString-to-ByteString" should {
    "serialize any request of type ByteString to the same ByteSting" in {
      val serializer = NoopMessageSerializer.serializerForRequest
      val out        = serializer.serialize(ByteString("sample string"))
      out shouldBe ByteString("sample string")
    }

    "serialize any response of type ByteString to the same ByteSting" in {
      val serializer = NoopMessageSerializer.serializerForResponse(Seq(MessageProtocol.empty))
      val out        = serializer.serialize(ByteString("sample string"))
      out shouldBe ByteString("sample string")
    }

    "deserialize any ByteString's to the same ByteSting" in {
      val deserializer = NoopMessageSerializer.deserializer(MessageProtocol.empty)
      val out          = deserializer.deserialize(ByteString("sample string"))
      out shouldBe ByteString("sample string")
    }
  }
} 
Example 136
Source File: MarathonApiServiceDiscovery.scala    From akka-management   with Apache License 2.0 5 votes vote down vote up
package akka.discovery.marathon

import java.net.InetAddress

import akka.actor.ActorSystem
import akka.discovery._
import akka.http.scaladsl._
import akka.http.scaladsl.model._
import akka.http.scaladsl.unmarshalling.Unmarshal
import akka.stream.ActorMaterializer
import scala.collection.immutable.Seq
import scala.concurrent.Future
import scala.concurrent.duration.FiniteDuration
import scala.util.Try

import AppList._
import JsonFormat._
import akka.annotation.ApiMayChange
import akka.discovery.ServiceDiscovery.{ Resolved, ResolvedTarget }
import akka.event.Logging

@ApiMayChange
object MarathonApiServiceDiscovery {

  
@ApiMayChange
class MarathonApiServiceDiscovery(system: ActorSystem) extends ServiceDiscovery {
  import MarathonApiServiceDiscovery._
  import system.dispatcher

  private val log = Logging(system, getClass)

  private val http = Http()(system)

  private val settings = Settings(system)

  private implicit val mat: ActorMaterializer = ActorMaterializer()(system)

  override def lookup(lookup: Lookup, resolveTimeout: FiniteDuration): Future[Resolved] = {
    val uri =
      Uri(settings.appApiUrl).withQuery(
        Uri.Query(
          "embed" -> "apps.tasks",
          "embed" -> "apps.deployments",
          "label" -> settings.appLabelQuery.format(lookup.serviceName)))

    val request = HttpRequest(uri = uri)

    log.info("Requesting seed nodes by: {}", request.uri)

    val portName = lookup.portName match {
      case Some(name) => name
      case None       => settings.appPortName
    }

    for {
      response <- http.singleRequest(request)

      entity <- response.entity.toStrict(resolveTimeout)

      appList <- {
        log.debug("Marathon API entity: [{}]", entity.data.utf8String)
        val unmarshalled = Unmarshal(entity).to[AppList]

        unmarshalled.failed.foreach { _ =>
          log.error(
            "Failed to unmarshal Marathon API response status [{}], entity: [{}], uri: [{}]",
            response.status.value,
            entity.data.utf8String,
            uri)
        }
        unmarshalled
      }

    } yield Resolved(lookup.serviceName, targets(appList, portName))
  }

} 
Example 137
Source File: autoApplyK.scala    From cats-tagless   with Apache License 2.0 5 votes vote down vote up
package cats.tagless

import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.collection.immutable.Seq
import scala.reflect.macros.whitebox


@compileTimeOnly("Cannot expand @autoApplyK")
class autoApplyK(autoDerivation: Boolean = true) extends StaticAnnotation {
  def macroTransform(annottees: Any*): Any = macro autoApplyKMacros.newDef
}

private [tagless] class autoApplyKMacros(override val c: whitebox.Context) extends MacroUtils with CovariantKMethodsGenerator {
  import c.universe._

  private def generateApplyKFor(algebraName: String)(algebraType: Tree, typeParams: Seq[TypeDef]) =
    typeClassInstance(
      TermName("applyKFor" + algebraName),
      typeParams,
      tq"_root_.cats.tagless.ApplyK[$algebraType]",
      q"_root_.cats.tagless.Derive.applyK[$algebraType]"
    )

  def instanceDef(algebra: AlgDefn.UnaryAlg): Tree =
    algebra.forVaryingEffectType(generateApplyKFor(algebra.name))

  def newDef(annottees: c.Tree*): c.Tree =
    enrichAlgebra(annottees.toList)(algebra => instanceDef(algebra) :: companionMapKDef(algebra) :: autoDerivationDef(algebra) :: Nil)
} 
Example 138
Source File: autoApply.scala    From cats-tagless   with Apache License 2.0 5 votes vote down vote up
package cats.tagless

import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.collection.immutable.Seq
import scala.reflect.macros.whitebox


@compileTimeOnly("Cannot expand @autoApply")
class autoApply extends StaticAnnotation {
  def macroTransform(annottees: Any*): Any = macro autoApplyMacros.applyInst
}


private[tagless] class autoApplyMacros(override val c: whitebox.Context) extends MacroUtils {
  import c.universe._

  private def generateApplyFor(algebraName: String)(algebraType: Tree, typeParams: Seq[TypeDef]) =
    typeClassInstance(
      TermName("applyFor" + algebraName),
      typeParams,
      tq"_root_.cats.Apply[$algebraType]",
      q"_root_.cats.tagless.Derive.apply[$algebraType]"
    )

  def applyInst(annottees: c.Tree*): c.Tree =
    enrichAlgebra(annottees.toList, AlgebraResolver.LastRegularTypeParam) { algebra =>
      algebra.forVaryingEffectType(generateApplyFor(algebra.name)) :: Nil
    }
} 
Example 139
Source File: autoProductNK.scala    From cats-tagless   with Apache License 2.0 5 votes vote down vote up
package cats.tagless
import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.collection.immutable.Seq
import scala.reflect.macros.whitebox


@compileTimeOnly("Cannot expand @autoProductK")
class autoProductNK extends StaticAnnotation {
  def macroTransform(annottees: Any*): Any = macro autoProductNKMacros.productKInst
}

private [tagless] class autoProductNKMacros(override val c: whitebox.Context) extends MacroUtils {
  import c.universe._

  def productMethod(typedef: TypeDefinition)(arity: Int): Tree = {
    def af(n: Int) = TermName("af" + n)

    val name = typedef.ident
    val range = 1 to arity

    // tparam"F1[_], F2[_], F3[_]"
    val effectTypeParams: List[TypeDef] =
      range.map(n => createTypeParam("F" + n, 1)).toList
    val effectTypeParamsNames = tArgs(effectTypeParams)

    //Tuple3K
    val productTypeName = tq"_root_.cats.tagless.${TypeName("Tuple" + arity + "K")}"

    val methods = typedef.impl.body.map {
      case q"def $method[..$typeParams](...$paramLists): ${_}[$resultType]" =>
        val returnItems = range.map(n => q"${af(n)}.$method(...${argumentLists(paramLists)})")
        q"""def $method[..$typeParams](...$paramLists): $productTypeName[..$effectTypeParamsNames]#λ[$resultType] =
           (..$returnItems)
        """

      case statement =>
        abort(s"autoProductK does not support algebra with such statement: $statement")
    }

    //af1: A[F1], af2: A[F2], af3: A[F3]
    val inboundInterpreters: Seq[ValDef] =
      (range zip effectTypeParamsNames).map {
        case (idx, fx) =>
          ValDef(
            Modifiers(Flag.PARAM),
            af(idx),
            typedef.applied(fx),
            EmptyTree
          )
      }

    q"""
        def ${TermName("product" + arity + "K")}[..$effectTypeParams](..$inboundInterpreters): $name[$productTypeName[..$effectTypeParamsNames]#λ] =
          new $name[$productTypeName[..$effectTypeParamsNames]#λ] {
            ..$methods
          }
      """

  }

  def productKInst(annottees: c.Tree*): c.Tree =
    enrich(annottees.toList) { td =>
      val productMethods = (3 to 9).map(productMethod(td))
      Seq(td.defn, addStats(td.companion, productMethods))
    }
} 
Example 140
Source File: autoInvariantK.scala    From cats-tagless   with Apache License 2.0 5 votes vote down vote up
package cats.tagless

import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.collection.immutable.Seq
import scala.reflect.macros.whitebox


@compileTimeOnly("Cannot expand @autoInvariantK")
class autoInvariantK(autoDerivation: Boolean = true) extends StaticAnnotation {
  def macroTransform(annottees: Any*): Any = macro autoInvariantKMacros.newDef
}

private [tagless] class autoInvariantKMacros(override val c: whitebox.Context) extends MacroUtils {
  import c.universe._

  private def generateInvariantKFor(algebraName: String)(algebraType: Tree, typeParams: Seq[TypeDef]) =
    typeClassInstance(
      TermName("invariantKFor" + algebraName),
      typeParams,
      tq"_root_.cats.tagless.InvariantK[$algebraType]",
      q"_root_.cats.tagless.Derive.invariantK[$algebraType]"
    )

  def instanceDef(algebra: AlgDefn.UnaryAlg): Tree =
    algebra.forVaryingEffectType(generateInvariantKFor(algebra.name))

  def instanceDefFullyRefined(algDefn: AlgDefn.UnaryAlg): Tree = {
    algDefn.forVaryingEffectTypeFullyRefined {
      (algebraType, tparams) =>
        val impl = Seq(
          generateInvariantKFor("FullyRefined" + algDefn.name)(
            algebraType,
            tparams
          ),
          generateAutoDerive(algDefn.fullyRefinedTypeSig)(
            algebraType,
            tparams
          )
        )
        q"object fullyRefined { ..$impl }"
    }
  }

  def companionIMapKDef(algDefn: AlgDefn.UnaryAlg) = {
    val from = TermName("af")
    val F = createFreshTypeParam("F", 1)
    val G = createFreshTypeParam("G", 1)
    val algebraF = algDefn.newTypeSig(F)
    val fullyRefinedAlgebraG = algDefn.dependentRefinedTypeSig(G, from)

    algDefn.forVaryingEffectType((algebraType, tparams) => q"""
      def imapK[$F, $G, ..$tparams]($from: $algebraF)(fk: _root_.cats.~>[..${tArgs(F, G)}])(gk: _root_.cats.~>[..${tArgs(G, F)}]): $fullyRefinedAlgebraG =
        _root_.cats.tagless.InvariantK[$algebraType].imapK($from)(fk)(gk).asInstanceOf[$fullyRefinedAlgebraG]
    """)
  }

  def generateAutoDerive(newTypeSig: TypeDef => TypTree)(algebraType: Tree, tparams: Seq[TypeDef]) = {
    val F = createFreshTypeParam("F", 1)
    val G = createFreshTypeParam("G", 1)
    val algebraF = newTypeSig(F)
    val algebraG = newTypeSig(G)

    q"""
      object autoDerive {
        @SuppressWarnings(Array("org.wartremover.warts.ImplicitParameter"))
        implicit def fromFunctorK[$F, $G, ..$tparams](
          implicit af: $algebraF,
          IK: _root_.cats.tagless.InvariantK[$algebraType],
          fk: _root_.cats.~>[..${tArgs(F, G)}],
          gk: _root_.cats.~>[..${tArgs(G, F)}])
          : $algebraG = IK.imapK(af)(fk)(gk)
      }"""
  }

  def autoDerivationDef(algDefn: AlgDefn.UnaryAlg) =
    if(autoDerive) algDefn.forVaryingEffectType(generateAutoDerive(algDefn.newTypeSig)) else EmptyTree

  def newDef(annottees: c.Tree*): c.Tree =
    enrichAlgebra(annottees.toList)(algebra => instanceDef(algebra) :: companionIMapKDef(algebra) :: instanceDefFullyRefined(algebra) :: autoDerivationDef(algebra) :: Nil)
} 
Example 141
Source File: autoSemigroupal.scala    From cats-tagless   with Apache License 2.0 5 votes vote down vote up
package cats.tagless

import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.collection.immutable.Seq
import scala.reflect.macros.whitebox


@compileTimeOnly("Cannot expand @autoSemigroupal")
class autoSemigroupal extends StaticAnnotation {
  def macroTransform(annottees: Any*): Any = macro autoSemigroupalMacros.semigroupalInst
}


private[tagless] class autoSemigroupalMacros(override val c: whitebox.Context) extends MacroUtils {
  import c.universe._

  private def generateSemigroupalFor(algebraName: String)(algebraType: Tree, typeParams: Seq[TypeDef]) =
    typeClassInstance(
      TermName("semigroupalFor" + algebraName),
      typeParams,
      tq"_root_.cats.Semigroupal[$algebraType]",
      q"_root_.cats.tagless.Derive.semigroupal[$algebraType]"
    )

  def semigroupalInst(annottees: c.Tree*): c.Tree =
    enrichAlgebra(annottees.toList, AlgebraResolver.LastRegularTypeParam) { algebra =>
      algebra.forVaryingEffectType(generateSemigroupalFor(algebra.name)) :: Nil
    }
} 
Example 142
Source File: autoFunctorK.scala    From cats-tagless   with Apache License 2.0 5 votes vote down vote up
package cats.tagless

import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.collection.immutable.Seq
import scala.reflect.macros.whitebox


@compileTimeOnly("Cannot expand @autoFunctorK")
class autoFunctorK(autoDerivation: Boolean = true) extends StaticAnnotation {
  def macroTransform(annottees: Any*): Any = macro autoFunctorKMacros.newDef
}

private [tagless] class autoFunctorKMacros(override val c: whitebox.Context) extends MacroUtils with CovariantKMethodsGenerator {
  import c.universe._

  private def generateFunctorKFor(algebraName: String)(algebraType: Tree, typeParams: Seq[TypeDef]) =
    typeClassInstance(
      TermName("functorKFor" + algebraName),
      typeParams,
      tq"_root_.cats.tagless.FunctorK[$algebraType]",
      q"_root_.cats.tagless.Derive.functorK[$algebraType]"
    )

  def instanceDef(algebra: AlgDefn.UnaryAlg): Tree =
    algebra.forVaryingEffectType(generateFunctorKFor(algebra.name))

  def instanceDefFullyRefined(algDefn: AlgDefn.UnaryAlg): Tree = {
    algDefn.forVaryingEffectTypeFullyRefined {
      (algebraType, tparams) =>
        val impl = Seq(
          generateFunctorKFor("FullyRefined" + algDefn.name)(
            algebraType,
            tparams
          ),
          generateAutoDerive(algDefn.fullyRefinedTypeSig)(
            algebraType,
            tparams
          )
        )
        q"object fullyRefined { ..$impl }"
    }
  }

  def newDef(annottees: c.Tree*): c.Tree =
    enrichAlgebra(annottees.toList)(
      algebra => instanceDef(algebra) :: companionMapKDef(algebra) :: instanceDefFullyRefined(algebra) :: autoDerivationDef(algebra) :: Nil)
}

private [tagless] trait CovariantKMethodsGenerator { self: MacroUtils =>
  import c.universe._

  def companionMapKDef(algDefn: AlgDefn.UnaryAlg) = {
    val from = TermName("af")
    val F = createFreshTypeParam("F", 1)
    val G = createFreshTypeParam("G", 1)
    val algebraF = algDefn.newTypeSig(F)
    val fullyRefinedAlgebraG = algDefn.dependentRefinedTypeSig(G, from)

    algDefn.forVaryingEffectType((algebraType, tparams) => q"""
      def mapK[$F, $G, ..$tparams]($from: $algebraF)(fk: _root_.cats.~>[..${tArgs(F, G)}]): $fullyRefinedAlgebraG =
        _root_.cats.tagless.FunctorK[$algebraType].mapK($from)(fk).asInstanceOf[$fullyRefinedAlgebraG]
    """)
  }

  def generateAutoDerive(newTypeSig: TypeDef => TypTree)(algebraType: Tree, tparams: Seq[TypeDef]) = {
    val F = createFreshTypeParam("F", 1)
    val G = createFreshTypeParam("G", 1)
    val algebraF = newTypeSig(F)
    val algebraG = newTypeSig(G)

    q"""
      object autoDerive {
        @SuppressWarnings(Array("org.wartremover.warts.ImplicitParameter"))
        implicit def fromFunctorK[$F, $G, ..$tparams](
          implicit fk: _root_.cats.~>[..${tArgs(F, G)}],
          FK: _root_.cats.tagless.FunctorK[$algebraType],
          af: $algebraF)
          : $algebraG = FK.mapK(af)(fk)
      }"""
  }

  def autoDerivationDef(algDefn: AlgDefn.UnaryAlg) =
    if(autoDerive) algDefn.forVaryingEffectType(generateAutoDerive(algDefn.newTypeSig)) else EmptyTree

} 
Example 143
Source File: autoContravariant.scala    From cats-tagless   with Apache License 2.0 5 votes vote down vote up
package cats.tagless

import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.collection.immutable.Seq
import scala.reflect.macros.whitebox


@compileTimeOnly("Cannot expand @autoContravariant")
class autoContravariant extends StaticAnnotation {
  def macroTransform(annottees: Any*): Any = macro autoContravariantMacros.contravariantInst
}

private[tagless] class autoContravariantMacros(override val c: whitebox.Context) extends MacroUtils  {
  import c.universe._

  private def generateContravariantFor(algebraName: String)(algebraType: Tree, typeParams: Seq[TypeDef]) =
    typeClassInstance(
      TermName("contravariantFor" + algebraName),
      typeParams,
      tq"_root_.cats.Contravariant[$algebraType]",
      q"_root_.cats.tagless.Derive.contravariant[$algebraType]"
    )

  def contravariantInst(annottees: c.Tree*): c.Tree =
    enrichAlgebra(annottees.toList, AlgebraResolver.LastRegularTypeParam) { algebra =>
      algebra.forVaryingEffectType(generateContravariantFor(algebra.name)) :: Nil
    }
} 
Example 144
Source File: autoSemigroupalK.scala    From cats-tagless   with Apache License 2.0 5 votes vote down vote up
package cats.tagless

import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.collection.immutable.Seq
import scala.reflect.macros.whitebox


@compileTimeOnly("Cannot expand @autoSemigroupalK")
class autoSemigroupalK extends StaticAnnotation {
  def macroTransform(annottees: Any*): Any = macro autoSemigroupalKMacros.semigroupalKInst
}

private[tagless] class autoSemigroupalKMacros(override val c: whitebox.Context) extends MacroUtils  {
  import c.universe._

  private def generateSemigroupalKFor(algebraName: String)(algebraType: Tree, typeParams: Seq[TypeDef]) =
    typeClassInstance(
      TermName("semigroupalKFor" + algebraName),
      typeParams,
      tq"_root_.cats.tagless.SemigroupalK[$algebraType]",
      q"_root_.cats.tagless.Derive.semigroupalK[$algebraType]"
    )

  def semigroupalKInst(annottees: c.Tree*): c.Tree =
    enrichAlgebra(annottees.toList) { algebra =>
      algebra.forVaryingEffectType(generateSemigroupalKFor(algebra.name)) :: Nil
    }
} 
Example 145
Source File: autoFlatMap.scala    From cats-tagless   with Apache License 2.0 5 votes vote down vote up
package cats.tagless

import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.collection.immutable.Seq
import scala.reflect.macros.whitebox


@compileTimeOnly("Cannot expand @autoFlatMap")
class autoFlatMap extends StaticAnnotation {
  def macroTransform(annottees: Any*): Any = macro autoFlatMapMacros.flatMapInst
}


private[tagless] class autoFlatMapMacros(override val c: whitebox.Context) extends MacroUtils {
  import c.universe._

  private def generateFlatMapFor(algebraName: String)(algebraType: Tree, typeParams: Seq[TypeDef]) =
    typeClassInstance(
      TermName("flatMapFor" + algebraName),
      typeParams,
      tq"_root_.cats.FlatMap[$algebraType]",
      q"_root_.cats.tagless.Derive.flatMap[$algebraType]"
    )

  def flatMapInst(annottees: c.Tree*): c.Tree =
    enrichAlgebra(annottees.toList, AlgebraResolver.LastRegularTypeParam) { algebra =>
      algebra.forVaryingEffectType(generateFlatMapFor(algebra.name)) :: Nil
    }
} 
Example 146
Source File: autoContravariantK.scala    From cats-tagless   with Apache License 2.0 5 votes vote down vote up
package cats.tagless

import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.collection.immutable.Seq
import scala.reflect.macros.whitebox


@compileTimeOnly("Cannot expand @autoFunctorK")
class autoContravariantK(autoDerivation: Boolean = true) extends StaticAnnotation {
  def macroTransform(annottees: Any*): Any = macro autoContravariantKMacros.contravariantKInst
}

private [tagless] class autoContravariantKMacros(override val c: whitebox.Context) extends MacroUtils {
  import c.universe._

  private def generateContravariantKFor(algebraName: String)(algebraType: Tree, typeParams: Seq[TypeDef]) =
    typeClassInstance(
      TermName("contravariantKFor" + algebraName),
      typeParams,
      tq"_root_.cats.tagless.ContravariantK[$algebraType]",
      q"_root_.cats.tagless.Derive.contravariantK[$algebraType]"
    )

  def contravariantKInst(annottees: c.Tree*): c.Tree =
    enrichAlgebra(annottees.toList) { algebra =>
      algebra.forVaryingEffectType(generateContravariantKFor(algebra.name)) :: Nil
    }
} 
Example 147
Source File: autoFunctor.scala    From cats-tagless   with Apache License 2.0 5 votes vote down vote up
package cats.tagless

import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.collection.immutable.Seq
import scala.reflect.macros.whitebox


@compileTimeOnly("Cannot expand @autoFunctor")
class autoFunctor extends StaticAnnotation {
  def macroTransform(annottees: Any*): Any = macro autoFunctorMacros.functorInst
}


private[tagless] class autoFunctorMacros(override val c: whitebox.Context) extends MacroUtils {
  import c.universe._

  private def generateFunctorFor(algebraName: String)(algebraType: Tree, typeParams: Seq[TypeDef]) =
    typeClassInstance(
      TermName("functorFor" + algebraName),
      typeParams,
      tq"_root_.cats.Functor[$algebraType]",
      q"_root_.cats.tagless.Derive.functor[$algebraType]"
    )

  def functorInst(annottees: c.Tree*): c.Tree =
    enrichAlgebra(annottees.toList, AlgebraResolver.LastRegularTypeParam) { algebra =>
      algebra.forVaryingEffectType(generateFunctorFor(algebra.name)) :: Nil
    }
} 
Example 148
Source File: autoInvariant.scala    From cats-tagless   with Apache License 2.0 5 votes vote down vote up
package cats.tagless

import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.collection.immutable.Seq
import scala.reflect.macros.whitebox


@compileTimeOnly("Cannot expand @autoInvariant")
class autoInvariant extends StaticAnnotation {
  def macroTransform(annottees: Any*): Any = macro autoInvariantMacros.invariantInst
}

private[tagless] class autoInvariantMacros(override val c: whitebox.Context) extends MacroUtils  {
  import c.universe._

  private def generateInvariantFor(algebraName: String)(algebraType: Tree, typeParams: Seq[TypeDef]) =
    typeClassInstance(
      TermName("invariantFor" + algebraName),
      typeParams,
      tq"_root_.cats.Invariant[$algebraType]",
      q"_root_.cats.tagless.Derive.invariant[$algebraType]"
    )

  def invariantInst(annottees: c.Tree*): c.Tree =
    enrichAlgebra(annottees.toList, AlgebraResolver.LastRegularTypeParam) { algebra =>
      algebra.forVaryingEffectType(generateInvariantFor(algebra.name)) :: Nil
    }
} 
Example 149
Source File: autoProfunctor.scala    From cats-tagless   with Apache License 2.0 5 votes vote down vote up
package cats.tagless
import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.collection.immutable.Seq
import scala.reflect.macros.whitebox


@compileTimeOnly("Cannot expand @autoProfunctor")
class autoProfunctor extends StaticAnnotation {
  def macroTransform(annottees: Any*): Any = macro autoProfunctorMacros.profunctorInst
}

private[tagless] class autoProfunctorMacros(override val c: whitebox.Context) extends MacroUtils {
  import c.universe._

  private def generateProfunctorFor(
    algebraName: String
  )(algebraType: Tree, typeParams: Seq[TypeDef]) =
    typeClassInstance(
      TermName("profunctorFor" + algebraName),
      typeParams,
      tq"_root_.cats.arrow.Profunctor[$algebraType]",
      q"_root_.cats.tagless.Derive.profunctor[$algebraType]"
    )

  def profunctorInst(annottees: c.Tree*): c.Tree =
    enrichAlgebra(annottees.toList, AlgebraResolver.TwoLastRegularTypeParams) {
      algebra =>
        algebra.forVaryingEffectType(generateProfunctorFor(algebra.name)) :: Nil
    }
} 
Example 150
Source File: autoBifunctor.scala    From cats-tagless   with Apache License 2.0 5 votes vote down vote up
package cats.tagless
import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.collection.immutable.Seq
import scala.reflect.macros.whitebox


@compileTimeOnly("Cannot expand @autoBifunctor")
class autoBifunctor extends StaticAnnotation {
  def macroTransform(annottees: Any*): Any = macro autoBifunctorMacros.bifunctorInst
}

private[tagless] class autoBifunctorMacros(override val c: whitebox.Context) extends MacroUtils {
  import c.universe._

  private def generateBifunctorFor(algebraName: String)(algebraType: Tree, typeParams: Seq[TypeDef]) =
    typeClassInstance(
      TermName("bifunctorFor" + algebraName),
      typeParams,
      tq"_root_.cats.Bifunctor[$algebraType]",
      q"_root_.cats.tagless.Derive.bifunctor[$algebraType]"
    )

  def bifunctorInst(annottees: c.Tree*): c.Tree =
    enrichAlgebra(annottees.toList, AlgebraResolver.TwoLastRegularTypeParams) {
      algebra =>
        algebra.forVaryingEffectType(generateBifunctorFor(algebra.name)) :: Nil
    }
} 
Example 151
Source File: autoInstrument.scala    From cats-tagless   with Apache License 2.0 5 votes vote down vote up
package cats.tagless

import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.collection.immutable.Seq
import scala.reflect.macros.whitebox


@compileTimeOnly("Cannot expand @autoInstrument")
class autoInstrument extends StaticAnnotation {
  def macroTransform(annottees: Any*): Any = macro autoInstrumentMacros.instrumentInst
}

private[tagless] class autoInstrumentMacros(override val c: whitebox.Context) extends MacroUtils  {
  import c.universe._

  private def generateInstrumentFor(algebraName: String)(algebraType: Tree, typeParams: Seq[TypeDef]) =
    typeClassInstance(
      TermName("instrumentFor" + algebraName),
      typeParams,
      tq"_root_.cats.tagless.diagnosis.Instrument[$algebraType]",
      q"_root_.cats.tagless.Derive.instrument[$algebraType]"
    )

  def instrumentInst(annottees: c.Tree*): c.Tree =
    enrichAlgebra(annottees.toList, AlgebraResolver.FirstHigherKindedTypeParam) { algebra =>
      algebra.forVaryingEffectType(generateInstrumentFor(algebra.name)) :: Nil
    }
} 
Example 152
Source File: AkkaPersistenceEventLogSpec.scala    From akka-stream-eventsourcing   with Apache License 2.0 5 votes vote down vote up
package com.github.krasserm.ases.log

import akka.actor.ActorSystem
import akka.stream.scaladsl.{Sink, Source}
import akka.testkit.TestKit
import com.github.krasserm.ases._
import org.scalatest.concurrent.ScalaFutures
import org.scalatest.{Matchers, WordSpecLike}

import scala.collection.immutable.Seq

class AkkaPersistenceEventLogSpec extends TestKit(ActorSystem("test")) with WordSpecLike with Matchers with ScalaFutures with StreamSpec {
  val akkaPersistenceEventLog: AkkaPersistenceEventLog = new AkkaPersistenceEventLog(journalId = "akka.persistence.journal.inmem")

  "An Akka Persistence event log" must {
    "provide a sink for writing events and a source for delivering replayed events" in {
      val persistenceId = "1"
      val events = Seq("a", "b", "c").map(Emitted(_, emitterId))
      val expected = durables(events, offset = 1).map(Delivered(_)) :+ Recovered

      Source(events).runWith(akkaPersistenceEventLog.sink(persistenceId)).futureValue
      akkaPersistenceEventLog.source[String](persistenceId).runWith(Sink.seq).futureValue should be(expected)
    }
    "provide a flow with an input port for writing events and and output port for delivering replayed and live events" in {
      val persistenceId = "2"
      val events1 = Seq("a", "b", "c").map(Emitted(_, emitterId))
      val events2 = Seq("d", "e", "f").map(Emitted(_, emitterId))
      val expected = (durables(events1, offset = 1).map(Delivered(_)) :+ Recovered) ++ durables(events2, offset = 4).map(Delivered(_))

      Source(events1).runWith(akkaPersistenceEventLog.sink(persistenceId)).futureValue
      Source(events2).via(akkaPersistenceEventLog.flow(persistenceId)).runWith(Sink.seq).futureValue should be(expected)
    }
    "provide a source that only delivers events of compatible types" in {
      val persistenceId = "3"
      val events = Seq("a", "b", 1, 2).map(Emitted(_, emitterId))
      val expected = durables(events, offset = 1).drop(2).map(Delivered(_)) :+ Recovered

      Source(events).runWith(akkaPersistenceEventLog.sink(persistenceId)).futureValue
      akkaPersistenceEventLog.source[Int](persistenceId).runWith(Sink.seq).futureValue should be(expected)
    }
  }
} 
Example 153
Source File: KafkaEventLogSpec.scala    From akka-stream-eventsourcing   with Apache License 2.0 5 votes vote down vote up
package com.github.krasserm.ases.log

import akka.actor.ActorSystem
import akka.stream.scaladsl.{Sink, Source}
import akka.testkit.TestKit
import com.github.krasserm.ases._
import org.apache.kafka.common.TopicPartition
import org.scalatest.concurrent.ScalaFutures
import org.scalatest.time.{Millis, Seconds, Span}
import org.scalatest.{Matchers, WordSpecLike}

import scala.collection.immutable.Seq

class KafkaEventLogSpec extends TestKit(ActorSystem("test")) with WordSpecLike with Matchers with ScalaFutures with StreamSpec with KafkaSpec {
  implicit val pc = PatienceConfig(timeout = Span(5, Seconds), interval = Span(10, Millis))

  val kafkaEventLog: KafkaEventLog = new KafkaEventLog(host, port)

  "A Kafka event log" must {
    "provide a sink for writing events and a source for delivering replayed events" in {
      val topicPartition = new TopicPartition("p-1", 0)
      val events = Seq("a", "b", "c").map(Emitted(_, emitterId))
      val expected = durables(events).map(Delivered(_)) :+ Recovered

      Source(events).runWith(kafkaEventLog.sink(topicPartition)).futureValue
      kafkaEventLog.source[String](topicPartition).take(4).runWith(Sink.seq).futureValue should be(expected)
    }
    "provide a flow with an input port for writing events and and output port for delivering replayed and live events" in {
      val topicPartition = new TopicPartition("p-2", 0)
      val events1 = Seq("a", "b", "c").map(Emitted(_, emitterId))
      val events2 = Seq("d", "e", "f").map(Emitted(_, emitterId))
      val expected = (durables(events1).map(Delivered(_)) :+ Recovered) ++ durables(events2, offset = 3).map(Delivered(_))

      Source(events1).runWith(kafkaEventLog.sink(topicPartition)).futureValue
      Source(events2).via(kafkaEventLog.flow(topicPartition)).take(7).runWith(Sink.seq).futureValue should be(expected)
    }
    "provide a source that only delivers events of compatible types" in {
      val topicPartition = new TopicPartition("p-3", 0)
      val events = Seq("a", "b", 1, 2).map(Emitted(_, emitterId))
      val expected = durables(events).drop(2).map(Delivered(_)) :+ Recovered

      Source(events).runWith(kafkaEventLog.sink(topicPartition)).futureValue
      kafkaEventLog.source[Int](topicPartition).take(3).runWith(Sink.seq).futureValue should be(expected)
    }
  }
} 
Example 154
Source File: RequestRoutingSpec.scala    From akka-stream-eventsourcing   with Apache License 2.0 5 votes vote down vote up
package com.github.krasserm.ases

import akka.NotUsed
import akka.actor.ActorSystem
import akka.stream.scaladsl.{Flow, Sink, Source}
import akka.testkit.TestKit
import com.github.krasserm.ases.log.AkkaPersistenceEventLog
import org.scalatest.concurrent.ScalaFutures
import org.scalatest.{Matchers, WordSpecLike}
import scala.collection.immutable.Seq

object RequestRoutingSpec {
  import EventSourcing._

  sealed trait Request {
    def aggregateId: String
  }
  case class GetState(aggregateId: String) extends Request              // Query
  case class Increment(aggregateId: String, delta: Int) extends Request // Command
  case class Incremented(aggregateId: String, delta: Int)               // Event
  case class Response(aggregateId: String, state: Int)

  val requestHandler: RequestHandler[Int, Incremented, Request, Response] = {
    case (s, GetState(aggregateId))     => respond(Response(aggregateId, s))
    case (_, Increment(aggregateId, d)) => emit(Seq(Incremented(aggregateId, d)), Response(aggregateId, _))
  }

  val eventHandler: EventHandler[Int, Incremented] =
    (s, e) => s + e.delta
}

class RequestRoutingSpec extends TestKit(ActorSystem("test")) with WordSpecLike with Matchers with ScalaFutures with StreamSpec {
  import RequestRoutingSpec._

  val akkaPersistenceEventLog: AkkaPersistenceEventLog =
    new log.AkkaPersistenceEventLog(journalId = "akka.persistence.journal.inmem")

  def processor(aggregateId: String): Flow[Request, Response, NotUsed] =
    EventSourcing(aggregateId, 0, requestHandler, eventHandler).join(akkaPersistenceEventLog.flow(aggregateId))

  def router: Flow[Request, Response, NotUsed] =
    Router(_.aggregateId, processor)

  "A request router" when {
    "configured to route based on aggregate id" must {
      "dynamically create a request processor for each aggregate id" in {
        val aggregateId1 = "a1"
        val aggregateId2 = "a2"

        val (pub, sub) = probes(router)

        pub.sendNext(Increment(aggregateId1, 3))
        sub.requestNext(Response(aggregateId1, 3))

        pub.sendNext(Increment(aggregateId2, 1))
        sub.requestNext(Response(aggregateId2, 1))

        pub.sendNext(Increment(aggregateId1, 2))
        sub.requestNext(Response(aggregateId1, 5))

        pub.sendNext(Increment(aggregateId2, -4))
        sub.requestNext(Response(aggregateId2, -3))
      }
      "handle single command using Source.single" in {
        val request = Increment("a3", 3)
        val expected = Response("a3", 3)
        Source.single(request)
          .via(router)
          .runWith(Sink.head)
          .futureValue should be(expected)
      }
      "handle single command using Source.apply(Seq)" in {
        val request = Increment("a4", 3)
        val expected = Response("a4", 3)
        Source(Seq(request))
          .via(router)
          .runWith(Sink.head)
          .futureValue should be(expected)
      }
      "handle multiple commands" in {
        Source(Seq(Increment("a5", 1), Increment("a5", 2), Increment("a5", 3)))
          .via(router)
          .runWith(Sink.seq)
          .futureValue should be(Seq(Response("a5", 1), Response("a5", 3), Response("a5", 6)))
      }
    }
  }
} 
Example 155
Source File: EventCollaborationSpec.scala    From akka-stream-eventsourcing   with Apache License 2.0 5 votes vote down vote up
package com.github.krasserm.ases

import akka.NotUsed
import akka.actor.ActorSystem
import akka.stream.scaladsl.{Flow, Sink}
import akka.testkit.TestKit
import com.github.krasserm.ases.log.{KafkaEventLog, KafkaSpec}
import org.apache.kafka.common.TopicPartition
import org.scalatest.concurrent.ScalaFutures
import org.scalatest.time.{Millis, Seconds, Span}
import org.scalatest.{Matchers, WordSpecLike}

import scala.collection.immutable.Seq

class EventCollaborationSpec extends TestKit(ActorSystem("test")) with WordSpecLike with Matchers with ScalaFutures with StreamSpec with KafkaSpec {
  import EventSourcingSpec._

  implicit val pc = PatienceConfig(timeout = Span(5, Seconds), interval = Span(10, Millis))

  val emitterId1 = "processor1"
  val emitterId2 = "processor2"

  val kafkaEventLog: KafkaEventLog =
    new log.KafkaEventLog(host, port)

  def processor(emitterId: String, topicPartition: TopicPartition): Flow[Request, Response, NotUsed] =
    EventSourcing(emitterId, 0, requestHandler, eventHandler).join(kafkaEventLog.flow(topicPartition))

  "A group of EventSourcing stages" when {
    "joined with a shared event log" can {
      "collaborate via publish-subscribe" in {
        val topicPartition = new TopicPartition("p-1", 0)    // shared topic partition
        val (pub1, sub1) = probes(processor(emitterId1, topicPartition)) // processor 1
        val (pub2, sub2) = probes(processor(emitterId2, topicPartition)) // processor 2

        pub1.sendNext(Increment(3))
        // Both processors receive event but
        // only processor 1 creates response
        sub1.requestNext(Response(3))

        pub2.sendNext(Increment(-4))
        // Both processors receive event but
        // only processor 2 creates response
        sub2.requestNext(Response(-1))

        // consume and verify events emitted by both processors
        kafkaEventLog.source[Incremented](topicPartition).via(log.replayed).map {
          case Durable(event, eid, _, sequenceNr) => (event, eid, sequenceNr)
        }.runWith(Sink.seq).futureValue should be(Seq(
          (Incremented(3), emitterId1, 0L),
          (Incremented(-4), emitterId2, 1L)
        ))
      }
    }
  }
} 
Example 156
Source File: StreamSpec.scala    From akka-stream-eventsourcing   with Apache License 2.0 5 votes vote down vote up
package com.github.krasserm.ases

import akka.stream.ActorMaterializer
import akka.stream.scaladsl.{Flow, Keep}
import akka.stream.testkit.scaladsl.{TestSink, TestSource}
import akka.stream.testkit.{TestPublisher, TestSubscriber}
import akka.testkit.TestKit
import org.scalatest.{BeforeAndAfterAll, Suite}

import scala.collection.immutable.Seq

trait StreamSpec extends BeforeAndAfterAll { this: TestKit with Suite =>
  implicit val materializer = ActorMaterializer()

  val emitterId = "emitter"

  override def afterAll(): Unit = {
    materializer.shutdown()
    TestKit.shutdownActorSystem(system)
    super.afterAll()
  }

  def probes[I, O, M](flow: Flow[I, O, M]): (TestPublisher.Probe[I], TestSubscriber.Probe[O]) =
    TestSource.probe[I].viaMat(flow)(Keep.left).toMat(TestSink.probe[O])(Keep.both).run()

  def durables[A](emitted: Seq[Emitted[A]], offset: Int = 0): Seq[Durable[A]] =
    emitted.zipWithIndex.map { case (e, i) => e.durable(i + offset) }
} 
Example 157
Source File: elasticsearchExtensions.scala    From akka-stream-extensions   with Apache License 2.0 5 votes vote down vote up
package com.mfglabs.stream
package extensions.elasticsearch

import scala.collection.immutable.Seq
import scala.concurrent.duration.FiniteDuration
import scala.concurrent.Future

import org.elasticsearch.action.search.{SearchResponse, SearchRequestBuilder}
import org.elasticsearch.client.{ Client => EsClient }
import org.elasticsearch.common.unit.TimeValue
import org.elasticsearch.index.query.QueryBuilder
import org.elasticsearch.search.SearchHit

import com.mfglabs.stream.ExecutionContextForBlockingOps

import akka.NotUsed
import akka.stream.scaladsl.Source

trait EsStream {
  import EsHelper._

  
  protected def searchStream(
    index           : String,
    scrollKeepAlive : FiniteDuration,
    scrollSize      : Int
  )(
    build           : SearchRequestBuilder => SearchRequestBuilder
  )(implicit es: EsClient, ec: ExecutionContextForBlockingOps): Source[SearchHit, NotUsed] = {
    val builder = build(
      es.prepareSearch(index)
        .setScroll(new TimeValue(scrollKeepAlive.toMillis))
        .setSize(scrollSize)
    )

    Source.unfoldAsync[Either[SearchRequestBuilder, SearchResponse], Seq[SearchHit]](Left(builder)){
      case Left(srb) =>
        srb.execute().asScala.map { sr =>
          Some(Right(sr) -> hits(sr))
        }(ec.value)

      case Right(psr) if psr.getHits.getHits.nonEmpty =>
        val next = es
          .prepareSearchScroll(psr.getScrollId())
          .setScroll(new TimeValue(scrollKeepAlive.toMillis))

        next.execute().asScala.map { sr =>
          Some(Right(sr) -> hits(sr))
        }(ec.value)

      case Right(_) => Future.successful(None)
    }.mapConcat { identity }
  }

}

object EsStream extends EsStream 
Example 158
Source File: TwitterAPIReading.scala    From jsoniter-scala   with MIT License 5 votes vote down vote up
package com.github.plokhotnyuk.jsoniter_scala.benchmark

import java.nio.charset.StandardCharsets.UTF_8

import com.avsystem.commons.serialization.json._
import com.github.plokhotnyuk.jsoniter_scala.benchmark.AVSystemCodecs._
import com.github.plokhotnyuk.jsoniter_scala.benchmark.BorerJsonEncodersDecoders._
import com.github.plokhotnyuk.jsoniter_scala.benchmark.CirceEncodersDecoders._
import com.github.plokhotnyuk.jsoniter_scala.benchmark.DslPlatformJson._
import com.github.plokhotnyuk.jsoniter_scala.benchmark.JacksonSerDesers._
import com.github.plokhotnyuk.jsoniter_scala.benchmark.JsoniterScalaCodecs._
import com.github.plokhotnyuk.jsoniter_scala.benchmark.PlayJsonFormats._
import com.github.plokhotnyuk.jsoniter_scala.benchmark.TwitterAPI._
import com.github.plokhotnyuk.jsoniter_scala.benchmark.SprayFormats._
import com.github.plokhotnyuk.jsoniter_scala.benchmark.UPickleReaderWriters._
import com.github.plokhotnyuk.jsoniter_scala.benchmark.WeePickleFromTos._
import com.github.plokhotnyuk.jsoniter_scala.core._
import com.rallyhealth.weejson.v1.jackson.FromJson
import com.rallyhealth.weepickle.v1.WeePickle.ToScala
import io.circe.parser._
import org.openjdk.jmh.annotations.Benchmark
import play.api.libs.json.Json
import spray.json._

import scala.collection.immutable.Seq

class TwitterAPIReading extends TwitterAPIBenchmark {
  @Benchmark
  def avSystemGenCodec(): Seq[Tweet] = JsonStringInput.read[Seq[Tweet]](new String(jsonBytes, UTF_8))

  @Benchmark
  def borer(): Seq[Tweet] = io.bullet.borer.Json.decode(jsonBytes).to[Seq[Tweet]].value

  @Benchmark
  def circe(): Seq[Tweet] = decode[Seq[Tweet]](new String(jsonBytes, UTF_8)).fold(throw _, identity)

  @Benchmark
  def dslJsonScala(): Seq[Tweet] = dslJsonDecode[Seq[Tweet]](jsonBytes)

  @Benchmark
  def jacksonScala(): Seq[Tweet] = jacksonMapper.readValue[Seq[Tweet]](jsonBytes)

  @Benchmark
  def jsoniterScala(): Seq[Tweet] = readFromArray[Seq[Tweet]](jsonBytes)

  @Benchmark
  def playJson(): Seq[Tweet] = Json.parse(jsonBytes).as[Seq[Tweet]]

  @Benchmark
  def sprayJson(): Seq[Tweet] = JsonParser(jsonBytes).convertTo[Seq[Tweet]]

  @Benchmark
  def uPickle(): Seq[Tweet] = read[Seq[Tweet]](jsonBytes)

  @Benchmark
  def weePickle(): Seq[Tweet] = FromJson(jsonBytes).transform(ToScala[Seq[Tweet]])
} 
Example 159
Source File: GitHubActionsAPI.scala    From jsoniter-scala   with MIT License 5 votes vote down vote up
package com.github.plokhotnyuk.jsoniter_scala.benchmark

import java.time.Instant

import com.fasterxml.jackson.databind.annotation.JsonSerialize
import com.github.plokhotnyuk.jsoniter_scala.macros._

import scala.collection.immutable.Seq

object GitHubActionsAPI {
  case class Artifact(
    id: Long,
    node_id: String,
    name: String,
    size_in_bytes: Long,
    url: String,
    archive_download_url: String,
    @JsonSerialize(using = classOf[StringifiedBooleanSerializer]) @stringified expired: Boolean,
    created_at: Instant,
    expires_at: Instant)

  case class Response(
    total_count: Int,
    artifacts: Seq[Artifact])
} 
Example 160
Source File: LeagueEntity.scala    From eventsourcing-intro   with Apache License 2.0 5 votes vote down vote up
package eu.reactivesystems.league.impl

import akka.Done
import com.lightbend.lagom.scaladsl.persistence.PersistentEntity

import scala.collection.immutable.Seq

class LeagueEntity extends PersistentEntity {

  import LeagueEntity._

  override type Command = LeagueCommand[_]
  override type Event = LeagueEvent
  override type State = LeagueState

  
  override def initialState: LeagueState =
    LeagueState(Set.empty[ClubData], Set.empty[GameData])

  override def behavior: Behavior = {
    case LeagueState(clubs, games) =>
      Actions()
        .onCommand[AddClub, Done] {
          case (AddClub(club), ctx, state) =>
            validateAddClub(club, state).fold(
              message => rejectCommand(ctx, message),
              event =>
                ctx.thenPersist(event) { _ =>
                  ctx.reply(Done)
              })
        }
        .onCommand[AddGame, Done] {
          case (AddGame(game), ctx, state) =>
            validateAddGame(game, state).fold(
              message => rejectCommand(ctx, message),
              events =>
                ctx.thenPersistAll(events: _*) { () =>
                  ctx.reply(Done)
              })
        }
        .onCommand[ChangeGame, Done] {
          case (ChangeGame(game), ctx, state) =>
            validateChangeGame(game, state).fold(
              message => rejectCommand(ctx, message),
              events =>
                ctx.thenPersistAll(events: _*) { () =>
                  ctx.reply(Done)
              })
        }
        .onEvent {
          case (ClubRegistered(club), state) =>
            state.copy(clubs = state.clubs + club)
          case (GamePlayed(game), state) =>
            state.copy(games = state.games + game)
          case (ResultRevoked(game), state) =>
            state.copy(games = state.games - game)
        }
  }

  private def validateAddClub(
      club: ClubData,
      state: LeagueState): Either[String, LeagueEvent] =
    if (state.clubs(club)) Left(s"Duplicate club $club")
    else if (state.clubs.size == LEAGUE_MAX)
      Left(s"Max league size $LEAGUE_MAX exceeded")
    else Right(ClubRegistered(club))

  private def validateAddGame(
      game: GameData,
      state: LeagueState): Either[String, Seq[LeagueEvent]] =
    if (state.games(game)) Left(s"Duplicate game $game")
    else {
      val newClubs = Set(game.home, game.away) diff state.clubs
      if ((state.clubs.size + newClubs.size) > LEAGUE_MAX)
        Left(s"Max league size $LEAGUE_MAX exceeded")
      else {
        Right(newClubs.map(ClubRegistered(_)).toVector :+ GamePlayed(game))
      }
    }

  private def validateChangeGame(
      game: GameData,
      state: LeagueState): Either[String, Seq[LeagueEvent]] =
    state.games
      .find(_ == game)
      .fold[Either[String, Seq[LeagueEvent]]](Left(s"Game $game not found."))(
        oldGame => Right(Seq(ResultRevoked(oldGame), GamePlayed(game))))

  private def rejectCommand(ctx: CommandContext[Done], message: String) = {
    ctx.invalidCommand(message)
    ctx.done
  }
}

object LeagueEntity {
  val LEAGUE_MAX = 18
} 
Example 161
Source File: LeagueLoader.scala    From eventsourcing-intro   with Apache License 2.0 5 votes vote down vote up
package eu.reactivesystems.league.impl

import akka.actor.PoisonPill
import akka.cluster.singleton.{
  ClusterSingletonManager,
  ClusterSingletonManagerSettings
}
import com.lightbend.lagom.scaladsl.api.ServiceLocator
import com.lightbend.lagom.scaladsl.api.ServiceLocator.NoServiceLocator
import com.lightbend.lagom.scaladsl.devmode.LagomDevModeComponents
import com.lightbend.lagom.scaladsl.persistence.cassandra.WriteSideCassandraPersistenceComponents
import com.lightbend.lagom.scaladsl.persistence.jdbc.ReadSideJdbcPersistenceComponents
import com.lightbend.lagom.scaladsl.playjson.{
  JsonSerializer,
  JsonSerializerRegistry
}
import com.lightbend.lagom.scaladsl.server._
import com.softwaremill.macwire._
import com.softwaremill.macwire.akkasupport._
import eu.reactivesystems.league.api.LeagueService
import play.api.db.HikariCPComponents
import play.api.libs.ws.ahc.AhcWSComponents

import scala.collection.immutable.Seq

class LeagueLoader extends LagomApplicationLoader {

  override def load(context: LagomApplicationContext): LagomApplication =
    new LeagueApplication(context) {
      override def serviceLocator: ServiceLocator = NoServiceLocator
    }

  override def loadDevMode(
      context: LagomApplicationContext): LagomApplication =
    new LeagueApplication(context) with LagomDevModeComponents

  override def describeServices = List(
    readDescriptor[LeagueService]
  )
}

abstract class LeagueApplication(context: LagomApplicationContext)
    extends LagomApplication(context)
    with WriteSideCassandraPersistenceComponents
    with ReadSideJdbcPersistenceComponents
    with HikariCPComponents
    with AhcWSComponents {

  // Bind the service that this server provides
  override lazy val lagomServer =
    serverFor[LeagueService](wire[LeagueServiceImpl])

  // Register the JSON serializer registry
  override lazy val jsonSerializerRegistry = LeagueSerializerRegistry

  // Register the league persistent entity
  persistentEntityRegistry.register(wire[LeagueEntity])

  // Register read side processor

  val leagueProjectionProps = wireProps[LeagueProjection]

  actorSystem.actorOf(
    ClusterSingletonManager.props(
      singletonProps = leagueProjectionProps,
      terminationMessage = PoisonPill,
      settings = ClusterSingletonManagerSettings(actorSystem)),
    name = "leagueProjection"
  )

}


object LeagueSerializerRegistry extends JsonSerializerRegistry {
  override def serializers: Seq[JsonSerializer[_]] = Seq(
    JsonSerializer[AddClub],
    JsonSerializer[AddGame],
    JsonSerializer[ChangeGame],
    JsonSerializer[ClubRegistered],
    JsonSerializer[GamePlayed],
    JsonSerializer[ResultRevoked],
    JsonSerializer[LeagueState]
  )
} 
Example 162
Source File: Patch.scala    From scastie   with Apache License 2.0 5 votes vote down vote up
package com.olegych.scastie.instrumentation

import scala.collection.immutable.Seq
import scala.meta._
import scala.meta.tokens.Token

case class Patch(from: Token, to: Token, replace: String) {
  def insideRange(token: Token): Boolean =
    (token.input eq from.input) &&
      token.end <= to.end &&
      token.start >= from.start

  val tokens: scala.Seq[Token] = replace.tokenize.get.tokens.toSeq
  def runOn(str: Seq[Token]): Seq[Token] = {
    str.flatMap {
      case `from`              => tokens
      case x if insideRange(x) => Nil
      case x                   => Seq(x)
    }
  }
}

object Patch {
  def verifyPatches(patches: Seq[Patch]): Unit = {
    // TODO(olafur) assert there's no conflicts.
  }
  def apply(input: Seq[Token], patches: Seq[Patch]): String = {
    verifyPatches(patches)
    // TODO(olafur) optimize, this is SUPER inefficient
    patches
      .foldLeft(input) {
        case (s, p) => p.runOn(s)
      }
      .map(_.syntax)
      .mkString("")
  }
} 
Example 163
Source File: instances.scala    From nexus   with Apache License 2.0 5 votes vote down vote up
package ch.epfl.bluebrain.nexus.service.marshallers

import akka.http.scaladsl.marshalling.GenericMarshallers.eitherMarshaller
import akka.http.scaladsl.marshalling._
import akka.http.scaladsl.model.MediaTypes.`application/json`
import akka.http.scaladsl.model._
import ch.epfl.bluebrain.nexus.admin.exceptions.AdminError
import ch.epfl.bluebrain.nexus.admin.organizations.OrganizationRejection
import ch.epfl.bluebrain.nexus.admin.projects.ProjectRejection
import ch.epfl.bluebrain.nexus.commons.circe.syntax._
import ch.epfl.bluebrain.nexus.commons.http.JsonLdCirceSupport.OrderedKeys
import ch.epfl.bluebrain.nexus.commons.http.RdfMediaTypes._
import ch.epfl.bluebrain.nexus.commons.http.directives.StatusFrom
import ch.epfl.bluebrain.nexus.iam.acls.AclRejection
import ch.epfl.bluebrain.nexus.iam.permissions.PermissionsRejection
import ch.epfl.bluebrain.nexus.iam.realms.RealmRejection
import ch.epfl.bluebrain.nexus.service.config.ServiceConfig.orderedKeys
import ch.epfl.bluebrain.nexus.service.exceptions.ServiceError
import ch.epfl.bluebrain.nexus.service.exceptions.ServiceError.InternalError
import ch.epfl.bluebrain.nexus.service.routes.ResourceRejection
import de.heikoseeberger.akkahttpcirce.FailFastCirceSupport
import io.circe._
import io.circe.syntax._
import monix.eval.Task
import monix.execution.Scheduler

import scala.collection.immutable.Seq
import scala.concurrent.Future
import scala.concurrent.duration.FiniteDuration

object instances extends FailFastCirceSupport {

  implicit val finiteDurationEncoder: Encoder[FiniteDuration] =
    Encoder.encodeString.contramap(fd => s"${fd.toMillis} ms")

  implicit val resourceRejectionEncoder: Encoder[ResourceRejection] =
    Encoder.instance {
      case r: ProjectRejection      => Encoder[ProjectRejection].apply(r)
      case r: OrganizationRejection => Encoder[OrganizationRejection].apply(r)
      case r: AclRejection          => Encoder[AclRejection].apply(r)
      case r: RealmRejection        => Encoder[RealmRejection].apply(r)
      case r: PermissionsRejection  => Encoder[PermissionsRejection].apply(r)
      case _                        => Encoder[ServiceError].apply(InternalError("unspecified"))
    }

  implicit val resourceRejectionStatusFrom: StatusFrom[ResourceRejection] =
    StatusFrom {
      case r: OrganizationRejection => OrganizationRejection.organizationStatusFrom(r)
      case r: ProjectRejection      => ProjectRejection.projectStatusFrom(r)
      case r: AclRejection          => AclRejection.aclRejectionStatusFrom(r)
      case r: RealmRejection        => RealmRejection.realmRejectionStatusFrom(r)
      case r: PermissionsRejection  => PermissionsRejection.permissionsRejectionStatusFrom(r)
    }

  override def unmarshallerContentTypes: Seq[ContentTypeRange] =
    List(`application/json`, `application/ld+json`, `application/sparql-results+json`)

  
  implicit final def rejection[A <: ResourceRejection: Encoder](implicit
      statusFrom: StatusFrom[A],
      printer: Printer = Printer.noSpaces.copy(dropNullValues = true),
      ordered: OrderedKeys = orderedKeys
  ): ToResponseMarshaller[A] = {
    val marshallers = Seq(`application/ld+json`, `application/json`).map { contentType =>
      Marshaller.withFixedContentType[A, HttpResponse](contentType) { rejection =>
        HttpResponse(
          status = statusFrom(rejection),
          entity = HttpEntity(contentType, printer.print(rejection.asJson.sortKeys))
        )
      }
    }
    Marshaller.oneOf(marshallers: _*)
  }

  implicit class EitherTask[R <: ResourceRejection, A](task: Task[Either[R, A]])(implicit s: Scheduler) {
    def runWithStatus(code: StatusCode): Future[Either[R, (StatusCode, A)]] =
      task.map(_.map(code -> _)).runToFuture
  }

  implicit class OptionTask[A](task: Task[Option[A]])(implicit s: Scheduler) {
    def runNotFound: Future[A] =
      task.flatMap {
        case Some(a) => Task.pure(a)
        case None    => Task.raiseError(AdminError.NotFound)
      }.runToFuture
  }
} 
Example 164
Source File: instances.scala    From nexus   with Apache License 2.0 5 votes vote down vote up
package ch.epfl.bluebrain.nexus.storage.routes

import akka.http.scaladsl.marshalling.GenericMarshallers.eitherMarshaller
import akka.http.scaladsl.marshalling._
import akka.http.scaladsl.model.MediaTypes._
import akka.http.scaladsl.model._
import ch.epfl.bluebrain.nexus.commons.http.RdfMediaTypes._
import ch.epfl.bluebrain.nexus.storage.JsonLdCirceSupport.sortKeys
import ch.epfl.bluebrain.nexus.storage.JsonLdCirceSupport.OrderedKeys
import ch.epfl.bluebrain.nexus.storage.Rejection
import ch.epfl.bluebrain.nexus.storage.config.AppConfig._
import de.heikoseeberger.akkahttpcirce.FailFastCirceSupport
import io.circe._
import io.circe.syntax._
import monix.eval.Task
import monix.execution.Scheduler

import scala.collection.immutable.Seq
import scala.concurrent.Future

object instances extends LowPriority {

  
  implicit final def valueWithStatusCodeMarshaller[A: Encoder](implicit
      printer: Printer = defaultPrinter,
      keys: OrderedKeys = orderedKeys
  ): ToResponseMarshaller[(StatusCode, A)] =
    jsonLdWithStatusCodeMarshaller.compose { case (status, value) => status -> value.asJson }

  private[routes] def onOf[A, Response](
      fMarshaller: MediaType.WithFixedCharset => Marshaller[A, Response]
  ): Marshaller[A, Response] = {
    val marshallers = Seq(`application/ld+json`, `application/json`).map(fMarshaller)
    Marshaller.oneOf(marshallers: _*)
  }
} 
Example 165
Source File: JsonLdCirceSupport.scala    From nexus   with Apache License 2.0 5 votes vote down vote up
package ch.epfl.bluebrain.nexus.storage

import akka.http.scaladsl.marshalling.{Marshaller, ToEntityMarshaller}
import akka.http.scaladsl.model.MediaTypes.`application/json`
import akka.http.scaladsl.model.{ContentTypeRange, HttpEntity}
import ch.epfl.bluebrain.nexus.commons.http.RdfMediaTypes
import ch.epfl.bluebrain.nexus.storage.JsonLdCirceSupport.{sortKeys, OrderedKeys}
import de.heikoseeberger.akkahttpcirce.FailFastCirceSupport
import io.circe.syntax._
import io.circe.{Encoder, Json, JsonObject, Printer}

import scala.collection.immutable.Seq


  def sortKeys(json: Json)(implicit keys: OrderedKeys): Json = {

    implicit val customStringOrdering: Ordering[String] = new Ordering[String] {
      private val middlePos = keys.withPosition("")

      private def position(key: String): Int = keys.withPosition.getOrElse(key, middlePos)

      override def compare(x: String, y: String): Int = {
        val posX = position(x)
        val posY = position(y)
        if (posX == middlePos && posY == middlePos) x compareTo y
        else posX compareTo posY
      }
    }

    def canonicalJson(json: Json): Json =
      json.arrayOrObject[Json](json, arr => Json.fromValues(arr.map(canonicalJson)), obj => sorted(obj).asJson)

    def sorted(jObj: JsonObject): JsonObject =
      JsonObject.fromIterable(jObj.toVector.sortBy(_._1).map { case (k, v) => k -> canonicalJson(v) })

    canonicalJson(json)
  }
} 
Example 166
Source File: RecordProcessorFactoryImpl.scala    From kinesis-stream   with MIT License 5 votes vote down vote up
package px.kinesis.stream.consumer

import akka.NotUsed
import akka.event.LoggingAdapter
import akka.stream.scaladsl.{Keep, Sink, Source}
import akka.stream.{KillSwitch, Materializer, OverflowStrategy}
import px.kinesis.stream.consumer.checkpoint.CheckpointTracker
import software.amazon.kinesis.processor.{ShardRecordProcessor, ShardRecordProcessorFactory}

import scala.collection.immutable.Seq
import scala.concurrent.ExecutionContext

class RecordProcessorFactoryImpl(
  sink: Sink[Record, NotUsed],
  workerId: String,
  checkpointTracker: CheckpointTracker,
  killSwitch: KillSwitch
)(implicit am: Materializer, ec: ExecutionContext, logging: LoggingAdapter) extends ShardRecordProcessorFactory {
  override def shardRecordProcessor(): ShardRecordProcessor = {
    val queue = Source
      .queue[Seq[Record]](0, OverflowStrategy.backpressure)
      .mapConcat(identity)
      .toMat(sink)(Keep.left)
      .run()

    new RecordProcessorImpl(queue, checkpointTracker, killSwitch, workerId)
  }
} 
Example 167
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 168
Source File: Util.scala    From mainecoon   with Apache License 2.0 5 votes vote down vote up
package mainecoon

import scala.meta.Term.Block
import scala.meta._
import scala.collection.immutable.Seq
import cats.implicits._

private[mainecoon] object Util {

  
  def typeParam(name: String, numOfTParams: Int = 1): Type.Param = {
    val tparams = Range(0, numOfTParams).toList.as(Type.Param(Nil, Name.Anonymous(), Nil, Type.Bounds(None, None), Nil, Nil))
    Type.Param(Nil, Type.Name(name), tparams, Type.Bounds(None, None), Nil, Nil)
  }

  def enrich(defn: Any)(f: TypeDefinition => TypeDefinition) : Block = {
    defn match {
      case TypeDefinition.FromAny(td) =>
        val enriched = f(td)
        Block(Seq(enriched.toDefn, enriched.companion))
      case t =>
        abort(s"$defn is not a class or trait.")
    }
  }

  def enrichAlgebra(defn: Any, higherKinded: Boolean = true)(f: AlgDefn => TypeDefinition): Block = {
    enrich(defn){ cls: TypeDefinition =>
      val ad = AlgDefn.from(cls, higherKinded).getOrElse(abort(s"${cls.name} does not have an higher-kinded type parameter, e.g. F[_]"))
      f(ad)
    }
  }

  implicit class CompanionExtension(val self: Defn.Object) extends AnyVal {
    import self._
    def addStats(stats: Seq[Stat]): Defn.Object =
      copy(templ = templ.copy(stats = Some(templ.stats.getOrElse(Nil) ++ stats)))

  }


  def arguments(params: Seq[Term.Param]): Seq[Term.Name] =
     params.map(p => Term.Name(p.name.value))

  def argumentss(params: Seq[Seq[Term.Param]]): Seq[Seq[Term.Name]] =
    params.map(arguments)
} 
Example 169
Source File: autoFunctor.scala    From mainecoon   with Apache License 2.0 5 votes vote down vote up
package mainecoon

import mainecoon.Util._

import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.collection.immutable.Seq
import scala.meta._


@compileTimeOnly("Cannot expand @autoFunctor")
class autoFunctor extends StaticAnnotation {
  inline def apply(defn: Any): Any = meta {
    enrichAlgebra(defn, higherKinded = false)(autoFunctor.functorInst)
  }
}


object autoFunctor {
  private[mainecoon] def functorInst(ad: AlgDefn): TypeDefinition = {
    import ad._
    import cls._

    val instanceDef =
      q"""
    implicit def ${Term.Name("functorFor" + name.value)}[..$extraTParams]: _root_.cats.Functor[$typeLambdaVaryingEffect] =
      new _root_.cats.Functor[$typeLambdaVaryingEffect] {
        def map[T, TTarget](delegatee_ : $name[..${tArgs("T")}])(mapFunction: T => TTarget): $name[..${tArgs("TTarget")}] =
          new ${Ctor.Ref.Name(name.value)}[..${tArgs("TTarget")}] {
            ..${autoFlatMap.mapMethods(templ, effectTypeName)}
          }
      }"""

    cls.copy(companion = cls.companion.addStats(Seq(instanceDef)))
  }
} 
Example 170
Source File: KeyWrapper.scala    From aerospike-scala   with Apache License 2.0 5 votes vote down vote up
package ru.tinkoff.aerospikemacro.converters

import com.aerospike.client.Value._
import com.aerospike.client.{Key, Value}
import ru.tinkoff.aerospikemacro.domain.{DBCredentials, WrapperException}

import scala.language.experimental.macros
import scala.reflect.macros.blackbox.Context


trait KeyWrapper[KT] {

  val dbName: String    = ""
  val tableName: String = ""

  def apply(k: KT): Key = new Key(dbName, tableName, toValue(k))

  def toValue(v: KT): Value = Value.get(v) match {
    case _: NullValue =>
      throw new WrapperException {
        val msg = "You need to write your own toValue function in KeyWrapper"
      }
    case other => other
  }
}

object KeyWrapper {
  import Utils._

  implicit def materializeK[T](implicit dbc: DBCredentials): KeyWrapper[T] = macro implK[T]

  def implK[T: c.WeakTypeTag](c: Context)(dbc: c.Expr[DBCredentials]): c.Expr[KeyWrapper[T]] = {
    import c.universe._
    val tpe = weakTypeOf[T]

    val db        = reify(dbc.splice.namespace)
    val tableName = reify(dbc.splice.setname)

    val toDBValue = pickValue(c)

    c.Expr[KeyWrapper[T]] {
      q"""
      import com.aerospike.client.{Key, Value}
      import com.aerospike.client.Value._
      import scala.collection.immutable.Seq
      import ru.tinkoff.aerospikescala.domain.ByteSegment
      import scala.util.{Failure, Success, Try}

      new KeyWrapper[$tpe] {
        override val dbName = $db
        override val tableName = $tableName
        override def toValue(v: $tpe): Value = $toDBValue
      }
     """
    }
  }

  def create[T](dbc: DBCredentials): KeyWrapper[T] = macro implK[T]

} 
Example 171
Source File: SubscriptionEvents.scala    From graphcool-framework   with Apache License 2.0 5 votes vote down vote up
package cool.graph.client.mutations

import cool.graph.ClientSqlMutaction
import cool.graph.Types.Id
import cool.graph.client.ClientInjector
import cool.graph.client.adapters.GraphcoolDataTypes
import cool.graph.client.mutactions._
import cool.graph.shared.models.Project

import scala.collection.immutable.Seq

object SubscriptionEvents {
  def extractFromSqlMutactions(project: Project, mutationId: Id, mutactions: Seq[ClientSqlMutaction])(
      implicit injector: ClientInjector): Seq[PublishSubscriptionEvent] = {
    mutactions.collect {
      case x: UpdateDataItem => fromUpdateMutaction(project, mutationId, x)
      case x: CreateDataItem => fromCreateMutaction(project, mutationId, x)
      case x: DeleteDataItem => fromDeleteMutaction(project, mutationId, x)
    }
  }

  def fromDeleteMutaction(project: Project, mutationId: Id, mutaction: DeleteDataItem)(implicit injector: ClientInjector): PublishSubscriptionEvent = {
    val nodeData: Map[String, Any] = mutaction.previousValues.userData
      .collect {
        case (key, Some(value)) =>
          (key, value match {
            case v: Vector[Any] => v.toList // Spray doesn't like Vector and formats it as string ("Vector(something)")
            case v              => v
          })
      } + ("id" -> mutaction.id)

    PublishSubscriptionEvent(
      project = project,
      value = Map("nodeId" -> mutaction.id, "node" -> nodeData, "modelId" -> mutaction.model.id, "mutationType" -> "DeleteNode"),
      mutationName = s"delete${mutaction.model.name}"
    )
  }

  def fromCreateMutaction(project: Project, mutationId: Id, mutaction: CreateDataItem)(implicit injector: ClientInjector): PublishSubscriptionEvent = {
    PublishSubscriptionEvent(
      project = project,
      value = Map("nodeId" -> mutaction.id, "modelId" -> mutaction.model.id, "mutationType" -> "CreateNode"),
      mutationName = s"create${mutaction.model.name}"
    )
  }

  def fromUpdateMutaction(project: Project, mutationId: Id, mutaction: UpdateDataItem)(implicit injector: ClientInjector): PublishSubscriptionEvent = {
    PublishSubscriptionEvent(
      project = project,
      value = Map(
        "nodeId"        -> mutaction.id,
        "changedFields" -> mutaction.namesOfUpdatedFields,
        "previousValues" -> GraphcoolDataTypes
          .convertToJson(mutaction.previousValues.userData)
          .compactPrint,
        "modelId"      -> mutaction.model.id,
        "mutationType" -> "UpdateNode"
      ),
      mutationName = s"update${mutaction.model.name}"
    )
  }
} 
Example 172
Source File: ActionWebhooks.scala    From graphcool-framework   with Apache License 2.0 5 votes vote down vote up
package cool.graph.client.mutations

import cool.graph.Types.Id
import cool.graph.client.ClientInjector
import cool.graph.client.mutactions._
import cool.graph.shared.models.{ActionTriggerMutationModelMutationType, Project}
import cool.graph.{DataItem, Mutaction}

import scala.collection.immutable.Seq

object ActionWebhooks {
  def extractFromCreateMutactions(project: Project, mutactions: Seq[CreateDataItem], mutationId: Id, requestId: String)(
      implicit injector: ClientInjector): Seq[Mutaction] = {
    for {
      newItem <- mutactions
      action  <- project.actionsFor(newItem.model.id, ActionTriggerMutationModelMutationType.Create)
    } yield {
      if (action.handlerWebhook.get.isAsync) {
        ActionWebhookForCreateDataItemAsync(
          model = newItem.model,
          project = project,
          nodeId = newItem.id,
          action = action,
          mutationId = mutationId,
          requestId = requestId
        )
      } else {
        ActionWebhookForCreateDataItemSync(
          model = newItem.model,
          project = project,
          nodeId = newItem.id,
          action = action,
          mutationId = mutationId,
          requestId = requestId
        )
      }
    }
  }

  def extractFromUpdateMutactions(project: Project, mutactions: Seq[UpdateDataItem], mutationId: Id, requestId: String, previousValues: DataItem)(
      implicit injector: ClientInjector): Seq[Mutaction] = {
    for {
      updatedItem <- mutactions
      action      <- project.actionsFor(updatedItem.model.id, ActionTriggerMutationModelMutationType.Update)
    } yield {
      if (action.handlerWebhook.get.isAsync) {
        ActionWebhookForUpdateDataItemAsync(
          model = updatedItem.model,
          project = project,
          nodeId = updatedItem.id,
          action = action,
          updatedFields = updatedItem.namesOfUpdatedFields,
          mutationId = mutationId,
          requestId = requestId,
          previousValues = previousValues
        )
      } else {
        ActionWebhookForUpdateDataItemSync(
          model = updatedItem.model,
          project = project,
          nodeId = updatedItem.id,
          action = action,
          updatedFields = updatedItem.namesOfUpdatedFields,
          mutationId = mutationId,
          requestId = requestId,
          previousValues = previousValues
        )
      }
    }
  }
} 
Example 173
Source File: DiffAwareSchemaValidator.scala    From graphcool-framework   with Apache License 2.0 5 votes vote down vote up
package cool.graph.system.migration.dataSchema.validation

import cool.graph.shared.errors.SystemErrors.SchemaError
import cool.graph.shared.models.Project
import cool.graph.system.database.SystemFields
import cool.graph.system.migration.dataSchema.SchemaDiff

import scala.collection.immutable.Seq
import scala.util.{Failure, Success, Try}

case class DiffAwareSchemaValidator(diffResultTry: Try[SchemaDiff], project: Project) {

  def validate(): Seq[SchemaError] = {
    diffResultTry match {
      case Success(schemaDiff) => validateInternal(schemaDiff)
      case Failure(e)          => List.empty // the Syntax Validator already returns an error for this case
    }
  }

  def validateInternal(schemaDiff: SchemaDiff): Seq[SchemaError] = {
    validateRemovedFields(schemaDiff) ++ validateRemovedTypes(schemaDiff)
  }

  def validateRemovedTypes(schemaDiff: SchemaDiff): Seq[SchemaError] = {
    for {
      removedType <- schemaDiff.removedTypes
      model       = project.getModelByName_!(removedType)
      if model.isSystem && !project.isEjected
    } yield SchemaErrors.systemTypeCannotBeRemoved(model.name)
  }

  def validateRemovedFields(schemaDiff: SchemaDiff): Seq[SchemaError] = {
    for {
      updatedType  <- schemaDiff.updatedTypes
      model        = project.getModelByName_!(updatedType.oldName)
      removedField <- updatedType.removedFields
      field        = model.getFieldByName_!(removedField)
      if field.isSystem && !SystemFields.isDeletableSystemField(field.name)
    } yield SchemaErrors.systemFieldCannotBeRemoved(updatedType.name, field.name)
  }
} 
Example 174
Source File: SchemaValidator.scala    From graphcool-framework   with Apache License 2.0 5 votes vote down vote up
package cool.graph.system.migration.dataSchema.validation

import cool.graph.shared.errors.SystemErrors.SchemaError
import cool.graph.shared.models.Project
import cool.graph.system.migration.dataSchema.{SchemaDiff, SchemaExport, SchemaFileHeader}

import scala.collection.immutable.Seq

case class SchemaValidator(schemaSyntaxValidator: SchemaSyntaxValidator, diffAwareSchemaValidator: DiffAwareSchemaValidator) {
  def validate(): Seq[SchemaError] = {
    schemaSyntaxValidator.validate() ++ diffAwareSchemaValidator.validate()
  }
}

object SchemaValidator {
  def apply(project: Project, newSchema: String, schemaFileHeader: SchemaFileHeader): SchemaValidator = {
    val oldSchema = SchemaExport.renderSchema(project)
    SchemaValidator(
      SchemaSyntaxValidator(newSchema),
      DiffAwareSchemaValidator(SchemaDiff(oldSchema, newSchema), project)
    )
  }
} 
Example 175
Source File: UpdateTypeAndFieldPositions.scala    From graphcool-framework   with Apache License 2.0 5 votes vote down vote up
package cool.graph.system.mutactions.internal

import cool.graph.Types.Id
import cool.graph._
import cool.graph.shared.models.{Client, Project}
import cool.graph.system.database.finder.{CachedProjectResolver, ProjectQueries, ProjectResolver}
import sangria.ast.{Document, ObjectTypeDefinition, TypeDefinition}
import scaldi.{Injectable, Injector}
import slick.dbio.DBIOAction
import slick.jdbc.MySQLProfile.backend.DatabaseDef

import scala.collection.immutable.Seq
import scala.collection.mutable
import scala.concurrent.Future

case class UpdateTypeAndFieldPositions(
    project: Project,
    client: Client,
    newSchema: Document,
    internalDatabase: DatabaseDef,
    projectQueries: ProjectQueries
)(implicit inj: Injector)
    extends SystemSqlMutaction
    with Injectable {
  import scala.concurrent.ExecutionContext.Implicits.global

  implicit val projectResolver = inject[ProjectResolver](identified by "uncachedProjectResolver")

  val mutactions: mutable.Buffer[SystemSqlMutaction] = mutable.Buffer.empty

  override def execute: Future[SystemSqlStatementResult[Any]] =
    refreshProject.flatMap { project =>
      val newTypePositions: Seq[Id] = newSchema.definitions.collect {
        case typeDef: TypeDefinition =>
          project
            .getModelByName(typeDef.name)
            .orElse(project.getEnumByName(typeDef.name))
            .map(_.id)
      }.flatten

      mutactions += UpdateProject(
        client = client,
        oldProject = project,
        project = project.copy(typePositions = newTypePositions.toList),
        internalDatabase = internalDatabase,
        projectQueries = projectQueries,
        bumpRevision = false
      )

      mutactions ++= newSchema.definitions.collect {
        case typeDef: ObjectTypeDefinition =>
          project.getModelByName(typeDef.name).map { model =>
            val newFieldPositions = typeDef.fields.flatMap { fieldDef =>
              model.getFieldByName(fieldDef.name).map(_.id)
            }.toList
            UpdateModel(project = project, oldModel = model, model = model.copy(fieldPositions = newFieldPositions))
          }
      }.flatten

      val y = mutactions.map(_.execute)
      Future.sequence(y).map { statementResults =>
        val asSingleAction = DBIOAction.sequence(statementResults.toList.map(_.sqlAction))
        SystemSqlStatementResult(sqlAction = asSingleAction)
      }
    }

  def refreshProject: Future[Project] = {
    projectResolver.resolve(project.id).map(_.get)
  }

  override def rollback: Option[Future[SystemSqlStatementResult[Any]]] = mutactions.map(_.rollback).headOption.flatten

} 
Example 176
Source File: InvalidateSchema.scala    From graphcool-framework   with Apache License 2.0 5 votes vote down vote up
package cool.graph.system.mutactions.internal

import cool.graph._
import cool.graph.messagebus.PubSubPublisher
import cool.graph.messagebus.pubsub.Only
import cool.graph.shared.models.{Client, Project}
import cool.graph.system.database.finder.CachedProjectResolver
import cool.graph.system.database.tables.{SeatTable, Tables}
import scaldi.{Injectable, Injector}
import slick.jdbc.MySQLProfile.backend.DatabaseDef

import scala.collection.immutable.Seq
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future


object InvalidateSchema {
  def apply(project: Project)(implicit inj: Injector): InvalidateSchema = InvalidateSchema(project.id)
}

case class InvalidateSchema(projectId: String)(implicit inj: Injector) extends InvalidateSchemaBase {
  def projectIds: Future[Vector[String]] = Future.successful(Vector(projectId))
}

case class InvalidateAllSchemas()(implicit inj: Injector) extends InvalidateSchemaBase {
  import slick.jdbc.MySQLProfile.api._

  var invalidationCount = 0

  def projectIds: Future[Vector[String]] = {
    val query = for {
      project <- Tables.Projects
    } yield {
      project.id
    }
    internalDatabase.run(query.result).map { projectIds =>
      invalidationCount = projectIds.size
      projectIds.toVector
    }
  }
}

case class InvalidateSchemaForAllProjects(client: Client)(implicit inj: Injector) extends InvalidateSchemaBase {
  def projectIds: Future[Vector[String]] = {
    import slick.jdbc.MySQLProfile.api._
    import slick.lifted.TableQuery

    val seatFuture = internalDatabase.run(TableQuery[SeatTable].filter(_.email === client.email).result)
    seatFuture.map { seats =>
      seats.toVector.map(_.projectId)
    }
  }
}

abstract class InvalidateSchemaBase()(implicit inj: Injector) extends Mutaction with Injectable {
  val internalDatabase: DatabaseDef = inject[DatabaseDef](identified by "internal-db")
  val cachedProjectResolver         = inject[CachedProjectResolver](identified by "cachedProjectResolver")
  val invalidationPublisher         = inject[PubSubPublisher[String]](identified by "schema-invalidation-publisher")

  override def execute: Future[MutactionExecutionResult] = {
    projectIds.flatMap { projectIdsOrAliases =>
      val invalidationFutures: Seq[Future[Unit]] = projectIdsOrAliases.map(cachedProjectResolver.invalidate)

      Future.sequence(invalidationFutures).map { _ =>
        invalidate(projectIds = projectIdsOrAliases)
        MutactionExecutionSuccess()
      }
    }
  }

  private def invalidate(projectIds: Seq[String]): Unit = projectIds.foreach(pid => invalidationPublisher.publish(Only(pid), pid))
  protected def projectIds: Future[Vector[String]]
  override def rollback = Some(ClientMutactionNoop().execute)
} 
Example 177
Source File: WFCommand.scala    From Scala-Reactive-Programming   with MIT License 5 votes vote down vote up
package com.packt.publishing.wf.impl

import akka.Done
import com.lightbend.lagom.scaladsl.persistence.PersistentEntity.ReplyType
import com.lightbend.lagom.scaladsl.playjson.{JsonSerializer, JsonSerializerRegistry}
import play.api.libs.json.{Format, Json}
import scala.collection.immutable.Seq

sealed trait WFCommand[R] extends ReplyType[R]

case class UseWFMessage(city: String, temperature: String) extends WFCommand[Done]

object UseWFMessage {
  implicit val format: Format[UseWFMessage] = Json.format[UseWFMessage]
}

case class WF(city: String, temperature: String) extends WFCommand[String]

object WF {
  implicit val format: Format[WF] = Json.format[WF]
}

object WFSerializerRegistry extends JsonSerializerRegistry {
  override def serializers: Seq[JsonSerializer[_]] = Seq(
    JsonSerializer[UseWFMessage],
    JsonSerializer[WF],
    JsonSerializer[WFChanged],
    JsonSerializer[WFState]
  )
} 
Example 178
Source File: WFCommand.scala    From Scala-Reactive-Programming   with MIT License 5 votes vote down vote up
package com.packt.publishing.wf.consumer.impl

import com.lightbend.lagom.scaladsl.persistence.PersistentEntity.ReplyType
import play.api.libs.json.Json
import akka.Done
import com.lightbend.lagom.scaladsl.playjson.{JsonSerializer, JsonSerializerRegistry}
import scala.collection.immutable.Seq

sealed trait WFCommand [T] extends ReplyType[T]

case class SaveNewWF(city:String, temperature: String) extends WFCommand[Done]

object SaveNewWF {
  implicit val formatter = Json.format[SaveNewWF]
}

object WFConsumerSerializerRegistry extends JsonSerializerRegistry {
  override def serializers: Seq[JsonSerializer[_]] = Seq(
    JsonSerializer[SaveNewWF],
    JsonSerializer[WFSaved],
    JsonSerializer[WFState]
  )
} 
Example 179
Source File: WFCommand.scala    From Scala-Reactive-Programming   with MIT License 5 votes vote down vote up
package com.packt.publishing.wf.impl

import akka.Done
import com.lightbend.lagom.scaladsl.persistence.PersistentEntity.ReplyType
import com.lightbend.lagom.scaladsl.playjson.{JsonSerializer, JsonSerializerRegistry}
import play.api.libs.json.{Format, Json}
import scala.collection.immutable.Seq

sealed trait WFCommand[R] extends ReplyType[R]

case class UseWFMessage(city: String, temperature: String) extends WFCommand[Done]

object UseWFMessage {
  implicit val format: Format[UseWFMessage] = Json.format[UseWFMessage]
}

case class WF(city: String, temperature: String) extends WFCommand[String]

object WF {
  implicit val format: Format[WF] = Json.format[WF]
}

object WFSerializerRegistry extends JsonSerializerRegistry {
  override def serializers: Seq[JsonSerializer[_]] = Seq(
    JsonSerializer[UseWFMessage],
    JsonSerializer[WF],
    JsonSerializer[WFChanged],
    JsonSerializer[WFState]
  )
} 
Example 180
Source File: WFCommand.scala    From Scala-Reactive-Programming   with MIT License 5 votes vote down vote up
package com.packt.publishing.wf.consumer.impl

import com.lightbend.lagom.scaladsl.persistence.PersistentEntity.ReplyType
import play.api.libs.json.Json
import akka.Done
import com.lightbend.lagom.scaladsl.playjson.{JsonSerializer, JsonSerializerRegistry}
import scala.collection.immutable.Seq

sealed trait WFCommand [T] extends ReplyType[T]

case class SaveNewWF(city:String, temperature: String) extends WFCommand[Done]

object SaveNewWF {
  implicit val formatter = Json.format[SaveNewWF]
}

object WFConsumerSerializerRegistry extends JsonSerializerRegistry {
  override def serializers: Seq[JsonSerializer[_]] = Seq(
    JsonSerializer[SaveNewWF],
    JsonSerializer[WFSaved],
    JsonSerializer[WFState]
  )
} 
Example 181
Source File: ApplicationStatus.scala    From reactive-lib   with Apache License 2.0 5 votes vote down vote up
package com.lightbend.rp.status

import akka.actor.{ ActorSystem, ExtendedActorSystem, Extension, ExtensionId, ExtensionIdProvider }
import akka.http.scaladsl.model.StatusCodes
import akka.http.scaladsl.server._
import akka.management.http.{ ManagementRouteProvider, ManagementRouteProviderSettings }
import scala.collection.immutable.Seq
import scala.concurrent.{ ExecutionContext, Future }

import Directives._

class ApplicationStatus(system: ExtendedActorSystem) extends Extension with ManagementRouteProvider {
  private val settings = Settings(system)

  private val healthChecks =
    settings
      .healthChecks
      .map(c =>
        system
          .dynamicAccess
          .createInstanceFor[HealthCheck](c, Seq.empty)
          .getOrElse(throw new IllegalArgumentException(s"Incompatible HealthCheck class definition: $c")))

  private val readinessChecks =
    settings
      .readinessChecks
      .map(c =>
        system
          .dynamicAccess
          .createInstanceFor[ReadinessCheck](c, Seq.empty)
          .getOrElse(throw new IllegalArgumentException(s"Incompatible ReadinessCheck class definition: $c")))

  def routes(settings: ManagementRouteProviderSettings): Route = pathPrefix("platform-tooling") {
    import system.dispatcher

    concat(
      path("ping")(complete("pong!")),
      path("healthy")(complete(isHealthy.map(h => if (h) StatusCodes.OK else StatusCodes.ServiceUnavailable))),
      path("ready")(complete(isReady.map(r => if (r) StatusCodes.OK else StatusCodes.ServiceUnavailable))))
  }

  def isHealthy(implicit ec: ExecutionContext): Future[Boolean] =
    Future
      .sequence(healthChecks.map(_.healthy(system)))
      .map(_.forall(identity))

  def isReady(implicit ec: ExecutionContext): Future[Boolean] =
    Future
      .sequence(readinessChecks.map(_.ready(system)))
      .map(_.forall(identity))
}

object ApplicationStatus extends ExtensionId[ApplicationStatus] with ExtensionIdProvider {
  override def lookup: ApplicationStatus.type = ApplicationStatus
  override def get(system: ActorSystem): ApplicationStatus = super.get(system)
  override def createExtension(system: ExtendedActorSystem): ApplicationStatus = new ApplicationStatus(system)
} 
Example 182
Source File: Settings.scala    From reactive-lib   with Apache License 2.0 5 votes vote down vote up
package com.lightbend.rp.servicediscovery.scaladsl

import akka.actor._
import com.typesafe.config.Config
import java.net.URI
import scala.collection.JavaConverters._
import scala.collection.immutable.Seq
import scala.concurrent.duration.{ Duration, FiniteDuration, MILLISECONDS }

final class Settings(system: ExtendedActorSystem) extends Extension {
  private val serviceDiscovery = system.settings.config.getConfig("com.lightbend.platform-tooling.service-discovery")

  val askTimeout: FiniteDuration = duration(serviceDiscovery, "ask-timeout")

  val externalServiceAddresses: Map[String, Seq[URI]] = {
    val data = serviceDiscovery.getObject("external-service-addresses")
    val config = data.toConfig

    data
      .keySet()
      .asScala
      .map(k => k -> config.getStringList(k).asScala.toVector.map(new URI(_)))
      .toMap
  }

  val externalServiceAddressLimit: Int = serviceDiscovery.getInt("external-service-address-limit")

  val retryDelays: Seq[FiniteDuration] =
    serviceDiscovery
      .getDurationList("retry-delays", MILLISECONDS)
      .asScala
      .toVector
      .map(Duration(_, MILLISECONDS))

  private def duration(config: Config, key: String): FiniteDuration =
    Duration(config.getDuration(key, MILLISECONDS), MILLISECONDS)
}

object Settings extends ExtensionId[Settings] with ExtensionIdProvider {
  override def get(system: ActorSystem): Settings = super.get(system)

  override def lookup: Settings.type = Settings

  override def createExtension(system: ExtendedActorSystem): Settings = new Settings(system)
} 
Example 183
Source File: ServiceLocatorSpec.scala    From reactive-lib   with Apache License 2.0 5 votes vote down vote up
package com.lightbend.rp.servicediscovery.javadsl

import akka.actor.ActorSystem
import akka.testkit.{ ImplicitSender, TestKit }
import com.lightbend.rp.servicediscovery.scaladsl.{ Service, Settings }
import com.typesafe.config.ConfigFactory
import java.net.URI
import java.util.Optional
import org.scalatest.{ AsyncFunSuiteLike, BeforeAndAfterAll, DiagrammedAssertions }
import scala.collection.JavaConverters._
import scala.collection.immutable.Seq

object ServiceLocatorSpec {
  def config = ConfigFactory
    .parseString(
      s"""|com.lightbend.platform-tooling.service-discovery {
          |  external-service-addresses {
          |    "has-one" = ["http://127.0.0.1:9000"]
          |    "has-two" = ["http://127.0.0.1:8000", "http://127.0.0.1:8001"]
          |  }
          |}
          |""".stripMargin)
    .withFallback(ConfigFactory.defaultApplication())
}

class ServiceLocatorSpec extends TestKit(ActorSystem("service-locator", ServiceLocatorSpec.config))
  with ImplicitSender
  with AsyncFunSuiteLike
  with DiagrammedAssertions
  with BeforeAndAfterAll {

  override def afterAll {
    TestKit.shutdownActorSystem(system)
  }

  implicit val settings = Settings(system)

  test("addressSelectionFirst should work for empty lists") {
    assert(ServiceLocator.addressSelectionFirst.select(Seq().asJava) ===
      Optional.empty[URI]())
  }

  test("addressSelectionFirst should work for non-empty lists") {
    assert(ServiceLocator.addressSelectionFirst.select(
      Seq(
        Service("myservice.com", new URI("http://127.0.0.1:9000")),
        Service("myotherservice.com", new URI("http://127.0.0.1:9001"))).asJava).get() ===
      Service("myservice.com", new URI("http://127.0.0.1:9000")))
  }

  test("addressSelectionRandom should work for empty lists") {
    assert(ServiceLocator.addressSelectionFirst.select(Seq().asJava) === Optional.empty[URI]())
  }

  test("addressSelectionRandom should work for non-empty lists") {
    assert(ServiceLocator.addressSelectionFirst.select(Seq(Service("hello", new URI("http://127.0.0.1:9000"))).asJava).isPresent)
  }
} 
Example 184
Source File: SocketBinding.scala    From reactive-lib   with Apache License 2.0 5 votes vote down vote up
package com.lightbend.rp.common

import scala.collection.immutable.Seq
import scala.collection.JavaConverters._

object SocketBinding {
  private val ValidEndpointChars =
    (('0' to '9') ++ ('A' to 'Z') ++ Seq('_')).toSet

  private val ProcotolMapping: Map[String, SocketProtocol] = Map(
    "http" -> HttpSocketProtocol,
    "tcp" -> TcpSocketProtocol,
    "udp" -> UdpSocketProtocol)

  private val reader = new EnvironmentReader(sys.env)

  def bindHost(name: String, default: String): String = reader.bindHost(name, default)

  def bindPort(name: String, default: Int): Int = reader.bindPort(name, default)

  def host(name: String, default: String): String = reader.host(name, default)

  def port(name: String, default: Int): Int = reader.port(name, default)

  def protocol(name: String): Option[SocketProtocol] = reader.protocol(name)

  private[common] class EnvironmentReader(environment: Map[String, String]) {

    def bindHost(name: String, default: String): String =
      environment
        .getOrElse(
          assembleName(name, "BIND_HOST"),
          host(name, default))

    def bindPort(name: String, default: Int): Int =
      environment
        .get(assembleName(name, "BIND_PORT"))
        .map(_.toInt)
        .getOrElse(port(name, default))

    def host(name: String, default: String): String =
      environment.getOrElse(assembleName(name, "HOST"), default)

    def port(name: String, default: Int): Int =
      environment.get(assembleName(name, "PORT")).fold(default)(_.toInt)

    def protocol(name: String): Option[SocketProtocol] =
      for {
        name <- environment.get(assembleName(name, "PROTOCOL"))
        protocol <- ProcotolMapping.get(name)
      } yield protocol

    val all: Seq[String] =
      environment
        .getOrElse("RP_ENDPOINTS", "")
        .split(',')
        .toVector

    private def assembleName(name: String, suffix: String): String =
      s"RP_ENDPOINT_${normalizeEndpointName(name)}_$suffix"

    private def normalizeEndpointName(endpointName: String): String =
      endpointName
        .toUpperCase
        .map(c => if (ValidEndpointChars.contains(c)) c else '_')
        .mkString
  }
} 
Example 185
Source File: ComposedMetricConnection.scala    From DataQuality   with GNU Lesser General Public License v3.0 5 votes vote down vote up
package models.metrics

import models.AppDB
import org.squeryl.PrimitiveTypeMode._
import org.squeryl.annotations.Column

import scala.collection.immutable.Seq
import scala.util.matching.Regex
import scala.util.parsing.combinator.JavaTokenParsers
^]".r ~ factor) ^^ {
    case t ~ ts => ts.foldLeft(t) {
      case (t1, "*" ~ t2) => Mul(t1, t2)
      case (t1, "/" ~ t2) => Div(t1, t2)
      case (t1, "^" ~ t2) => Pow(t1, t2)
    }
  }

  lazy val factor = "(" ~> expr <~ ")" | num | met
  lazy val num = floatingPointNumber ^^ { t => Num(t.toDouble) }
  lazy val met = rgx ^^ { t => Met(t.toString)}

} 
Example 186
Source File: ComposedMetricConnection.scala    From DataQuality   with GNU Lesser General Public License v3.0 5 votes vote down vote up
package dbmodel.metrics

import dbmodel.AppDB
import org.squeryl.PrimitiveTypeMode._
import org.squeryl.annotations.Column

import scala.collection.immutable.Seq
import scala.util.matching.Regex
import scala.util.parsing.combinator.JavaTokenParsers
^]".r ~ factor) ^^ {
    case t ~ ts => ts.foldLeft(t) {
      case (t1, "*" ~ t2) => Mul(t1, t2)
      case (t1, "/" ~ t2) => Div(t1, t2)
      case (t1, "^" ~ t2) => Pow(t1, t2)
    }
  }

  lazy val factor = "(" ~> expr <~ ")" | num | met
  lazy val num = floatingPointNumber ^^ { t => Num(t.toDouble) }
  lazy val met = rgx ^^ { t => Met(t.toString)}

} 
Example 187
Source File: Hedge.scala    From banditsbook-scala   with MIT License 5 votes vote down vote up
package com.github.everpeace.banditsbook.algorithm.hedge

import breeze.linalg.Vector._
import breeze.linalg._
import breeze.numerics.exp
import breeze.stats.distributions.{Rand, RandBasis}
import breeze.storage.Zero
import com.github.everpeace.banditsbook.algorithm._
import com.github.everpeace.banditsbook.arm.Arm

import scala.collection.immutable.Seq
import scala.reflect.ClassTag


object Hedge {

  case class State(η: Double, counts: Vector[Int], gains: Vector[Double])

  def Algorithm(η: Double)(implicit zeroReward: Zero[Double], zeroInt: Zero[Int], tag: ClassTag[Double], rand: RandBasis = Rand)
  = {
    require(η > 0, "η must be positive.")
    new Algorithm[Double, State] {

      override def initialState(arms: Seq[Arm[Double]]): State = State(
        η, zeros(arms.size), zeros(arms.size)
      )

      override def selectArm(arms: Seq[Arm[Double]], state: State): Int = {
        val gains = state.gains
        val η = state.η
        val p = exp(gains / η) / sum(exp(gains / η))
        CategoricalDistribution(p).draw
      }

      override def updateState(arms: Seq[Arm[Double]], state: State, chosen: Int, reward: Double): State = {
        val counts = state.counts
        val gains = state.gains

        val count = counts(chosen) + 1
        counts.update(chosen, count)

        val expectation = gains(chosen) + reward
        gains.update(chosen, expectation)

        state.copy(counts = counts, gains = gains)
      }
    }
  }
} 
Example 188
Source File: TestHedge.scala    From banditsbook-scala   with MIT License 5 votes vote down vote up
package com.github.everpeace.banditsbook.algorithm.hedge

import java.io.{File, PrintWriter}

import breeze.linalg._
import breeze.stats.MeanAndVariance
import com.github.everpeace.banditsbook.arm._
import com.github.everpeace.banditsbook.testing_framework.TestRunner
import com.github.everpeace.banditsbook.testing_framework.TestRunner._
import com.typesafe.config.ConfigFactory

import scala.collection.immutable.Seq

object TestHedge extends _TestHedge with App{
  run()
}

trait _TestHedge {
  def run() = {
//    implicit val randBasis = RandBasis.mt0

    val conf = ConfigFactory.load()
    val baseKey = "banditsbook.algorithm.hedge.test-hedge"
    val (_means, Some(ηs), horizon, nSims, outDir) = readConfig(conf, baseKey, Some("ηs"))
    val means = shuffle(_means)
    val arms = Seq(means:_*).map(μ => BernoulliArm(μ))

    val outputPath = new File(outDir, "test-hedge-results.csv")
    val file = new PrintWriter(outputPath.toString)
    file.write("eta, sim_num, step, chosen_arm, reward, cumulative_reward\n")
    try {
      println("-------------------------------")
      println("Hedge Algorithm")
      println("-------------------------------")
      println(s"   arms = ${means.map("(μ="+_+")").mkString(", ")} (Best Arm = ${argmax(means)})")
      println(s"horizon = $horizon")
      println(s"  nSims = $nSims")
      println(s"      η = (${ηs.mkString(",")})")
      println("")

      val meanOfFinalRewards = scala.collection.mutable.Map.empty[Double, MeanAndVariance]
      val res = for {
        η <- ηs
      } yield {
        println(s"starts simulation on η=$η.")

        val algo = Hedge.Algorithm(η)
        val res = TestRunner.run(algo, arms, nSims, horizon)

        for {
          sim <- 0 until nSims
        } {
          val st = sim * horizon
          val end = ((sim + 1) * horizon) - 1
        }
        val finalRewards = res.cumRewards((horizon-1) until (nSims * horizon, horizon))
        import breeze.stats._
        val meanAndVar = meanAndVariance(finalRewards)
        meanOfFinalRewards += η -> meanAndVar
        println(s"reward stats: ${TestRunner.toString(meanAndVar)}")

        res.rawResults.valuesIterator.foreach{ v =>
          file.write(s"${Seq(η, v._1, v._2, v._3, v._4, v._5).mkString(",")}\n")
        }
        println(s"finished simulation on η=$η.")
      }
      println("")
      println(s"reward stats summary")
      println(s"${meanOfFinalRewards.iterator.toSeq.sortBy(_._1).map(p => (s"η=${p._1}", TestRunner.toString(p._2))).mkString("\n")}")
    } finally {
      file.close()
      println("")
      println(s"results are written to ${outputPath}")
    }
  }
} 
Example 189
Source File: TestStandard.scala    From banditsbook-scala   with MIT License 5 votes vote down vote up
package com.github.everpeace.banditsbook.algorithm.epsilon_greedy

import java.io.{File, PrintWriter}

import breeze.linalg._
import breeze.stats.MeanAndVariance
import com.github.everpeace.banditsbook.arm._
import com.github.everpeace.banditsbook.testing_framework.TestRunner
import com.github.everpeace.banditsbook.testing_framework.TestRunner._
import com.typesafe.config.ConfigFactory

import scala.collection.immutable.Seq

object TestStandard extends _TestStandard with App {
  run()
}

trait _TestStandard {
  def run() = {
//    implicit val randBasis = RandBasis.mt0

    val conf = ConfigFactory.load()
    val baseKey = "banditsbook.algorithm.epsilon_greedy.test-standard"
    val (_means, Some(εs), horizon, nSims, outDir) = readConfig(conf, baseKey, Some("εs"))
    val means = shuffle(_means)
    val arms = Seq(means:_*).map(μ => BernoulliArm(μ))

    val outputPath = new File(outDir, "test-standard-epsilon-greedy-results.csv")
    val file = new PrintWriter(outputPath.toString)
    file.write("epsilon, sim_num, step, chosen_arm, reward, cumulative_reward\n")
    try {
      println("---------------------------------")
      println("Standard Epsilon Greedy Algorithm")
      println("---------------------------------")
      println(s"   arms = ${means.map("(μ="+_+")").mkString(", ")} (Best Arm = ${argmax(means)})")
      println(s"horizon = $horizon")
      println(s"  nSims = $nSims")
      println(s"      ε = (${εs.mkString(",")})")
      println("")

      val meanOfFinalRewards = scala.collection.mutable.Map.empty[Double, MeanAndVariance]
      val res = for {
        ε <- εs
      } yield {
        println(s"starts simulation on ε=$ε.")

        val algo = Standard.Algorithm(ε)
        val res = TestRunner.run(algo, arms, nSims, horizon)

        for {
          sim <- 0 until nSims
        } {
          val st = sim * horizon
          val end = ((sim + 1) * horizon) - 1
        }
        val finalRewards = res.cumRewards((horizon-1) until (nSims * horizon, horizon))
        import breeze.stats._
        val meanAndVar = meanAndVariance(finalRewards)
        meanOfFinalRewards += ε -> meanAndVar
        println(s"reward stats: ${TestRunner.toString(meanAndVar)}")

        res.rawResults.valuesIterator.foreach{ v =>
          file.write(s"${Seq(ε.toString, v._1.toString, v._2.toString, v._3.toString, v._4.toString, v._5.toString).mkString(",")}\n")
        }
        println(s"finished simulation on ε=$ε.")
      }
      println("")
      println(s"reward stats summary")
      println(s"${meanOfFinalRewards.iterator.toSeq.sortBy(_._1).map(p => (s"ε = ${p._1}", TestRunner.toString(p._2))).mkString("\n")}")
    } finally {
      file.close()
      println("")
      println(s"results are written to ${outputPath}")
    }
  }
} 
Example 190
Source File: Standard.scala    From banditsbook-scala   with MIT License 5 votes vote down vote up
package com.github.everpeace.banditsbook.algorithm.epsilon_greedy

import breeze.linalg.argmax
import breeze.stats.distributions.{Bernoulli, Rand, RandBasis}
import breeze.storage.Zero
import com.github.everpeace.banditsbook.algorithm.Algorithm
import com.github.everpeace.banditsbook.arm.Arm

import scala.collection.immutable.Seq
import scala.reflect.ClassTag


object Standard {

  import breeze.linalg.Vector
  import Vector._

  case class State(ε: Double, counts: Vector[Int], expectations: Vector[Double])

  def Algorithm(ε: Double)(implicit zeroDouble: Zero[Double], zeroInt: Zero[Int], tag: ClassTag[Double], rand: RandBasis = Rand)
  = new Algorithm[Double, State] {

    override def initialState(arms: Seq[Arm[Double]]): State =
      State(ε, zeros[Int](arms.size), zeros[Double](arms.size))

    override def selectArm(arms: Seq[Arm[Double]], state: State): Int =
      Bernoulli.distribution(state.ε).draw() match {
        case true =>
          // Exploit
          argmax(state.expectations)
        case false =>
          // Explore
          Rand.randInt(state.expectations.size).draw()
      }

    override def updateState(arms: Seq[Arm[Double]], state: State, chosen: Int, reward: Double): State = {
      val counts = state.counts
      val expectations = state.expectations

      val count = counts(chosen) + 1
      counts.update(chosen, count)

      val expectation = (((count - 1) / count.toDouble) * expectations(chosen)) + ((1 / count.toDouble) * reward)
      expectations.update(chosen, expectation)
      state.copy(counts = counts, expectations = expectations)
    }
  }
}