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

com.github.phisgr.gatling.kt.grpc.grpcDsl.kt Maven / Gradle / Ivy

@file:JvmMultifileClass
@file:JvmName("GrpcDsl")

package com.github.phisgr.gatling.kt.grpc

import com.github.phisgr.gatling.grpc.Predef
import com.github.phisgr.gatling.grpc.action.StreamCancelBuilder
import com.github.phisgr.gatling.grpc.action.`StreamMessageAction$`
import com.github.phisgr.gatling.grpc.action.StreamReconciliateBuilder
import com.github.phisgr.gatling.grpc.stream.BidiStreamCall
import com.github.phisgr.gatling.grpc.stream.ClientStreamCall
import com.github.phisgr.gatling.grpc.stream.ServerStreamCall
import com.github.phisgr.gatling.grpc.stream.StreamCall
import com.github.phisgr.gatling.kt.getOrThrow
import com.github.phisgr.gatling.kt.grpc.action.*
import com.github.phisgr.gatling.kt.internal.ActionBuilderWrapper
import com.github.phisgr.gatling.kt.internal.elString
import com.github.phisgr.gatling.kt.internal.toScalaF
import com.github.phisgr.gatling.kt.internal.validation
import com.github.phisgr.gatling.kt.javapb.asScala
import com.github.phisgr.gatling.kt.javapb.fromSession
import com.google.protobuf.Message
import io.gatling.commons.validation.Validation
import io.gatling.javaapi.core.ActionBuilder
import io.gatling.javaapi.core.Session
import io.gatling.javaapi.core.internal.Expressions.toExpression
import io.gatling.javaapi.core.internal.Expressions.toStaticValueExpression
import io.grpc.ManagedChannelBuilder
import io.grpc.MethodDescriptor
import scala.Function1
import scala.reflect.ClassTag
import java.util.function.Function
import io.gatling.core.session.Session as SessionS

private typealias ExpressionS = Function1>

fun dynamicChannel(channelAttributeName: String): DynamicGrpcProtocol =
    DynamicGrpcProtocol(Predef.dynamicChannel(channelAttributeName))

fun grpc(managedChannelBuilder: ManagedChannelBuilder<*>) = StaticGrpcProtocol(Predef.grpc(managedChannelBuilder))
fun grpc(requestName: String): Grpc = Grpc(requestName.elString)

class Grpc(@PublishedApi internal val requestName: ExpressionS) {
    fun  rpc(method: MethodDescriptor) =
        Unary(requestName, method)

    // EL streamName methods
    fun  serverStream(method: MethodDescriptor, streamName: String) =
        ServerStream(requestName, method, streamName.elString)

    inline fun  bidiStream(method: MethodDescriptor, streamName: String) =
        bidiStream(method, streamName, Req::class.java)

    inline fun  clientStream(method: MethodDescriptor, streamName: String) =
        clientStream(method, streamName, Req::class.java)

    fun  bidiStream(method: MethodDescriptor, streamName: String, clazz: Class) =
        BidiStream(requestName, method, streamName.elString, clazz)

    fun  clientStream(method: MethodDescriptor, streamName: String, clazz: Class) =
        ClientStream(requestName, method, streamName.elString, clazz)


    // Java Function streamName methods
    fun  serverStream(method: MethodDescriptor, streamName: Function) =
        ServerStream(requestName, method, streamName.asScala())

    fun  bidiStream(
        method: MethodDescriptor,
        streamName: Function,
        clazz: Class,
    ) = BidiStream(requestName, method, streamName.asScala(), clazz)

    fun  clientStream(
        method: MethodDescriptor,
        streamName: Function,
        clazz: Class,
    ) = ClientStream(requestName, method, streamName.asScala(), clazz)


    // Kotlin inline function streamName methods
    @JvmSynthetic
    inline fun  serverStream(
        method: MethodDescriptor,
        crossinline streamName: (Session) -> String,
    ) = ServerStream(requestName, method) { session -> validation { streamName(Session(session)) } }

    inline fun  bidiStream(
        method: MethodDescriptor,
        crossinline streamName: (Session) -> String,
    ) = BidiStream(requestName, method, { session -> validation { streamName(Session(session)) } }, Req::class.java)

    inline fun  clientStream(
        method: MethodDescriptor,
        crossinline streamName: (Session) -> String,
    ) = ClientStream(requestName, method, { session -> validation { streamName(Session(session)) } }, Req::class.java)
}

inline fun  Unary.payload(el: String): GrpcCallActionBuilder =
    payload(el, Req::class.java)

@JvmSynthetic
inline fun  Unary.payload(
    crossinline newBuilder: () -> ReqBuilder,
    crossinline f: ReqBuilder.(Session) -> Req,
): GrpcCallActionBuilder =
    payload(fromSession(newBuilder, f))

class Unary(
    val requestName: ExpressionS,
    val method: MethodDescriptor,
) {

    @PublishedApi
    @JvmSynthetic
    internal fun payload(body: ExpressionS): GrpcCallActionBuilder =
        GrpcCallActionBuilder(
            Predef
                .grpc(requestName)
                .rpc(method)
                .payload(body)
        )

    fun payload(el: String, clazz: Class): GrpcCallActionBuilder = payload(toExpression(el, clazz))
    fun payload(body: Req): GrpcCallActionBuilder = payload(toStaticValueExpression(body))
    fun payload(f: Function): GrpcCallActionBuilder = payload(f.asScala())

    @JvmSynthetic
    inline fun payload(crossinline f: (Session) -> Req): GrpcCallActionBuilder =
        payload(toScalaF { session: SessionS -> f(Session(session)) })
}

