1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty5.resolver;
17
18 import io.netty5.util.concurrent.EventExecutor;
19 import io.netty5.util.concurrent.Future;
20 import io.netty5.util.concurrent.Promise;
21
22 import java.util.Arrays;
23 import java.util.List;
24
25 import static java.util.Objects.requireNonNull;
26
27
28
29
30
31
32 public final class CompositeNameResolver<T> extends SimpleNameResolver<T> {
33
34 private final NameResolver<T>[] resolvers;
35
36
37
38
39
40
41 public CompositeNameResolver(EventExecutor executor, NameResolver<T>... resolvers) {
42 super(executor);
43 requireNonNull(resolvers, "resolvers");
44 for (int i = 0; i < resolvers.length; i++) {
45 requireNonNull(resolvers[i], "resolvers[" + i + "]");
46 }
47 if (resolvers.length < 2) {
48 throw new IllegalArgumentException("resolvers: " + Arrays.asList(resolvers) +
49 " (expected: at least 2 resolvers)");
50 }
51 this.resolvers = resolvers.clone();
52 }
53
54 @Override
55 protected void doResolve(String inetHost, Promise<T> promise) throws Exception {
56 doResolveRec(inetHost, promise, 0, null);
57 }
58
59 private void doResolveRec(final String inetHost,
60 final Promise<T> promise,
61 final int resolverIndex,
62 Throwable lastFailure) throws Exception {
63 if (resolverIndex >= resolvers.length) {
64 promise.setFailure(lastFailure);
65 } else {
66 NameResolver<T> resolver = resolvers[resolverIndex];
67 resolver.resolve(inetHost).addListener(future -> {
68 if (future.isSuccess()) {
69 promise.setSuccess(future.getNow());
70 } else {
71 doResolveRec(inetHost, promise, resolverIndex + 1, future.cause());
72 }
73 });
74 }
75 }
76
77 @Override
78 protected void doResolveAll(String inetHost, Promise<List<T>> promise) throws Exception {
79 doResolveAllRec(inetHost, promise, 0, null);
80 }
81
82 private void doResolveAllRec(final String inetHost,
83 final Promise<List<T>> promise,
84 final int resolverIndex,
85 Throwable lastFailure) throws Exception {
86 if (resolverIndex >= resolvers.length) {
87 promise.setFailure(lastFailure);
88 } else {
89 NameResolver<T> resolver = resolvers[resolverIndex];
90 resolver.resolveAll(inetHost).addListener(future -> {
91 if (future.isSuccess()) {
92 promise.setSuccess(future.getNow());
93 } else {
94 doResolveAllRec(inetHost, promise, resolverIndex + 1, future.cause());
95 }
96 });
97 }
98 }
99 }