Kora фреймворк для написания Java / Kotlin приложений с упором на производительность, эффективность, прозрачность сделанный разработчиками Т-Банк / Тинькофф

Kora is a framework for writing Java / Kotlin applications with a focus on performance, efficiency, transparency made by T-Bank / Tinkoff developers

Skip to content

gRPC client

Module for gRPC client service support based on grpc.io functionality.

Dependency

Dependency build.gradle:

implementation "ru.tinkoff.kora:grpc-client"
implementation "io.grpc:grpc-protobuf:1.62.2"
implementation "javax.annotation:javax.annotation-api:1.3.2"

Module:

@KoraApp
public interface Application extends GrpcClientModule { }

Dependency build.gradle.kts:

implementation("ru.tinkoff.kora:grpc-client")
implementation("io.grpc:grpc-protobuf:1.62.2")
implementation("javax.annotation:javax.annotation-api:1.3.2")

Module:

@KoraApp
interface Application : GrpcClientModule

Plugin

The code for the gRPC client is created with protobuf gradle plugin.

Plugin build.gradle:

plugins {
    id "com.google.protobuf" version "0.9.4"
}

protobuf {
    protoc { artifact = "com.google.protobuf:protoc:3.25.3" }
    plugins {
        grpc { artifact = "io.grpc:protoc-gen-grpc-java:1.62.2" }
    }
    generateProtoTasks {
        all()*.plugins { grpc {} }
    }
}

sourceSets {
    main.java {
        srcDirs "build/generated/source/proto/main/grpc"
        srcDirs "build/generated/source/proto/main/java"
    }
}

Plugin build.gradle.kts:

import com.google.protobuf.gradle.id

plugins {
    id("com.google.protobuf") version ("0.9.4")
}

protobuf {
    protoc { artifact = "com.google.protobuf:protoc:3.25.3" }
    plugins {
        id("grpc") { artifact = "io.grpc:protoc-gen-grpc-java:1.62.2" }
    }
    generateProtoTasks {
        ofSourceSet("main").forEach { it.plugins { id("grpc") { } } }
    }
}

kotlin {
    sourceSets.main {
        kotlin.srcDir("build/generated/source/proto/main/grpc")
        kotlin.srcDir("build/generated/source/proto/main/java")
    }
}

Configuration

gRPC service named SimpleService, will have configuration with path of grpcClient.SimpleService.

Example of the complete configuration described in the GrpcClientConfig class (default or example values are specified):

grpcClient {
    SimpleService {
        url = "grpc://localhost:8090" //(1)!
        timeout = "10s"  //(2)!
        telemetry {
            logging {
                enabled = false //(3)!
            }
            metrics {
                enabled = true //(4)!
                slo = [ 1, 10, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 30000, 60000, 90000 ] //(5)!
            }
            tracing {
                enabled = true //(6)!
            }
        }
    }
}
  1. URL of the server where to make requests (required)
  2. Maximum request time (optional)
  3. Enables module logging (default false)
  4. Enables module metrics (default true)
  5. Configures SLO for DistributionSummary metrics
  6. Enables module tracing (default true)
grpcClient:
  SimpleService:
    url: "grpc://localhost:8090" //(1)!
    timeout: "10s" //(2)!
    telemetry:
      logging:
        enabled: false #(1)!
      metrics:
        enabled: true #(2)!
        slo: [ 1, 10, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 30000, 60000, 90000 ] #(3)!
      telemetry:
        enabled: true #(4)!
  1. URL of the server where to make requests (required)
  2. Maximum request time (optional)
  3. Enables module logging (default false)
  4. Enables module metrics (default true)
  5. Configures SLO for DistributionSummary metrics
  6. Enables module tracing (default true)

You can also configure Netty transport.

Service

Created gRPC services can be injected as dependency:

@KoraApp
public interface Application extends HoconConfigModule, GrpcClientModule {

    default SomeService(SimpleServiceGrpc.SimpleServiceBlockingStub grpcService) {
        return new SomeService(grpcService);
    }
}
@KoraApp
interface Application : HoconConfigModule, GrpcClientModule {
    fun SomeService(grpcService: SimpleServiceGrpc.SimpleServiceBlockingStub?) {
        return SomeService(grpcService)
    }
}

Interceptors

Interceptors allow you to intercept requests before they are passed to services.

Default

The following interceptors are used at client startup by default:

  • GrpcClientConfigInterceptor.

Custom

In order to add your custom interceptor, you need to register the interceptor as a component with the service tag:

@Tag(SimpleServiceGrpc.class)
@Component
public final class MyClientInterceptor implements ClientInterceptor {
    @Override
    public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(MethodDescriptor<ReqT, RespT> method, CallOptions callOptions, Channel next) {
        LoggerFactory.getLogger(Application.class).info("INTERCEPTED");
        return next.newCall(method, callOptions);
    }
}
@Tag(SimpleServiceGrpc::class)
@Component
class MyClientInterceptor : ClientInterceptor {
    fun <ReqT, RespT> interceptCall(
        method: MethodDescriptor<ReqT, RespT>,
        callOptions: CallOptions,
        next: Channel
    ): ClientCall<ReqT, RespT> {
        return next.newCall(method, callOptions)
    }
}

Alternatively you can modify the gRPC service with GraphInterceptor.