2121import java .util .HashMap ;
2222import java .util .Map ;
2323import java .util .Objects ;
24- import java .util .Optional ;
2524import java .util .function .Consumer ;
2625
2726import org .jspecify .annotations .Nullable ;
28-
2927import org .springframework .boot .context .properties .ConfigurationProperties ;
28+ import org .springframework .boot .context .properties .PropertyMapper ;
3029import org .springframework .boot .convert .DurationUnit ;
3130import org .springframework .context .EnvironmentAware ;
3231import org .springframework .core .env .Environment ;
3736import org .springframework .grpc .client .VirtualTargets ;
3837import org .springframework .util .unit .DataSize ;
3938
40- import io .grpc .ManagedChannel ;
41-
4239/**
4340 * Configuration properties for the gRPC client side.
4441 *
@@ -55,7 +52,8 @@ public class GrpcClientProperties implements EnvironmentAware, VirtualTargets {
5552 private final Map <String , ChannelConfig > channels = new HashMap <>();
5653
5754 /**
58- * Container for channel-level configuration that can be shared across named channels.
55+ * Container for channel-level default configuration that named channels can inherit
56+ * from.
5957 */
6058 private final Channel channel = new Channel ();
6159
@@ -72,6 +70,7 @@ public class GrpcClientProperties implements EnvironmentAware, VirtualTargets {
7270 private Environment environment ;
7371
7472 GrpcClientProperties () {
73+ this .defaultChannel .setAddress ("static://localhost:9090" );
7574 this .environment = new StandardEnvironment ();
7675 }
7776
@@ -104,8 +103,8 @@ public void setEnvironment(Environment environment) {
104103 * Gets the configured channel with the given name. If no channel is configured for
105104 * the specified name then one is created using the default channel as a template.
106105 * Named channels inherit settings from the {@code channel.defaults} configuration
107- * (not from the default-channel) unless {@code inherit-defaults} is set to false on
108- * the channel.
106+ * (not from the default-channel) if {@code inherit-defaults} is set to true on the
107+ * channel.
109108 * @param name the name of the channel
110109 * @return the configured channel if found (optionally merged with defaults), or a
111110 * newly created channel using the default channel as a template
@@ -149,32 +148,10 @@ public String getTarget(String authority) {
149148 }
150149
151150 /**
152- * Represents the configuration for a {@link ManagedChannel gRPC channel} .
151+ * Represents the configuration for a gRPC channel.
153152 */
154153 public static class ChannelConfig {
155154
156- private static final String DEFAULT_ADDRESS = "static://localhost:9090" ;
157-
158- private static final String DEFAULT_LOAD_BALANCING_POLICY = "round_robin" ;
159-
160- private static final boolean DEFAULT_ENABLE_KEEP_ALIVE = false ;
161-
162- private static final Duration DEFAULT_IDLE_TIMEOUT = Duration .ofSeconds (20 );
163-
164- private static final Duration DEFAULT_KEEP_ALIVE_TIME = Duration .ofMinutes (5 );
165-
166- private static final Duration DEFAULT_KEEP_ALIVE_TIMEOUT = Duration .ofSeconds (20 );
167-
168- private static final boolean DEFAULT_KEEP_ALIVE_WITHOUT_CALLS = false ;
169-
170- private static final DataSize DEFAULT_MAX_INBOUND_MESSAGE_SIZE = DataSize .ofBytes (4194304 );
171-
172- private static final DataSize DEFAULT_MAX_INBOUND_METADATA_SIZE = DataSize .ofBytes (8192 );
173-
174- private static final NegotiationType DEFAULT_NEGOTIATION_TYPE = NegotiationType .PLAINTEXT ;
175-
176- private static final boolean DEFAULT_SECURE = true ;
177-
178155 /**
179156 * The target address uri to connect to.
180157 */
@@ -261,10 +238,10 @@ public static class ChannelConfig {
261238 /**
262239 * Whether to inherit settings from the channel defaults configuration.
263240 */
264- private @ Nullable Boolean inheritDefaults ;
241+ private boolean inheritDefaults ;
265242
266243 public String getAddress () {
267- return Objects .requireNonNullElse (this .address , DEFAULT_ADDRESS );
244+ return Objects .requireNonNullElse (this .address , "static://localhost:9090" );
268245 }
269246
270247 public void setAddress (final String address ) {
@@ -280,15 +257,15 @@ public void setDefaultDeadline(@Nullable Duration defaultDeadline) {
280257 }
281258
282259 public String getDefaultLoadBalancingPolicy () {
283- return Objects .requireNonNullElse (this .defaultLoadBalancingPolicy , DEFAULT_LOAD_BALANCING_POLICY );
260+ return Objects .requireNonNullElse (this .defaultLoadBalancingPolicy , "round_robin" );
284261 }
285262
286263 public void setDefaultLoadBalancingPolicy (final String defaultLoadBalancingPolicy ) {
287264 this .defaultLoadBalancingPolicy = defaultLoadBalancingPolicy ;
288265 }
289266
290267 public boolean isEnableKeepAlive () {
291- return Objects .requireNonNullElse (this .enableKeepAlive , DEFAULT_ENABLE_KEEP_ALIVE );
268+ return Objects .requireNonNullElse (this .enableKeepAlive , false );
292269 }
293270
294271 public void setEnableKeepAlive (boolean enableKeepAlive ) {
@@ -300,39 +277,39 @@ public Health getHealth() {
300277 }
301278
302279 public Duration getIdleTimeout () {
303- return Objects .requireNonNullElse (this .idleTimeout , DEFAULT_IDLE_TIMEOUT );
280+ return Objects .requireNonNullElse (this .idleTimeout , Duration . ofSeconds ( 20 ) );
304281 }
305282
306283 public void setIdleTimeout (Duration idleTimeout ) {
307284 this .idleTimeout = idleTimeout ;
308285 }
309286
310287 public Duration getKeepAliveTime () {
311- return Objects .requireNonNullElse (this .keepAliveTime , DEFAULT_KEEP_ALIVE_TIME );
288+ return Objects .requireNonNullElse (this .keepAliveTime , Duration . ofMinutes ( 5 ) );
312289 }
313290
314291 public void setKeepAliveTime (Duration keepAliveTime ) {
315292 this .keepAliveTime = keepAliveTime ;
316293 }
317294
318295 public Duration getKeepAliveTimeout () {
319- return Objects .requireNonNullElse (this .keepAliveTimeout , DEFAULT_KEEP_ALIVE_TIMEOUT );
296+ return Objects .requireNonNullElse (this .keepAliveTimeout , Duration . ofSeconds ( 20 ) );
320297 }
321298
322299 public void setKeepAliveTimeout (Duration keepAliveTimeout ) {
323300 this .keepAliveTimeout = keepAliveTimeout ;
324301 }
325302
326303 public boolean isKeepAliveWithoutCalls () {
327- return Objects .requireNonNullElse (this .keepAliveWithoutCalls , DEFAULT_KEEP_ALIVE_WITHOUT_CALLS );
304+ return Objects .requireNonNullElse (this .keepAliveWithoutCalls , false );
328305 }
329306
330307 public void setKeepAliveWithoutCalls (boolean keepAliveWithoutCalls ) {
331308 this .keepAliveWithoutCalls = keepAliveWithoutCalls ;
332309 }
333310
334311 public DataSize getMaxInboundMessageSize () {
335- return Objects .requireNonNullElse (this .maxInboundMessageSize , DEFAULT_MAX_INBOUND_MESSAGE_SIZE );
312+ return Objects .requireNonNullElse (this .maxInboundMessageSize , DataSize . ofBytes ( 4194304 ) );
336313 }
337314
338315 public void setMaxInboundMessageSize (final DataSize maxInboundMessageSize ) {
@@ -341,7 +318,7 @@ public void setMaxInboundMessageSize(final DataSize maxInboundMessageSize) {
341318 }
342319
343320 public DataSize getMaxInboundMetadataSize () {
344- return Objects .requireNonNullElse (this .maxInboundMetadataSize , DEFAULT_MAX_INBOUND_METADATA_SIZE );
321+ return Objects .requireNonNullElse (this .maxInboundMetadataSize , DataSize . ofBytes ( 8192 ) );
345322 }
346323
347324 public void setMaxInboundMetadataSize (DataSize maxInboundMetadataSize ) {
@@ -362,15 +339,15 @@ else if (maxSize != null && maxSize.toBytes() == -1) {
362339 }
363340
364341 public NegotiationType getNegotiationType () {
365- return Objects .requireNonNullElse (this .negotiationType , DEFAULT_NEGOTIATION_TYPE );
342+ return Objects .requireNonNullElse (this .negotiationType , NegotiationType . PLAINTEXT );
366343 }
367344
368345 public void setNegotiationType (NegotiationType negotiationType ) {
369346 this .negotiationType = negotiationType ;
370347 }
371348
372349 public boolean isSecure () {
373- return Objects .requireNonNullElse (this .secure , DEFAULT_SECURE );
350+ return Objects .requireNonNullElse (this .secure , true );
374351 }
375352
376353 public void setSecure (boolean secure ) {
@@ -394,7 +371,7 @@ public void setUserAgent(@Nullable String userAgent) {
394371 }
395372
396373 public boolean isInheritDefaults () {
397- return Objects . requireNonNullElse ( this .inheritDefaults , false ) ;
374+ return this .inheritDefaults ;
398375 }
399376
400377 public void setInheritDefaults (boolean inheritDefaults ) {
@@ -435,27 +412,22 @@ ChannelConfig copy() {
435412 */
436413 ChannelConfig mergeWith (ChannelConfig other ) {
437414 ChannelConfig merged = this .copy ();
438- merged .address = Optional .ofNullable (other .address ).orElse (merged .address );
439- merged .defaultDeadline = Optional .ofNullable (other .defaultDeadline ).orElse (merged .defaultDeadline );
440- merged .defaultLoadBalancingPolicy = Optional .ofNullable (other .defaultLoadBalancingPolicy )
441- .orElse (merged .defaultLoadBalancingPolicy );
442- merged .enableKeepAlive = Optional .ofNullable (other .enableKeepAlive ).orElse (merged .enableKeepAlive );
443- merged .idleTimeout = Optional .ofNullable (other .idleTimeout ).orElse (merged .idleTimeout );
444- merged .keepAliveTime = Optional .ofNullable (other .keepAliveTime ).orElse (merged .keepAliveTime );
445- merged .keepAliveTimeout = Optional .ofNullable (other .keepAliveTimeout ).orElse (merged .keepAliveTimeout );
446- merged .keepAliveWithoutCalls = Optional .ofNullable (other .keepAliveWithoutCalls )
447- .orElse (merged .keepAliveWithoutCalls );
448- merged .maxInboundMessageSize = Optional .ofNullable (other .maxInboundMessageSize )
449- .orElse (merged .maxInboundMessageSize );
450- merged .maxInboundMetadataSize = Optional .ofNullable (other .maxInboundMetadataSize )
451- .orElse (merged .maxInboundMetadataSize );
452- merged .negotiationType = Optional .ofNullable (other .negotiationType ).orElse (merged .negotiationType );
453- merged .secure = Optional .ofNullable (other .secure ).orElse (merged .secure );
454- merged .userAgent = Optional .ofNullable (other .userAgent ).orElse (merged .userAgent );
455-
415+ PropertyMapper map = PropertyMapper .get ();
416+ map .from (other .address ).to (merged ::setAddress );
417+ map .from (other .defaultDeadline ).to (merged ::setDefaultDeadline );
418+ map .from (other .defaultLoadBalancingPolicy ).to (merged ::setDefaultLoadBalancingPolicy );
419+ map .from (other .enableKeepAlive ).to (merged ::setEnableKeepAlive );
420+ map .from (other .idleTimeout ).to (merged ::setIdleTimeout );
421+ map .from (other .keepAliveTime ).to (merged ::setKeepAliveTime );
422+ map .from (other .keepAliveTimeout ).to (merged ::setKeepAliveTimeout );
423+ map .from (other .keepAliveWithoutCalls ).to (merged ::setKeepAliveWithoutCalls );
424+ map .from (other .maxInboundMessageSize ).to (merged ::setMaxInboundMessageSize );
425+ map .from (other .maxInboundMetadataSize ).to (merged ::setMaxInboundMetadataSize );
426+ map .from (other .negotiationType ).to (merged ::setNegotiationType );
427+ map .from (other .secure ).to (merged ::setSecure );
428+ map .from (other .userAgent ).to (merged ::setUserAgent );
456429 merged .health .mergeWith (other .health );
457430 merged .ssl .mergeWith (other .ssl );
458-
459431 if (!other .serviceConfig .isEmpty ()) {
460432 merged .serviceConfig .putAll (other .serviceConfig );
461433 }
@@ -515,8 +487,9 @@ void copyValuesFrom(Health other) {
515487 * @param other the configuration to merge with
516488 */
517489 void mergeWith (Health other ) {
518- this .enabled = Optional .ofNullable (other .enabled ).orElse (this .enabled );
519- this .serviceName = Optional .ofNullable (other .serviceName ).orElse (this .serviceName );
490+ PropertyMapper map = PropertyMapper .get ();
491+ map .from (other .enabled ).to (this ::setEnabled );
492+ map .from (other .serviceName ).to (this ::setServiceName );
520493 }
521494
522495 }
@@ -569,8 +542,9 @@ void copyValuesFrom(Ssl other) {
569542 * @param other the configuration to merge with
570543 */
571544 void mergeWith (Ssl other ) {
572- this .enabled = Optional .ofNullable (other .enabled ).orElse (this .enabled );
573- this .bundle = Optional .ofNullable (other .bundle ).orElse (this .bundle );
545+ PropertyMapper map = PropertyMapper .get ();
546+ map .from (other .enabled ).to (this ::setEnabled );
547+ map .from (other .bundle ).to (this ::setBundle );
574548 }
575549
576550 }
0 commit comments