View Javadoc
1   /*
2    * Copyright 2020 The Netty Project
3    *
4    * The Netty Project licenses this file to you under the Apache License,
5    * version 2.0 (the "License"); you may not use this file except in compliance
6    * with the License. You may obtain a copy of the License at:
7    *
8    *   https://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations
14   * under the License.
15   */
16  package io.netty.handler.address;
17  
18  import io.netty.channel.ChannelHandler.Sharable;
19  import io.netty.channel.ChannelHandlerContext;
20  import io.netty.channel.ChannelOutboundHandlerAdapter;
21  import io.netty.channel.ChannelPromise;
22  import io.netty.resolver.AddressResolver;
23  import io.netty.resolver.AddressResolverGroup;
24  import io.netty.util.concurrent.Future;
25  import io.netty.util.concurrent.FutureListener;
26  import io.netty.util.internal.ObjectUtil;
27  
28  import java.net.SocketAddress;
29  
30  /**
31   * {@link ChannelOutboundHandlerAdapter} which will resolve the {@link SocketAddress} that is passed to
32   * {@link #connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise)} if it is not already resolved
33   * and the {@link AddressResolver} supports the type of {@link SocketAddress}.
34   */
35  @Sharable
36  public class ResolveAddressHandler extends ChannelOutboundHandlerAdapter {
37  
38      private final AddressResolverGroup<? extends SocketAddress> resolverGroup;
39  
40      public ResolveAddressHandler(AddressResolverGroup<? extends SocketAddress> resolverGroup) {
41          this.resolverGroup = ObjectUtil.checkNotNull(resolverGroup, "resolverGroup");
42      }
43  
44      @Override
45      public void connect(final ChannelHandlerContext ctx, SocketAddress remoteAddress,
46                          final SocketAddress localAddress, final ChannelPromise promise)  {
47          AddressResolver<? extends SocketAddress> resolver = resolverGroup.getResolver(ctx.executor());
48          if (resolver.isSupported(remoteAddress) && !resolver.isResolved(remoteAddress)) {
49              resolver.resolve(remoteAddress).addListener((FutureListener<SocketAddress>) future -> {
50                  Throwable cause = future.cause();
51                  if (cause != null) {
52                      promise.setFailure(cause);
53                  } else {
54                      ctx.connect(future.getNow(), localAddress, promise);
55                  }
56                  ctx.pipeline().remove(ResolveAddressHandler.this);
57              });
58          } else {
59              ctx.connect(remoteAddress, localAddress, promise);
60              ctx.pipeline().remove(this);
61          }
62      }
63  }