All Downloads are FREE. Search and download functionalities are using the official Maven repository.

kalix.javasdk.testkit.impl.ActionResultImpl.scala Maven / Gradle / Ivy

/*
 * Copyright 2024 Lightbend Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package kalix.javasdk.testkit.impl

import kalix.javasdk.SideEffect
import kalix.javasdk.action.Action
import kalix.javasdk.impl.GrpcDeferredCall
import kalix.javasdk.impl.action.ActionEffectImpl
import kalix.javasdk.testkit.ActionResult
import kalix.javasdk.testkit.DeferredCallDetails
import java.util.concurrent.CompletionStage
import java.util.{ List => JList }

import io.grpc.Status

import scala.compat.java8.FutureConverters._
import scala.concurrent.ExecutionContext
import scala.jdk.CollectionConverters._

/**
 * INTERNAL API
 */
private[kalix] object ActionResultImpl {

  private def toDeferredCallDetails(sideEffects: Seq[SideEffect]): JList[DeferredCallDetails[_, _]] =
    sideEffects
      .map(s => TestKitDeferredCall(s.call.asInstanceOf[GrpcDeferredCall[_, _]]): DeferredCallDetails[_, _])
      .asJava
}

/**
 * INTERNAL API
 */
final class ActionResultImpl[T](effect: ActionEffectImpl.PrimaryEffect[T]) extends ActionResult[T] {
  import ActionResultImpl._

  def this(effect: Action.Effect[T]) = this(effect.asInstanceOf[ActionEffectImpl.PrimaryEffect[T]])

  private implicit val ec = ExecutionContext.Implicits.global

  /** @return true if the call had an effect with a reply, false if not */
  override def isReply(): Boolean = effect.isInstanceOf[ActionEffectImpl.ReplyEffect[T]]

  override def getReply(): T = {
    val reply = getEffectOfType(classOf[ActionEffectImpl.ReplyEffect[T]])
    reply.msg
  }

  //TODO add metadata??

  /** @return true if the call was forwarded, false if not */
  override def isForward(): Boolean = effect.isInstanceOf[ActionEffectImpl.ForwardEffect[T]]

  override def getForward(): DeferredCallDetails[Any, T] =
    effect match {
      case ActionEffectImpl.ForwardEffect(serviceCall: GrpcDeferredCall[Any @unchecked, T @unchecked], _) =>
        TestKitDeferredCall(serviceCall)
      case _ =>
        throw new IllegalStateException(
          "expected effect type [ActionEffectImpl.ForwardEffect] but found [" + effect.getClass.getName + "]")
    }

  // TODO rewrite
  /** @return true if the call was async, false if not */
  override def isAsync(): Boolean = effect.isInstanceOf[ActionEffectImpl.AsyncEffect[T]]

  override def getAsyncResult(): CompletionStage[ActionResult[T]] = {
    val async = getEffectOfType(classOf[ActionEffectImpl.AsyncEffect[T]])
    async.effect.map(new ActionResultImpl(_).asInstanceOf[ActionResult[T]]).toJava
  }

  /** @return true if the call was an error, false if not */
  override def isError(): Boolean = effect.isInstanceOf[ActionEffectImpl.ErrorEffect[T]]

  override def getError(): String = {
    val error = getEffectOfType(classOf[ActionEffectImpl.ErrorEffect[T]])
    error.description
  }

  override def isIgnore(): Boolean = effect == ActionEffectImpl.IgnoreEffect()

  override def getErrorStatusCode(): Status.Code = {
    val error = getEffectOfType(classOf[ActionEffectImpl.ErrorEffect[T]])
    error.statusCode.getOrElse(Status.Code.UNKNOWN)
  }

  /**
   * Look at effect and verifies that it is of type E or fail if not.
   *
   * @return
   *   The next effect if it is of type E, for additional assertions.
   */
  private def getEffectOfType[E](expectedClass: Class[E]): E = {
    if (expectedClass.isInstance(effect)) effect.asInstanceOf[E]
    else
      throw new NoSuchElementException(
        "expected effect type [" + expectedClass.getName + "] but found [" + effect.getClass.getName + "]")
  }

  override def getSideEffects(): JList[DeferredCallDetails[_, _]] =
    toDeferredCallDetails(effect.internalSideEffects())

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy