U
UTMStack
gRPC Service Implementation

This page details the gRPC service implementation for the Agent Infrastructure, covering client channel configuration, service definitions, method handlers, and generated stub factories. It serves as the primary communication layer between the control plane and distributed agents, facilitating both standard RPC calls and bidirectional streaming.

Source Protobuf

The implementation on this page is generated from the agent.proto file using the gRPC proto compiler (version 1.65.1).

Architecture Overview

The gRPC implementation is divided into two main components: the Spring-managed client configuration that establishes the connection, and the generated service stubs that define the API contract.

Client Configuration

The GrpcConfiguration class provides a Spring-managed ManagedChannel bean using Netty. It handles connection establishment, security interceptors, and lifecycle management.

Channel Setup

The channel is built using NettyChannelBuilder and relies on application properties for routing.

@Configuration
public class GrpcConfiguration {
    private ManagedChannel channel;

    @Value("${grpc.server.address}")
    private String serverAddress;

    @Value("${grpc.server.port}")
    private Integer serverPort;

    @Bean
    public ManagedChannel managedChannel() throws SSLException {
        this.channel = NettyChannelBuilder
                .forAddress(serverAddress, serverPort)
                .intercept(new GrpcInterceptor())
                .sslContext(GrpcSslContexts.forClient()
                    .trustManager(InsecureTrustManagerFactory.INSTANCE)
                    .build())
                .build();
        return this.channel;
    }
    
    @PreDestroy
    public void shutdownChannel() {
        this.channel.shutdown();
    }
}

Security Notice: The current configuration uses InsecureTrustManagerFactory.INSTANCE, which blindly trusts all SSL certificates. This is suitable for development or internal cluster communication but must be replaced with a proper trust manager containing valid CA certificates before deploying to production environments.

The @PreDestroy annotation ensures that the ManagedChannel is gracefully shut down when the Spring application context closes, preventing resource leaks and dangling connections.

Configuration Properties

Ensure the following properties are set in your application.yml or environment variables:

Service Definition (AgentService)

The AgentService defines the contract for agent lifecycle management and command execution. The service name is registered internally as agent.AgentService.

Available RPC Methods

Client Stubs

The generated AgentServiceGrpc class provides three types of client stubs to accommodate different asynchronous programming models.

Class: AgentServiceBlockingStub
Used for standard, synchronous execution where the calling thread blocks until the server responds. Ideal for simple scripts or background workers where thread blocking is acceptable.

AgentServiceBlockingStub stub = AgentServiceGrpc.newBlockingStub(channel);
AuthResponse response = stub.registerAgent(agentRequest);

Class: AgentServiceStub
Used for fully asynchronous, non-blocking execution using StreamObserver callbacks. This is required for the AgentStream bidirectional streaming method.

AgentServiceStub asyncStub = AgentServiceGrpc.newStub(channel);
asyncStub.registerAgent(agentRequest, new StreamObserver<AuthResponse>() {
    @Override
    public void onNext(AuthResponse response) { /* Handle success */ }
    @Override
    public void onError(Throwable t) { /* Handle error */ }
    @Override
    public void onCompleted() { /* Handle completion */ }
});

Class: AgentServiceFutureStub
Returns a Guava ListenableFuture. Useful when integrating gRPC calls into existing reactive pipelines or when you need to chain multiple asynchronous operations together.

AgentServiceFutureStub futureStub = AgentServiceGrpc.newFutureStub(channel);
ListenableFuture<AuthResponse> future = futureStub.registerAgent(agentRequest);

Consuming the Service

To consume the AgentService within your Spring application, follow these steps:

Ensure the GrpcConfiguration is loaded in your context, and autowire the ManagedChannel into your service class.

Create the appropriate stub (Blocking, Async, or Future) using the injected channel. It is recommended to do this during bean initialization rather than per-request.

Build your protobuf request objects (e.g., AgentRequest.newBuilder().build()).

Invoke the method on the stub. The GrpcInterceptor will automatically attach any necessary authentication headers or tracing IDs to the outgoing request.

Server Implementation Details

If you are implementing the server side of this contract, you must extend the generated AgentServiceImplBase class and override the default methods.

By default, all methods in AgentServiceImplBase throw an UNIMPLEMENTED gRPC status exception. You must explicitly override and implement the logic for each method you intend to support.

@GrpcService
public class AgentServiceImpl extends AgentServiceGrpc.AgentServiceImplBase {
    
    @Override
    public void registerAgent(AgentRequest request, StreamObserver<AuthResponse> responseObserver) {
        // 1. Process the request
        // 2. Build the response
        AuthResponse response = AuthResponse.newBuilder().setToken("...").build();
        
        // 3. Send response and complete
        responseObserver.onNext(response);
        responseObserver.onCompleted();
    }
    
    // Implement other methods...
}
UTMStack
UTMStack © 2026 All rights reserved