io.grpc.StatusRuntimeException Scala Examples

The following examples show how to use io.grpc.StatusRuntimeException. 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: ResultAssertions.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.grpc.adapter.client

import com.daml.platform.hello.HelloResponse
import com.google.protobuf.ByteString
import io.grpc.{Status, StatusRuntimeException}
import org.scalatest.{Assertion, Matchers}

import scala.util.Random

trait ResultAssertions { self: Matchers =>

  protected def elemCount: Int = 1024
  protected lazy val elemRange: Range = 1.to(elemCount)
  protected lazy val halfCount: Int = elemCount / 2
  protected lazy val halfRange: Range = elemRange.take(halfCount)

  protected def isCancelledException(err: Throwable): Assertion = {
    err shouldBe a[StatusRuntimeException]
    err.asInstanceOf[StatusRuntimeException].getStatus.getCode shouldEqual Status.CANCELLED.getCode
  }

  protected def assertElementsAreInOrder(expectedCount: Long)(
      results: Seq[HelloResponse]
  ): Assertion = {
    results should have length expectedCount
    results.map(_.respInt) shouldEqual (1 to expectedCount.toInt)
  }

  protected def elementsAreSummed(results: Seq[HelloResponse]): Assertion = {
    results should have length 1
    results.foldLeft(0)(_ + _.respInt) shouldEqual elemRange.sum
  }

  protected def everyElementIsDoubled(results: Seq[HelloResponse]): Assertion = {
    results should have length elemCount.toLong
    //the order does matter
    results.map(_.respInt) shouldEqual elemRange.map(_ * 2)
  }

  protected def genPayload(): ByteString = {
    val bytes = new Array[Byte](1024)
    Random.nextBytes(bytes)
    ByteString.copyFrom(bytes)
  }
} 
Example 2
Source File: HelloWorldClient.scala    From grpc-scala-sample   with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
package io.grpc.examples.helloworld

import java.util.concurrent.TimeUnit
import java.util.logging.{Level, Logger}

import io.grpc.examples.helloworld.helloworld.{HelloRequest, GreeterGrpc}
import io.grpc.examples.helloworld.helloworld.GreeterGrpc.GreeterBlockingStub
import io.grpc.{StatusRuntimeException, ManagedChannelBuilder, ManagedChannel}


  def greet(name: String): Unit = {
    logger.info("Will try to greet " + name + " ...")
    val request = HelloRequest(name = name)
    try {
      val response = blockingStub.sayHello(request)
      logger.info("Greeting: " + response.message)
    }
    catch {
      case e: StatusRuntimeException =>
        logger.log(Level.WARNING, "RPC failed: {0}", e.getStatus)
    }
  }
} 
Example 3
Source File: GrpcSerializersTest.scala    From scio   with Apache License 2.0 5 votes vote down vote up
package com.spotify.scio.coders.instances.kryo

import com.spotify.scio.coders.{Coder, CoderMaterializer}
import io.grpc.{Metadata, Status, StatusRuntimeException}
import org.apache.beam.sdk.util.CoderUtils
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers

import scala.jdk.CollectionConverters._

class GrpcSerializersTest extends AnyFlatSpec with Matchers {

  "StatusRuntimeException" should "roundtrip with nullable fields present" in {
    val metadata = new Metadata()
    metadata.put(Metadata.Key.of[String]("k", Metadata.ASCII_STRING_MARSHALLER), "v")

    roundtrip(
      new StatusRuntimeException(
        Status.OK.withCause(new RuntimeException("bar")).withDescription("bar"),
        metadata
      )
    )
  }

  it should "roundtrip with nullable fields absent" in {
    roundtrip(new StatusRuntimeException(Status.OK))
  }

  private def roundtrip(t: StatusRuntimeException): Unit = {
    val kryoBCoder = CoderMaterializer.beamWithDefault(Coder[StatusRuntimeException])

    val bytes = CoderUtils.encodeToByteArray(kryoBCoder, t)
    val copy = CoderUtils.decodeFromByteArray(kryoBCoder, bytes)

    checkStatusEq(t.getStatus, copy.getStatus)
    checkTrailersEq(t.getTrailers, copy.getTrailers)
  }

  private def checkTrailersEq(metadata1: Metadata, metadata2: Metadata): Unit =
    (Option(metadata1), Option(metadata2)) match {
      case (Some(m1), Some(m2)) =>
        m1.keys.size shouldEqual m2.keys.size
        m1.keys.asScala.foreach { k =>
          m1.get(Metadata.Key.of[String](k, Metadata.ASCII_STRING_MARSHALLER)) shouldEqual
            m2.get(Metadata.Key.of[String](k, Metadata.ASCII_STRING_MARSHALLER))
        }
      case (None, None) =>
      case _            => fail(s"Metadata were unequal: ($metadata1, $metadata2)")
    }

  private def checkStatusEq(s1: Status, s2: Status): Unit = {
    s1.getCode shouldEqual s2.getCode
    s1.getDescription shouldEqual s2.getDescription
    if (s1.getCause != null) {
      s1.getCause.getClass shouldEqual s2.getCause.getClass
      s1.getCause.getMessage shouldEqual s2.getCause.getMessage
    } else if (s2.getCause != null) {
      fail(s"Status $s1 is missing a cause")
    }
  }
} 
Example 4
Source File: GrpcSerializers.scala    From scio   with Apache License 2.0 5 votes vote down vote up
package com.spotify.scio.coders.instances.kryo

import com.esotericsoftware.kryo.Kryo
import com.esotericsoftware.kryo.io.{Input, Output}
import com.twitter.chill.KSerializer
import io.grpc.{Metadata, Status, StatusRuntimeException}

private[coders] object GrpcSerializers {

  class StatusSerializer extends KSerializer[Status] {
    override def write(kryo: Kryo, output: Output, status: Status): Unit = {
      output.writeInt(status.getCode().value())
      output.writeString(status.getDescription)
      kryo.writeClassAndObject(output, status.getCause)
    }

    override def read(kryo: Kryo, input: Input, `type`: Class[Status]): Status = {
      val code = input.readInt()
      val description = input.readString()
      val cause = kryo.readClassAndObject(input).asInstanceOf[Throwable]

      Status
        .fromCodeValue(code)
        .withDescription(description)
        .withCause(cause)
    }
  }

  class StatusRuntimeExceptionSerializer extends KSerializer[StatusRuntimeException] {
    lazy val statusSer = new StatusSerializer()

    override def write(kryo: Kryo, output: Output, e: StatusRuntimeException): Unit = {
      kryo.writeObject(output, e.getStatus, statusSer)
      kryo.writeObjectOrNull(output, e.getTrailers, classOf[Metadata])
    }

    override def read(
      kryo: Kryo,
      input: Input,
      `type`: Class[StatusRuntimeException]
    ): StatusRuntimeException = {
      val status = kryo.readObject(input, classOf[Status], statusSer)
      val trailers = kryo.readObjectOrNull(input, classOf[Metadata])

      new StatusRuntimeException(status, trailers)
    }
  }
} 
Example 5
Source File: OnlineAction.scala    From marvin-engine-executor   with Apache License 2.0 5 votes vote down vote up
package org.marvin.executor.actions

import akka.Done
import akka.actor.SupervisorStrategy._
import akka.actor.{Actor, ActorLogging, ActorRef, OneForOneStrategy, Props, Status}
import akka.pattern.{ask, pipe}
import akka.util.Timeout
import io.grpc.StatusRuntimeException
import org.marvin.artifact.manager.ArtifactSaver
import org.marvin.executor.actions.OnlineAction.{OnlineExecute, OnlineHealthCheck, OnlineReload}
import org.marvin.executor.proxies.EngineProxy.{ExecuteOnline, HealthCheck, Reload}
import org.marvin.executor.proxies.OnlineActionProxy
import org.marvin.artifact.manager.ArtifactSaver.SaveToLocal
import org.marvin.model.{EngineActionMetadata, EngineMetadata}
import org.marvin.util.ProtocolUtil

import scala.collection.mutable.ListBuffer
import scala.concurrent.Future
import scala.concurrent.duration._
import scala.util.{Failure, Success}

object OnlineAction {
  case class OnlineExecute(message: String, params: String)
  case class OnlineReload(protocol: String)
  case class OnlineHealthCheck()
}

class OnlineAction(actionName: String, metadata: EngineMetadata) extends Actor with ActorLogging {
  var onlineActionProxy: ActorRef = _
  var artifactSaver: ActorRef = _
  var engineActionMetadata: EngineActionMetadata = _
  var artifactsToLoad: String = _
  implicit val ec = context.dispatcher

  override def preStart() = {
    engineActionMetadata = metadata.actionsMap(actionName)
    artifactsToLoad = engineActionMetadata.artifactsToLoad.mkString(",")
    onlineActionProxy = context.actorOf(Props(new OnlineActionProxy(engineActionMetadata)), name = "onlineActionProxy")
    artifactSaver = context.actorOf(ArtifactSaver.build(metadata), name = "artifactSaver")
  }

