From 29669431fc36e1446fcc4a0a00f7ac555b6691f9 Mon Sep 17 00:00:00 2001 From: nsce9806q Date: Sun, 5 Nov 2023 15:41:40 +0900 Subject: [PATCH 1/2] Add ManagedChannelContainer to AbstractGatewayFilterFactory. #3120 --- .../JsonToGrpcGatewayFilterFactory.java | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/factory/JsonToGrpcGatewayFilterFactory.java b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/factory/JsonToGrpcGatewayFilterFactory.java index 2b0286e073..5b344b579c 100644 --- a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/factory/JsonToGrpcGatewayFilterFactory.java +++ b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/factory/JsonToGrpcGatewayFilterFactory.java @@ -24,6 +24,7 @@ import java.util.NoSuchElementException; import java.util.Objects; import java.util.function.Function; +import java.util.concurrent.ConcurrentHashMap; import javax.net.ssl.SSLException; @@ -182,9 +183,12 @@ class GRPCResponseDecorator extends ServerHttpResponseDecorator { private final ObjectNode objectNode; + private final ConcurrentHashMap ManagedChannelContainer; + GRPCResponseDecorator(ServerWebExchange exchange, Config config) { super(exchange.getResponse()); this.exchange = exchange; + this.ManagedChannelContainer = new ConcurrentHashMap<>(); try { Resource descriptorFile = resourceLoader.getResource(config.getProtoDescriptor()); Resource protoFile = resourceLoader.getResource(config.getProtoFile()); @@ -223,7 +227,7 @@ public Mono writeWith(Publisher body) { } private ClientCall createClientCallForType(Config config, - Descriptors.ServiceDescriptor serviceDescriptor, Descriptors.Descriptor outputType) { + Descriptors.ServiceDescriptor serviceDescriptor, Descriptors.Descriptor outputType) { MethodDescriptor.Marshaller marshaller = ProtoUtils .marshaller(DynamicMessage.newBuilder(outputType).build()); MethodDescriptor methodDescriptor = MethodDescriptor @@ -304,13 +308,20 @@ private Function wrapGRPCResponse() { }; } - // We are creating this on every call, should optimize? private ManagedChannel createChannelChannel(String host, int port) { - NettyChannelBuilder nettyChannelBuilder = NettyChannelBuilder.forAddress(host, port); + String key = host + ":" + port; + ManagedChannel managedChannel = ManagedChannelContainer.get(key); try { - return grpcSslConfigurer.configureSsl(nettyChannelBuilder); - } - catch (SSLException e) { + if (managedChannel == null) { + NettyChannelBuilder nettyChannelBuilder = NettyChannelBuilder.forAddress(host, port); + managedChannel = grpcSslConfigurer.configureSsl(nettyChannelBuilder); + if (ManagedChannelContainer.putIfAbsent(key, managedChannel) != null) { + managedChannel.shutdown(); + return ManagedChannelContainer.get(key); + }; + } + return managedChannel; + } catch (SSLException e) { throw new RuntimeException(e); } } From 4eda3e2e808bca6f69c2369b6b13a2860be5c09f Mon Sep 17 00:00:00 2001 From: ChangEn Yea Date: Fri, 15 Mar 2024 07:56:34 +0900 Subject: [PATCH 2/2] Refactor JsonToGrpcGatewayFilterFactory.GRPCResponseDecorator.createChannelChannel and modify for Checkstyle compliance --- .../JsonToGrpcGatewayFilterFactory.java | 27 ++++++++----------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/factory/JsonToGrpcGatewayFilterFactory.java b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/factory/JsonToGrpcGatewayFilterFactory.java index 5b344b579c..9b30834f70 100644 --- a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/factory/JsonToGrpcGatewayFilterFactory.java +++ b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/factory/JsonToGrpcGatewayFilterFactory.java @@ -23,8 +23,8 @@ import java.util.List; import java.util.NoSuchElementException; import java.util.Objects; -import java.util.function.Function; import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Function; import javax.net.ssl.SSLException; @@ -183,12 +183,12 @@ class GRPCResponseDecorator extends ServerHttpResponseDecorator { private final ObjectNode objectNode; - private final ConcurrentHashMap ManagedChannelContainer; + private final ConcurrentHashMap managedChannelContainer; GRPCResponseDecorator(ServerWebExchange exchange, Config config) { super(exchange.getResponse()); this.exchange = exchange; - this.ManagedChannelContainer = new ConcurrentHashMap<>(); + this.managedChannelContainer = new ConcurrentHashMap<>(); try { Resource descriptorFile = resourceLoader.getResource(config.getProtoDescriptor()); Resource protoFile = resourceLoader.getResource(config.getProtoFile()); @@ -227,7 +227,7 @@ public Mono writeWith(Publisher body) { } private ClientCall createClientCallForType(Config config, - Descriptors.ServiceDescriptor serviceDescriptor, Descriptors.Descriptor outputType) { + Descriptors.ServiceDescriptor serviceDescriptor, Descriptors.Descriptor outputType) { MethodDescriptor.Marshaller marshaller = ProtoUtils .marshaller(DynamicMessage.newBuilder(outputType).build()); MethodDescriptor methodDescriptor = MethodDescriptor @@ -310,20 +310,15 @@ private Function wrapGRPCResponse() { private ManagedChannel createChannelChannel(String host, int port) { String key = host + ":" + port; - ManagedChannel managedChannel = ManagedChannelContainer.get(key); - try { - if (managedChannel == null) { + return managedChannelContainer.computeIfAbsent(key, k -> { + try { NettyChannelBuilder nettyChannelBuilder = NettyChannelBuilder.forAddress(host, port); - managedChannel = grpcSslConfigurer.configureSsl(nettyChannelBuilder); - if (ManagedChannelContainer.putIfAbsent(key, managedChannel) != null) { - managedChannel.shutdown(); - return ManagedChannelContainer.get(key); - }; + return grpcSslConfigurer.configureSsl(nettyChannelBuilder); } - return managedChannel; - } catch (SSLException e) { - throw new RuntimeException(e); - } + catch (SSLException e) { + throw new RuntimeException(e); + } + }); } }