sealed class ListeningStream>(private val callClazz: Class) {
    abstract val requestName: ExpressionS
    abstract val streamName: ExpressionS
    abstract val direction: String
    fun cancelStream(): ActionBuilder =
        ActionBuilderWrapper(StreamCancelBuilder(requestName, streamName, direction))

    /**
     * See [com.github.phisgr.gatling.grpc.request.ListeningStream.reconciliate].
     */
    fun reconciliate(waitFor: WaitType = NO_WAIT, sync: Boolean = false): ActionBuilder =
        ActionBuilderWrapper(StreamReconciliateBuilder(requestName, streamName, direction, waitFor, sync))

    fun status(session: Session): Status =
        `StreamMessageAction$`.`MODULE$`
            .fetchCall(callClazz, streamName, session.asScala(), direction)
            .getOrThrow()
            .state()
}

inline fun  ServerStream.start(
    el: String,
): ServerStreamStartActionBuilder =
    start(el, Req::class.java)

@JvmSynthetic
inline fun  ServerStream.start(
    crossinline newBuilder: () -> ReqBuilder,
    crossinline f: ReqBuilder.(Session) -> Req,
): ServerStreamStartActionBuilder =
    start(fromSession(newBuilder, f))

class ServerStream(
    override val requestName: ExpressionS,
    val method: MethodDescriptor,
    override val streamName: ExpressionS,
) : ListeningStream>(ServerStreamCall::class.java) {
    fun withRequestName(el: String): ServerStream = ServerStream(
        el.elString, method, streamName
    )

    @PublishedApi
    @JvmSynthetic
    internal fun start(body: ExpressionS): ServerStreamStartActionBuilder =
        ServerStreamStartActionBuilder(
            Predef
                .grpc(requestName)
                .serverStream(method, streamName)
                .start(body)
        )

    fun start(el: String, clazz: Class): ServerStreamStartActionBuilder = start(toExpression(el, clazz))
    fun start(body: Req): ServerStreamStartActionBuilder = start(toStaticValueExpression(body))
    fun start(f: Function): ServerStreamStartActionBuilder = start(f.asScala())

    @JvmSynthetic
    inline fun start(crossinline f: (Session) -> Req): ServerStreamStartActionBuilder =
        start(toScalaF { session: SessionS -> f(Session(session)) })

    override val direction: String
        get() = "server"
}

@JvmSynthetic
inline fun  BidiStream.send(
    crossinline newBuilder: () -> ReqBuilder,
    crossinline f: ReqBuilder.(Session) -> Req,
): StreamSendBuilder =
    send(fromSession(newBuilder, f))

class BidiStream(
    override val requestName: ExpressionS,
    val method: MethodDescriptor,
    override val streamName: ExpressionS,
    private val clazz: Class,
) : ListeningStream>(BidiStreamCall::class.java) {
    fun withRequestName(el: String): BidiStream = BidiStream(
        el.elString, method, streamName, clazz
    )

    fun connect(): BidiStreamStartActionBuilder =
        BidiStreamStartActionBuilder(streamS.connect())

    @PublishedApi
    @JvmSynthetic
    internal fun send(body: ExpressionS): StreamSendBuilder =
        StreamSendBuilder(streamS.send(body))

    fun send(el: String): StreamSendBuilder = send(toExpression(el, clazz))
    fun send(body: Req): StreamSendBuilder = send(toStaticValueExpression(body))
    fun send(f: Function): StreamSendBuilder = send(f.asScala())

    @JvmSynthetic
    inline fun send(crossinline f: (Session) -> Req): StreamSendBuilder =
        send(toScalaF { session: SessionS -> f(Session(session)) })

    fun complete(waitFor: WaitType = NO_WAIT): ActionBuilder =
        ActionBuilderWrapper(streamS.complete(waitFor))

    private val streamS = Predef.grpc(requestName).bidiStream(method, streamName, ClassTag.apply(clazz))

    override val direction: String
        get() = "bidi"
}

@JvmSynthetic
inline fun  ClientStream.send(
    crossinline newBuilder: () -> ReqBuilder,
    crossinline f: ReqBuilder.(Session) -> Req,
): StreamSendBuilder =
    send(fromSession(newBuilder, f))

class ClientStream(
    val requestName: ExpressionS,
    val method: MethodDescriptor,
    val streamName: ExpressionS,
    private val clazz: Class,
) {
    fun withRequestName(el: String): ClientStream = ClientStream(
        el.elString, method, streamName, clazz
    )

    fun connect(): ClientStreamStartActionBuilder =
        ClientStreamStartActionBuilder(streamS.connect())

    @PublishedApi
    @JvmSynthetic
    internal fun send(body: ExpressionS): StreamSendBuilder =
        StreamSendBuilder(streamS.send(body))

    fun send(el: String): StreamSendBuilder = send(toExpression(el, clazz))
    fun send(body: Req): StreamSendBuilder = send(toStaticValueExpression(body))
    fun send(f: Function): StreamSendBuilder = send(f.asScala())

    @JvmSynthetic
    inline fun send(crossinline f: (Session) -> Req): ActionBuilder =
        send(toScalaF { session: SessionS -> f(Session(session)) })

    fun cancelStream(): ActionBuilder = ActionBuilderWrapper(streamS.cancelStream())
    fun completeAndWait(): ActionBuilder = ActionBuilderWrapper(streamS.completeAndWait())

    fun status(session: Session): StreamCall.ClientStreamState =
        `StreamMessageAction$`.`MODULE$`
            .fetchCall(
                ClientStreamCall::class.java,
                streamName,
                session.asScala(),
                "client",
            )
            .getOrThrow()
            .state()

    private val streamS = Predef.grpc(requestName).clientStream(method, streamName, ClassTag.apply(clazz))
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy