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(new FutureListener<SocketAddress>() {
50                  @Override
51                  public void operationComplete(Future<SocketAddress> future) {
52                      Throwable cause = future.cause();
53                      if (cause != null) {
54                          promise.setFailure(cause);
55                      } else {
56                          ctx.connect(future.getNow(), localAddress, promise);
57                      }
58                      ctx.pipeline().remove(ResolveAddressHandler.this);
59                  }
60              });
61          } else {
62              ctx.connect(remoteAddress, localAddress, promise);
63              ctx.pipeline().remove(this);
64          }
65      }
66  }