1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package com.linecorp.centraldogma.client.spring;
17
18 import java.net.UnknownHostException;
19 import java.util.List;
20 import java.util.Optional;
21 import java.util.concurrent.ExecutionException;
22 import java.util.concurrent.TimeUnit;
23 import java.util.concurrent.TimeoutException;
24
25 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory;
27 import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
28 import org.springframework.boot.context.properties.EnableConfigurationProperties;
29 import org.springframework.context.annotation.Bean;
30 import org.springframework.context.annotation.Configuration;
31 import org.springframework.core.env.Environment;
32
33 import com.google.common.net.HostAndPort;
34
35 import com.linecorp.armeria.client.ClientFactory;
36 import com.linecorp.armeria.client.ClientFactoryBuilder;
37 import com.linecorp.centraldogma.client.CentralDogma;
38 import com.linecorp.centraldogma.client.armeria.ArmeriaCentralDogmaBuilder;
39 import com.linecorp.centraldogma.client.armeria.ArmeriaClientConfigurator;
40 import com.linecorp.centraldogma.client.armeria.DnsAddressEndpointGroupConfigurator;
41
42
43
44
45 @Configuration
46 @ConditionalOnMissingBean(CentralDogma.class)
47 @EnableConfigurationProperties(CentralDogmaSettings.class)
48 public class CentralDogmaClientAutoConfiguration {
49
50 private static final Logger logger = LoggerFactory.getLogger(CentralDogmaClientAutoConfiguration.class);
51
52 static final long DEFAULT_INITIALIZATION_TIMEOUT_MILLIS = 15000;
53
54
55
56
57 @Bean
58 public CentralDogma dogmaClient(
59 Environment env,
60 CentralDogmaSettings settings,
61 Optional<List<CentralDogmaClientFactoryConfigurator>> factoryConfigurators,
62 Optional<ArmeriaClientConfigurator> armeriaClientConfigurator,
63 Optional<DnsAddressEndpointGroupConfigurator> dnsAddressEndpointGroupConfigurator)
64 throws UnknownHostException {
65
66 final ArmeriaCentralDogmaBuilder builder = new ArmeriaCentralDogmaBuilder();
67
68 if (factoryConfigurators.isPresent()) {
69 final ClientFactoryBuilder clientFactoryBuilder = ClientFactory.builder();
70 factoryConfigurators.get().forEach(configurator -> configurator.configure(clientFactoryBuilder));
71 builder.clientFactory(clientFactoryBuilder.build());
72 }
73
74 builder.clientConfigurator(cb -> armeriaClientConfigurator.ifPresent(
75 configurator -> configurator.configure(cb)));
76 dnsAddressEndpointGroupConfigurator.ifPresent(builder::dnsAddressEndpointGroupConfigurator);
77
78
79 final Long healthCheckIntervalMillis = settings.getHealthCheckIntervalMillis();
80 if (healthCheckIntervalMillis != null) {
81 builder.healthCheckIntervalMillis(healthCheckIntervalMillis);
82 }
83
84
85 final Boolean useTls = settings.getUseTls();
86 if (useTls != null) {
87 builder.useTls(useTls);
88 }
89
90
91 final String accessToken = settings.getAccessToken();
92 if (accessToken != null) {
93 builder.accessToken(accessToken);
94 }
95
96
97 final String profile = settings.getProfile();
98 final List<String> hosts = settings.getHosts();
99 if (profile != null) {
100 if (hosts != null) {
101 throw new IllegalStateException(
102 "'hosts' and 'profile' are mutually exclusive. Do not set both of them.");
103 }
104 builder.profile(CentralDogmaClientAutoConfiguration.class.getClassLoader(), profile);
105 } else if (hosts != null) {
106 for (String h : hosts) {
107 final HostAndPort hostAndPort = HostAndPort.fromString(h);
108 if (hostAndPort.hasPort()) {
109 builder.host(hostAndPort.getHost(), hostAndPort.getPort());
110 } else {
111 builder.host(hostAndPort.getHost());
112 }
113 }
114 } else {
115
116 final String[] springBootProfiles = env.getActiveProfiles();
117 logger.info("Using the Spring Boot profiles as the source of the Central Dogma client profile: {}",
118 springBootProfiles);
119 builder.profile(springBootProfiles);
120 }
121
122
123 final Integer maxNumRetriesOnReplicationLag = settings.getMaxNumRetriesOnReplicationLag();
124 if (maxNumRetriesOnReplicationLag != null) {
125 builder.maxNumRetriesOnReplicationLag(maxNumRetriesOnReplicationLag);
126 }
127
128 final Long retryIntervalOnReplicationLagMillis = settings.getRetryIntervalOnReplicationLagMillis();
129 if (retryIntervalOnReplicationLagMillis != null) {
130 builder.retryIntervalOnReplicationLagMillis(retryIntervalOnReplicationLagMillis);
131 }
132
133 final CentralDogma centralDogma = builder.build();
134 Long initializationTimeoutMillis = settings.initializationTimeoutMillis();
135 if (initializationTimeoutMillis == null) {
136 initializationTimeoutMillis = DEFAULT_INITIALIZATION_TIMEOUT_MILLIS;
137 }
138 if (initializationTimeoutMillis > 0) {
139 try {
140 centralDogma.whenEndpointReady().get(initializationTimeoutMillis, TimeUnit.MILLISECONDS);
141 } catch (InterruptedException | ExecutionException | TimeoutException e) {
142 throw new IllegalStateException(
143 "Failed to initialize the endpoints of " + centralDogma + " in " +
144 initializationTimeoutMillis + " milliseconds", e);
145 }
146 }
147 return centralDogma;
148 }
149 }