  override val supervisorStrategy =
    OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = metadata.onlineActionTimeout milliseconds) {
      case _: StatusRuntimeException => Restart
      case _: Exception => Escalate
  }

  override def receive  = {
    case OnlineExecute(message, params) =>
      implicit val futureTimeout = Timeout(metadata.onlineActionTimeout milliseconds)

      log.info(s"Starting to process execute to $actionName. Message: [$message] and params: [$params].")

      val originalSender = sender
      ask(onlineActionProxy, ExecuteOnline(message, params)) pipeTo originalSender


    case OnlineReload(protocol) =>
      implicit val futureTimeout = Timeout(metadata.reloadTimeout milliseconds)

      log.info(s"Starting to process reload to $actionName. Protocol: [$protocol].")

      if(protocol == null || protocol.isEmpty){
        onlineActionProxy forward Reload()

      }else{
        val splitedProtocols = ProtocolUtil.splitProtocol(protocol, metadata)

        val futures:ListBuffer[Future[Any]] = ListBuffer[Future[Any]]()
        for(artifactName <- engineActionMetadata.artifactsToLoad) {
          futures += (artifactSaver ? SaveToLocal(artifactName, splitedProtocols(artifactName)))
        }

        val origSender = sender()
        Future.sequence(futures).onComplete{
          case Success(_) => onlineActionProxy.ask(Reload(protocol)) pipeTo origSender
          case Failure(e) => {
            log.error(s"Failure to reload artifacts using protocol $protocol.")
            origSender ! Status.Failure(e)
          }
        }
      }

    case OnlineHealthCheck =>
      implicit val futureTimeout = Timeout(metadata.healthCheckTimeout milliseconds)
      log.info(s"Starting to process health to $actionName.")

      val originalSender = sender
      ask(onlineActionProxy, HealthCheck) pipeTo originalSender

    case Done =>
      log.info("Work Done!")

    case _ =>
      log.warning(s"Not valid message !!")

  }
} 
Example 6
Source File: TestServiceImpl.scala    From akka-grpc   with Apache License 2.0 5 votes vote down vote up
package akka.grpc.interop

import scala.concurrent.ExecutionContext
import scala.concurrent.Future
import scala.reflect.ClassTag
import scala.collection.immutable

import akka.grpc.scaladsl.{GrpcMarshalling}

import akka.NotUsed
import akka.actor.ActorSystem
import akka.grpc._
import akka.stream.scaladsl.{Flow, Source}
import akka.stream.{ Materializer, SystemMaterializer }

import com.google.protobuf.ByteString
import io.grpc.{ Status, StatusRuntimeException }

// Generated by our plugin
import io.grpc.testing.integration.test.TestService
import io.grpc.testing.integration.messages._
import io.grpc.testing.integration.empty.Empty

object TestServiceImpl {
  val parametersToResponseFlow: Flow[ResponseParameters, StreamingOutputCallResponse, NotUsed] =
    Flow[ResponseParameters]
      .map { parameters =>
        StreamingOutputCallResponse(
          Some(Payload(body = ByteString.copyFrom(new Array[Byte](parameters.size)))))
      }
}


class TestServiceImpl(implicit sys: ActorSystem) extends TestService {
  import TestServiceImpl._

  implicit val mat: Materializer = SystemMaterializer(sys).materializer
  implicit val ec: ExecutionContext = sys.dispatcher
  
  override def emptyCall(req: Empty) =
    Future.successful(Empty())

  override def unaryCall(req: SimpleRequest): Future[SimpleResponse] = {
    req.responseStatus match {
      case None =>
        Future.successful(SimpleResponse(Some(Payload(ByteString.copyFrom(new Array[Byte](req.responseSize))))))
      case Some(requestStatus) =>
        val responseStatus = Status.fromCodeValue(requestStatus.code).withDescription(requestStatus.message)
        //  - Either one of the following works
        Future.failed(new GrpcServiceException(responseStatus))
        // throw new GrpcServiceException(responseStatus)
    }
  }

  override def cacheableUnaryCall(in: SimpleRequest): Future[SimpleResponse] = ???

  override def fullDuplexCall(in: Source[StreamingOutputCallRequest, NotUsed]): Source[StreamingOutputCallResponse, NotUsed] =
    in.map(req => {
      req.responseStatus.foreach(reqStatus =>
        throw new GrpcServiceException(
          Status.fromCodeValue(reqStatus.code).withDescription(reqStatus.message)))
      req
    }).mapConcat(
      _.responseParameters.to[immutable.Seq]).via(parametersToResponseFlow)

  override def halfDuplexCall(in: Source[StreamingOutputCallRequest, NotUsed]): Source[StreamingOutputCallResponse, NotUsed] = ???

  override def streamingInputCall(in: Source[StreamingInputCallRequest, NotUsed]): Future[StreamingInputCallResponse] = {
    in
      .map(_.payload.map(_.body.size).getOrElse(0))
      .runFold(0)(_ + _)
      .map { sum =>
        StreamingInputCallResponse(sum)
      }
  }

  override def streamingOutputCall(in: StreamingOutputCallRequest): Source[StreamingOutputCallResponse, NotUsed] =
    Source(in.responseParameters.to[immutable.Seq]).via(parametersToResponseFlow)

  override def unimplementedCall(in: Empty): Future[Empty] = ???
} 
Example 7
Source File: RetryPolicyDefaults.scala    From akka-cloudpubsub   with Apache License 2.0 5 votes vote down vote up
package com.qubit.pubsub.client.retry

import java.util.concurrent.Executors

import com.gilt.gfc.concurrent.ThreadFactoryBuilder
import com.typesafe.scalalogging.LazyLogging
import io.grpc.{Status, StatusRuntimeException}

import scala.concurrent.ExecutionContext
import scala.util.Failure

object RetryPolicyDefaults extends LazyLogging {
  import atmos.dsl._
  import Slf4jSupport._

  import scala.concurrent.duration._

  private val unrecoverableErrorCodes = Set(Status.Code.PERMISSION_DENIED,
                                            Status.Code.UNAUTHENTICATED,
                                            Status.Code.INVALID_ARGUMENT)
  private val rateLimitingErrorCodes =
    Set(Status.Code.RESOURCE_EXHAUSTED, Status.Code.UNAVAILABLE)

  val retryPolicy = retryFor {
    10.attempts
  } using selectedBackoff {
    case Failure(sre: StatusRuntimeException)
        if rateLimitingErrorCodes.contains(sre.getStatus.getCode) =>
      linearBackoff { 50.seconds }
    case _ =>
      exponentialBackoff { 30.seconds } randomized 10.second -> 100.seconds
  } monitorWith {
    logger.underlying
  } onError {
    case sre: StatusRuntimeException
        if unrecoverableErrorCodes.contains(sre.getStatus.getCode) =>
      stopRetrying
  }

  val retryExecCtx = ExecutionContext.fromExecutor(
    Executors.newFixedThreadPool(
      10,
      ThreadFactoryBuilder("retry-pool", "retry-worker").build()
    ))
} 
Example 8
Source File: Fs2ServerCallListener.scala    From fs2-grpc   with MIT License 5 votes vote down vote up
package org.lyranthe.fs2_grpc
package java_runtime
package server

import cats.effect._
import cats.effect.concurrent.Deferred
import cats.implicits._
import fs2.Stream
import io.grpc.{Metadata, Status, StatusException, StatusRuntimeException}

private[server] trait Fs2ServerCallListener[F[_], G[_], Request, Response] {
  def source: G[Request]
  def isCancelled: Deferred[F, Unit]
  def call: Fs2ServerCall[F, Request, Response]

  private def reportError(t: Throwable)(implicit F: Sync[F]): F[Unit] = {
    t match {
      case ex: StatusException =>
        call.closeStream(ex.getStatus, Option(ex.getTrailers).getOrElse(new Metadata()))
      case ex: StatusRuntimeException =>
        call.closeStream(ex.getStatus, Option(ex.getTrailers).getOrElse(new Metadata()))
      case ex =>
        // TODO: Customize failure trailers?
        call.closeStream(Status.INTERNAL.withDescription(ex.getMessage).withCause(ex), new Metadata())
    }
  }

  private def handleUnaryResponse(headers: Metadata, response: F[Response])(implicit F: Sync[F]): F[Unit] =
    call.sendHeaders(headers) *> call.request(1) *> response >>= call.sendMessage

  private def handleStreamResponse(headers: Metadata, response: Stream[F, Response])(implicit F: Sync[F]): F[Unit] =
    call.sendHeaders(headers) *> call.request(1) *> response.evalMap(call.sendMessage).compile.drain

  private def unsafeRun(f: F[Unit])(implicit F: ConcurrentEffect[F]): Unit = {
    val bracketed = F.guaranteeCase(f) {
      case ExitCase.Completed => call.closeStream(Status.OK, new Metadata())
      case ExitCase.Canceled => call.closeStream(Status.CANCELLED, new Metadata())
      case ExitCase.Error(t) => reportError(t)
    }

    // Exceptions are reported by closing the call
    F.runAsync(F.race(bracketed, isCancelled.get))(_ => IO.unit).unsafeRunSync()
  }

  def unsafeUnaryResponse(headers: Metadata, implementation: G[Request] => F[Response])(implicit
      F: ConcurrentEffect[F]
  ): Unit =
    unsafeRun(handleUnaryResponse(headers, implementation(source)))

  def unsafeStreamResponse(headers: Metadata, implementation: G[Request] => Stream[F, Response])(implicit
      F: ConcurrentEffect[F]
  ): Unit =
    unsafeRun(handleStreamResponse(headers, implementation(source)))
} 
Example 9
Source File: GrpcException.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.grpc

import com.daml.grpc.GrpcStatus.SpecificGrpcStatus
import io.grpc.{Metadata, Status, StatusException, StatusRuntimeException}

object GrpcException {
  def unapply(exception: Exception): Option[(Status, Metadata)] =
    exception match {
      case e: StatusRuntimeException => Some((e.getStatus, e.getTrailers))
      case e: StatusException => Some((e.getStatus, e.getTrailers))
      case _ => None
    }

  private[grpc] final class SpecificGrpcException(status: SpecificGrpcStatus) {
    def unapply(exception: Exception): Boolean =
      exception match {
        case e: StatusRuntimeException => status.unapply(e.getStatus)
        case e: StatusException => status.unapply(e.getStatus)
        case _ => false
      }
  }

  val OK = new SpecificGrpcException(GrpcStatus.OK)
  val CANCELLED = new SpecificGrpcException(GrpcStatus.CANCELLED)
  val UNKNOWN = new SpecificGrpcException(GrpcStatus.UNKNOWN)
  val INVALID_ARGUMENT = new SpecificGrpcException(GrpcStatus.INVALID_ARGUMENT)
  val DEADLINE_EXCEEDED = new SpecificGrpcException(GrpcStatus.DEADLINE_EXCEEDED)
  val NOT_FOUND = new SpecificGrpcException(GrpcStatus.NOT_FOUND)
  val ALREADY_EXISTS = new SpecificGrpcException(GrpcStatus.ALREADY_EXISTS)
  val PERMISSION_DENIED = new SpecificGrpcException(GrpcStatus.PERMISSION_DENIED)
  val RESOURCE_EXHAUSTED = new SpecificGrpcException(GrpcStatus.RESOURCE_EXHAUSTED)
  val FAILED_PRECONDITION = new SpecificGrpcException(GrpcStatus.FAILED_PRECONDITION)
  val ABORTED = new SpecificGrpcException(GrpcStatus.ABORTED)
  val OUT_OF_RANGE = new SpecificGrpcException(GrpcStatus.OUT_OF_RANGE)
  val UNIMPLEMENTED = new SpecificGrpcException(GrpcStatus.UNIMPLEMENTED)
  val INTERNAL = new SpecificGrpcException(GrpcStatus.INTERNAL)
  val UNAVAILABLE = new SpecificGrpcException(GrpcStatus.UNAVAILABLE)
  val DATA_LOSS = new SpecificGrpcException(GrpcStatus.DATA_LOSS)
  val UNAUTHENTICATED = new SpecificGrpcException(GrpcStatus.UNAUTHENTICATED)
} 
Example 10
Source File: AkkaClientWithReferenceServiceSpecBase.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.grpc.adapter.operation

import akka.stream.scaladsl.Sink
import com.daml.grpc.adapter.client.ReferenceClientCompatibilityCheck
import com.daml.grpc.adapter.client.akka.ClientAdapter
import com.daml.grpc.adapter.{ExecutionSequencerFactory, TestExecutionSequencerFactory}
import com.daml.ledger.api.testing.utils.AkkaBeforeAndAfterAll
import com.daml.platform.hello.HelloRequest
import io.grpc.StatusRuntimeException
import org.scalatest.concurrent.ScalaFutures
import org.scalatest.{BeforeAndAfterAll, Matchers, WordSpec}

import java.net.SocketAddress

abstract class AkkaClientWithReferenceServiceSpecBase(
    override protected val socketAddress: Option[SocketAddress])
    extends WordSpec
    with Matchers
    with BeforeAndAfterAll
    with AkkaBeforeAndAfterAll
    with ScalaFutures
    with ReferenceClientCompatibilityCheck
    with AkkaClientCompatibilityCheck
    with ReferenceServiceFixture {

  protected implicit val esf: ExecutionSequencerFactory = TestExecutionSequencerFactory.instance

  "Akka client" when {

    "testing with reference service" should {
      behave like akkaClientCompatible(clientStub)
    }

    "handle request errors when server streaming" in {
      val elemsF = ClientAdapter
        .serverStreaming(HelloRequest(-1), clientStub.serverStreaming)
        .runWith(Sink.ignore)

      whenReady(elemsF.failed)(_ shouldBe a[StatusRuntimeException])
    }

  }
} 
Example 11
Source File: LedgerContext.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.platform.sandbox.perf

import akka.actor.ActorSystem
import akka.pattern
import com.daml.lf.data.Ref.PackageId
import com.daml.ledger.api.domain
import com.daml.ledger.api.v1.active_contracts_service.ActiveContractsServiceGrpc
import com.daml.ledger.api.v1.active_contracts_service.ActiveContractsServiceGrpc.ActiveContractsServiceStub
import com.daml.ledger.api.v1.command_service.CommandServiceGrpc
import com.daml.ledger.api.v1.command_service.CommandServiceGrpc.CommandService
import com.daml.ledger.api.v1.ledger_identity_service.LedgerIdentityServiceGrpc.LedgerIdentityServiceStub
import com.daml.ledger.api.v1.ledger_identity_service.{
  GetLedgerIdentityRequest,
  LedgerIdentityServiceGrpc
}
import com.daml.ledger.api.v1.testing.reset_service.ResetServiceGrpc.ResetService
import com.daml.ledger.api.v1.testing.reset_service.{ResetRequest, ResetServiceGrpc}
import io.grpc.{Channel, StatusRuntimeException}
import org.slf4j.LoggerFactory
import scalaz.syntax.tag._

import scala.concurrent.duration._
import scala.concurrent.{ExecutionContext, Future}

