Skip to content

Simple Spring Cloud GRPC Gateway with workaround to help reactor-netty pass endStream metadata flag obtained from the server to netty, which then correctly pass msg with error (grpc-status!=0) to the client.

Notifications You must be signed in to change notification settings

rrevyakin/spring-cloud-grpc-gateway-with-workaround

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Service description

Simple Spring Cloud GRPC Gateway with workaround to help reactor-netty pass endStream metadata flag obtained from the server to netty, which then correctly pass msg with error (grpc-status!=0) to the client. Works only with workaround in reactory-netty done here - https://github.com/rrevyakin/reactor-netty-with-grpc-workaround/tree/v.1.0.21.1

Problem description

When preparing a response in the netty implementation, the endStream http/2 flag is set - it depends on what type the nettyResponse variable will be in HttpServerOperations: endStream=true is set if nettyResponse instanceof LastHttpContent. After contacting the server, HttpClientResponse res contains the correct response. It can be DefaultFullHttpResponse (implements LastHttpContent) or DefaultHttpResponse (does not implement LastHttpContent). The problem is that when creating HttpServerOperations, the nettyResponse field is instantiated by DefaultHttpResponse (it is then populated with data from HttpClientResponse res). That is, even if HttpClientResponse was DefaultFullHttpResponse in the nettyResponse field, HttpServerOperations will still have DefaultHttpResponse, which leads to the fact that when sending a response from gateway to the client, the response instanceOf LastHttpContent check is always false, which in turn leads to setting endStream=false. That is, in the process of preparing a response from the server to be sent to the client, endStream=true is always lost.

Workaround description

CustomNettyRoutingFilter is a copy of org.springframework.cloud.gateway.filter.NettyRoutingFilter with additional method - copyResponse. Its purpose is to set the nettyResponse value from HttpClientResponse res to the nettyResponse of the HttpServerOperations object. Respectively, when the server responds with an error, a DefaultFullHttpResponse is generated, passed to HttpServerOperations, because of this, the check for LastHttpContent passes and endStream=true is set in the response to the client. As a result of the implementation of the described workaround solution, gateway began to correctly respond not only to successful requests, but also to requests that lead to errors on the server.

com.example.gateway.CustomNettyRoutingFilter.copyResponse:

private static void copyResponse(HttpClientResponse clientResponse, ServerHttpResponse serverResponse) {
    HttpResponse realHttpResponse = clientResponse.nettyResponse();
    ((HttpServerOperations) ((AbstractServerHttpResponse) serverResponse).getNativeResponse())
            .setNettyResponse(realHttpResponse);
}

About

Simple Spring Cloud GRPC Gateway with workaround to help reactor-netty pass endStream metadata flag obtained from the server to netty, which then correctly pass msg with error (grpc-status!=0) to the client.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages