java.util.concurrent.CompletableFuture Scala Examples

The following examples show how to use java.util.concurrent.CompletableFuture. 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: RequestRunner.scala    From aws-spi-akka-http   with Apache License 2.0 5 votes vote down vote up
package com.github.matsluni.akkahttpspi

import java.util.concurrent.CompletableFuture

import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.HttpRequest
import akka.http.scaladsl.settings.ConnectionPoolSettings
import akka.stream.Materializer
import akka.stream.scaladsl.{Keep, Sink}
import org.slf4j.LoggerFactory
import software.amazon.awssdk.http.SdkHttpFullResponse
import software.amazon.awssdk.http.async.SdkAsyncHttpResponseHandler

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

class RequestRunner(connectionPoolSettings: ConnectionPoolSettings)(implicit sys: ActorSystem,
                                                          ec: ExecutionContext,
                                                          mat: Materializer) {
  val logger = LoggerFactory.getLogger(this.getClass)

  def run(httpRequest: HttpRequest,
          handler: SdkAsyncHttpResponseHandler): CompletableFuture[Void] = {
    val result = Http()
      .singleRequest(httpRequest, settings = connectionPoolSettings)
      .flatMap { response =>
        val sdkResponse = SdkHttpFullResponse.builder()
          .headers(response.headers.groupBy(_.name()).map{ case (k, v) => k -> v.map(_.value()).asJava }.asJava)
          .statusCode(response.status.intValue())
          .statusText(response.status.reason)
          .build

        handler.onHeaders(sdkResponse)

        val (complete, publisher) = response
          .entity
          .dataBytes
          .map(_.asByteBuffer)
          .alsoToMat(Sink.ignore)(Keep.right)
          .toMat(Sink.asPublisher(fanout = false))(Keep.both)
          .run()

        handler.onStream(publisher)

        complete
      }

    result.failed.foreach(handler.onError)
    FutureConverters.toJava(result.map(_ => null: Void)).toCompletableFuture
  }
} 
Example 2
Source File: AbstractOrchestrator.scala    From squbs   with Apache License 2.0 5 votes vote down vote up
package org.squbs.pattern.orchestration.japi

import java.util.concurrent.CompletableFuture

import akka.actor.{Actor, ActorRef, ActorSelection}
import akka.pattern.{AskableActorRef, AskableActorSelection}
import akka.util.Timeout
import org.squbs.pattern.orchestration.Orchestrator

import scala.concurrent.Future
import scala.util.{Failure, Success, Try}

abstract class AbstractOrchestrator extends Actor with Orchestrator {

  override def receive = super.receive

  def ask(actor: ActorRef, message: Any, timeout: Timeout): Ask = {
    val future = new AskableActorRef(actor).ask(message)(timeout)
    new Ask(future)
  }

  def ask(actor: ActorSelection, message: Any, timeout: Timeout): Ask = {
    val future = new AskableActorSelection(actor).ask(message)(timeout)
    new Ask(future)
  }

  class Ask private[japi](private val future: Future[Any]) {

    def thenComplete[T](cFuture: CompletableFuture[T]): Unit = {
      // Dragons here: DO NOT call nextMessageId from inside future.onComplete as that executes
      // outside the context of the actor. Instead, obtain the (val) id eagerly inside the actor and
      // give it to the function so it becomes pre-assigned.
      val nextId = nextMessageId
      import context.dispatcher
      future onComplete { self ! UniqueTryWrapper(nextId, _) }
      expectOnce {
        case UniqueTryWrapper(`nextId`, tt: Try[_]) =>
          tt match {
            case Success(t) => cFuture.complete(t.asInstanceOf[T])
            case Failure(e) => cFuture.completeExceptionally(e)
          }
      }
    }
  }
} 
Example 3
Source File: FutureAsyncHandler.scala    From pulsar4s   with Apache License 2.0 5 votes vote down vote up
package com.sksamuel.pulsar4s

import java.util.concurrent.CompletableFuture

import org.apache.pulsar.client.api
import org.apache.pulsar.client.api.TypedMessageBuilder

import scala.compat.java8.FutureConverters
import scala.compat.java8.FutureConverters.CompletionStageOps
import scala.concurrent.ExecutionContext
import scala.concurrent.Future
import scala.util.Failure
import scala.util.Success
import scala.util.Try

class FutureAsyncHandler(implicit ec: ExecutionContext) extends AsyncHandler[Future] {

  implicit class VoidCompletableFutureOps(val completableFuture: CompletableFuture[Void]) {
    def toScala: Future[Unit] = new CompletionStageOps(completableFuture).toScala.map(_ => ())
  }

  override def failed(e: Throwable): Future[Nothing] = Future.failed(e)

  override def createProducer[T](builder: api.ProducerBuilder[T]): Future[Producer[T]] = {
    builder.createAsync().thenApply[Producer[T]](new DefaultProducer(_)).toScala
  } 

  override def send[T](t: T, producer: api.Producer[T]): Future[MessageId] = {
    val future = producer.sendAsync(t)
    FutureConverters.toScala(future).map(MessageId.fromJava)
  }

  override def receive[T](consumer: api.Consumer[T]): Future[ConsumerMessage[T]] = {
    val future = consumer.receiveAsync()
    FutureConverters.toScala(future).map(ConsumerMessage.fromJava)
  }

  override def unsubscribeAsync(consumer: api.Consumer[_]): Future[Unit] = consumer.unsubscribeAsync().toScala

  override def getLastMessageId[T](consumer: api.Consumer[T]): Future[MessageId] = {
    val future = consumer.getLastMessageIdAsync()
    FutureConverters.toScala(future).map(MessageId.fromJava)
  }

  override def close(producer: api.Producer[_]): Future[Unit] = producer.closeAsync().toScala
  override def close(consumer: api.Consumer[_]): Future[Unit] = consumer.closeAsync().toScala

  override def seekAsync(consumer: api.Consumer[_], messageId: MessageId): Future[Unit] =
    consumer.seekAsync(messageId).toScala
  
  override def seekAsync(reader: api.Reader[_], messageId: MessageId): Future[Unit] =
    reader.seekAsync(messageId).toScala
  
  override def seekAsync(reader: api.Reader[_], timestamp: Long): Future[Unit] =
    reader.seekAsync(timestamp).toScala

  override def transform[A, B](f: Future[A])(fn: A => Try[B]): Future[B] = f.flatMap { a =>
    fn(a) match {
      case Success(b) => Future.successful(b)
      case Failure(e) => Future.failed(e)
    }
  }

  override def acknowledgeAsync[T](consumer: api.Consumer[T], messageId: MessageId): Future[Unit] =
    consumer.acknowledgeAsync(messageId).toScala

  override def negativeAcknowledgeAsync[T](consumer: JConsumer[T], messageId: MessageId): Future[Unit] =
    Future.successful(consumer.negativeAcknowledge(messageId))

  override def acknowledgeCumulativeAsync[T](consumer: api.Consumer[T], messageId: MessageId): Future[Unit] =
    consumer.acknowledgeCumulativeAsync(messageId).toScala

  override def close(reader: api.Reader[_]): Future[Unit] = reader.closeAsync().toScala
  override def flush(producer: api.Producer[_]): Future[Unit] = producer.flushAsync().toScala

  override def nextAsync[T](reader: api.Reader[T]): Future[ConsumerMessage[T]] =
    reader.readNextAsync().toScala.map(ConsumerMessage.fromJava)

  override def send[T](builder: TypedMessageBuilder[T]): Future[MessageId] =
    builder.sendAsync().toScala.map(MessageId.fromJava)
} 
Example 4
Source File: ScalazAsyncHandler.scala    From pulsar4s   with Apache License 2.0 5 votes vote down vote up
package com.sksamuel.pulsar4s.scalaz

import java.util.concurrent.CompletableFuture
import java.util.function.BiConsumer

import com.sksamuel.pulsar4s.{AsyncHandler, ConsumerMessage, DefaultProducer, MessageId, Producer}
import org.apache.pulsar.client.api
import org.apache.pulsar.client.api.Consumer
import org.apache.pulsar.client.api.{ProducerBuilder, Reader, TypedMessageBuilder}
import scalaz.concurrent.Task

import scala.language.implicitConversions
import scala.util.{Failure, Success, Try}

class ScalazAsyncHandler extends AsyncHandler[Task] {

  implicit def completableVoidToTask(f: => CompletableFuture[Void]): Task[Unit] =
    completableToTask(f).map(_ => ())

  implicit def completableToTask[T](f: => CompletableFuture[T]): Task[T] = {
    Task.async[T] { k =>
      f.whenCompleteAsync(new BiConsumer[T, Throwable] {
        override def accept(t: T, e: Throwable): Unit = {
          if (e != null)
            k.apply(scalaz.\/.left(e))
          else
            k.apply(scalaz.\/.right(t))
        }
      })
    }
  }

  override def failed(e: Throwable): Task[Nothing] = Task.fail(e)

  override def createProducer[T](builder: ProducerBuilder[T]): Task[Producer[T]] =
    completableToTask(builder.createAsync()).map(new DefaultProducer(_))

  override def send[T](t: T, producer: api.Producer[T]): Task[MessageId] =
    completableToTask(producer.sendAsync(t)).map(MessageId.fromJava)

  override def receive[T](consumer: api.Consumer[T]): Task[ConsumerMessage[T]] =
    completableToTask(consumer.receiveAsync).map(ConsumerMessage.fromJava)
  
  override def getLastMessageId[T](consumer: api.Consumer[T]): Task[MessageId] =
    completableToTask(consumer.getLastMessageIdAsync()).map(MessageId.fromJava)

  override def unsubscribeAsync(consumer: api.Consumer[_]): Task[Unit] =
    consumer.unsubscribeAsync()

  override def seekAsync(consumer: api.Consumer[_], messageId: MessageId): Task[Unit] =
    consumer.seekAsync(messageId)
  
  override def seekAsync(reader: api.Reader[_], messageId: MessageId): Task[Unit] =
    reader.seekAsync(messageId)
  
  override def seekAsync(reader: api.Reader[_], timestamp: Long): Task[Unit] =
    reader.seekAsync(timestamp)

  override def transform[A, B](f: Task[A])(fn: A => Try[B]): Task[B] = f.flatMap { a =>
    fn(a) match {
      case Success(b) => Task.now(b)
      case Failure(e) => Task.fail(e)
    }
  }

  override def acknowledgeAsync[T](consumer: api.Consumer[T], messageId: MessageId): Task[Unit] =
    consumer.acknowledgeAsync(messageId)

  override def acknowledgeCumulativeAsync[T](consumer: api.Consumer[T], messageId: MessageId): Task[Unit] =
    consumer.acknowledgeCumulativeAsync(messageId)

  override def negativeAcknowledgeAsync[T](consumer: Consumer[T], messageId: MessageId): Task[Unit] =
    Task { consumer.negativeAcknowledge(messageId) }

  override def close(reader: Reader[_]): Task[Unit] = reader.closeAsync()
  override def close(producer: api.Producer[_]): Task[Unit] = producer.closeAsync()
  override def close(consumer: api.Consumer[_]): Task[Unit] = consumer.closeAsync()

  override def flush(producer: api.Producer[_]): Task[Unit] = producer.flushAsync()

  override def nextAsync[T](reader: Reader[T]): Task[ConsumerMessage[T]] =
    reader.readNextAsync().map(ConsumerMessage.fromJava)

  override def send[T](builder: TypedMessageBuilder[T]): Task[MessageId] =
    builder.sendAsync().map(MessageId.fromJava)
}

object ScalazAsyncHandler {
  implicit def handler: AsyncHandler[Task] = new ScalazAsyncHandler
} 
Example 5
Source File: CatsAsyncHandler.scala    From pulsar4s   with Apache License 2.0 5 votes vote down vote up
package com.sksamuel.pulsar4s.cats

import java.util.concurrent.CompletableFuture
import java.util.function.BiConsumer

import cats.implicits._
import cats.effect._
import com.sksamuel.pulsar4s.{AsyncHandler, ConsumerMessage, DefaultProducer, MessageId, Producer}
import org.apache.pulsar.client.api
import org.apache.pulsar.client.api.{ProducerBuilder, Reader, TypedMessageBuilder}

import scala.language.higherKinds
import scala.util.{Failure, Success, Try}


object CatsAsyncHandler extends CatsAsyncHandlerLowPriority {
  implicit def handler: AsyncHandler[IO] = asyncHandlerForCatsEffectAsync[IO]
}

trait CatsAsyncHandlerLowPriority {
  object CompletableFutureConverters {
    implicit class CompletableOps[T](f: => CompletableFuture[T]) {
      def toF[F[_]: Async]: F[T] =
        Async[F].async[T] { k =>
          f.whenCompleteAsync(new BiConsumer[T, Throwable] {
            override def accept(t: T, e: Throwable): Unit = {
              if (e != null) k.apply(Left(e))
              else k.apply(Right(t))
            }
          })
        }

    }
  }

  implicit def asyncHandlerForCatsEffectAsync[F[_]: Async]: AsyncHandler[F] = new AsyncHandler[F] {
    import CompletableFutureConverters._

    override def failed(e: Throwable): F[Nothing] = Async[F].raiseError(e)

    override def createProducer[T](builder: ProducerBuilder[T]): F[Producer[T]] = builder.createAsync().toF[F].map(new DefaultProducer(_))

    override def send[T](t: T, producer: api.Producer[T]): F[MessageId] = producer.sendAsync(t).toF[F].map(MessageId.fromJava)
    override def receive[T](consumer: api.Consumer[T]): F[ConsumerMessage[T]] = consumer.receiveAsync().toF[F].map(ConsumerMessage.fromJava)

    override def unsubscribeAsync(consumer: api.Consumer[_]): F[Unit] = consumer.unsubscribeAsync().toF[F].void

    override def getLastMessageId[T](consumer: api.Consumer[T]): F[MessageId] = consumer.getLastMessageIdAsync().toF[F].map(MessageId.fromJava)

    override def close(producer: api.Producer[_]): F[Unit] = producer.closeAsync().toF[F].void
    override def close(consumer: api.Consumer[_]): F[Unit] = consumer.closeAsync().toF[F].void

    override def seekAsync(consumer: api.Consumer[_], messageId: MessageId): F[Unit] = consumer.seekAsync(messageId).toF[F].void
    override def seekAsync(reader: api.Reader[_], messageId: MessageId): F[Unit] = reader.seekAsync(messageId).toF[F].void
    override def seekAsync(reader: api.Reader[_], timestamp: Long): F[Unit] = reader.seekAsync(timestamp).toF[F].void

    override def transform[A, B](t: F[A])(fn: A => Try[B]): F[B] =
      t.flatMap { a =>
        fn(a) match {
          case Success(b) => Async[F].pure(b)
          case Failure(e) => Async[F].raiseError(e)
        }
      }

    override def acknowledgeAsync[T](consumer: api.Consumer[T], messageId: MessageId): F[Unit] =
      consumer.acknowledgeAsync(messageId).toF[F].void

    override def acknowledgeCumulativeAsync[T](consumer: api.Consumer[T], messageId: MessageId): F[Unit] =
      consumer.acknowledgeCumulativeAsync(messageId).toF[F].void

    override def negativeAcknowledgeAsync[T](consumer: api.Consumer[T], messageId: MessageId): F[Unit] =
      Async[F].delay { consumer.negativeAcknowledge(messageId) }

    override def close(reader: Reader[_]): F[Unit] = reader.closeAsync().toF[F].void
    override def flush(producer: api.Producer[_]): F[Unit] = producer.flushAsync().toF[F].void

    override def nextAsync[T](reader: Reader[T]): F[ConsumerMessage[T]] =
      reader.readNextAsync().toF[F].map(ConsumerMessage.fromJava)

    override def send[T](builder: TypedMessageBuilder[T]): F[MessageId] =
      builder.sendAsync().toF[F].map(MessageId.fromJava)
  }

} 
Example 6
Source File: MonixAsyncHandler.scala    From pulsar4s   with Apache License 2.0 5 votes vote down vote up
package com.sksamuel.pulsar4s.monixs

import java.util.concurrent.CompletableFuture

import com.sksamuel.pulsar4s.{AsyncHandler, ConsumerMessage, DefaultProducer, MessageId, Producer}
import monix.eval.Task
import org.apache.pulsar.client.api
import org.apache.pulsar.client.api.Consumer
import org.apache.pulsar.client.api.{ProducerBuilder, Reader, TypedMessageBuilder}

import scala.compat.java8.FutureConverters
import scala.concurrent.Future
import scala.language.implicitConversions
import scala.util.{Failure, Success, Try}

class MonixAsyncHandler extends AsyncHandler[Task] {

  implicit def completableTToFuture[T](f: => CompletableFuture[T]): Future[T] =
    FutureConverters.toScala(f)

  implicit def completableVoidToTask(f: => CompletableFuture[Void]): Task[Unit] =
    Task.deferFuture(FutureConverters.toScala(f)).map(_ => ())

  override def failed(e: Throwable): Task[Nothing] = Task.raiseError(e)

  override def createProducer[T](builder: ProducerBuilder[T]): Task[Producer[T]] =
    Task.deferFuture(FutureConverters.toScala(builder.createAsync())).map(new DefaultProducer(_))

  override def send[T](t: T, producer: api.Producer[T]): Task[MessageId] = {
    Task.deferFuture {
      val future = producer.sendAsync(t)
      FutureConverters.toScala(future)
    }.map { id => MessageId.fromJava(id) }
  }

  override def receive[T](consumer: api.Consumer[T]): Task[ConsumerMessage[T]] = {
    Task.deferFuture {
      val future = consumer.receiveAsync()
      FutureConverters.toScala(future)
    }.map(ConsumerMessage.fromJava)
  }

  override def getLastMessageId[T](consumer: api.Consumer[T]): Task[MessageId] = {
    Task.deferFuture {
      val future = consumer.getLastMessageIdAsync()
      FutureConverters.toScala(future)
    }.map(MessageId.fromJava)
  }

  def unsubscribeAsync(consumer: api.Consumer[_]): Task[Unit] = consumer.unsubscribeAsync()

  override def close(producer: api.Producer[_]): Task[Unit] = producer.closeAsync()
  override def close(consumer: api.Consumer[_]): Task[Unit] = consumer.closeAsync()

  override def seekAsync(consumer: api.Consumer[_], messageId: MessageId): Task[Unit] =
    consumer.seekAsync(messageId)
  
  override def seekAsync(reader: api.Reader[_], messageId: MessageId): Task[Unit] =
    reader.seekAsync(messageId)
  
  override def seekAsync(reader: api.Reader[_], timestamp: Long): Task[Unit] =
    reader.seekAsync(timestamp)


  override def transform[A, B](t: Task[A])(fn: A => Try[B]): Task[B] =
    t.flatMap { a =>
      fn(a) match {
        case Success(b) => Task.now(b)
        case Failure(e) => Task.raiseError(e)
      }
    }

  override def acknowledgeAsync[T](consumer: api.Consumer[T], messageId: MessageId): Task[Unit] =
    consumer.acknowledgeAsync(messageId)

  override def acknowledgeCumulativeAsync[T](consumer: api.Consumer[T], messageId: MessageId): Task[Unit] =
    consumer.acknowledgeCumulativeAsync(messageId)

  override def negativeAcknowledgeAsync[T](consumer: Consumer[T], messageId: MessageId): Task[Unit] =
    Task { consumer.negativeAcknowledge(messageId) }

  override def close(reader: Reader[_]): Task[Unit] = reader.closeAsync()
  override def flush(producer: api.Producer[_]): Task[Unit] = producer.flushAsync()

  override def nextAsync[T](reader: Reader[T]): Task[ConsumerMessage[T]] =
    Task.deferFuture(reader.readNextAsync()).map(ConsumerMessage.fromJava)

  override def send[T](builder: TypedMessageBuilder[T]): Task[MessageId] =
    Task.deferFuture(builder.sendAsync()).map(MessageId.fromJava)
}

object MonixAsyncHandler {
  implicit def handler: AsyncHandler[Task] = new MonixAsyncHandler
} 
Example 7
Source File: GrpcMarshalling.scala    From akka-grpc   with Apache License 2.0 5 votes vote down vote up
package akka.grpc.javadsl

import java.util.concurrent.{ CompletableFuture, CompletionStage }
import java.util.Optional

import akka.NotUsed
import akka.actor.ActorSystem
import akka.actor.ClassicActorSystemProvider
import akka.grpc._
import akka.grpc.internal.{ CancellationBarrierGraphStage, GrpcResponseHelpers, MissingParameterException }
import akka.grpc.GrpcProtocol.{ GrpcProtocolReader, GrpcProtocolWriter }
import akka.http.javadsl.model.{ HttpRequest, HttpResponse }
import akka.japi.Function
import akka.stream.Materializer
import akka.stream.javadsl.{ Sink, Source }
import akka.util.ByteString

import com.github.ghik.silencer.silent

object GrpcMarshalling {

  def negotiated[T](
      req: HttpRequest,
      f: (GrpcProtocolReader, GrpcProtocolWriter) => CompletionStage[T]): Optional[CompletionStage[T]] =
    GrpcProtocol
      .negotiate(req)
      .map {
        case (maybeReader, writer) =>
          maybeReader.map(reader => f(reader, writer)).fold[CompletionStage[T]](failure, identity)
      }
      .fold(Optional.empty[CompletionStage[T]])(Optional.of)

  def unmarshal[T](
      data: Source[ByteString, AnyRef],
      u: ProtobufSerializer[T],
      mat: Materializer,
      reader: GrpcProtocolReader): CompletionStage[T] =
    data.via(reader.dataFrameDecoder).map(u.deserialize).runWith(Sink.headOption[T], mat).thenCompose[T] { opt =>
      if (opt.isPresent) CompletableFuture.completedFuture(opt.get)
      else failure(new MissingParameterException())
    }

  def unmarshalStream[T](
      data: Source[ByteString, AnyRef],
      u: ProtobufSerializer[T],
      @silent("never used") mat: Materializer,
      reader: GrpcProtocolReader): CompletionStage[Source[T, NotUsed]] = {
    CompletableFuture.completedFuture[Source[T, NotUsed]](
      data
        .mapMaterializedValue(_ => NotUsed)
        .via(reader.dataFrameDecoder)
        .map(japiFunction(u.deserialize))
        // In gRPC we signal failure by returning an error code, so we
        // don't want the cancellation bubbled out
        .via(new CancellationBarrierGraphStage)
        .mapMaterializedValue(japiFunction(_ => NotUsed)))
  }

  def marshal[T](
      e: T,
      m: ProtobufSerializer[T],
      writer: GrpcProtocolWriter,
      system: ClassicActorSystemProvider,
      eHandler: Function[ActorSystem, Function[Throwable, Trailers]] = GrpcExceptionHandler.defaultMapper)
      : HttpResponse =
    marshalStream(Source.single(e), m, writer, system, eHandler)

  def marshalStream[T](
      e: Source[T, NotUsed],
      m: ProtobufSerializer[T],
      writer: GrpcProtocolWriter,
      system: ClassicActorSystemProvider,
      eHandler: Function[ActorSystem, Function[Throwable, Trailers]] = GrpcExceptionHandler.defaultMapper)
      : HttpResponse =
    GrpcResponseHelpers(e.asScala, scalaAnonymousPartialFunction(eHandler))(m, writer, system)

  private def failure[R](error: Throwable): CompletableFuture[R] = {
    val future: CompletableFuture[R] = new CompletableFuture()
    future.completeExceptionally(error)
    future
  }
} 
Example 8
Source File: ServiceHandler.scala    From akka-grpc   with Apache License 2.0 5 votes vote down vote up
package akka.grpc.javadsl

import java.util.concurrent.{ CompletableFuture, CompletionStage }

import akka.annotation.ApiMayChange
import akka.annotation.InternalApi
import akka.grpc.scaladsl.{ ServiceHandler => sServiceHandler }
import akka.http.javadsl.model.{ HttpRequest, HttpResponse, StatusCodes }
// using japi because bindAndHandleAsync expects that
import akka.japi.{ Function => JFunction }

import scala.annotation.varargs

@ApiMayChange
object ServiceHandler {

  
  @varargs
  def handler(handlers: JFunction[HttpRequest, CompletionStage[HttpResponse]]*)
      : JFunction[HttpRequest, CompletionStage[HttpResponse]] = {
    val servicesHandler = concat(handlers: _*)
    (req: HttpRequest) => if (sServiceHandler.isGrpcRequest(req)) servicesHandler(req) else unsupportedMediaType
  }

  private[javadsl] def concat(handlers: JFunction[HttpRequest, CompletionStage[HttpResponse]]*)
      : JFunction[HttpRequest, CompletionStage[HttpResponse]] =
    (req: HttpRequest) =>
      handlers.foldLeft(notFound) { (comp, next) =>
        comp.thenCompose(res => if (res.status == StatusCodes.NOT_FOUND) next.apply(req) else comp)
      }

} 
Example 9
Source File: DropwizardRoundTripTest.scala    From guardrail   with MIT License 5 votes vote down vote up
package core.Dropwizard

import com.fasterxml.jackson.databind.ObjectMapper
import examples.client.dropwizard.user.{ UserClient, GetUserByNameResponse => GetUserByNameClientResponse }
import examples.server.dropwizard.definitions.User
import examples.server.dropwizard.user.UserHandler._
import examples.server.dropwizard.user._
import helpers.MockHelpers._
import java.util
import java.util.Optional
import java.util.concurrent.{ CompletableFuture, CompletionStage }
import org.asynchttpclient.{ Request, Response }
import org.mockito.{ ArgumentMatchersSugar, MockitoSugar }
import org.scalatest.concurrent.Waiters
import org.scalatest.{ FreeSpec, Matchers }
import scala.compat.java8.FunctionConverters._

class DropwizardRoundTripTest extends FreeSpec with Matchers with Waiters with MockitoSugar with ArgumentMatchersSugar {
  private implicit val mapper = new ObjectMapper

  "Test server" in {
    val USERNAME = "foobar"

    val serverFuture  = new CompletableFuture[GetUserByNameResponse]
    val asyncResponse = mockAsyncResponse(serverFuture)

    val resource = new UserResource(new UserHandler {
      override def createUser(body: User): CompletionStage[CreateUserResponse]                                          = ???
      override def createUsersWithArrayInput(body: util.List[User]): CompletionStage[CreateUsersWithArrayInputResponse] = ???
      override def createUsersWithListInput(body: util.List[User]): CompletionStage[CreateUsersWithListInputResponse]   = ???
      override def loginUser(username: String, password: String): CompletionStage[LoginUserResponse]                    = ???
      override def logoutUser(): CompletionStage[LogoutUserResponse]                                                    = ???
      override def updateUser(username: String, body: User): CompletionStage[UpdateUserResponse]                        = ???
      override def deleteUser(username: String): CompletionStage[DeleteUserResponse]                                    = ???

      override def getUserByName(username: String): CompletionStage[GetUserByNameResponse] = {
        username match {
          case USERNAME =>
            serverFuture.complete(
              GetUserByNameResponse.Ok(
                new User.Builder()
                  .withEmail("[email protected]")
                  .withFirstName("Foo")
                  .withLastName("Bar")
                  .withId(1)
                  .withUsername(USERNAME)
                  .build()
              )
            )
          case "" =>
            serverFuture.complete(GetUserByNameResponse.BadRequest)
          case _ =>
            serverFuture.complete(GetUserByNameResponse.NotFound)
        }
        serverFuture
      }
    })

    val httpClient: Request => CompletionStage[Response] = { request =>
      val userPath = "^/v2/user/([^/]*)$".r
      request.getUri.getPath match {
        case userPath(username) =>
          resource.getUserByName(username, asyncResponse)
          serverFuture.thenApply({ response =>
            val entityBody = response match {
              case r: GetUserByNameResponse.Ok => Some(r.getEntityBody)
              case _                           => None
            }
            mockAHCResponse(request.getUrl, response.getStatusCode, entityBody)
          })
        case _ =>
          CompletableFuture.completedFuture(mockAHCResponse(request.getUrl, 404))
      }
    }

    val client = new UserClient.Builder()
      .withHttpClient(httpClient.asJava)
      .withObjectMapper(mapper)
      .build()

    val w = new Waiter
    client
      .getUserByName(USERNAME)
      .call()
      .whenComplete({ (response, t) =>
        w { t shouldBe null }
        response match {
          case r: GetUserByNameClientResponse.Ok =>
            w {
              r.getValue.getUsername.get shouldBe USERNAME
              r.getValue.getPassword shouldBe Optional.empty
            }
          case _: GetUserByNameClientResponse.BadRequest => w { fail("Got BadRequest") }
          case _: GetUserByNameClientResponse.NotFound   => w { fail("Got NotFound") }
        }
        w.dismiss()
      })
    w.await(dismissals(1))
  }
} 
Example 10
Source File: JavaInvalidCharacterEscapingTest.scala    From guardrail   with MIT License 5 votes vote down vote up
package core.Dropwizard

import com.fasterxml.jackson.annotation.JsonProperty
import com.fasterxml.jackson.databind.ObjectMapper
import invalidCharacters.client.dropwizard.invalidCharacters.InvalidCharactersClient
import invalidCharacters.server.dropwizard.definitions.{InvalidCharacters, InvalidCharactersEnum}
import io.netty.buffer.Unpooled
import java.net.{SocketAddress, URI, URLDecoder}
import java.util.concurrent.{CompletableFuture, CompletionStage}
import java.util.function
import org.asynchttpclient.Response.ResponseBuilder
import org.asynchttpclient.netty.EagerResponseBodyPart
import org.asynchttpclient.uri.Uri
import org.asynchttpclient.{HttpResponseStatus, Request, Response}
import org.scalatest.freespec.AnyFreeSpec
import org.scalatest.matchers.must.Matchers
import scala.collection.JavaConverters._

object JavaInvalidCharacterEscapingTest {
  private implicit class RichString(private val s: String) extends AnyVal {
    def dec: String = URLDecoder.decode(s, "UTF-8")
  }

  private object OkStatus extends HttpResponseStatus(Uri.create("http://localhost:1234/foo?foo^bar=query-param")) {
    override def getStatusCode = 200
    override def getStatusText = "OK"
    override def getProtocolName = "HTTP"
    override def getProtocolMajorVersion = 1
    override def getProtocolMinorVersion = 1
    override def getProtocolText = "HTTP/1.1"
    override def getRemoteAddress: SocketAddress = ???
    override def getLocalAddress: SocketAddress = ???
  }
}

class JavaInvalidCharacterEscapingTest extends AnyFreeSpec with Matchers {
  import JavaInvalidCharacterEscapingTest._

  "Invalid characters in Java enums should be escaped" in {
    InvalidCharactersEnum.NORMAL.getName mustBe "normal"
    InvalidCharactersEnum.BANG_MOO_COLON_COW_SEMICOLON.getName mustBe "!moo:cow;"
    InvalidCharactersEnum.POUND_YEAH.getName mustBe "#yeah"
    InvalidCharactersEnum.WEIRD_AT.getName mustBe "weird@"
  }

  "Invalid characters in Java POJO properties should be escaped" in {
    val invChar = new InvalidCharacters.Builder("stuff", InvalidCharactersEnum.POUND_YEAH).build()
    invChar.getCloseSquareBraceMoo mustBe "stuff"
    invChar.getSomeEnumAsteriskCaret mustBe InvalidCharactersEnum.POUND_YEAH

    classOf[InvalidCharacters].getDeclaredField("closeSquareBraceMoo").getAnnotation(classOf[JsonProperty]).value mustBe "]moo"
    classOf[InvalidCharacters].getDeclaredField("someEnumAsteriskCaret").getAnnotation(classOf[JsonProperty]).value mustBe "some-enum*^"
  }

  "Invalid characters in Java operation param names should be escaped" in {
    val httpClient = new function.Function[Request, CompletionStage[Response]] {
      override def apply(request: Request): CompletionStage[Response] = {
        println(request.getUri)
        println(request.getQueryParams.asScala.map(_.getName))
        val qps = request.getQueryParams.asScala.map(p => (p.getName.dec, p.getValue.dec))
        val fps = request.getFormParams.asScala.map(p => (p.getName.dec, p.getValue.dec))
        qps.find(_._1 == "foo^bar").map(_._2) mustBe Some("firstarg")
        fps.find(_._1 == "a*b").map(_._2) mustBe Some("secondarg")
        fps.find(_._1 == "bc?").map(_._2) mustBe Some("thirdarg")
        fps.find(_._1 == "d/c").map(_._2) mustBe Some("fourtharg")
        val response = new ResponseBuilder()
        response.accumulate(OkStatus)
        response.accumulate(new EagerResponseBodyPart(
          Unpooled.copiedBuffer(new ObjectMapper().writeValueAsBytes(new InvalidCharacters.Builder("foo", InvalidCharactersEnum.WEIRD_AT).build())),
          true
        ))
        CompletableFuture.completedFuture(response.build())
      }
    }

    val client = new InvalidCharactersClient.Builder(new URI("http://localhost:1234")).withHttpClient(httpClient).build()
    val response = client.getFoo("firstarg", "secondarg", "thirdarg", "fourtharg").call().toCompletableFuture.get()
    response.fold(
      { invChar =>
        invChar.getCloseSquareBraceMoo mustBe "foo"
        invChar.getSomeEnumAsteriskCaret mustBe invalidCharacters.client.dropwizard.definitions.InvalidCharactersEnum.WEIRD_AT
      }
    )
  }
} 
Example 11
Source File: MockHelpers.scala    From guardrail   with MIT License 5 votes vote down vote up
package helpers