final class LedgerContext(channel: Channel, packageIds: Iterable[PackageId])(
    implicit executionContext: ExecutionContext
) {

  private val logger = LoggerFactory.getLogger(this.getClass)

  val ledgerId: domain.LedgerId =
    domain.LedgerId(
      LedgerIdentityServiceGrpc
        .blockingStub(channel)
        .getLedgerIdentity(GetLedgerIdentityRequest())
        .ledgerId)

  def reset()(implicit system: ActorSystem): Future[LedgerContext] = {
    def waitForNewLedger(retries: Int): Future[domain.LedgerId] =
      if (retries <= 0)
        Future.failed(new RuntimeException("waitForNewLedger: out of retries"))
      else {
        ledgerIdentityService
          .getLedgerIdentity(GetLedgerIdentityRequest())
          .flatMap { resp =>
            // TODO: compare with current Ledger ID and retry when not changed
            Future.successful(domain.LedgerId(resp.ledgerId))
          }
          .recoverWith {
            case _: StatusRuntimeException =>
              logger.debug(
                "waitForNewLedger: retrying identity request in 1 second. {} retries remain",
                retries - 1)
              pattern.after(1.seconds, system.scheduler)(waitForNewLedger(retries - 1))
            case t: Throwable =>
              logger.warn("waitForNewLedger: failed to reconnect!")
              throw t
          }
      }
    for {
      _ <- resetService.reset(ResetRequest(ledgerId.unwrap))
      _ <- waitForNewLedger(10)
    } yield new LedgerContext(channel, packageIds)
  }

  def ledgerIdentityService: LedgerIdentityServiceStub =
    LedgerIdentityServiceGrpc.stub(channel)

  def commandService: CommandService =
    CommandServiceGrpc.stub(channel)

  def acsService: ActiveContractsServiceStub =
    ActiveContractsServiceGrpc.stub(channel)

  def resetService: ResetService =
    ResetServiceGrpc.stub(channel)

} 
Example 12
Source File: ApiValueToLfValueConverter.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.http.util

import com.daml.lf
import com.daml.ledger.api.validation.ValueValidator
import com.daml.ledger.api.{v1 => lav1}
import io.grpc.StatusRuntimeException
import scalaz.{Show, \/}

object ApiValueToLfValueConverter {
  final case class Error(cause: StatusRuntimeException)

  object Error {
    implicit val ErrorShow: Show[Error] = Show shows { e =>
      import com.daml.util.ExceptionOps._
      s"ApiValueToLfValueConverter.Error: ${e.cause.description}"
    }
  }

  type ApiValueToLfValue =
    lav1.value.Value => Error \/ lf.value.Value[lf.value.Value.ContractId]

  def apiValueToLfValue: ApiValueToLfValue = { a: lav1.value.Value =>
    \/.fromEither(ValueValidator.validateValue(a)).leftMap(e => Error(e))
  }
} 
Example 13
Source File: ValidatorTestUtils.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.validation

import brave.propagation
import com.daml.lf.data.Ref
import com.daml.ledger.api.domain
import com.daml.ledger.api.messages.transaction
import io.grpc.Status.Code
import io.grpc.StatusRuntimeException
import org.scalatest._

import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future
trait ValidatorTestUtils extends Matchers with Inside with OptionValues { self: Suite =>

  protected val traceIdHigh = 1L
  protected val traceId = 2L
  protected val spanId = 3L
  protected val parentSpanId = Some(4L)
  protected val sampled = true
  protected val includedModule = "includedModule"
  protected val includedTemplate = "includedTemplate"
  protected val expectedLedgerId = "expectedLedgerId"
  protected val packageId = Ref.PackageId.assertFromString("packageId")
  protected val absoluteOffset = Ref.LedgerString.assertFromString("42")
  protected val party = Ref.Party.assertFromString("party")
  protected val verbose = false
  protected val eventId = "eventId"
  protected val transactionId = "42"
  protected val offsetOrdering = Ordering.by[domain.LedgerOffset.Absolute, Int](_.value.toInt)
  protected val ledgerEnd = domain.LedgerOffset.Absolute(Ref.LedgerString.assertFromString("1000"))

  protected def hasExpectedFilters(req: transaction.GetTransactionsRequest) = {
    val filtersByParty = req.filter.filtersByParty
    filtersByParty should have size 1
    inside(filtersByParty.headOption.value) {
      case (p, filters) =>
        p shouldEqual party
        filters shouldEqual domain.Filters(
          Some(domain.InclusiveFilters(Set(Ref.Identifier(
            Ref.PackageId.assertFromString(packageId),
            Ref.QualifiedName(
              Ref.DottedName.assertFromString(includedModule),
              Ref.DottedName.assertFromString(includedTemplate))
          )))))
    }
  }

  protected def hasExpectedTraceContext(req: transaction.GetTransactionsRequest) = {
    inside(req.traceContext.value) {
      case e => isExpectedTraceContext(e)
    }
  }

  protected def isExpectedTraceContext(e: propagation.TraceContext) = {
    e.traceIdHigh() shouldEqual traceIdHigh
    e.traceId() shouldEqual traceId
    e.spanId() shouldEqual spanId
    Option(e.parentId()) shouldEqual parentSpanId
    e.sampled() shouldEqual sampled
  }

  protected def requestMustFailWith(
      request: Future[_],
      code: Code,
      description: String): Future[Assertion] = {
    val f = request.map(Right(_)).recover { case ex: StatusRuntimeException => Left(ex) }
    f.map(inside(_)(isError(code, description)))
  }

  protected def requestMustFailWith(
      request: Either[StatusRuntimeException, _],
      code: Code,
      description: String): Assertion = {
    inside(request)(isError(code, description))
  }
  protected def isError(expectedCode: Code, expectedDescription: String)
    : PartialFunction[Either[StatusRuntimeException, _], Assertion] = {

    case Left(err) =>
      err.getStatus should have('code (expectedCode))
      err.getStatus should have('description (expectedDescription))

  }

} 
Example 14
Source File: PartyValidator.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.validation

import com.daml.lf.data.Ref.Party
import com.daml.platform.server.api.validation.ErrorFactories.invalidArgument
import com.daml.platform.server.api.validation.FieldValidations.requireParty
import io.grpc.StatusRuntimeException

class PartyValidator(partyNameChecker: PartyNameChecker) {
  type Result[X] = Either[StatusRuntimeException, X]

  def requireKnownParties(parties: Traversable[String]): Result[Set[Party]] =
    for {
      ps <- requireParties(parties.toSet)
      knownParties <- requireKnownParties(ps)
    } yield (knownParties)

  private def requireParties(parties: Set[String]): Result[Set[Party]] =
    parties.foldLeft[Result[Set[Party]]](Right(Set.empty)) { (acc, partyTxt) =>
      for {
        parties <- acc
        party <- requireParty(partyTxt)
      } yield parties + party
    }

  private def requireKnownParties(partiesInRequest: Set[Party]): Result[Set[Party]] = {
    val unknownParties = partiesInRequest.filterNot(partyNameChecker.isKnownParty)
    if (unknownParties.nonEmpty)
      Left(invalidArgument(s"Unknown parties: ${unknownParties.mkString("[", ", ", "]")}"))
    else Right(partiesInRequest)
  }
} 
Example 15
Source File: LedgerOffsetValidator.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.validation

import com.daml.ledger.api.domain
import com.daml.ledger.api.v1.ledger_offset.LedgerOffset
import com.daml.ledger.api.v1.ledger_offset.LedgerOffset.LedgerBoundary
import com.daml.platform.server.api.validation.ErrorFactories.{invalidArgument, missingField}
import com.daml.platform.server.api.validation.FieldValidations.requireLedgerString
import io.grpc.StatusRuntimeException

object LedgerOffsetValidator {

  private val boundary = "boundary"

  def validateOptional(
      ledgerOffset: Option[LedgerOffset],
      fieldName: String): Either[StatusRuntimeException, Option[domain.LedgerOffset]] =
    ledgerOffset
      .map(validate(_, fieldName))
      .fold[Either[StatusRuntimeException, Option[domain.LedgerOffset]]](Right(None))(
        _.map(Some(_)))

  def validate(
      ledgerOffset: LedgerOffset,
      fieldName: String): Either[StatusRuntimeException, domain.LedgerOffset] = {
    ledgerOffset match {
      case LedgerOffset(LedgerOffset.Value.Absolute(value)) =>
        requireLedgerString(value, fieldName).map(domain.LedgerOffset.Absolute)
      case LedgerOffset(LedgerOffset.Value.Boundary(value)) =>
        convertLedgerBoundary(fieldName, value)
      case LedgerOffset(LedgerOffset.Value.Empty) =>
        Left(missingField(fieldName + ".(" + boundary + "|value)"))
    }
  }

  private def convertLedgerBoundary(
      fieldName: String,
      value: LedgerBoundary): Either[StatusRuntimeException, domain.LedgerOffset] = {
    value match {
      case LedgerBoundary.Unrecognized(invalid) =>
        Left(
          invalidArgument(
            s"Unknown ledger $boundary value '$invalid' in field $fieldName.$boundary"))
      case LedgerBoundary.LEDGER_BEGIN => Right(domain.LedgerOffset.LedgerBegin)
      case LedgerBoundary.LEDGER_END => Right(domain.LedgerOffset.LedgerEnd)
    }
  }
} 
Example 16
Source File: TransactionFilterValidator.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.validation

import com.daml.lf.data.Ref
import com.daml.ledger.api.domain
import com.daml.ledger.api.domain.InclusiveFilters
import com.daml.ledger.api.v1.transaction_filter.{Filters, TransactionFilter}
import com.daml.ledger.api.v1.value.Identifier
import com.daml.platform.server.api.validation.ErrorFactories
import com.daml.platform.server.api.validation.FieldValidations._
import io.grpc.StatusRuntimeException
import scalaz.Traverse
import scalaz.std.either._
import scalaz.std.list._
import scalaz.syntax.traverse._

object TransactionFilterValidator {

  def validate(
      txFilter: TransactionFilter,
      fieldName: String): Either[StatusRuntimeException, domain.TransactionFilter] = {
    if (txFilter.filtersByParty.isEmpty) {
      Left(ErrorFactories.invalidArgument("filtersByParty cannot be empty"))
    } else {
      val convertedFilters =
        txFilter.filtersByParty.toList.traverseU {
          case (k, v) =>
            for {
              key <- requireParty(k)
              value <- validateFilters(v)
            } yield key -> value
        }
      convertedFilters.map(m => domain.TransactionFilter(m.toMap))
    }
  }

  def validateFilters(filters: Filters): Either[StatusRuntimeException, domain.Filters] = {
    filters.inclusive
      .fold[Either[StatusRuntimeException, domain.Filters]](Right(domain.Filters.noFilter)) {
        inclusive =>
          val validatedIdents =
            Traverse[List].traverseU[Identifier, Either[StatusRuntimeException, Ref.Identifier]](
              inclusive.templateIds.toList)((id: Identifier) => validateIdentifier(id))
          validatedIdents.map(ids => domain.Filters(Some(InclusiveFilters(ids.toSet))))
      }
  }
} 
Example 17
Source File: SubmitAndWaitRequestValidator.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.validation

import java.time.{Duration, Instant}

import com.daml.ledger.api.messages.command.submission
import com.daml.ledger.api.v1.command_service.SubmitAndWaitRequest
import com.daml.platform.server.api.validation.FieldValidations.requirePresence
import com.daml.platform.server.util.context.TraceContextConversions.toBrave
import io.grpc.StatusRuntimeException

class SubmitAndWaitRequestValidator(commandsValidator: CommandsValidator) {

  def validate(
      req: SubmitAndWaitRequest,
      currentLedgerTime: Instant,
      currentUtcTime: Instant,
      maxDeduplicationTime: Option[Duration])
    : Either[StatusRuntimeException, submission.SubmitRequest] =
    for {
      commands <- requirePresence(req.commands, "commands")
      validatedCommands <- commandsValidator.validateCommands(
        commands,
        currentLedgerTime,
        currentUtcTime,
        maxDeduplicationTime)
    } yield submission.SubmitRequest(validatedCommands, req.traceContext.map(toBrave))

} 
Example 18
Source File: SubmitRequestValidator.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.validation

import java.time.{Duration, Instant}

import com.daml.ledger.api.messages.command.submission
import com.daml.ledger.api.v1.command_submission_service.SubmitRequest
import com.daml.platform.server.api.validation.FieldValidations.requirePresence
import com.daml.platform.server.util.context.TraceContextConversions.toBrave
import io.grpc.StatusRuntimeException

class SubmitRequestValidator(commandsValidator: CommandsValidator) {

  def validate(
      req: SubmitRequest,
      currentLedgerTime: Instant,
      currentUtcTime: Instant,
      maxDeduplicationTime: Option[Duration])
    : Either[StatusRuntimeException, submission.SubmitRequest] =
    for {
      commands <- requirePresence(req.commands, "commands")
      validatedCommands <- commandsValidator.validateCommands(
        commands,
        currentLedgerTime,
        currentUtcTime,
        maxDeduplicationTime)
    } yield submission.SubmitRequest(validatedCommands, req.traceContext.map(toBrave))

} 
Example 19
Source File: CompletionServiceRequestValidator.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.validation

import com.daml.lf.data.Ref
import com.daml.ledger.api.domain.{ApplicationId, LedgerId}
import com.daml.ledger.api.messages.command.completion
import com.daml.ledger.api.messages.command.completion.CompletionStreamRequest
import com.daml.ledger.api.v1.command_completion_service.{
  CompletionEndRequest,
  CompletionStreamRequest => GrpcCompletionStreamRequest
}
import com.daml.platform.server.api.validation.FieldValidations
import com.daml.platform.server.util.context.TraceContextConversions.toBrave
import io.grpc.StatusRuntimeException
import com.daml.platform.server.api.validation.ErrorFactories._

class CompletionServiceRequestValidator(ledgerId: LedgerId, partyNameChecker: PartyNameChecker)
    extends FieldValidations {

  private val partyValidator = new PartyValidator(partyNameChecker)

  def validateCompletionStreamRequest(request: GrpcCompletionStreamRequest)
    : Either[StatusRuntimeException, CompletionStreamRequest] =
    for {
      _ <- matchLedgerId(ledgerId)(LedgerId(request.ledgerId))
      nonEmptyAppId <- requireNonEmptyString(request.applicationId, "application_id")
      appId <- Ref.LedgerString
        .fromString(nonEmptyAppId)
        .left
        .map(invalidField("application_id", _))
      nonEmptyParties <- requireNonEmpty(request.parties, "parties")
      knownParties <- partyValidator.requireKnownParties(nonEmptyParties)
      convertedOffset <- LedgerOffsetValidator.validateOptional(request.offset, "offset")
    } yield
      CompletionStreamRequest(
        ledgerId,
        ApplicationId(appId),
        knownParties,
        convertedOffset
      )

  def validateCompletionEndRequest(
      req: CompletionEndRequest): Either[StatusRuntimeException, completion.CompletionEndRequest] =
    for {
      ledgerId <- matchLedgerId(ledgerId)(LedgerId(req.ledgerId))
    } yield completion.CompletionEndRequest(ledgerId, req.traceContext.map(toBrave))

}