1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty5.bootstrap;
17
18 import io.netty5.channel.Channel;
19 import io.netty5.channel.ChannelFactory;
20 import io.netty5.channel.ChannelFutureListeners;
21 import io.netty5.channel.ChannelPipeline;
22 import io.netty5.channel.EventLoop;
23 import io.netty5.channel.EventLoopGroup;
24 import io.netty5.channel.ReflectiveChannelFactory;
25 import io.netty5.resolver.AddressResolver;
26 import io.netty5.resolver.AddressResolverGroup;
27 import io.netty5.resolver.DefaultAddressResolverGroup;
28 import io.netty5.resolver.NameResolver;
29 import io.netty5.util.concurrent.Future;
30 import io.netty5.util.concurrent.Promise;
31 import io.netty5.util.internal.logging.InternalLogger;
32 import io.netty5.util.internal.logging.InternalLoggerFactory;
33
34 import java.net.InetAddress;
35 import java.net.InetSocketAddress;
36 import java.net.SocketAddress;
37
38 import static java.util.Objects.requireNonNull;
39
40
41
42
43
44
45
46
47 public class Bootstrap extends AbstractBootstrap<Bootstrap, Channel, ChannelFactory<? extends Channel>> {
48
49 private static final InternalLogger logger = InternalLoggerFactory.getInstance(Bootstrap.class);
50
51 private static final AddressResolverGroup<?> DEFAULT_RESOLVER = DefaultAddressResolverGroup.INSTANCE;
52
53 private final BootstrapConfig config = new BootstrapConfig(this);
54
55 @SuppressWarnings("unchecked")
56 private volatile AddressResolverGroup<SocketAddress> resolver =
57 (AddressResolverGroup<SocketAddress>) DEFAULT_RESOLVER;
58 private volatile SocketAddress remoteAddress;
59 volatile ChannelFactory<? extends Channel> channelFactory;
60
61 public Bootstrap() { }
62
63 private Bootstrap(Bootstrap bootstrap) {
64 super(bootstrap);
65 resolver = bootstrap.resolver;
66 remoteAddress = bootstrap.remoteAddress;
67 channelFactory = bootstrap.channelFactory;
68 }
69
70
71
72
73
74
75
76
77
78 @SuppressWarnings("unchecked")
79 public Bootstrap resolver(AddressResolverGroup<?> resolver) {
80 this.resolver = (AddressResolverGroup<SocketAddress>) (resolver == null ? DEFAULT_RESOLVER : resolver);
81 return this;
82 }
83
84
85
86
87
88 public Bootstrap remoteAddress(SocketAddress remoteAddress) {
89 this.remoteAddress = remoteAddress;
90 return this;
91 }
92
93
94
95
96 public Bootstrap remoteAddress(String inetHost, int inetPort) {
97 remoteAddress = InetSocketAddress.createUnresolved(inetHost, inetPort);
98 return this;
99 }
100
101
102
103
104 public Bootstrap remoteAddress(InetAddress inetHost, int inetPort) {
105 remoteAddress = new InetSocketAddress(inetHost, inetPort);
106 return this;
107 }
108
109
110
111
112
113
114 public Bootstrap channel(Class<? extends Channel> channelClass) {
115 requireNonNull(channelClass, "channelClass");
116 return channelFactory(new ReflectiveChannelFactory<Channel>(channelClass));
117 }
118
119
120
121
122
123
124
125
126 public Bootstrap channelFactory(ChannelFactory<? extends Channel> channelFactory) {
127 requireNonNull(channelFactory, "channelFactory");
128 if (this.channelFactory != null) {
129 throw new IllegalStateException("channelFactory set already");
130 }
131
132 this.channelFactory = channelFactory;
133 return this;
134 }
135
136
137
138
139 public Future<Channel> connect() {
140 validate();
141 SocketAddress remoteAddress = this.remoteAddress;
142 if (remoteAddress == null) {
143 throw new IllegalStateException("remoteAddress not set");
144 }
145
146 return doResolveAndConnect(remoteAddress, config.localAddress());
147 }
148
149
150
151
152 public Future<Channel> connect(String inetHost, int inetPort) {
153 return connect(InetSocketAddress.createUnresolved(inetHost, inetPort));
154 }
155
156
157
158
159 public Future<Channel> connect(InetAddress inetHost, int inetPort) {
160 return connect(new InetSocketAddress(inetHost, inetPort));
161 }
162
163
164
165
166 public Future<Channel> connect(SocketAddress remoteAddress) {
167 requireNonNull(remoteAddress, "remoteAddress");
168
169 validate();
170 return doResolveAndConnect(remoteAddress, config.localAddress());
171 }
172
173
174
175
176 public Future<Channel> connect(SocketAddress remoteAddress, SocketAddress localAddress) {
177 requireNonNull(remoteAddress, "remoteAddress");
178 validate();
179 return doResolveAndConnect(remoteAddress, localAddress);
180 }
181
182
183
184
185 private Future<Channel> doResolveAndConnect(final SocketAddress remoteAddress, final SocketAddress localAddress) {
186 EventLoop loop = group.next();
187 final Future<Channel> regFuture = initAndRegister(loop);
188
189 Promise<Channel> resolveAndConnectPromise = loop.newPromise();
190 if (regFuture.isDone()) {
191 if (regFuture.isFailed()) {
192 return regFuture;
193 }
194 Channel channel = regFuture.getNow();
195 doResolveAndConnect0(channel, remoteAddress, localAddress, resolveAndConnectPromise);
196 } else {
197
198 regFuture.addListener(future -> {
199
200
201 Throwable cause = future.cause();
202 if (cause != null) {
203
204
205 resolveAndConnectPromise.setFailure(cause);
206 } else {
207 Channel channel = future.getNow();
208 doResolveAndConnect0(channel, remoteAddress, localAddress, resolveAndConnectPromise);
209 }
210 });
211 }
212 return resolveAndConnectPromise.asFuture();
213 }
214
215 private void doResolveAndConnect0(final Channel channel, SocketAddress remoteAddress,
216 final SocketAddress localAddress, final Promise<Channel> promise) {
217 try {
218 final EventLoop eventLoop = channel.executor();
219 final AddressResolver<SocketAddress> resolver = this.resolver.getResolver(eventLoop);
220
221 if (!resolver.isSupported(remoteAddress) || resolver.isResolved(remoteAddress)) {
222
223 doConnect(remoteAddress, localAddress, channel, promise);
224 return;
225 }
226
227 final Future<SocketAddress> resolveFuture = resolver.resolve(remoteAddress);
228
229 if (resolveFuture.isDone()) {
230 final Throwable resolveFailureCause = resolveFuture.cause();
231
232 if (resolveFailureCause != null) {
233
234 channel.close();
235 promise.setFailure(resolveFailureCause);
236 } else {
237
238 doConnect(resolveFuture.getNow(), localAddress, channel, promise);
239 return;
240 }
241 }
242
243
244 resolveFuture.addListener(future -> {
245 if (future.cause() != null) {
246 channel.close();
247 promise.setFailure(future.cause());
248 } else {
249 doConnect(future.getNow(), localAddress, channel, promise);
250 }
251 });
252 } catch (Throwable cause) {
253 promise.tryFailure(cause);
254 }
255 }
256
257 private static void doConnect(
258 SocketAddress remoteAddress, SocketAddress localAddress, Channel channel, Promise<Channel> promise) {
259
260
261 channel.executor().execute(() -> {
262 final Future<Void> future;
263 if (localAddress == null) {
264 future = channel.connect(remoteAddress);
265 } else {
266 future = channel.connect(remoteAddress, localAddress);
267 }
268 future.addListener(channel, ChannelFutureListeners.CLOSE_ON_FAILURE);
269 future.map(v -> channel).cascadeTo(promise);
270 });
271 }
272
273 @Override
274 Future<Channel> init(Channel channel) {
275 ChannelPipeline p = channel.pipeline();
276
277 setChannelOptions(channel, newOptionsArray(), logger);
278 setAttributes(channel, newAttributesArray());
279
280 p.addLast(config.handler());
281
282 return channel.executor().newSucceededFuture(channel);
283 }
284
285 @Override
286 Channel newChannel(EventLoop eventLoop) throws Exception {
287 return channelFactory.newChannel(eventLoop);
288 }
289
290 @Override
291 public Bootstrap validate() {
292 super.validate();
293 if (config.handler() == null) {
294 throw new IllegalStateException("handler not set");
295 }
296 if (config.channelFactory() == null) {
297 throw new IllegalStateException("channelFactory not set");
298 }
299 return this;
300 }
301
302 @Override
303 @SuppressWarnings("CloneDoesntCallSuperClone")
304 public Bootstrap clone() {
305 return new Bootstrap(this);
306 }
307
308
309
310
311
312
313 public Bootstrap clone(EventLoopGroup group) {
314 Bootstrap bs = new Bootstrap(this);
315 bs.group = group;
316 return bs;
317 }
318
319 @Override
320 public final BootstrapConfig config() {
321 return config;
322 }
323
324 final SocketAddress remoteAddress() {
325 return remoteAddress;
326 }
327
328 final AddressResolverGroup<?> resolver() {
329 return resolver;
330 }
331 }