import com.fasterxml.jackson.databind.ObjectMapper
import io.netty.handler.codec.http.EmptyHttpHeaders
import java.io.ByteArrayInputStream
import java.nio.ByteBuffer
import java.nio.charset.StandardCharsets
import java.util.Collections
import java.util.concurrent.CompletableFuture
import javax.ws.rs.container.AsyncResponse
import org.asynchttpclient.Response
import org.asynchttpclient.uri.Uri
import org.mockito.{ ArgumentMatchersSugar, MockitoSugar }
import org.scalatest.Assertions
import scala.reflect.ClassTag

object MockHelpers extends Assertions with MockitoSugar with ArgumentMatchersSugar {
  def mockAsyncResponse[T](future: CompletableFuture[T])(implicit cls: ClassTag[T]): AsyncResponse = {
    val asyncResponse = mock[AsyncResponse]

    when(asyncResponse.resume(any[T])) thenAnswer [AnyRef] { response =>
      response match {
        case t: Throwable => future.completeExceptionally(t)
        case other: T     => future.complete(other)
        case other        => fail(s"AsyncResponse.resume expected an object of type ${cls.runtimeClass.getName}, but got ${other.getClass.getName} instead")
      }
    }

    asyncResponse
  }

  def mockAHCResponse[T](uri: String, status: Int, maybeBody: Option[T] = None)(implicit mapper: ObjectMapper): Response = {
    val response = mock[Response]
    when(response.getUri) thenReturn Uri.create(uri)
    when(response.hasResponseStatus) thenReturn true
    when(response.getStatusCode) thenReturn status
    when(response.getStatusText) thenReturn "Some Status"
    when(response.hasResponseHeaders) thenReturn true
    when(response.getHeaders) thenReturn EmptyHttpHeaders.INSTANCE
    when(response.getHeader(any)) thenReturn null
    when(response.getHeaders(any)) thenReturn Collections.emptyList()
    maybeBody match {
      case None =>
        when(response.hasResponseBody) thenReturn true
      case Some(body) =>
        val responseBytes = mapper.writeValueAsBytes(body)
        val responseStr   = new String(responseBytes, StandardCharsets.UTF_8)
        when(response.hasResponseBody) thenReturn true
        when(response.getResponseBody(any)) thenReturn responseStr
        when(response.getResponseBody) thenReturn responseStr
        when(response.getResponseBodyAsStream) thenReturn new ByteArrayInputStream(responseBytes)
        when(response.getResponseBodyAsByteBuffer) thenReturn ByteBuffer.wrap(responseBytes)
        when(response.getResponseBodyAsBytes) thenReturn responseBytes
    }
    response
  }

} 
Example 12
Source File: DateTimeSpecs.scala    From guardrail   with MIT License 5 votes vote down vote up
package dateTime.server.springMvc.dateTime

import java.time.{ LocalDate, OffsetDateTime }
import java.util.concurrent.CompletableFuture

import org.junit.runner.RunWith
import org.mockito.{ ArgumentMatchersSugar, MockitoSugar }
import org.scalatest.{ BeforeAndAfterAll, FreeSpec, Matchers }
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.autoconfigure.EnableAutoConfiguration
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.context.annotation.ComponentScan
import org.springframework.http.MediaType
import org.springframework.test.context.TestContextManager
import org.springframework.test.context.junit4.SpringRunner
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.{ asyncDispatch, post, get}
import org.springframework.test.web.servlet.result.MockMvcResultHandlers.print
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.{ request, status }
import spring.test.TestApplication

@RunWith(classOf[SpringRunner])
@SpringBootTest(classes = Array(classOf[TestApplication]))
@AutoConfigureMockMvc
@ComponentScan
@EnableAutoConfiguration
class DateTimeSpecs extends FreeSpec with Matchers with BeforeAndAfterAll with MockitoSugar with ArgumentMatchersSugar {
  @Autowired var mvc: MockMvc                    = _
  @Autowired var handlerMock: DateTimeHandler = _

  new TestContextManager(this.getClass).prepareTestInstance(this)

  "test jsre310 stuff" - {
    "dates everywhere" in {

      val offsetDtNow = OffsetDateTime.now
      val localDtNow = LocalDate.now

      when(
        handlerMock.getSomething(
          eqTo(offsetDtNow),
          eqTo(java.util.Optional.of(offsetDtNow)),
          eqTo(localDtNow),
          eqTo(java.util.Optional.of(localDtNow))
        )
      ).thenReturn(CompletableFuture.completedFuture(DateTimeHandler.GetSomethingResponse.NoContent))

      val mvcResult = mvc
        .perform(
          get("/foo")
            .param("dateTime", offsetDtNow.toString)
            .param("optionalDateTime", offsetDtNow.toString)
            .param("date", localDtNow.toString)
            .param("optionalDate", localDtNow.toString)
            .contentType(MediaType.APPLICATION_JSON)
        )
        .andExpect(request.asyncStarted)
        .andReturn

      mvc.perform(asyncDispatch(mvcResult)).andDo(print()).andExpect(status.isNoContent)
    }
  }
} 
Example 13
Source File: AliasSpecs.scala    From guardrail   with MIT License 5 votes vote down vote up
package alias.server.springMvc.foo

import java.util.concurrent.CompletableFuture

import org.junit.runner.RunWith
import org.mockito.{ArgumentMatchersSugar, MockitoSugar}
import org.scalatest.{BeforeAndAfterAll, FreeSpec, Matchers}
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.autoconfigure.EnableAutoConfiguration
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.context.annotation.ComponentScan
import org.springframework.http.MediaType
import org.springframework.test.context.TestContextManager
import org.springframework.test.context.junit4.SpringRunner
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.{asyncDispatch, get, post}
import org.springframework.test.web.servlet.result.MockMvcResultHandlers.print
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.{request, status}
import spring.test.TestApplication

@RunWith(classOf[SpringRunner])
@SpringBootTest(classes = Array(classOf[TestApplication]))
@AutoConfigureMockMvc
@ComponentScan
@EnableAutoConfiguration
class AliasSpecs extends FreeSpec with Matchers with BeforeAndAfterAll with MockitoSugar with ArgumentMatchersSugar {
  @Autowired var mvc: MockMvc               = _
  @Autowired var handlerMock: FooHandler = _

  new TestContextManager(this.getClass).prepareTestInstance(this)

  "test alias.foo" - {
    "optional body handled with alias param" in {

      when(handlerMock.doFoo(java.util.Optional.of(1L), java.util.Optional.of(42L)))
        .thenReturn(CompletableFuture.completedFuture(FooHandler.DoFooResponse.Created(42L)))

      val mvcResult = mvc
        .perform(
          post("/foo?long=1")
            .contentType(MediaType.APPLICATION_JSON)
            .content("42")
        )
        .andExpect(request.asyncStarted)
        .andReturn

      mvc.perform(asyncDispatch(mvcResult)).andDo(print()).andExpect(status.isCreated)
    }
  }
} 
Example 14
Source File: CaffeineImplForAsyncCache.scala    From graphcool-framework   with Apache License 2.0 5 votes vote down vote up
package cool.graph.cache

import java.util.concurrent.{CompletableFuture, Executor}
import java.util.function.BiFunction

import com.github.benmanes.caffeine.cache.{AsyncCacheLoader, Caffeine, AsyncLoadingCache => AsyncCaffeineCache, Cache => CaffeineCache}
import scala.compat.java8.FunctionConverters._
import scala.compat.java8.FutureConverters._

import scala.concurrent.{ExecutionContext, Future}

object CaffeineImplForAsyncCache {
  def lfu[K, V >: Null](initialCapacity: Int, maxCapacity: Int)(implicit ec: ExecutionContext): AsyncCache[K, V] = {
    val caffeineCache = Caffeine
      .newBuilder()
      .initialCapacity(initialCapacity)
      .maximumSize(maxCapacity)
      .asInstanceOf[Caffeine[K, V]]
      .buildAsync[K, V](dummyLoader[K, V])
    CaffeineImplForAsyncCache(caffeineCache)
  }

  //LfuCache requires a loader function on creation - this will not be used.
  private def dummyLoader[K, V] = new AsyncCacheLoader[K, V] {
    def asyncLoad(k: K, e: Executor) =
      Future.failed[V](new RuntimeException("Dummy loader should not be used by LfuCache")).toJava.toCompletableFuture
  }
}

case class CaffeineImplForAsyncCache[K, V >: Null](underlying: AsyncCaffeineCache[K, V])(implicit ec: ExecutionContext) extends AsyncCache[K, V] {

  override def get(key: K): Future[Option[V]] = {
    val cacheEntry = underlying.getIfPresent(key)
    if (cacheEntry != null) {
      cacheEntry.toScala.map(Some(_))
    } else {
      Future.successful(None)
    }
  }

  override def put(key: K, value: Future[Option[V]]): Unit = {
    val asCompletableNullableFuture = value.map(_.orNull).toJava.toCompletableFuture
    underlying.put(key, asCompletableNullableFuture)
  }

  override def remove(key: K): Unit = underlying.synchronous().invalidate(key)

  override def getOrUpdate(key: K, fn: () => Future[V]): Future[V] = {
    val javaFn = toCaffeineMappingFunction[K, V](fn)
    underlying.get(key, javaFn).toScala
  }

  override def getOrUpdateOpt(key: K, fn: () => Future[Option[V]]): Future[Option[V]] = {
    val nullable: () => Future[V] = () => fn().map(_.orNull)
    val javaFn                    = toCaffeineMappingFunction[K, V](nullable)
    val cacheEntry                = underlying.get(key, javaFn)
    if (cacheEntry != null) {
      cacheEntry.toScala.map(Option(_))
    } else {
      Future.successful(None)
    }
  }

  private def toCaffeineMappingFunction[K, V](genValue: () ⇒ Future[V]): BiFunction[K, Executor, CompletableFuture[V]] = {
    asJavaBiFunction[K, Executor, CompletableFuture[V]]((_, _) ⇒ genValue().toJava.toCompletableFuture)
  }
} 
Example 15
Source File: CouchbaseReadSideImpl.scala    From akka-persistence-couchbase   with Apache License 2.0 5 votes vote down vote up
package com.lightbend.lagom.internal.javadsl.persistence.couchbase

import java.util.concurrent.{CompletableFuture, CompletionStage}
import java.util.function.{BiFunction, Function => JFunction}

import akka.Done
import akka.actor.ActorSystem
import akka.dispatch.MessageDispatcher
import akka.stream.alpakka.couchbase.javadsl.CouchbaseSession
import com.lightbend.lagom.internal.persistence.couchbase.CouchbaseOffsetStore
import com.lightbend.lagom.javadsl.persistence.couchbase.CouchbaseReadSide
import com.lightbend.lagom.javadsl.persistence.{AggregateEvent, AggregateEventTag, Offset, ReadSideProcessor}
import javax.inject.{Inject, Singleton}
import play.api.inject.Injector

@Singleton
private[lagom] class CouchbaseReadSideImpl @Inject() (
    system: ActorSystem,
    couchbaseSession: CouchbaseSession,
    offsetStore: CouchbaseOffsetStore,
    injector: Injector
) extends CouchbaseReadSide {
  private val dispatcher = system.settings.config.getString("lagom.persistence.read-side.use-dispatcher")
  private implicit val ec: MessageDispatcher = system.dispatchers.lookup(dispatcher)

  override def builder[Event <: AggregateEvent[Event]](
      readSideId: String
  ): CouchbaseReadSide.ReadSideHandlerBuilder[Event] =
    new CouchbaseReadSide.ReadSideHandlerBuilder[Event] {
      type Handler[E] = CouchbaseReadSideHandler.Handler[E]

      private var globalPrepareCallback: CouchbaseSession => CompletionStage[Done] =
        (_) => CompletableFuture.completedFuture(Done.getInstance())

      private var prepareCallback: (CouchbaseSession, AggregateEventTag[Event]) => CompletionStage[Done] =
        (_, _) => CompletableFuture.completedFuture(Done.getInstance())

      private var handlers = Map.empty[Class[_ <: Event], Handler[Event]]

      override def setGlobalPrepare(
          callback: JFunction[CouchbaseSession, CompletionStage[Done]]
      ): CouchbaseReadSide.ReadSideHandlerBuilder[Event] = {
        globalPrepareCallback = callback.apply
        this
      }

      override def setPrepare(
          callback: BiFunction[CouchbaseSession, AggregateEventTag[Event], CompletionStage[Done]]
      ): CouchbaseReadSide.ReadSideHandlerBuilder[Event] = {
        prepareCallback = callback.apply
        this
      }

      override def setEventHandler[E <: Event](
          eventClass: Class[E],
          handler: CouchbaseReadSide.TriConsumer[CouchbaseSession, E, Offset, CompletionStage[Done]]
      ): CouchbaseReadSide.ReadSideHandlerBuilder[Event] = {
        handlers += (eventClass -> ((cs: CouchbaseSession, event: E, offset: Offset) => handler(cs, event, offset)))
        this
      }

      override def setEventHandler[E <: Event](
          eventClass: Class[E],
          handler: BiFunction[CouchbaseSession, E, CompletionStage[Done]]
      ): CouchbaseReadSide.ReadSideHandlerBuilder[Event] = {
        handlers += (eventClass -> ((cs: CouchbaseSession, event: E, offset: Offset) => handler(cs, event)))
        this
      }

      override def build(): ReadSideProcessor.ReadSideHandler[Event] =
        new CouchbaseReadSideHandler[Event](
          couchbaseSession,
          offsetStore,
          handlers,
          globalPrepareCallback,
          prepareCallback,
          readSideId,
          dispatcher
        )
    }
} 
Example 16
Source File: JRFutureSpec.scala    From redis4cats   with Apache License 2.0 5 votes vote down vote up
package dev.profunktor.redis4cats.effect

import java.util.concurrent.CompletableFuture

import cats.effect.{ Blocker, ContextShift, IO }
import scala.concurrent.ExecutionContext
import munit.FunSuite

class JRFutureSpec extends FunSuite {

  implicit val cs: ContextShift[IO] = IO.contextShift(ExecutionContext.global)

  val currentThread: IO[String] = IO(Thread.currentThread().getName)

  test("it shifts back once the Future is converted") {
    val ioa =
      Blocker[IO].use { blocker =>
        JRFuture.fromCompletableFuture[IO, String] {
          IO {
            val jFuture = new CompletableFuture[String]()
            jFuture.complete("foo")
            jFuture
          }
        }(blocker)
      }

    (ioa *> currentThread)
      .flatMap(t => IO(assert(t.contains("scala-execution-context-global"))))
      .unsafeToFuture()
  }

  test("it shifts back even when the CompletableFuture fails") {
    val ioa =
      Blocker[IO].use { blocker =>
        JRFuture.fromCompletableFuture[IO, String] {
          IO {
            val jFuture = new CompletableFuture[String]()
            jFuture.completeExceptionally(new RuntimeException("Purposely fail"))
            jFuture
          }
        }(blocker)
      }

    (ioa.attempt *> currentThread)
      .flatMap(t => IO(assert(t.contains("scala-execution-context-global"))))
      .unsafeToFuture()
  }

} 
Example 17
Source File: CassandraReadSideImpl.scala    From lagom   with Apache License 2.0 5 votes vote down vote up
package com.lightbend.lagom.internal.javadsl.persistence.cassandra

import java.util
import java.util.concurrent.CompletableFuture
import java.util.concurrent.CompletionStage
import java.util.function.BiFunction
import java.util.function.Function
import java.util.function.Supplier

import javax.inject.Inject
import javax.inject.Singleton
import akka.Done
import akka.actor.ActorSystem
import com.datastax.driver.core.BoundStatement
import com.lightbend.lagom.internal.javadsl.persistence.ReadSideImpl
import com.lightbend.lagom.internal.persistence.cassandra.CassandraOffsetStore
import com.lightbend.lagom.javadsl.persistence.ReadSideProcessor.ReadSideHandler
import com.lightbend.lagom.javadsl.persistence._
import com.lightbend.lagom.javadsl.persistence.cassandra.CassandraReadSide.ReadSideHandlerBuilder
import com.lightbend.lagom.javadsl.persistence.cassandra.CassandraReadSide
import com.lightbend.lagom.javadsl.persistence.cassandra.CassandraSession
import play.api.inject.Injector


@Singleton
private[lagom] final class CassandraReadSideImpl @Inject() (
    system: ActorSystem,
    session: CassandraSession,
    offsetStore: CassandraOffsetStore,
    readSide: ReadSideImpl,
    injector: Injector
) extends CassandraReadSide {
  private val dispatcher = system.settings.config.getString("lagom.persistence.read-side.use-dispatcher")
  implicit val ec        = system.dispatchers.lookup(dispatcher)

  override def builder[Event <: AggregateEvent[Event]](eventProcessorId: String): ReadSideHandlerBuilder[Event] = {
    new ReadSideHandlerBuilder[Event] {
      import CassandraAutoReadSideHandler.Handler
      private var prepareCallback: AggregateEventTag[Event] => CompletionStage[Done] =
        tag => CompletableFuture.completedFuture(Done.getInstance())
      private var globalPrepareCallback: () => CompletionStage[Done] =
        () => CompletableFuture.completedFuture(Done.getInstance())
      private var handlers = Map.empty[Class[_ <: Event], Handler[Event]]

      override def setGlobalPrepare(callback: Supplier[CompletionStage[Done]]): ReadSideHandlerBuilder[Event] = {
        globalPrepareCallback = () => callback.get
        this
      }

      override def setPrepare(
          callback: Function[AggregateEventTag[Event], CompletionStage[Done]]
      ): ReadSideHandlerBuilder[Event] = {
        prepareCallback = callback.apply
        this
      }

      override def setEventHandler[E <: Event](
          eventClass: Class[E],
          handler: Function[E, CompletionStage[util.List[BoundStatement]]]
      ): ReadSideHandlerBuilder[Event] = {
        handlers += (eventClass -> ((event: E, offset: Offset) => handler(event)))
        this
      }

      override def setEventHandler[E <: Event](
          eventClass: Class[E],
          handler: BiFunction[E, Offset, CompletionStage[util.List[BoundStatement]]]
      ): ReadSideHandlerBuilder[Event] = {
        handlers += (eventClass -> handler.apply _)
        this
      }

      override def build(): ReadSideHandler[Event] = {
        new CassandraAutoReadSideHandler[Event](
          session,
          offsetStore,
          handlers,
          globalPrepareCallback,
          prepareCallback,
          eventProcessorId,
          dispatcher
        )
      }
    }
  }
} 
Example 18
Source File: NoServiceLocator.scala    From lagom   with Apache License 2.0 5 votes vote down vote up
package com.lightbend.lagom.registry.impl

import java.net.URI
import java.util.Optional
import java.util.concurrent.CompletionStage
import java.util.function.{ Function => JFunction }

import com.lightbend.lagom.javadsl.api.Descriptor.Call
import com.lightbend.lagom.javadsl.api.ServiceLocator


class NoServiceLocator extends ServiceLocator {
  import java.util.concurrent.CompletableFuture

  override def locate(name: String, serviceCall: Call[_, _]): CompletionStage[Optional[URI]] =
    CompletableFuture.completedFuture(Optional.empty())

  override def doWithService[T](
      name: String,
      serviceCall: Call[_, _],
      block: JFunction[URI, CompletionStage[T]]
  ): CompletionStage[Optional[T]] =
    CompletableFuture.completedFuture(Optional.empty())
} 
Example 19
Source File: util.scala    From fs2-blobstore   with Apache License 2.0 5 votes vote down vote up
package blobstore

import java.util.concurrent.{CancellationException, CompletableFuture, CompletionException}
import cats.effect.Concurrent
import cats.syntax.flatMap._
import cats.syntax.functor._

object util {
  def liftJavaFuture[F[_], A](fa: F[CompletableFuture[A]])(implicit F: Concurrent[F]): F[A] = fa.flatMap { cf =>
    F.cancelable { cb =>
      cf.handle[Unit]((result: A, err: Throwable) =>
        Option(err) match {
          case None =>
            cb(Right(result))
          case Some(_: CancellationException) =>
            ()
          case Some(ex: CompletionException) =>
            cb(Left(Option(ex.getCause).getOrElse(ex)))
          case Some(ex) =>
            cb(Left(ex))
        }
      )
      F.delay(cf.cancel(true)).void
    }
  }
} 
Example 20
Source File: FutureTimeoutSupport.scala    From perf_tester   with Apache License 2.0 5 votes vote down vote up
package akka.pattern

import scala.concurrent.{ ExecutionContext, Promise, Future }
import akka.actor._
import scala.util.control.NonFatal
import scala.concurrent.duration.FiniteDuration
import java.util.concurrent.CompletionStage
import java.util.concurrent.CompletableFuture
import akka.dispatch.Futures
import java.util.function.BiConsumer

trait FutureTimeoutSupport {
  
  def afterCompletionStage[T](duration: FiniteDuration, using: Scheduler)(value: ⇒ CompletionStage[T])(implicit ec: ExecutionContext): CompletionStage[T] =
    if (duration.isFinite() && duration.length < 1) {
      try value catch { case NonFatal(t) ⇒ Futures.failedCompletionStage(t) }
    } else {
      val p = new CompletableFuture[T]
      using.scheduleOnce(duration) {
        try {
          val future = value
          future.whenComplete(new BiConsumer[T, Throwable] {
            override def accept(t: T, ex: Throwable): Unit = {
              if (t != null) p.complete(t)
              if (ex != null) p.completeExceptionally(ex)
            }
          })
        } catch {
          case NonFatal(ex) ⇒ p.completeExceptionally(ex)
        }
      }
      p
    }
} 
Example 21
Source File: RetryUtilsSuite.scala    From azure-event-hubs-spark   with Apache License 2.0 5 votes vote down vote up
package org.apache.spark.eventhubs.utils

import java.io.IOException
import java.util.concurrent.CompletableFuture

import com.microsoft.azure.eventhubs.EventHubException
import org.scalatest.FunSuite
import org.scalatest.concurrent.ScalaFutures

import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future

class RetryUtilsSuite extends FunSuite with ScalaFutures {

  import RetryUtilsSuite._

  test("don't retry successful Future") {
    val tries = incrementFutureIterator(1)
    val result = RetryUtils.retryScala(tries.next, "test", maxRetry = 3, delay = 1).futureValue
    assert(1 === result)
  }

  test("don't retry failed Future with normal exception") {
    val fails = Iterator(Future.failed(new IOException("not retry")))
    val tries = fails ++ incrementFutureIterator(1)
    val exception =
      RetryUtils.retryScala(tries.next, "test", maxRetry = 3, delay = 1).failed.futureValue
    assert("not retry" === exception.getMessage)
  }

  test("don't retry failed Future with non-transient EventHubException") {
    val tries = Iterator(nonTransientEHE()) ++ incrementFutureIterator(1)
    val exception =
      RetryUtils.retryScala(tries.next, "test", maxRetry = 3, delay = 1).failed.futureValue
    assert("nonTransient" === exception.getMessage)
  }

  test("retry maxRetry times until success") {
    val fails = Iterator(failedWithEHE(), causedByEHE(), failedWithEHE())
    val tries = fails ++ incrementFutureIterator(4)

    val result = RetryUtils.retryScala(tries.next, "test", maxRetry = 3, delay = 1).futureValue
    assert(4 === result)
  }

  test("retry maxRetry times until failure") {
    val fails = Iterator(failedWithEHE(), causedByEHE(), failedWithEHE(), causedByEHE())
    val tries = fails ++ incrementFutureIterator(4)

    val exception =
      RetryUtils.retryScala(tries.next, "test", maxRetry = 3, delay = 1).failed.futureValue
    assert("causedBy" === exception.getMessage)
  }

  test("retryNotNull") {
    val nullFuture: CompletableFuture[AnyRef] =
      CompletableFuture.completedFuture(null.asInstanceOf[AnyRef])
    val normalFuture: CompletableFuture[Int] =
      CompletableFuture.completedFuture(10)

    val tries = Iterator.continually(nullFuture).take(9) ++ Iterator(normalFuture)
    val result = RetryUtils.retryNotNull(tries.next, "test").futureValue
    assert(10 === result)
  }
}

object RetryUtilsSuite {
  def failedWithEHE(): Future[Int] = Future.failed(new EventHubException(true, "failedWith"))

  def causedByEHE(): Future[Int] = {
    val causedBy = new EventHubException(true, "causedBy")
    Future.failed(new IOException(causedBy))
  }

  def nonTransientEHE(): Future[Int] = Future.failed(new EventHubException(false, "nonTransient"))

  def incrementFutureIterator(value: Int = 0): Iterator[Future[Int]] =
    Iterator.from(value).map(Future(_))
} 
Example 22
Source File: CacheAsyncConnection.scala    From play-ws   with Apache License 2.0 5 votes vote down vote up
package play.api.libs.ws.ahc.cache

import java.util.concurrent.Callable
import java.util.concurrent.CompletableFuture
import java.util.concurrent.Executor
import java.util.concurrent.TimeUnit
import java.util.function.BiConsumer

import play.shaded.ahc.org.asynchttpclient.AsyncHandler
import play.shaded.ahc.org.asynchttpclient.ListenableFuture
import play.shaded.ahc.org.asynchttpclient.Request
import org.slf4j.LoggerFactory
import play.shaded.ahc.org.asynchttpclient.handler.ProgressAsyncHandler


class CacheFuture[T](handler: AsyncHandler[T]) extends ListenableFuture[T] {

  private var innerFuture: java.util.concurrent.CompletableFuture[T] = _

  def setInnerFuture(future: java.util.concurrent.CompletableFuture[T]) = {
    innerFuture = future
  }

  override def isDone: Boolean = innerFuture.isDone

  override def done(): Unit = {}

  override def touch(): Unit = {}

  override def abort(t: Throwable): Unit = {
    innerFuture.completeExceptionally(t)
  }

  override def isCancelled: Boolean = {
    innerFuture.isCancelled
  }

  override def get(): T = {
    get(1000L, java.util.concurrent.TimeUnit.MILLISECONDS)
  }

  override def get(timeout: Long, unit: TimeUnit): T = {
    innerFuture.get(timeout, unit)
  }

  override def cancel(mayInterruptIfRunning: Boolean): Boolean = {
    innerFuture.cancel(mayInterruptIfRunning)
  }

  override def toString: String = {
    s"CacheFuture"
  }

  override def toCompletableFuture: CompletableFuture[T] = innerFuture

  override def addListener(listener: Runnable, executor: Executor): ListenableFuture[T] = {
    innerFuture.whenCompleteAsync(
      new BiConsumer[T, Throwable]() {
        override def accept(t: T, u: Throwable): Unit = listener.run()
      },
      executor
    )
    this
  }
} 
Example 23
Source File: AuthServiceStatic.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.api.auth

import java.util.concurrent.{CompletableFuture, CompletionStage}

import io.grpc.Metadata


final class AuthServiceStatic(claims: PartialFunction[String, Claims]) extends AuthService {
  override def decodeMetadata(headers: Metadata): CompletionStage[Claims] = {
    if (headers.containsKey(AUTHORIZATION_KEY)) {
      val authorizationValue = headers.get(AUTHORIZATION_KEY).stripPrefix("Bearer ")
      CompletableFuture.completedFuture(claims.lift(authorizationValue).getOrElse(Claims.empty))
    } else {
      CompletableFuture.completedFuture(Claims.empty)
    }
  }
}

object AuthServiceStatic {
  def apply(claims: PartialFunction[String, Claims]) = new AuthServiceStatic(claims)
} 
Example 24
Source File: AuthServiceJWT.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.api.auth

import java.util.concurrent.{CompletableFuture, CompletionStage}

import com.daml.lf.data.Ref
import com.daml.jwt.{JwtVerifier, JwtVerifierBase}
import com.daml.ledger.api.auth.AuthServiceJWT.Error
import io.grpc.Metadata
import org.slf4j.{Logger, LoggerFactory}
import spray.json._

import scala.collection.mutable.ListBuffer
import scala.util.Try


class AuthServiceJWT(verifier: JwtVerifierBase) extends AuthService {

  protected val logger: Logger = LoggerFactory.getLogger(AuthServiceJWT.getClass)

  override def decodeMetadata(headers: Metadata): CompletionStage[Claims] = {
    decodeAndParse(headers).fold(
      error => {
        logger.warn("Authorization error: " + error.message)
        CompletableFuture.completedFuture(Claims.empty)
      },
      token => CompletableFuture.completedFuture(payloadToClaims(token))
    )
  }

  private[this] def parsePayload(jwtPayload: String): Either[Error, AuthServiceJWTPayload] = {
    import AuthServiceJWTCodec.JsonImplicits._
    Try(JsonParser(jwtPayload).convertTo[AuthServiceJWTPayload]).toEither.left.map(t =>
      Error("Could not parse JWT token: " + t.getMessage))
  }

  private[this] def decodeAndParse(headers: Metadata): Either[Error, AuthServiceJWTPayload] = {
    val bearerTokenRegex = "Bearer (.*)".r

    for {
      headerValue <- Option
        .apply(headers.get(AUTHORIZATION_KEY))
        .toRight(Error("Authorization header not found"))
      token <- bearerTokenRegex
        .findFirstMatchIn(headerValue)
        .map(_.group(1))
        .toRight(Error("Authorization header does not use Bearer format"))
      decoded <- verifier
        .verify(com.daml.jwt.domain.Jwt(token))
        .toEither
        .left
        .map(e => Error("Could not verify JWT token: " + e.message))
      parsed <- parsePayload(decoded.payload)
    } yield parsed
  }

  private[this] def payloadToClaims(payload: AuthServiceJWTPayload): Claims = {
    val claims = ListBuffer[Claim]()

    // Any valid token authorizes the user to use public services
    claims.append(ClaimPublic)

    if (payload.admin)
      claims.append(ClaimAdmin)

    payload.actAs
      .foreach(party => claims.append(ClaimActAsParty(Ref.Party.assertFromString(party))))

    payload.readAs
      .foreach(party => claims.append(ClaimReadAsParty(Ref.Party.assertFromString(party))))

    Claims(
      claims = claims.toList,
      ledgerId = payload.ledgerId,
      participantId = payload.participantId,
      applicationId = payload.applicationId,
      expiration = payload.exp,
    )
  }
}

object AuthServiceJWT {
  final case class Error(message: String)

  def apply(verifier: com.auth0.jwt.interfaces.JWTVerifier) =
    new AuthServiceJWT(new JwtVerifier(verifier))

  def apply(verifier: JwtVerifierBase) =
    new AuthServiceJWT(verifier)
} 
Example 25
Source File: FakeTopicAdmin.scala    From ohara   with Apache License 2.0 4 votes vote down vote up
package oharastream.ohara.configurator.fake

import java.util.concurrent.{CompletableFuture, CompletionStage, ConcurrentHashMap}
import java.{lang, util}

import oharastream.ohara.common.setting.TopicKey
import oharastream.ohara.kafka.{TopicAdmin, TopicCreator, TopicDescription, TopicOption}

private[configurator] class FakeTopicAdmin extends TopicAdmin {
  import scala.jdk.CollectionConverters._

  override val connectionProps: String = "Unknown"

  private[this] val cachedTopics = new ConcurrentHashMap[TopicKey, TopicDescription]()

  override def createPartitions(topicKey: TopicKey, numberOfPartitions: Int): CompletionStage[Void] = {
    val previous = cachedTopics.get(topicKey)
    val f        = new CompletableFuture[Void]()
    if (previous == null)
      f.completeExceptionally(
        new NoSuchElementException(
          s"the topic:$topicKey doesn't exist. actual:${cachedTopics.keys().asScala.mkString(",")}"
        )
      )
    else {
      cachedTopics.put(
        topicKey,
        new TopicDescription(
          previous.topicKey,
          previous.partitionInfos(),
          previous.options
        )
      )
    }
    f
  }

  override def topicKeys: CompletionStage[util.Set[TopicKey]] = CompletableFuture.completedFuture(cachedTopics.keySet())

  override def topicDescription(key: TopicKey): CompletionStage[TopicDescription] = {
    val topic = cachedTopics.get(key)
    val f     = new CompletableFuture[TopicDescription]()
    if (topic == null) f.completeExceptionally(new NoSuchElementException(s"$key does not exist"))
    else f.complete(topic)
    f
  }

  override def topicCreator(): TopicCreator =
    (_: Int, _: Short, options: util.Map[String, String], topicKey: TopicKey) => {
      val f = new CompletableFuture[Void]()
      if (cachedTopics.contains(topicKey))
        f.completeExceptionally(new IllegalArgumentException(s"$topicKey already exists!"))
      else {
        val topicInfo = new TopicDescription(
          topicKey,
          java.util.List.of(),
          options.asScala
            .map {
              case (key, value) =>
                new TopicOption(
                  key,
                  value,
                  false,
                  false,
                  false
                )
            }
            .toSeq
            .asJava
        )
        if (cachedTopics.putIfAbsent(topicKey, topicInfo) != null)
          throw new RuntimeException(s"the $topicKey already exists in kafka")
        f.complete(null)
      }
      f
    }

  private[this] var _closed = false

  override def close(): Unit = _closed = true

  override def closed(): Boolean = _closed

  override def brokerPorts(): CompletionStage[util.Map[String, Integer]] =
    CompletableFuture.completedFuture(java.util.Map.of())

  override def exist(topicKey: TopicKey): CompletionStage[lang.Boolean] =
    CompletableFuture.completedFuture(cachedTopics.containsKey(topicKey))

  override def deleteTopic(topicKey: TopicKey): CompletionStage[lang.Boolean] = {
    val f       = new CompletableFuture[lang.Boolean]()
    val removed = cachedTopics.remove(topicKey)
    if (removed == null) f.complete(false)
    else f.complete(true)
    f
  }
}