diff --git a/consul/src/main/java/com/linecorp/armeria/client/consul/ConsulEndpointGroupBuilder.java b/consul/src/main/java/com/linecorp/armeria/client/consul/ConsulEndpointGroupBuilder.java index f8bc61d81d8..02f2be14e2e 100644 --- a/consul/src/main/java/com/linecorp/armeria/client/consul/ConsulEndpointGroupBuilder.java +++ b/consul/src/main/java/com/linecorp/armeria/client/consul/ConsulEndpointGroupBuilder.java @@ -21,7 +21,6 @@ import java.net.URI; import java.time.Duration; -import com.linecorp.armeria.client.Endpoint; import com.linecorp.armeria.client.endpoint.AbstractDynamicEndpointGroupBuilder; import com.linecorp.armeria.client.endpoint.EndpointSelectionStrategy; import com.linecorp.armeria.common.Flags; @@ -44,7 +43,7 @@ */ @UnstableApi public final class ConsulEndpointGroupBuilder - extends AbstractDynamicEndpointGroupBuilder implements ConsulConfigSetters { + extends AbstractDynamicEndpointGroupBuilder implements ConsulConfigSetters { private static final long DEFAULT_HEALTH_CHECK_INTERVAL_MILLIS = 10_000; @@ -146,29 +145,4 @@ public ConsulEndpointGroup build() { consulClientBuilder.build(), serviceName, registryFetchIntervalMillis, useHealthyEndpoints, datacenter, filter); } - - @Override - public ConsulEndpointGroupBuilder allowEmptyEndpoints(boolean allowEmptyEndpoints) { - return (ConsulEndpointGroupBuilder) super.allowEmptyEndpoints(allowEmptyEndpoints); - } - - /** - * Sets the timeout to wait until a successful {@link Endpoint} selection. - * {@link Duration#ZERO} disables the timeout. - * If unspecified, {@link Flags#defaultResponseTimeoutMillis()} is used by default. - */ - @Override - public ConsulEndpointGroupBuilder selectionTimeout(Duration selectionTimeout) { - return (ConsulEndpointGroupBuilder) super.selectionTimeout(selectionTimeout); - } - - /** - * Sets the timeout to wait until a successful {@link Endpoint} selection. - * {@code 0} disables the timeout. - * If unspecified, {@link Flags#defaultResponseTimeoutMillis()} is used by default. - */ - @Override - public ConsulEndpointGroupBuilder selectionTimeoutMillis(long selectionTimeoutMillis) { - return (ConsulEndpointGroupBuilder) super.selectionTimeoutMillis(selectionTimeoutMillis); - } } diff --git a/core/src/main/java/com/linecorp/armeria/client/AbstractDnsResolverBuilder.java b/core/src/main/java/com/linecorp/armeria/client/AbstractDnsResolverBuilder.java index 18b6987bdb5..9cfd568eb9f 100644 --- a/core/src/main/java/com/linecorp/armeria/client/AbstractDnsResolverBuilder.java +++ b/core/src/main/java/com/linecorp/armeria/client/AbstractDnsResolverBuilder.java @@ -56,7 +56,7 @@ * A skeletal builder implementation for DNS resolvers. */ @UnstableApi -public abstract class AbstractDnsResolverBuilder { +public abstract class AbstractDnsResolverBuilder> { private DnsCache dnsCache = DnsCache.ofDefault(); private String cacheSpec = Flags.dnsCacheSpec(); @@ -92,6 +92,14 @@ public abstract class AbstractDnsResolverBuilder { */ protected AbstractDnsResolverBuilder() {} + /** + * Return {@code this}. + */ + @SuppressWarnings("unchecked") + protected final SELF self() { + return (SELF) this; + } + /** * Sets if this resolver should generate detailed trace information in exception messages so that * it is easier to understand the cause of resolution failure. This flag is enabled by default. @@ -100,9 +108,9 @@ protected AbstractDnsResolverBuilder() {} * {@link LoggingDnsQueryLifeCycleObserverFactory}. */ @Deprecated - public AbstractDnsResolverBuilder traceEnabled(boolean traceEnabled) { + public SELF traceEnabled(boolean traceEnabled) { this.traceEnabled = traceEnabled; - return this; + return self(); } /** @@ -110,7 +118,7 @@ public AbstractDnsResolverBuilder traceEnabled(boolean traceEnabled) { * {@code 0} disables the timeout. * If unspecified, {@value DnsUtil#DEFAULT_DNS_QUERY_TIMEOUT_MILLIS} ms will be used. */ - public AbstractDnsResolverBuilder queryTimeout(Duration queryTimeout) { + public SELF queryTimeout(Duration queryTimeout) { requireNonNull(queryTimeout, "queryTimeout"); checkArgument(!queryTimeout.isNegative(), "queryTimeout: %s (expected: >= 0)", queryTimeout); return queryTimeoutMillis(queryTimeout.toMillis()); @@ -128,10 +136,10 @@ protected final long queryTimeoutMillis() { * {@code 0} disables the timeout. * If unspecified, {@value DnsUtil#DEFAULT_DNS_QUERY_TIMEOUT_MILLIS} ms will be used. */ - public AbstractDnsResolverBuilder queryTimeoutMillis(long queryTimeoutMillis) { + public SELF queryTimeoutMillis(long queryTimeoutMillis) { checkArgument(queryTimeoutMillis >= 0, "queryTimeoutMillis: %s (expected: >= 0)", queryTimeoutMillis); this.queryTimeoutMillis = queryTimeoutMillis; - return this; + return self(); } /** @@ -140,7 +148,7 @@ public AbstractDnsResolverBuilder queryTimeoutMillis(long queryTimeoutMillis) { * search domain resolution. * If unspecified, the value of {@link #queryTimeout(Duration)} is used. */ - public AbstractDnsResolverBuilder queryTimeoutForEachAttempt(Duration queryTimeoutForEachAttempt) { + public SELF queryTimeoutForEachAttempt(Duration queryTimeoutForEachAttempt) { requireNonNull(queryTimeoutForEachAttempt, "queryTimeoutForEachAttempt"); final long queryTimeoutMillisForEachAttempt = queryTimeoutForEachAttempt.toMillis(); checkArgument(queryTimeoutMillisForEachAttempt > 0, "queryTimeoutForEachAttempt: %s (expected: > 0)", @@ -154,20 +162,20 @@ public AbstractDnsResolverBuilder queryTimeoutForEachAttempt(Duration queryTimeo * search domain resolution. * If unspecified, the value of {@link #queryTimeoutMillis(long)} is used. */ - public AbstractDnsResolverBuilder queryTimeoutMillisForEachAttempt(long queryTimeoutMillisForEachAttempt) { + public SELF queryTimeoutMillisForEachAttempt(long queryTimeoutMillisForEachAttempt) { checkArgument(queryTimeoutMillisForEachAttempt > 0, "queryTimeoutMillisForEachAttempt: %s (expected: > 0)", queryTimeoutMillisForEachAttempt); this.queryTimeoutMillisForEachAttempt = queryTimeoutMillisForEachAttempt; - return this; + return self(); } /** * Sets if this resolver has to send a DNS query with the RD (recursion desired) flag set. * This flag is enabled by default. */ - public AbstractDnsResolverBuilder recursionDesired(boolean recursionDesired) { + public SELF recursionDesired(boolean recursionDesired) { this.recursionDesired = recursionDesired; - return this; + return self(); } /** @@ -179,24 +187,24 @@ public AbstractDnsResolverBuilder recursionDesired(boolean recursionDesired) { * * @see #serverAddressStreamProvider(DnsServerAddressStreamProvider) */ - public AbstractDnsResolverBuilder maxQueriesPerResolve(int maxQueriesPerResolve) { + public SELF maxQueriesPerResolve(int maxQueriesPerResolve) { checkArgument(maxQueriesPerResolve > 0, "maxQueriesPerResolve: %s (expected: > 0)", maxQueriesPerResolve); this.maxQueriesPerResolve = maxQueriesPerResolve; - return this; + return self(); } /** * Sets the DNS server addresses to send queries to. Operating system default is used by default. */ - public AbstractDnsResolverBuilder serverAddresses(InetSocketAddress... serverAddresses) { + public SELF serverAddresses(InetSocketAddress... serverAddresses) { return serverAddresses(ImmutableList.copyOf(requireNonNull(serverAddresses, "serverAddresses"))); } /** * Sets the DNS server addresses to send queries to. Operating system default is used by default. */ - public AbstractDnsResolverBuilder serverAddresses(Iterable serverAddresses) { + public SELF serverAddresses(Iterable serverAddresses) { final DnsServerAddresses addrs = DnsServerAddresses.sequential(serverAddresses); return serverAddressStreamProvider(hostname -> addrs.stream()); } @@ -212,11 +220,11 @@ protected final DnsServerAddressStreamProvider serverAddressStreamProvider() { * Sets the {@link DnsServerAddressStreamProvider} which is used to determine which DNS server is used to * resolve each hostname. */ - public AbstractDnsResolverBuilder serverAddressStreamProvider( + public SELF serverAddressStreamProvider( DnsServerAddressStreamProvider serverAddressStreamProvider) { requireNonNull(serverAddressStreamProvider, "serverAddressStreamProvider"); this.serverAddressStreamProvider = serverAddressStreamProvider; - return this; + return self(); } /** @@ -226,7 +234,7 @@ public AbstractDnsResolverBuilder serverAddressStreamProvider( * @deprecated Use {@link #serverAddressStreamProvider(DnsServerAddressStreamProvider)} instead. */ @Deprecated - public AbstractDnsResolverBuilder dnsServerAddressStreamProvider( + public SELF dnsServerAddressStreamProvider( DnsServerAddressStreamProvider dnsServerAddressStreamProvider) { return serverAddressStreamProvider(dnsServerAddressStreamProvider); } @@ -234,10 +242,10 @@ public AbstractDnsResolverBuilder dnsServerAddressStreamProvider( /** * Sets the capacity of the datagram packet buffer in bytes. */ - public AbstractDnsResolverBuilder maxPayloadSize(int maxPayloadSize) { + public SELF maxPayloadSize(int maxPayloadSize) { checkArgument(maxPayloadSize > 0, "maxPayloadSize: %s (expected: > 0)", maxPayloadSize); this.maxPayloadSize = maxPayloadSize; - return this; + return self(); } /** @@ -245,9 +253,9 @@ public AbstractDnsResolverBuilder maxPayloadSize(int maxPayloadSize) { * about how much data the resolver can read per response. Some DNS Server may not support this and so * fail to answer queries. */ - public AbstractDnsResolverBuilder optResourceEnabled(boolean optResourceEnabled) { + public SELF optResourceEnabled(boolean optResourceEnabled) { this.optResourceEnabled = optResourceEnabled; - return this; + return self(); } /** @@ -261,21 +269,21 @@ protected final HostsFileEntriesResolver hostsFileEntriesResolver() { * Sets the {@link HostsFileEntriesResolver} which is used to first check if the hostname is locally * aliased. */ - public AbstractDnsResolverBuilder hostsFileEntriesResolver( + public SELF hostsFileEntriesResolver( HostsFileEntriesResolver hostsFileEntriesResolver) { this.hostsFileEntriesResolver = hostsFileEntriesResolver; - return this; + return self(); } /** * Sets the {@link DnsQueryLifecycleObserverFactory} that is used to generate objects which can observe * individual DNS queries. */ - public AbstractDnsResolverBuilder dnsQueryLifecycleObserverFactory( + public SELF dnsQueryLifecycleObserverFactory( DnsQueryLifecycleObserverFactory observerFactory) { requireNonNull(observerFactory, "observerFactory"); dnsQueryLifecycleObserverFactory = observerFactory; - return this; + return self(); } /** @@ -285,7 +293,7 @@ public AbstractDnsResolverBuilder dnsQueryLifecycleObserverFactory( * @deprecated Use {@link #enableDnsQueryMetrics(boolean)} instead. */ @Deprecated - public AbstractDnsResolverBuilder disableDnsQueryMetrics() { + public SELF disableDnsQueryMetrics() { return enableDnsQueryMetrics(false); } @@ -293,9 +301,9 @@ public AbstractDnsResolverBuilder disableDnsQueryMetrics() { * Enables the default {@link DnsQueryLifecycleObserverFactory} that collects DNS query * metrics through {@link MeterRegistry}. This option is enabled by default. */ - public AbstractDnsResolverBuilder enableDnsQueryMetrics(boolean enable) { + public SELF enableDnsQueryMetrics(boolean enable) { dnsQueryMetricsEnabled = enable; - return this; + return self(); } /** @@ -308,7 +316,7 @@ protected final List searchDomains() { /** * Sets the search domains of the resolver. */ - public AbstractDnsResolverBuilder searchDomains(String... searchDomains) { + public SELF searchDomains(String... searchDomains) { requireNonNull(searchDomains, "searchDomains"); return searchDomains(ImmutableList.copyOf(searchDomains)); } @@ -316,10 +324,10 @@ public AbstractDnsResolverBuilder searchDomains(String... searchDomains) { /** * Sets the list of search domains of the resolver. */ - public AbstractDnsResolverBuilder searchDomains(Iterable searchDomains) { + public SELF searchDomains(Iterable searchDomains) { requireNonNull(searchDomains, "searchDomains"); this.searchDomains = ImmutableList.copyOf(searchDomains); - return this; + return self(); } /** @@ -332,19 +340,19 @@ protected final int ndots() { /** * Sets the number of dots which must appear in a name before an initial absolute query is made. */ - public AbstractDnsResolverBuilder ndots(int ndots) { + public SELF ndots(int ndots) { checkArgument(ndots >= 0, "ndots: %s (expected: >= 0)", ndots); this.ndots = ndots; - return this; + return self(); } /** * Sets if the domain and host names should be decoded to unicode when received. * See rfc3492. This flag is enabled by default. */ - public AbstractDnsResolverBuilder decodeIdn(boolean decodeIdn) { + public SELF decodeIdn(boolean decodeIdn) { this.decodeIdn = decodeIdn; - return this; + return self(); } /** @@ -358,9 +366,9 @@ protected final MeterRegistry meterRegistry() { /** * Sets {@link MeterRegistry} to collect the DNS query metrics. */ - public AbstractDnsResolverBuilder meterRegistry(MeterRegistry meterRegistry) { + public SELF meterRegistry(MeterRegistry meterRegistry) { this.meterRegistry = meterRegistry; - return this; + return self(); } /** @@ -376,11 +384,11 @@ protected final String cacheSpec() { * *

Note that {@link #cacheSpec(String)} and {@link #dnsCache(DnsCache)} are mutually exclusive. */ - public AbstractDnsResolverBuilder cacheSpec(String cacheSpec) { + public SELF cacheSpec(String cacheSpec) { requireNonNull(cacheSpec, "cacheSpec"); this.cacheSpec = cacheSpec; needsToCreateDnsCache = true; - return this; + return self(); } /** @@ -407,13 +415,13 @@ protected final int maxTtl() { * *

Note that {@link #ttl(int, int)} and {@link #dnsCache(DnsCache)} are mutually exclusive. */ - public AbstractDnsResolverBuilder ttl(int minTtl, int maxTtl) { + public SELF ttl(int minTtl, int maxTtl) { checkArgument(minTtl > 0 && minTtl <= maxTtl, "minTtl: %s, maxTtl: %s (expected: 1 <= minTtl <= maxTtl)", minTtl, maxTtl); this.minTtl = minTtl; this.maxTtl = maxTtl; needsToCreateDnsCache = true; - return this; + return self(); } /** @@ -429,11 +437,11 @@ protected final int negativeTtl() { * *

Note that {@link #negativeTtl(int)} and {@link #dnsCache(DnsCache)} are mutually exclusive. */ - public AbstractDnsResolverBuilder negativeTtl(int negativeTtl) { + public SELF negativeTtl(int negativeTtl) { checkArgument(negativeTtl >= 0, "negativeTtl: %s (expected: >= 0)", negativeTtl); needsToCreateDnsCache = true; this.negativeTtl = negativeTtl; - return this; + return self(); } /** @@ -447,10 +455,10 @@ public AbstractDnsResolverBuilder negativeTtl(int negativeTtl) { * mutually exclusive with {@link #dnsCache(DnsCache)}. */ @UnstableApi - public AbstractDnsResolverBuilder dnsCache(DnsCache dnsCache) { + public SELF dnsCache(DnsCache dnsCache) { requireNonNull(dnsCache, "dnsCache"); this.dnsCache = dnsCache; - return this; + return self(); } /** diff --git a/core/src/main/java/com/linecorp/armeria/client/AbstractRuleBuilder.java b/core/src/main/java/com/linecorp/armeria/client/AbstractRuleBuilder.java index 2266f09de7d..2b9a5d44982 100644 --- a/core/src/main/java/com/linecorp/armeria/client/AbstractRuleBuilder.java +++ b/core/src/main/java/com/linecorp/armeria/client/AbstractRuleBuilder.java @@ -28,6 +28,7 @@ import com.google.common.collect.Iterables; import com.google.common.collect.Sets; +import com.linecorp.armeria.client.circuitbreaker.CircuitBreaker; import com.linecorp.armeria.client.circuitbreaker.CircuitBreakerRule; import com.linecorp.armeria.client.circuitbreaker.CircuitBreakerRuleWithContent; import com.linecorp.armeria.client.retry.RetryRule; @@ -36,6 +37,7 @@ import com.linecorp.armeria.common.HttpStatus; import com.linecorp.armeria.common.HttpStatusClass; import com.linecorp.armeria.common.RequestHeaders; +import com.linecorp.armeria.common.Response; import com.linecorp.armeria.common.ResponseHeaders; import com.linecorp.armeria.common.TimeoutException; import com.linecorp.armeria.common.annotation.Nullable; @@ -46,7 +48,7 @@ * {@link CircuitBreakerRule} and {@link CircuitBreakerRuleWithContent}. */ @UnstableApi -public abstract class AbstractRuleBuilder { +public abstract class AbstractRuleBuilder> { private final BiPredicate requestHeadersFilter; @@ -70,119 +72,187 @@ protected AbstractRuleBuilder( this.requestHeadersFilter = (BiPredicate) requestHeadersFilter; } + @SuppressWarnings("unchecked") + final SELF self() { + return (SELF) this; + } + /** * Adds the specified {@code responseHeadersFilter}. + * + *

When this is used for a {@link CircuitBreakerRule}, and the specified {@code responseHeadersFilter} + * returns {@code true}, a {@link Response} is reported as a success or failure to a + * {@link CircuitBreaker} or ignored depending on the build methods({@code #thenSuccess()}, + * {@code #thenFailure()} and {@code #thenIgnore()}). */ - public AbstractRuleBuilder onResponseHeaders( + public SELF onResponseHeaders( BiPredicate responseHeadersFilter) { this.responseHeadersFilter = combinePredicates(this.responseHeadersFilter, responseHeadersFilter, "responseHeadersFilter"); - return this; + return self(); } /** - * Adds the specified {@code responseTrailersFilter}. + * Adds the specified {@code responseTrailersFilter}. Note that using this method makes the entire + * response buffered, which may lead to excessive memory usage. + * + *

When this is used for a {@link CircuitBreakerRule}, and the specified {@code responseTrailersFilter} + * returns {@code true}, a {@link Response} is reported as a success or failure to a + * {@link CircuitBreaker} or ignored depending on the build methods({@code #thenSuccess()}, + * {@code #thenFailure()} and {@code #thenIgnore()}). */ - public AbstractRuleBuilder onResponseTrailers( + public SELF onResponseTrailers( BiPredicate responseTrailersFilter) { this.responseTrailersFilter = combinePredicates(this.responseTrailersFilter, responseTrailersFilter, "responseTrailersFilter"); - return this; + return self(); } /** - * Adds the specified {@code grpcTrailersFilter}. + * Adds the specified {@code grpcTrailersFilter}. Note that using this method makes the entire + * response buffered, which may lead to excessive memory usage. + * + *

When this is used for a {@link CircuitBreakerRule}, and the specified {@code grpcTrailersFilter} + * returns {@code true}, a {@link Response} is reported as a success or failure to a + * {@link CircuitBreaker} or ignored depending on the build methods({@code #thenSuccess()}, + * {@code #thenFailure()} and {@code #thenIgnore()}). */ - public AbstractRuleBuilder onGrpcTrailers( + public SELF onGrpcTrailers( BiPredicate grpcTrailersFilter) { this.grpcTrailersFilter = combinePredicates(this.grpcTrailersFilter, grpcTrailersFilter, "grpcTrailersFilter"); - return this; + return self(); } /** * Adds the specified {@link HttpStatusClass}es. + * + *

When this is used for a {@link CircuitBreakerRule}, and the response status is one of the specified + * {@link HttpStatusClass}es, a {@link Response} is reported as a success or failure to a + * {@link CircuitBreaker} or ignored depending on the build methods({@code #thenSuccess()}, + * {@code #thenFailure()} and {@code #thenIgnore()}). */ - public AbstractRuleBuilder onStatusClass(HttpStatusClass... statusClasses) { + public SELF onStatusClass(HttpStatusClass... statusClasses) { return onStatusClass(ImmutableSet.copyOf(requireNonNull(statusClasses, "statusClasses"))); } /** * Adds the specified {@link HttpStatusClass}es. + * + *

When this is used for a {@link CircuitBreakerRule}, and the response status is one of the specified + * {@link HttpStatusClass}es, a {@link Response} is reported as a success or failure to a + * {@link CircuitBreaker} or ignored depending on the build methods({@code #thenSuccess()}, + * {@code #thenFailure()} and {@code #thenIgnore()}). */ - public AbstractRuleBuilder onStatusClass(Iterable statusClasses) { + public SELF onStatusClass(Iterable statusClasses) { requireNonNull(statusClasses, "statusClasses"); checkArgument(!Iterables.isEmpty(statusClasses), "statusClasses can't be empty."); final Set statusClasses0 = Sets.immutableEnumSet(statusClasses); onResponseHeaders((ctx, headers) -> statusClasses0.contains(headers.status().codeClass())); - return this; + return self(); } /** * Adds the {@link HttpStatusClass#SERVER_ERROR}. + * + *

When this is used for a {@link CircuitBreakerRule}, and the response status is + * {@link HttpStatusClass#SERVER_ERROR}, a {@link Response} is reported as a success or failure to a + * {@link CircuitBreaker} or ignored depending on the build methods({@code #thenSuccess()}, + * {@code #thenFailure()} and {@code #thenIgnore()}). */ - public AbstractRuleBuilder onServerErrorStatus() { + public SELF onServerErrorStatus() { return onStatusClass(HttpStatusClass.SERVER_ERROR); } /** * Adds the specified {@link HttpStatus}es. + * + *

When this is used for a {@link CircuitBreakerRule}, and the response status is one of the specified + * {@link HttpStatus}es, a {@link Response} is reported as a success or failure to a + * {@link CircuitBreaker} or ignored depending on the build methods({@code #thenSuccess()}, + * {@code #thenFailure()} and {@code #thenIgnore()}). */ - public AbstractRuleBuilder onStatus(HttpStatus... statuses) { + public SELF onStatus(HttpStatus... statuses) { return onStatus(ImmutableSet.copyOf(requireNonNull(statuses, "statuses"))); } /** * Adds the specified {@link HttpStatus}es. + * + *

When this is used for a {@link CircuitBreakerRule}, and the response status is one of the specified + * {@link HttpStatus}es, a {@link Response} is reported as a success or failure to a + * {@link CircuitBreaker} or ignored depending on the build methods({@code #thenSuccess()}, + * {@code #thenFailure()} and {@code #thenIgnore()}). */ - public AbstractRuleBuilder onStatus(Iterable statuses) { + public SELF onStatus(Iterable statuses) { requireNonNull(statuses, "statuses"); checkArgument(!Iterables.isEmpty(statuses), "statuses can't be empty."); final Set statuses0 = ImmutableSet.copyOf(statuses); onResponseHeaders((ctx, headers) -> statuses0.contains(headers.status())); - return this; + return self(); } /** * Adds the specified {@code statusFilter}. + * + *

When this is used for a {@link CircuitBreakerRule}, and the response status matches the specified + * {@code statusFilter}, a {@link Response} is reported as a success or failure to a + * {@link CircuitBreaker} or ignored depending on the build methods({@code #thenSuccess()}, + * {@code #thenFailure()} and {@code #thenIgnore()}). */ - public AbstractRuleBuilder onStatus( - BiPredicate statusFilter) { + public SELF onStatus(BiPredicate statusFilter) { requireNonNull(statusFilter, "statusFilter"); onResponseHeaders((ctx, headers) -> statusFilter.test(ctx, headers.status())); - return this; + return self(); } /** * Adds the specified exception type. + * + *

When this is used for a {@link CircuitBreakerRule}, and the raised exception is an instance of the + * specified {@code exception}, a {@link Response} is reported as a success or failure to a + * {@link CircuitBreaker} or ignored depending on the build methods({@code #thenSuccess()}, + * {@code #thenFailure()} and {@code #thenIgnore()}). */ - public AbstractRuleBuilder onException(Class exception) { + public SELF onException(Class exception) { requireNonNull(exception, "exception"); return onException((unused, ex) -> exception.isInstance(ex)); } /** * Adds the specified {@code exceptionFilter}. + * + *

When this is used for a {@link CircuitBreakerRule}, and the specified {@code exceptionFilter} returns + * {@code true} for the raised exception, a {@link Response} is reported as a success or failure to a + * {@link CircuitBreaker} or ignored depending on the build methods({@code #thenSuccess()}, + * {@code #thenFailure()} and {@code #thenIgnore()}). */ - public AbstractRuleBuilder onException( - BiPredicate exceptionFilter) { + public SELF onException(BiPredicate exceptionFilter) { this.exceptionFilter = combinePredicates(this.exceptionFilter, exceptionFilter, "exceptionFilter"); - return this; + return self(); } /** * Adds any {@link Exception}. + * + *

When this is used for a {@link CircuitBreakerRule}, a {@link Response} is reported as a success or + * failure to a {@link CircuitBreaker} or ignored depending on the build methods({@code #thenSuccess()}, + * {@code #thenFailure()} and {@code #thenIgnore()}). */ - public AbstractRuleBuilder onException() { + public SELF onException() { return onException((unused1, unused2) -> true); } /** * Adds {@link TimeoutException}. + * + *

When this is used for a {@link CircuitBreakerRule}, a {@link Response} is reported as a success or + * failure to a {@link CircuitBreaker} or ignored depending on the build methods({@code #thenSuccess()}, + * {@code #thenFailure()} and {@code #thenIgnore()}). */ - public AbstractRuleBuilder onTimeoutException() { + public SELF onTimeoutException() { return onException((ctx, ex) -> { if (ctx.isTimedOut()) { return true; @@ -210,19 +280,28 @@ private static BiPredicate combinePredicates( /** * Adds an {@link UnprocessedRequestException}. + * + *

When this is used for a {@link CircuitBreakerRule}, a {@link Response} is reported as a success or + * failure to a {@link CircuitBreaker} or ignored depending on the build methods({@code #thenSuccess()}, + * {@code #thenFailure()} and {@code #thenIgnore()}). */ - public AbstractRuleBuilder onUnprocessed() { + public SELF onUnprocessed() { return onException(UnprocessedRequestException.class); } /** * Adds the specified {@code totalDurationFilter}. + * + *

When this is used for a {@link CircuitBreakerRule}, and the specified {@code totalDurationFilter} + * returns {@code true}, a {@link Response} is reported as a success or + * failure to a {@link CircuitBreaker} or ignored depending on the build methods({@code #thenSuccess()}, + * {@code #thenFailure()} and {@code #thenIgnore()}). */ - public AbstractRuleBuilder onTotalDuration( + public SELF onTotalDuration( BiPredicate totalDurationFilter) { this.totalDurationFilter = combinePredicates(this.totalDurationFilter, totalDurationFilter, "totalDurationFilter"); - return this; + return self(); } /** diff --git a/core/src/main/java/com/linecorp/armeria/client/AbstractRuleWithContentBuilder.java b/core/src/main/java/com/linecorp/armeria/client/AbstractRuleWithContentBuilder.java index 7f07975f046..81ff0d24341 100644 --- a/core/src/main/java/com/linecorp/armeria/client/AbstractRuleWithContentBuilder.java +++ b/core/src/main/java/com/linecorp/armeria/client/AbstractRuleWithContentBuilder.java @@ -36,7 +36,9 @@ * @param the response type */ @UnstableApi -public abstract class AbstractRuleWithContentBuilder extends AbstractRuleBuilder { +public abstract class AbstractRuleWithContentBuilder + , T extends Response> + extends AbstractRuleBuilder { @Nullable private BiFunction> @@ -54,7 +56,7 @@ protected AbstractRuleWithContentBuilder( * Adds the specified {@code responseFilter}. */ @SuppressWarnings("unchecked") - public AbstractRuleWithContentBuilder onResponse( + public SELF onResponse( BiFunction> responseFilter) { requireNonNull(responseFilter, "responseFilter"); @@ -88,7 +90,7 @@ public AbstractRuleWithContentBuilder onResponse( } }; } - return this; + return self(); } /** diff --git a/core/src/main/java/com/linecorp/armeria/client/DnsResolverGroupBuilder.java b/core/src/main/java/com/linecorp/armeria/client/DnsResolverGroupBuilder.java index ac5c45a37cb..eb90ff00c94 100644 --- a/core/src/main/java/com/linecorp/armeria/client/DnsResolverGroupBuilder.java +++ b/core/src/main/java/com/linecorp/armeria/client/DnsResolverGroupBuilder.java @@ -19,7 +19,6 @@ import static com.google.common.base.Preconditions.checkArgument; import static java.util.Objects.requireNonNull; -import java.net.InetSocketAddress; import java.time.Duration; import java.util.function.ToLongFunction; @@ -33,12 +32,9 @@ import io.netty.handler.codec.dns.DnsRecord; import io.netty.resolver.AddressResolver; import io.netty.resolver.AddressResolverGroup; -import io.netty.resolver.HostsFileEntriesResolver; import io.netty.resolver.ResolvedAddressTypes; import io.netty.resolver.dns.DnsNameResolver; import io.netty.resolver.dns.DnsNameResolverBuilder; -import io.netty.resolver.dns.DnsQueryLifecycleObserverFactory; -import io.netty.resolver.dns.DnsServerAddressStreamProvider; /** * Builds an {@link AddressResolverGroup} which builds {@link AddressResolver}s that update DNS caches @@ -48,7 +44,7 @@ * meaning DNS queries after TTL will retrieve a refreshed result right away. If refreshing fails, * the {@link AddressResolver} will retry with {@link #autoRefreshBackoff(Backoff)}. */ -public final class DnsResolverGroupBuilder extends AbstractDnsResolverBuilder { +public final class DnsResolverGroupBuilder extends AbstractDnsResolverBuilder { static final ToLongFunction DEFAULT_AUTO_REFRESH_TIMEOUT_FUNCTION = hostname -> Long.MAX_VALUE; @@ -204,143 +200,4 @@ RefreshingAddressResolverGroup build(EventLoopGroup eventLoopGroup) { hostsFileEntriesResolver(), buildConfigurator(eventLoopGroup)); } - - // Override the return type of the chaining methods in the super class. - - @Override - public DnsResolverGroupBuilder traceEnabled(boolean traceEnabled) { - return (DnsResolverGroupBuilder) super.traceEnabled(traceEnabled); - } - - @Override - public DnsResolverGroupBuilder queryTimeout(Duration queryTimeout) { - return (DnsResolverGroupBuilder) super.queryTimeout(queryTimeout); - } - - @Override - public DnsResolverGroupBuilder queryTimeoutMillis(long queryTimeoutMillis) { - return (DnsResolverGroupBuilder) super.queryTimeoutMillis(queryTimeoutMillis); - } - - @Override - public DnsResolverGroupBuilder queryTimeoutForEachAttempt(Duration queryTimeoutForEachAttempt) { - return (DnsResolverGroupBuilder) super.queryTimeoutForEachAttempt(queryTimeoutForEachAttempt); - } - - @Override - public DnsResolverGroupBuilder queryTimeoutMillisForEachAttempt(long queryTimeoutMillisForEachAttempt) { - return (DnsResolverGroupBuilder) super.queryTimeoutMillisForEachAttempt( - queryTimeoutMillisForEachAttempt); - } - - @Override - public DnsResolverGroupBuilder recursionDesired(boolean recursionDesired) { - return (DnsResolverGroupBuilder) super.recursionDesired(recursionDesired); - } - - @Override - public DnsResolverGroupBuilder maxQueriesPerResolve(int maxQueriesPerResolve) { - return (DnsResolverGroupBuilder) super.maxQueriesPerResolve(maxQueriesPerResolve); - } - - @Override - public DnsResolverGroupBuilder serverAddresses(InetSocketAddress... serverAddresses) { - return (DnsResolverGroupBuilder) super.serverAddresses(serverAddresses); - } - - @Override - public DnsResolverGroupBuilder serverAddresses(Iterable serverAddresses) { - return (DnsResolverGroupBuilder) super.serverAddresses(serverAddresses); - } - - @Override - public DnsResolverGroupBuilder serverAddressStreamProvider( - DnsServerAddressStreamProvider serverAddressStreamProvider) { - return (DnsResolverGroupBuilder) super.serverAddressStreamProvider(serverAddressStreamProvider); - } - - @Deprecated - @Override - public DnsResolverGroupBuilder dnsServerAddressStreamProvider( - DnsServerAddressStreamProvider dnsServerAddressStreamProvider) { - return (DnsResolverGroupBuilder) super.dnsServerAddressStreamProvider(dnsServerAddressStreamProvider); - } - - @Override - public DnsResolverGroupBuilder maxPayloadSize(int maxPayloadSize) { - return (DnsResolverGroupBuilder) super.maxPayloadSize(maxPayloadSize); - } - - @Override - public DnsResolverGroupBuilder optResourceEnabled(boolean optResourceEnabled) { - return (DnsResolverGroupBuilder) super.optResourceEnabled(optResourceEnabled); - } - - @Override - public DnsResolverGroupBuilder hostsFileEntriesResolver( - HostsFileEntriesResolver hostsFileEntriesResolver) { - return (DnsResolverGroupBuilder) super.hostsFileEntriesResolver(hostsFileEntriesResolver); - } - - @Override - public DnsResolverGroupBuilder dnsQueryLifecycleObserverFactory( - DnsQueryLifecycleObserverFactory observerFactory) { - return (DnsResolverGroupBuilder) super.dnsQueryLifecycleObserverFactory(observerFactory); - } - - @Deprecated - @Override - public DnsResolverGroupBuilder disableDnsQueryMetrics() { - return (DnsResolverGroupBuilder) super.disableDnsQueryMetrics(); - } - - @Override - public DnsResolverGroupBuilder searchDomains(String... searchDomains) { - return (DnsResolverGroupBuilder) super.searchDomains(searchDomains); - } - - @Override - public DnsResolverGroupBuilder searchDomains(Iterable searchDomains) { - return (DnsResolverGroupBuilder) super.searchDomains(searchDomains); - } - - @Override - public DnsResolverGroupBuilder ndots(int ndots) { - return (DnsResolverGroupBuilder) super.ndots(ndots); - } - - @Override - public DnsResolverGroupBuilder decodeIdn(boolean decodeIdn) { - return (DnsResolverGroupBuilder) super.decodeIdn(decodeIdn); - } - - @Override - public DnsResolverGroupBuilder meterRegistry(MeterRegistry meterRegistry) { - return (DnsResolverGroupBuilder) super.meterRegistry(meterRegistry); - } - - @Override - public DnsResolverGroupBuilder cacheSpec(String cacheSpec) { - return (DnsResolverGroupBuilder) super.cacheSpec(cacheSpec); - } - - @Override - public DnsResolverGroupBuilder ttl(int minTtl, int maxTtl) { - return (DnsResolverGroupBuilder) super.ttl(minTtl, maxTtl); - } - - @Override - public DnsResolverGroupBuilder negativeTtl(int negativeTtl) { - return (DnsResolverGroupBuilder) super.negativeTtl(negativeTtl); - } - - @Override - public DnsResolverGroupBuilder dnsCache(DnsCache dnsCache) { - return (DnsResolverGroupBuilder) super.dnsCache(dnsCache); - } - - @Override - public DnsResolverGroupBuilder enableDnsQueryMetrics(boolean enable) { - return (DnsResolverGroupBuilder) super.enableDnsQueryMetrics(enable); - } } diff --git a/core/src/main/java/com/linecorp/armeria/client/circuitbreaker/AbstractCircuitBreakerMappingBuilder.java b/core/src/main/java/com/linecorp/armeria/client/circuitbreaker/AbstractCircuitBreakerMappingBuilder.java index 729170e5cde..1ed6215c369 100644 --- a/core/src/main/java/com/linecorp/armeria/client/circuitbreaker/AbstractCircuitBreakerMappingBuilder.java +++ b/core/src/main/java/com/linecorp/armeria/client/circuitbreaker/AbstractCircuitBreakerMappingBuilder.java @@ -23,7 +23,8 @@ * based on a combination of host, method and path. */ @UnstableApi -public abstract class AbstractCircuitBreakerMappingBuilder { +public abstract class AbstractCircuitBreakerMappingBuilder + > { private boolean perHost; private boolean perMethod; @@ -34,28 +35,36 @@ public abstract class AbstractCircuitBreakerMappingBuilder { */ protected AbstractCircuitBreakerMappingBuilder() {} + /** + * Return {@code this}. + */ + @SuppressWarnings("unchecked") + protected final SELF self() { + return (SELF) this; + } + /** * Adds host dimension to the mapping Key. */ - public AbstractCircuitBreakerMappingBuilder perHost() { + public SELF perHost() { perHost = true; - return this; + return self(); } /** * Adds method dimension to the mapping Key. */ - public AbstractCircuitBreakerMappingBuilder perMethod() { + public SELF perMethod() { perMethod = true; - return this; + return self(); } /** * Adds path dimension to the mapping Key. */ - public AbstractCircuitBreakerMappingBuilder perPath() { + public SELF perPath() { perPath = true; - return this; + return self(); } /** diff --git a/core/src/main/java/com/linecorp/armeria/client/circuitbreaker/CircuitBreakerMappingBuilder.java b/core/src/main/java/com/linecorp/armeria/client/circuitbreaker/CircuitBreakerMappingBuilder.java index 2c98a7c6ae2..d822198a645 100644 --- a/core/src/main/java/com/linecorp/armeria/client/circuitbreaker/CircuitBreakerMappingBuilder.java +++ b/core/src/main/java/com/linecorp/armeria/client/circuitbreaker/CircuitBreakerMappingBuilder.java @@ -19,22 +19,8 @@ /** * Builder class for building a {@link CircuitBreakerMapping} based on a combination of host, method and path. */ -public final class CircuitBreakerMappingBuilder extends AbstractCircuitBreakerMappingBuilder { - - @Override - public CircuitBreakerMappingBuilder perHost() { - return (CircuitBreakerMappingBuilder) super.perHost(); - } - - @Override - public CircuitBreakerMappingBuilder perMethod() { - return (CircuitBreakerMappingBuilder) super.perMethod(); - } - - @Override - public CircuitBreakerMappingBuilder perPath() { - return (CircuitBreakerMappingBuilder) super.perPath(); - } +public final class CircuitBreakerMappingBuilder + extends AbstractCircuitBreakerMappingBuilder { /** * Returns a newly-created {@link CircuitBreakerMapping} with the specified {@link CircuitBreakerFactory} diff --git a/core/src/main/java/com/linecorp/armeria/client/circuitbreaker/CircuitBreakerRuleBuilder.java b/core/src/main/java/com/linecorp/armeria/client/circuitbreaker/CircuitBreakerRuleBuilder.java index 01924b548f8..56a32de7ee3 100644 --- a/core/src/main/java/com/linecorp/armeria/client/circuitbreaker/CircuitBreakerRuleBuilder.java +++ b/core/src/main/java/com/linecorp/armeria/client/circuitbreaker/CircuitBreakerRuleBuilder.java @@ -21,7 +21,6 @@ import static com.linecorp.armeria.client.circuitbreaker.CircuitBreakerRuleUtil.NEXT_DECISION; import static com.linecorp.armeria.client.circuitbreaker.CircuitBreakerRuleUtil.SUCCESS_DECISION; -import java.time.Duration; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; import java.util.function.BiFunction; @@ -29,21 +28,15 @@ import com.linecorp.armeria.client.AbstractRuleBuilder; import com.linecorp.armeria.client.ClientRequestContext; -import com.linecorp.armeria.client.UnprocessedRequestException; -import com.linecorp.armeria.common.HttpHeaders; -import com.linecorp.armeria.common.HttpStatus; -import com.linecorp.armeria.common.HttpStatusClass; import com.linecorp.armeria.common.RequestHeaders; import com.linecorp.armeria.common.Response; -import com.linecorp.armeria.common.ResponseHeaders; -import com.linecorp.armeria.common.TimeoutException; import com.linecorp.armeria.common.annotation.Nullable; import com.linecorp.armeria.internal.client.AbstractRuleBuilderUtil; /** * A builder for creating a new {@link CircuitBreakerRule}. */ -public final class CircuitBreakerRuleBuilder extends AbstractRuleBuilder { +public final class CircuitBreakerRuleBuilder extends AbstractRuleBuilder { CircuitBreakerRuleBuilder( BiPredicate requestHeadersFilter) { @@ -108,174 +101,4 @@ public boolean requiresResponseTrailers() { } }; } - - // Override the return type and Javadoc of chaining methods in superclass. - /** - * Adds the specified {@code responseHeadersFilter} for a {@link CircuitBreakerRule}. - * If the specified {@code responseHeadersFilter} returns {@code true}, - * depending on the build methods({@link #thenSuccess()}, {@link #thenFailure()} and {@link #thenIgnore()}), - * a {@link Response} is reported as a success or failure to a {@link CircuitBreaker} or ignored. - */ - @Override - public CircuitBreakerRuleBuilder onResponseHeaders( - BiPredicate responseHeadersFilter) { - return (CircuitBreakerRuleBuilder) super.onResponseHeaders(responseHeadersFilter); - } - - /** - * Adds the specified {@code responseTrailersFilter} for a {@link CircuitBreakerRule}. - * If the specified {@code responseTrailersFilter} returns {@code true}, - * depending on the build methods({@link #thenSuccess()}, {@link #thenFailure()} and {@link #thenIgnore()}), - * a {@link Response} is reported as a success or failure to a {@link CircuitBreaker} or ignored. - */ - @Override - public CircuitBreakerRuleBuilder onResponseTrailers( - BiPredicate responseTrailersFilter) { - return (CircuitBreakerRuleBuilder) super.onResponseTrailers(responseTrailersFilter); - } - - /** - * Adds the specified {@code grpcTrailersFilter} for a {@link CircuitBreakerRule}. - * If the specified {@code grpcTrailersFilter} returns {@code true}, - * depending on the build methods({@link #thenSuccess()}, {@link #thenFailure()} and {@link #thenIgnore()}), - * a {@link Response} is reported as a success or failure to a {@link CircuitBreaker} or ignored. - */ - @Override - public CircuitBreakerRuleBuilder onGrpcTrailers( - BiPredicate grpcTrailersFilter) { - return (CircuitBreakerRuleBuilder) super.onGrpcTrailers(grpcTrailersFilter); - } - - /** - * Adds the specified {@link HttpStatusClass}es for a {@link CircuitBreakerRule}. - * If the class of the response status is one of the specified {@link HttpStatusClass}es, - * depending on the build methods({@link #thenSuccess()}, {@link #thenFailure()} and {@link #thenIgnore()}), - * a {@link Response} is reported as a success or failure to a {@link CircuitBreaker} or ignored. - */ - @Override - public CircuitBreakerRuleBuilder onStatusClass(HttpStatusClass... statusClasses) { - return (CircuitBreakerRuleBuilder) super.onStatusClass(statusClasses); - } - - /** - * Adds the specified {@link HttpStatusClass}es for a {@link CircuitBreakerRule}. - * If the class of the response status is one of the specified {@link HttpStatusClass}es, - * depending on the build methods({@link #thenSuccess()}, {@link #thenFailure()} and {@link #thenIgnore()}), - * a {@link Response} is reported as a success or failure to a {@link CircuitBreaker} or ignored. - */ - @Override - public CircuitBreakerRuleBuilder onStatusClass(Iterable statusClasses) { - return (CircuitBreakerRuleBuilder) super.onStatusClass(statusClasses); - } - - /** - * Adds the {@link HttpStatusClass#SERVER_ERROR} for a {@link CircuitBreakerRule}. - * If the class of the response status is {@link HttpStatusClass#SERVER_ERROR}, - * depending on the build methods({@link #thenSuccess()}, {@link #thenFailure()} and {@link #thenIgnore()}), - * a {@link Response} is reported as a success or failure to a {@link CircuitBreaker} or ignored. - */ - @Override - public CircuitBreakerRuleBuilder onServerErrorStatus() { - return (CircuitBreakerRuleBuilder) super.onServerErrorStatus(); - } - - /** - * Adds the specified {@link HttpStatus}es for a {@link CircuitBreakerRule}. - * If the response status is one of the specified {@link HttpStatus}es, - * depending on the build methods({@link #thenSuccess()}, {@link #thenFailure()} and {@link #thenIgnore()}), - * a {@link Response} is reported as a success or failure to a {@link CircuitBreaker} or ignored. - */ - @Override - public CircuitBreakerRuleBuilder onStatus(HttpStatus... statuses) { - return (CircuitBreakerRuleBuilder) super.onStatus(statuses); - } - - /** - * Adds the specified {@link HttpStatus}es for a {@link CircuitBreakerRule}. - * If the response status is one of the specified {@link HttpStatus}es, - * depending on the build methods({@link #thenSuccess()}, {@link #thenFailure()} and {@link #thenIgnore()}), - * a {@link Response} is reported as a success or failure to a {@link CircuitBreaker} or ignored. - */ - @Override - public CircuitBreakerRuleBuilder onStatus(Iterable statuses) { - return (CircuitBreakerRuleBuilder) super.onStatus(statuses); - } - - /** - * Adds the specified {@code statusFilter} for a {@link CircuitBreakerRule}. - * If the response status matches the specified {@code statusFilter}, - * depending on the build methods({@link #thenSuccess()}, {@link #thenFailure()} and {@link #thenIgnore()}), - * a {@link Response} is reported as a success or failure to a {@link CircuitBreaker} or ignored. - */ - @Override - public CircuitBreakerRuleBuilder onStatus( - BiPredicate statusFilter) { - return (CircuitBreakerRuleBuilder) super.onStatus(statusFilter); - } - - /** - * Adds the specified exception type for a {@link CircuitBreakerRule}. - * If an {@link Exception} is raised and it is an instance of the specified {@code exception}, - * depending on the build methods({@link #thenSuccess()}, {@link #thenFailure()} and {@link #thenIgnore()}), - * a {@link Response} is reported as a success or failure to a {@link CircuitBreaker} or ignored. - */ - @Override - public CircuitBreakerRuleBuilder onException(Class exception) { - return (CircuitBreakerRuleBuilder) super.onException(exception); - } - - /** - * Adds the specified {@code exceptionFilter} for a {@link CircuitBreakerRule}. - * If an {@link Exception} is raised and the specified {@code exceptionFilter} returns {@code true}, - * depending on the build methods({@link #thenSuccess()}, {@link #thenFailure()} and {@link #thenIgnore()}), - * a {@link Response} is reported as a success or failure to a {@link CircuitBreaker} or ignored. - */ - @Override - public CircuitBreakerRuleBuilder onException( - BiPredicate exceptionFilter) { - return (CircuitBreakerRuleBuilder) super.onException(exceptionFilter); - } - - /** - * Reports a {@link Response} as a success or failure to a {@link CircuitBreaker}, - * or ignores it according to the build methods({@link #thenSuccess()}, {@link #thenFailure()} - * and {@link #thenIgnore()}), if an {@link Exception} is raised. - */ - @Override - public CircuitBreakerRuleBuilder onException() { - return (CircuitBreakerRuleBuilder) super.onException(); - } - - /** - * Reports a {@link Response} as a success or failure to a {@link CircuitBreaker}, - * or ignores it according to the build methods({@link #thenSuccess()}, {@link #thenFailure()} - * and {@link #thenIgnore()}), if a {@link TimeoutException} is raised. - */ - @Override - public CircuitBreakerRuleBuilder onTimeoutException() { - return (CircuitBreakerRuleBuilder) super.onTimeoutException(); - } - - /** - * Reports a {@link Response} as a success or failure to a {@link CircuitBreaker}, - * or ignores it according to the build methods({@link #thenSuccess()}, {@link #thenFailure()} and - * {@link #thenIgnore()}), if an {@link UnprocessedRequestException}, which means that the request has not - * been processed by the server, is raised. - */ - @Override - public CircuitBreakerRuleBuilder onUnprocessed() { - return (CircuitBreakerRuleBuilder) super.onUnprocessed(); - } - - /** - * Adds the specified {@code totalDurationFilter} for a {@link CircuitBreakerRule}. - * If the specified {@code totalDurationFilter} returns {@code true}, - * depending on the build methods({@link #thenSuccess()}, {@link #thenFailure()} and {@link #thenIgnore()}), - * a {@link Response} is reported as a success or failure to a {@link CircuitBreaker} or ignored. - */ - @Override - public CircuitBreakerRuleBuilder onTotalDuration( - BiPredicate totalDurationFilter) { - return (CircuitBreakerRuleBuilder) super.onTotalDuration(totalDurationFilter); - } } diff --git a/core/src/main/java/com/linecorp/armeria/client/circuitbreaker/CircuitBreakerRuleWithContentBuilder.java b/core/src/main/java/com/linecorp/armeria/client/circuitbreaker/CircuitBreakerRuleWithContentBuilder.java index 5c8fae50719..69729cb104a 100644 --- a/core/src/main/java/com/linecorp/armeria/client/circuitbreaker/CircuitBreakerRuleWithContentBuilder.java +++ b/core/src/main/java/com/linecorp/armeria/client/circuitbreaker/CircuitBreakerRuleWithContentBuilder.java @@ -18,20 +18,14 @@ import static com.linecorp.armeria.client.circuitbreaker.CircuitBreakerRuleUtil.NEXT_DECISION; -import java.time.Duration; import java.util.concurrent.CompletionStage; import java.util.function.BiFunction; import java.util.function.BiPredicate; import com.linecorp.armeria.client.AbstractRuleWithContentBuilder; import com.linecorp.armeria.client.ClientRequestContext; -import com.linecorp.armeria.client.UnprocessedRequestException; -import com.linecorp.armeria.common.HttpHeaders; -import com.linecorp.armeria.common.HttpStatus; -import com.linecorp.armeria.common.HttpStatusClass; import com.linecorp.armeria.common.RequestHeaders; import com.linecorp.armeria.common.Response; -import com.linecorp.armeria.common.ResponseHeaders; import com.linecorp.armeria.internal.client.AbstractRuleBuilderUtil; /** @@ -39,7 +33,7 @@ * @param the response type */ public final class CircuitBreakerRuleWithContentBuilder - extends AbstractRuleWithContentBuilder { + extends AbstractRuleWithContentBuilder, T> { CircuitBreakerRuleWithContentBuilder( BiPredicate requestHeadersFilter) { @@ -99,198 +93,4 @@ private CircuitBreakerRuleWithContent build(CircuitBreakerDecision decision) }; return CircuitBreakerRuleUtil.orElse(first, second); } - - // Override the return type and Javadoc of chaining methods in superclass. - - /** - * Adds the specified {@code responseFilter} for a {@link CircuitBreakerRuleWithContent}. - * If the specified {@code responseFilter} completes with {@code true}, - * depending on the build methods({@link #thenSuccess()}, {@link #thenFailure()} and {@link #thenIgnore()}), - * a {@link Response} is reported as a success or failure to a {@link CircuitBreaker} or ignored. - */ - @Override - public CircuitBreakerRuleWithContentBuilder onResponse( - BiFunction> responseFilter) { - return (CircuitBreakerRuleWithContentBuilder) super.onResponse(responseFilter); - } - - /** - * Adds the specified {@code responseHeadersFilter} for a {@link CircuitBreakerRuleWithContent}. - * If the specified {@code responseHeadersFilter} returns {@code true}, - * depending on the build methods({@link #thenSuccess()}, {@link #thenFailure()} and {@link #thenIgnore()}), - * a {@link Response} is reported as a success or failure to a {@link CircuitBreaker} or ignored. - */ - @SuppressWarnings("unchecked") - @Override - public CircuitBreakerRuleWithContentBuilder onResponseHeaders( - BiPredicate responseHeadersFilter) { - return (CircuitBreakerRuleWithContentBuilder) super.onResponseHeaders(responseHeadersFilter); - } - - /** - * Adds the specified {@code responseTrailersFilter} for a {@link CircuitBreakerRuleWithContent}. - * If the specified {@code responseTrailersFilter} returns {@code true}, - * depending on the build methods({@link #thenSuccess()}, {@link #thenFailure()} and {@link #thenIgnore()}), - * a {@link Response} is reported as a success or failure to a {@link CircuitBreaker} or ignored. - */ - @SuppressWarnings("unchecked") - @Override - public CircuitBreakerRuleWithContentBuilder onResponseTrailers( - BiPredicate responseTrailersFilter) { - return (CircuitBreakerRuleWithContentBuilder) super.onResponseTrailers(responseTrailersFilter); - } - - /** - * Adds the specified {@code grpcTrailersFilter} for a {@link CircuitBreakerRuleWithContent}. - * If the specified {@code grpcTrailersFilter} returns {@code true}, - * depending on the build methods({@link #thenSuccess()}, {@link #thenFailure()} and {@link #thenIgnore()}), - * a {@link Response} is reported as a success or failure to a {@link CircuitBreaker} or ignored. - */ - @Override - @SuppressWarnings("unchecked") - public CircuitBreakerRuleWithContentBuilder onGrpcTrailers( - BiPredicate grpcTrailersFilter) { - return (CircuitBreakerRuleWithContentBuilder) super.onGrpcTrailers(grpcTrailersFilter); - } - - /** - * Adds the specified {@link HttpStatusClass}es for a {@link CircuitBreakerRuleWithContent}. - * If the class of the response status is one of the specified {@link HttpStatusClass}es, - * depending on the build methods({@link #thenSuccess()}, {@link #thenFailure()} and {@link #thenIgnore()}), - * a {@link Response} is reported as a success or failure to a {@link CircuitBreaker} or ignored. - */ - @SuppressWarnings("unchecked") - @Override - public CircuitBreakerRuleWithContentBuilder onStatusClass(HttpStatusClass... statusClasses) { - return (CircuitBreakerRuleWithContentBuilder) super.onStatusClass(statusClasses); - } - - /** - * Adds the specified {@link HttpStatusClass}es for a {@link CircuitBreakerRuleWithContent}. - * If the class of the response status is one of the specified {@link HttpStatusClass}es, - * depending on the build methods({@link #thenSuccess()}, {@link #thenFailure()} and {@link #thenIgnore()}), - * a {@link Response} is reported as a success or failure to a {@link CircuitBreaker} or ignored. - */ - @SuppressWarnings("unchecked") - @Override - public CircuitBreakerRuleWithContentBuilder onStatusClass(Iterable statusClasses) { - return (CircuitBreakerRuleWithContentBuilder) super.onStatusClass(statusClasses); - } - - /** - * Adds the {@link HttpStatusClass#SERVER_ERROR} for a {@link CircuitBreakerRuleWithContent}. - * If the class of the response status is {@link HttpStatusClass#SERVER_ERROR}, - * depending on the build methods({@link #thenSuccess()}, {@link #thenFailure()} and {@link #thenIgnore()}), - * a {@link Response} is reported as a success or failure to a {@link CircuitBreaker} or ignored. - */ - @SuppressWarnings("unchecked") - @Override - public CircuitBreakerRuleWithContentBuilder onServerErrorStatus() { - return (CircuitBreakerRuleWithContentBuilder) super.onServerErrorStatus(); - } - - /** - * Adds the specified {@link HttpStatus}es for a {@link CircuitBreakerRuleWithContent}. - * If the response status is one of the specified {@link HttpStatus}es, - * depending on the build methods({@link #thenSuccess()}, {@link #thenFailure()} and {@link #thenIgnore()}), - * a {@link Response} is reported as a success or failure to a {@link CircuitBreaker} or ignored. - */ - @SuppressWarnings("unchecked") - @Override - public CircuitBreakerRuleWithContentBuilder onStatus(HttpStatus... statuses) { - return (CircuitBreakerRuleWithContentBuilder) super.onStatus(statuses); - } - - /** - * Adds the specified {@link HttpStatus}es for a {@link CircuitBreakerRuleWithContent}. - * If the response status is one of the specified {@link HttpStatus}es, - * depending on the build methods({@link #thenSuccess()}, {@link #thenFailure()} and {@link #thenIgnore()}), - * a {@link Response} is reported as a success or failure to a {@link CircuitBreaker} or ignored. - */ - @SuppressWarnings("unchecked") - @Override - public CircuitBreakerRuleWithContentBuilder onStatus(Iterable statuses) { - return (CircuitBreakerRuleWithContentBuilder) super.onStatus(statuses); - } - - /** - * Adds the specified {@code statusFilter} for a {@link CircuitBreakerRuleWithContent}. - * If the response status matches the specified {@code statusFilter}, - * depending on the build methods({@link #thenSuccess()}, {@link #thenFailure()} and {@link #thenIgnore()}), - * a {@link Response} is reported as a success or failure to a {@link CircuitBreaker} or ignored. - */ - @SuppressWarnings("unchecked") - @Override - public CircuitBreakerRuleWithContentBuilder onStatus( - BiPredicate statusFilter) { - return (CircuitBreakerRuleWithContentBuilder) super.onStatus(statusFilter); - } - - /** - * Adds the specified exception type for a {@link CircuitBreakerRuleWithContent}. - * If an {@link Exception} is raised and it is an instance of the specified {@code exception}, - * depending on the build methods({@link #thenSuccess()}, {@link #thenFailure()} and {@link #thenIgnore()}), - * a {@link Response} is reported as a success or failure to a {@link CircuitBreaker} or ignored. - */ - @SuppressWarnings("unchecked") - @Override - public CircuitBreakerRuleWithContentBuilder onException(Class exception) { - return (CircuitBreakerRuleWithContentBuilder) super.onException(exception); - } - - /** - * Adds the specified {@code exceptionFilter} for a {@link CircuitBreakerRuleWithContent}. - * If an {@link Exception} is raised and the specified {@code exceptionFilter} returns {@code true}, - * depending on the build methods({@link #thenSuccess()}, {@link #thenFailure()} and {@link #thenIgnore()}), - * a {@link Response} is reported as a success or failure to a {@link CircuitBreaker} or ignored. - */ - @SuppressWarnings("unchecked") - @Override - public CircuitBreakerRuleWithContentBuilder onException( - BiPredicate exceptionFilter) { - return (CircuitBreakerRuleWithContentBuilder) super.onException(exceptionFilter); - } - - /** - * Reports a {@link Response} as a success or failure to a {@link CircuitBreaker}, - * or ignores it according to the build methods({@link #thenSuccess()}, {@link #thenFailure()} and - * {@link #thenIgnore()}), if an {@link Exception} is raised. - */ - @SuppressWarnings("unchecked") - @Override - public CircuitBreakerRuleWithContentBuilder onException() { - return (CircuitBreakerRuleWithContentBuilder) super.onException(); - } - - @SuppressWarnings("unchecked") - @Override - public CircuitBreakerRuleWithContentBuilder onTimeoutException() { - return (CircuitBreakerRuleWithContentBuilder) super.onTimeoutException(); - } - - /** - * Reports a {@link Response} as a success or failure to a {@link CircuitBreaker}, - * or ignores it according to the build methods({@link #thenSuccess()}, {@link #thenFailure()} and - * {@link #thenIgnore()}), if an {@link UnprocessedRequestException}, which means that the request has not - * been processed by the server, is raised. - */ - @SuppressWarnings("unchecked") - @Override - public CircuitBreakerRuleWithContentBuilder onUnprocessed() { - return (CircuitBreakerRuleWithContentBuilder) super.onUnprocessed(); - } - - /** - * Adds the specified {@code totalDurationFilter} for a {@link CircuitBreakerRuleWithContent}. - * If the specified {@code totalDurationFilter} returns {@code true}, - * depending on the build methods({@link #thenSuccess()}, {@link #thenFailure()} and {@link #thenIgnore()}), - * a {@link Response} is reported as a success or failure to a {@link CircuitBreaker} or ignored. - */ - @SuppressWarnings("unchecked") - @Override - public CircuitBreakerRuleWithContentBuilder onTotalDuration( - BiPredicate totalDurationFilter) { - return (CircuitBreakerRuleWithContentBuilder) super.onTotalDuration(totalDurationFilter); - } } diff --git a/core/src/main/java/com/linecorp/armeria/client/endpoint/AbstractDynamicEndpointGroupBuilder.java b/core/src/main/java/com/linecorp/armeria/client/endpoint/AbstractDynamicEndpointGroupBuilder.java index 4f8d0f8b71b..dacfe255140 100644 --- a/core/src/main/java/com/linecorp/armeria/client/endpoint/AbstractDynamicEndpointGroupBuilder.java +++ b/core/src/main/java/com/linecorp/armeria/client/endpoint/AbstractDynamicEndpointGroupBuilder.java @@ -17,8 +17,6 @@ import static com.google.common.base.Preconditions.checkArgument; -import java.time.Duration; - import com.linecorp.armeria.client.Endpoint; import com.linecorp.armeria.common.annotation.UnstableApi; @@ -26,7 +24,8 @@ * A skeletal builder implementation for a {@link DynamicEndpointGroup} and its subtypes. */ @UnstableApi -public abstract class AbstractDynamicEndpointGroupBuilder implements DynamicEndpointGroupSetters { +public abstract class AbstractDynamicEndpointGroupBuilder + > implements DynamicEndpointGroupSetters { private boolean allowEmptyEndpoints = true; private long selectionTimeoutMillis; @@ -40,14 +39,22 @@ protected AbstractDynamicEndpointGroupBuilder(long selectionTimeoutMillis) { this.selectionTimeoutMillis = selectionTimeoutMillis; } + /** + * Return {@code this}. + */ + @SuppressWarnings("unchecked") + protected final SELF self() { + return (SELF) this; + } + // Note that we don't have `selectionStrategy()` here because some subclasses are delegating and // thus they use the `EndpointSelectionStrategy` of the delegate. // See: AbstractHealthCheckedEndpointGroupBuilder @Override - public AbstractDynamicEndpointGroupBuilder allowEmptyEndpoints(boolean allowEmptyEndpoints) { + public SELF allowEmptyEndpoints(boolean allowEmptyEndpoints) { this.allowEmptyEndpoints = allowEmptyEndpoints; - return this; + return self(); } /** @@ -58,20 +65,14 @@ protected boolean shouldAllowEmptyEndpoints() { } @Override - public AbstractDynamicEndpointGroupBuilder selectionTimeout(Duration selectionTimeout) { - return (AbstractDynamicEndpointGroupBuilder) - DynamicEndpointGroupSetters.super.selectionTimeout(selectionTimeout); - } - - @Override - public AbstractDynamicEndpointGroupBuilder selectionTimeoutMillis(long selectionTimeoutMillis) { + public SELF selectionTimeoutMillis(long selectionTimeoutMillis) { checkArgument(selectionTimeoutMillis >= 0, "selectionTimeoutMillis: %s (expected: >= 0)", selectionTimeoutMillis); if (selectionTimeoutMillis == 0) { selectionTimeoutMillis = Long.MAX_VALUE; } this.selectionTimeoutMillis = selectionTimeoutMillis; - return this; + return self(); } /** diff --git a/core/src/main/java/com/linecorp/armeria/client/endpoint/DynamicEndpointGroupBuilder.java b/core/src/main/java/com/linecorp/armeria/client/endpoint/DynamicEndpointGroupBuilder.java index 94a745309bf..3b4ca4ea29c 100644 --- a/core/src/main/java/com/linecorp/armeria/client/endpoint/DynamicEndpointGroupBuilder.java +++ b/core/src/main/java/com/linecorp/armeria/client/endpoint/DynamicEndpointGroupBuilder.java @@ -17,8 +17,6 @@ import static java.util.Objects.requireNonNull; -import java.time.Duration; - import com.linecorp.armeria.common.Flags; import com.linecorp.armeria.common.annotation.Nullable; import com.linecorp.armeria.common.annotation.UnstableApi; @@ -28,7 +26,7 @@ */ @UnstableApi public final class DynamicEndpointGroupBuilder - extends AbstractDynamicEndpointGroupBuilder { + extends AbstractDynamicEndpointGroupBuilder { @Nullable private EndpointSelectionStrategy selectionStrategy; @@ -46,21 +44,6 @@ public DynamicEndpointGroupBuilder selectionStrategy(EndpointSelectionStrategy s return this; } - @Override - public DynamicEndpointGroupBuilder allowEmptyEndpoints(boolean allowEmptyEndpoints) { - return (DynamicEndpointGroupBuilder) super.allowEmptyEndpoints(allowEmptyEndpoints); - } - - @Override - public DynamicEndpointGroupBuilder selectionTimeout(Duration selectionTimeout) { - return (DynamicEndpointGroupBuilder) super.selectionTimeout(selectionTimeout); - } - - @Override - public DynamicEndpointGroupBuilder selectionTimeoutMillis(long selectionTimeoutMillis) { - return (DynamicEndpointGroupBuilder) super.selectionTimeoutMillis(selectionTimeoutMillis); - } - /** * Returns a newly created {@link DynamicEndpointGroup} with the properties configured so far. */ diff --git a/core/src/main/java/com/linecorp/armeria/client/endpoint/DynamicEndpointGroupSetters.java b/core/src/main/java/com/linecorp/armeria/client/endpoint/DynamicEndpointGroupSetters.java index dc7ce47ede1..928aac40246 100644 --- a/core/src/main/java/com/linecorp/armeria/client/endpoint/DynamicEndpointGroupSetters.java +++ b/core/src/main/java/com/linecorp/armeria/client/endpoint/DynamicEndpointGroupSetters.java @@ -29,13 +29,13 @@ * Sets properties for building {@link DynamicEndpointGroup}. */ @UnstableApi -public interface DynamicEndpointGroupSetters { +public interface DynamicEndpointGroupSetters> { /** * Sets whether to allow an empty {@link Endpoint} list. * If unspecified, an empty {@link Endpoint} list is allowed. */ - DynamicEndpointGroupSetters allowEmptyEndpoints(boolean allowEmptyEndpoints); + SELF allowEmptyEndpoints(boolean allowEmptyEndpoints); /** * Sets the timeout to wait until a successful {@link Endpoint} selection. @@ -43,7 +43,7 @@ public interface DynamicEndpointGroupSetters { * If unspecified, {@link Flags#defaultConnectTimeoutMillis()} is used by default. */ @UnstableApi - default DynamicEndpointGroupSetters selectionTimeout(Duration selectionTimeout) { + default SELF selectionTimeout(Duration selectionTimeout) { requireNonNull(selectionTimeout, "selectionTimeout"); checkArgument(!selectionTimeout.isNegative(), "selectionTimeout: %s (expected: >= 0)", selectionTimeout); @@ -56,5 +56,5 @@ default DynamicEndpointGroupSetters selectionTimeout(Duration selectionTimeout) * If unspecified, {@link Flags#defaultConnectTimeoutMillis()} is used by default. */ @UnstableApi - DynamicEndpointGroupSetters selectionTimeoutMillis(long selectionTimeoutMillis); + SELF selectionTimeoutMillis(long selectionTimeoutMillis); } diff --git a/core/src/main/java/com/linecorp/armeria/client/endpoint/dns/DnsAddressEndpointGroupBuilder.java b/core/src/main/java/com/linecorp/armeria/client/endpoint/dns/DnsAddressEndpointGroupBuilder.java index 6b06686a546..c907a02fa54 100644 --- a/core/src/main/java/com/linecorp/armeria/client/endpoint/dns/DnsAddressEndpointGroupBuilder.java +++ b/core/src/main/java/com/linecorp/armeria/client/endpoint/dns/DnsAddressEndpointGroupBuilder.java @@ -17,30 +17,21 @@ import static com.google.common.base.Preconditions.checkArgument; -import java.net.InetSocketAddress; -import java.time.Duration; - import com.google.common.annotations.VisibleForTesting; -import com.linecorp.armeria.client.DnsCache; import com.linecorp.armeria.client.Endpoint; -import com.linecorp.armeria.client.endpoint.EndpointSelectionStrategy; -import com.linecorp.armeria.client.retry.Backoff; import com.linecorp.armeria.common.annotation.Nullable; import com.linecorp.armeria.internal.client.dns.DefaultDnsResolver; -import io.micrometer.core.instrument.MeterRegistry; import io.netty.channel.EventLoop; -import io.netty.resolver.HostsFileEntriesResolver; import io.netty.resolver.ResolvedAddressTypes; -import io.netty.resolver.dns.DnsQueryLifecycleObserverFactory; -import io.netty.resolver.dns.DnsServerAddressStreamProvider; /** * Builds a new {@link DnsAddressEndpointGroup} that sources its {@link Endpoint} list from the {@code A} or * {@code AAAA} DNS records of a certain hostname. */ -public final class DnsAddressEndpointGroupBuilder extends DnsEndpointGroupBuilder { +public final class DnsAddressEndpointGroupBuilder + extends DnsEndpointGroupBuilder { private int port; @Nullable @@ -82,187 +73,4 @@ public DnsAddressEndpointGroup build() { eventLoop, backoff(), minTtl(), maxTtl(), resolvedAddressTypes, hostname(), port, dnsQueryListeners()); } - - // Override the return type of the chaining methods in the DnsEndpointGroupBuilder. - - @Override - public DnsAddressEndpointGroupBuilder eventLoop(EventLoop eventLoop) { - return (DnsAddressEndpointGroupBuilder) super.eventLoop(eventLoop); - } - - @Override - public DnsAddressEndpointGroupBuilder backoff(Backoff backoff) { - return (DnsAddressEndpointGroupBuilder) super.backoff(backoff); - } - - @Override - public DnsAddressEndpointGroupBuilder selectionStrategy(EndpointSelectionStrategy selectionStrategy) { - return (DnsAddressEndpointGroupBuilder) super.selectionStrategy(selectionStrategy); - } - - // Override the return type of the chaining methods in the AbstractDnsResolverBuilder. - - @Override - public DnsAddressEndpointGroupBuilder traceEnabled(boolean traceEnabled) { - return (DnsAddressEndpointGroupBuilder) super.traceEnabled(traceEnabled); - } - - @Override - public DnsAddressEndpointGroupBuilder queryTimeout(Duration queryTimeout) { - return (DnsAddressEndpointGroupBuilder) super.queryTimeout(queryTimeout); - } - - @Override - public DnsAddressEndpointGroupBuilder queryTimeoutMillis(long queryTimeoutMillis) { - return (DnsAddressEndpointGroupBuilder) super.queryTimeoutMillis(queryTimeoutMillis); - } - - @Override - public DnsAddressEndpointGroupBuilder queryTimeoutForEachAttempt(Duration queryTimeoutForEachAttempt) { - return (DnsAddressEndpointGroupBuilder) super.queryTimeoutForEachAttempt(queryTimeoutForEachAttempt); - } - - @Override - public DnsAddressEndpointGroupBuilder queryTimeoutMillisForEachAttempt( - long queryTimeoutMillisForEachAttempt) { - return (DnsAddressEndpointGroupBuilder) super.queryTimeoutMillisForEachAttempt( - queryTimeoutMillisForEachAttempt); - } - - @Override - public DnsAddressEndpointGroupBuilder recursionDesired(boolean recursionDesired) { - return (DnsAddressEndpointGroupBuilder) super.recursionDesired(recursionDesired); - } - - @Override - public DnsAddressEndpointGroupBuilder maxQueriesPerResolve(int maxQueriesPerResolve) { - return (DnsAddressEndpointGroupBuilder) super.maxQueriesPerResolve(maxQueriesPerResolve); - } - - @Override - public DnsAddressEndpointGroupBuilder serverAddresses(InetSocketAddress... serverAddresses) { - return (DnsAddressEndpointGroupBuilder) super.serverAddresses(serverAddresses); - } - - @Override - public DnsAddressEndpointGroupBuilder serverAddresses(Iterable serverAddresses) { - return (DnsAddressEndpointGroupBuilder) super.serverAddresses(serverAddresses); - } - - @Override - public DnsAddressEndpointGroupBuilder serverAddressStreamProvider( - DnsServerAddressStreamProvider serverAddressStreamProvider) { - return (DnsAddressEndpointGroupBuilder) super.serverAddressStreamProvider(serverAddressStreamProvider); - } - - @Override - public DnsAddressEndpointGroupBuilder dnsServerAddressStreamProvider( - DnsServerAddressStreamProvider dnsServerAddressStreamProvider) { - return (DnsAddressEndpointGroupBuilder) super.dnsServerAddressStreamProvider( - dnsServerAddressStreamProvider); - } - - @Override - public DnsAddressEndpointGroupBuilder maxPayloadSize(int maxPayloadSize) { - return (DnsAddressEndpointGroupBuilder) super.maxPayloadSize(maxPayloadSize); - } - - @Override - public DnsAddressEndpointGroupBuilder optResourceEnabled(boolean optResourceEnabled) { - return (DnsAddressEndpointGroupBuilder) super.optResourceEnabled(optResourceEnabled); - } - - @Override - public DnsAddressEndpointGroupBuilder hostsFileEntriesResolver( - HostsFileEntriesResolver hostsFileEntriesResolver) { - return (DnsAddressEndpointGroupBuilder) super.hostsFileEntriesResolver(hostsFileEntriesResolver); - } - - @Override - public DnsAddressEndpointGroupBuilder dnsQueryLifecycleObserverFactory( - DnsQueryLifecycleObserverFactory observerFactory) { - return (DnsAddressEndpointGroupBuilder) super.dnsQueryLifecycleObserverFactory(observerFactory); - } - - @Deprecated - @Override - public DnsAddressEndpointGroupBuilder disableDnsQueryMetrics() { - return (DnsAddressEndpointGroupBuilder) super.disableDnsQueryMetrics(); - } - - @Override - public DnsAddressEndpointGroupBuilder enableDnsQueryMetrics(boolean enable) { - return (DnsAddressEndpointGroupBuilder) super.enableDnsQueryMetrics(enable); - } - - @Override - public DnsAddressEndpointGroupBuilder searchDomains(String... searchDomains) { - return (DnsAddressEndpointGroupBuilder) super.searchDomains(searchDomains); - } - - @Override - public DnsAddressEndpointGroupBuilder searchDomains(Iterable searchDomains) { - return (DnsAddressEndpointGroupBuilder) super.searchDomains(searchDomains); - } - - @Override - public DnsAddressEndpointGroupBuilder ndots(int ndots) { - return (DnsAddressEndpointGroupBuilder) super.ndots(ndots); - } - - @Override - public DnsAddressEndpointGroupBuilder decodeIdn(boolean decodeIdn) { - return (DnsAddressEndpointGroupBuilder) super.decodeIdn(decodeIdn); - } - - @Override - public DnsAddressEndpointGroupBuilder meterRegistry(MeterRegistry meterRegistry) { - return (DnsAddressEndpointGroupBuilder) super.meterRegistry(meterRegistry); - } - - @Override - public DnsAddressEndpointGroupBuilder cacheSpec(String cacheSpec) { - return (DnsAddressEndpointGroupBuilder) super.cacheSpec(cacheSpec); - } - - @Override - public DnsAddressEndpointGroupBuilder ttl(int minTtl, int maxTtl) { - return (DnsAddressEndpointGroupBuilder) super.ttl(minTtl, maxTtl); - } - - @Override - public DnsAddressEndpointGroupBuilder negativeTtl(int negativeTtl) { - return (DnsAddressEndpointGroupBuilder) super.negativeTtl(negativeTtl); - } - - @Override - public DnsAddressEndpointGroupBuilder dnsCache(DnsCache dnsCache) { - return (DnsAddressEndpointGroupBuilder) super.dnsCache(dnsCache); - } - - @Override - public DnsAddressEndpointGroupBuilder allowEmptyEndpoints(boolean allowEmptyEndpoints) { - return (DnsAddressEndpointGroupBuilder) super.allowEmptyEndpoints(allowEmptyEndpoints); - } - - @Override - public DnsAddressEndpointGroupBuilder selectionTimeout(Duration selectionTimeout) { - return (DnsAddressEndpointGroupBuilder) super.selectionTimeout(selectionTimeout); - } - - @Override - public DnsAddressEndpointGroupBuilder selectionTimeoutMillis(long selectionTimeoutMillis) { - return (DnsAddressEndpointGroupBuilder) super.selectionTimeoutMillis(selectionTimeoutMillis); - } - - @Override - public DnsAddressEndpointGroupBuilder addDnsQueryListeners( - Iterable dnsQueryListeners) { - return (DnsAddressEndpointGroupBuilder) super.addDnsQueryListeners(dnsQueryListeners); - } - - @Override - public DnsAddressEndpointGroupBuilder addDnsQueryListeners(DnsQueryListener... dnsQueryListeners) { - return (DnsAddressEndpointGroupBuilder) super.addDnsQueryListeners(dnsQueryListeners); - } } diff --git a/core/src/main/java/com/linecorp/armeria/client/endpoint/dns/DnsEndpointGroupBuilder.java b/core/src/main/java/com/linecorp/armeria/client/endpoint/dns/DnsEndpointGroupBuilder.java index f6c284c9ab5..cca0945a26c 100644 --- a/core/src/main/java/com/linecorp/armeria/client/endpoint/dns/DnsEndpointGroupBuilder.java +++ b/core/src/main/java/com/linecorp/armeria/client/endpoint/dns/DnsEndpointGroupBuilder.java @@ -45,8 +45,8 @@ import io.netty.handler.codec.dns.DnsRecord; import io.netty.resolver.dns.DnsNameResolverBuilder; -abstract class DnsEndpointGroupBuilder - extends AbstractDnsResolverBuilder implements DynamicEndpointGroupSetters { +abstract class DnsEndpointGroupBuilder> + extends AbstractDnsResolverBuilder implements DynamicEndpointGroupSetters { private final String hostname; @Nullable @@ -82,12 +82,12 @@ final EventLoop getOrAcquireEventLoop() { /** * Sets the {@link EventLoop} to use for sending DNS queries. */ - public DnsEndpointGroupBuilder eventLoop(EventLoop eventLoop) { + public SELF eventLoop(EventLoop eventLoop) { requireNonNull(eventLoop, "eventLoop"); checkArgument(TransportType.isSupported(eventLoop), "unsupported event loop type: %s", eventLoop); this.eventLoop = eventLoop; - return this; + return self(); } final Backoff backoff() { @@ -99,17 +99,17 @@ final Backoff backoff() { * server sent an error response. {@code Backoff.exponential(1000, 32000).withJitter(0.2)} is used by * default. */ - public DnsEndpointGroupBuilder backoff(Backoff backoff) { + public SELF backoff(Backoff backoff) { this.backoff = requireNonNull(backoff, "backoff"); - return this; + return self(); } /** * Sets the {@link EndpointSelectionStrategy} that determines the enumeration order of {@link Endpoint}s. */ - public DnsEndpointGroupBuilder selectionStrategy(EndpointSelectionStrategy selectionStrategy) { + public SELF selectionStrategy(EndpointSelectionStrategy selectionStrategy) { this.selectionStrategy = requireNonNull(selectionStrategy, "selectionStrategy"); - return this; + return self(); } final EndpointSelectionStrategy selectionStrategy() { @@ -121,15 +121,15 @@ final boolean shouldAllowEmptyEndpoints() { } @Override - public DnsEndpointGroupBuilder allowEmptyEndpoints(boolean allowEmptyEndpoints) { + public SELF allowEmptyEndpoints(boolean allowEmptyEndpoints) { dnsDynamicEndpointGroupBuilder.allowEmptyEndpoints(allowEmptyEndpoints); - return this; + return self(); } @Override - public DnsEndpointGroupBuilder selectionTimeout(Duration selectionTimeout) { + public SELF selectionTimeout(Duration selectionTimeout) { dnsDynamicEndpointGroupBuilder.selectionTimeout(selectionTimeout); - return this; + return self(); } /** @@ -139,9 +139,9 @@ public DnsEndpointGroupBuilder selectionTimeout(Duration selectionTimeout) { * used by default. */ @Override - public DnsEndpointGroupBuilder selectionTimeoutMillis(long selectionTimeoutMillis) { + public SELF selectionTimeoutMillis(long selectionTimeoutMillis) { dnsDynamicEndpointGroupBuilder.selectionTimeoutMillis(selectionTimeoutMillis); - return this; + return self(); } final long selectionTimeoutMillis() { @@ -167,13 +167,13 @@ final DefaultDnsResolver buildResolver(Consumer customiz * If no {@link DnsQueryListener} is configured, {@link DnsQueryListener#of()} is used by default. */ @UnstableApi - public DnsEndpointGroupBuilder addDnsQueryListeners( + public SELF addDnsQueryListeners( Iterable dnsQueryListeners) { requireNonNull(dnsQueryListeners, "dnsQueryListeners"); for (DnsQueryListener listener: dnsQueryListeners) { this.dnsQueryListeners.add(listener); } - return this; + return self(); } /** @@ -181,7 +181,7 @@ public DnsEndpointGroupBuilder addDnsQueryListeners( * If no {@link DnsQueryListener} is configured, {@link DnsQueryListener#of()} is used by default. */ @UnstableApi - public DnsEndpointGroupBuilder addDnsQueryListeners(DnsQueryListener... dnsQueryListeners) { + public SELF addDnsQueryListeners(DnsQueryListener... dnsQueryListeners) { requireNonNull(dnsQueryListeners, "dnsQueryListeners"); return addDnsQueryListeners(ImmutableList.copyOf(dnsQueryListeners)); } @@ -195,7 +195,8 @@ final List dnsQueryListeners() { * DnsEndpointGroupBuilder can't extend AbstractDynamicEndpointGroupBuilder because it already extends * AbstractDnsResolverBuilder. */ - private static class DnsDynamicEndpointGroupBuilder extends AbstractDynamicEndpointGroupBuilder { + private static class DnsDynamicEndpointGroupBuilder + extends AbstractDynamicEndpointGroupBuilder { protected DnsDynamicEndpointGroupBuilder(long selectionTimeoutMillis) { super(selectionTimeoutMillis); } diff --git a/core/src/main/java/com/linecorp/armeria/client/endpoint/dns/DnsServiceEndpointGroupBuilder.java b/core/src/main/java/com/linecorp/armeria/client/endpoint/dns/DnsServiceEndpointGroupBuilder.java index 000dc38ebd4..6c383f9f0d8 100644 --- a/core/src/main/java/com/linecorp/armeria/client/endpoint/dns/DnsServiceEndpointGroupBuilder.java +++ b/core/src/main/java/com/linecorp/armeria/client/endpoint/dns/DnsServiceEndpointGroupBuilder.java @@ -15,25 +15,16 @@ */ package com.linecorp.armeria.client.endpoint.dns; -import java.net.InetSocketAddress; -import java.time.Duration; - -import com.linecorp.armeria.client.DnsCache; import com.linecorp.armeria.client.Endpoint; -import com.linecorp.armeria.client.endpoint.EndpointSelectionStrategy; -import com.linecorp.armeria.client.retry.Backoff; -import io.micrometer.core.instrument.MeterRegistry; import io.netty.channel.EventLoop; -import io.netty.resolver.HostsFileEntriesResolver; -import io.netty.resolver.dns.DnsQueryLifecycleObserverFactory; -import io.netty.resolver.dns.DnsServerAddressStreamProvider; /** * Builds a new {@link DnsServiceEndpointGroup} that sources its {@link Endpoint} list from the {@code SRV} * DNS records of a certain hostname. */ -public final class DnsServiceEndpointGroupBuilder extends DnsEndpointGroupBuilder { +public final class DnsServiceEndpointGroupBuilder + extends DnsEndpointGroupBuilder { DnsServiceEndpointGroupBuilder(String hostname) { super(hostname); @@ -49,188 +40,4 @@ public DnsServiceEndpointGroup build() { eventLoop, backoff(), minTtl(), maxTtl(), hostname(), dnsQueryListeners()); } - - // Override the return type of the chaining methods in the DnsEndpointGroupBuilder. - - @Override - public DnsServiceEndpointGroupBuilder eventLoop(EventLoop eventLoop) { - return (DnsServiceEndpointGroupBuilder) super.eventLoop(eventLoop); - } - - @Override - public DnsServiceEndpointGroupBuilder backoff(Backoff backoff) { - return (DnsServiceEndpointGroupBuilder) super.backoff(backoff); - } - - @Override - public DnsServiceEndpointGroupBuilder selectionStrategy(EndpointSelectionStrategy selectionStrategy) { - return (DnsServiceEndpointGroupBuilder) super.selectionStrategy(selectionStrategy); - } - - // Override the return type of the chaining methods in the AbstractDnsResolverBuilder. - - @Override - public DnsServiceEndpointGroupBuilder traceEnabled(boolean traceEnabled) { - return (DnsServiceEndpointGroupBuilder) super.traceEnabled(traceEnabled); - } - - @Override - public DnsServiceEndpointGroupBuilder queryTimeout(Duration queryTimeout) { - return (DnsServiceEndpointGroupBuilder) super.queryTimeout(queryTimeout); - } - - @Override - public DnsServiceEndpointGroupBuilder queryTimeoutMillis(long queryTimeoutMillis) { - return (DnsServiceEndpointGroupBuilder) super.queryTimeoutMillis(queryTimeoutMillis); - } - - @Override - public DnsServiceEndpointGroupBuilder queryTimeoutForEachAttempt(Duration queryTimeoutForEachAttempt) { - return (DnsServiceEndpointGroupBuilder) super.queryTimeoutForEachAttempt(queryTimeoutForEachAttempt); - } - - @Override - public DnsServiceEndpointGroupBuilder queryTimeoutMillisForEachAttempt( - long queryTimeoutMillisForEachAttempt) { - return (DnsServiceEndpointGroupBuilder) super.queryTimeoutMillisForEachAttempt( - queryTimeoutMillisForEachAttempt); - } - - @Override - public DnsServiceEndpointGroupBuilder recursionDesired(boolean recursionDesired) { - return (DnsServiceEndpointGroupBuilder) super.recursionDesired(recursionDesired); - } - - @Override - public DnsServiceEndpointGroupBuilder maxQueriesPerResolve(int maxQueriesPerResolve) { - return (DnsServiceEndpointGroupBuilder) super.maxQueriesPerResolve(maxQueriesPerResolve); - } - - @Override - public DnsServiceEndpointGroupBuilder serverAddresses(InetSocketAddress... serverAddresses) { - return (DnsServiceEndpointGroupBuilder) super.serverAddresses(serverAddresses); - } - - @Override - public DnsServiceEndpointGroupBuilder serverAddresses(Iterable serverAddresses) { - return (DnsServiceEndpointGroupBuilder) super.serverAddresses(serverAddresses); - } - - @Override - public DnsServiceEndpointGroupBuilder serverAddressStreamProvider( - DnsServerAddressStreamProvider serverAddressStreamProvider) { - return (DnsServiceEndpointGroupBuilder) super.serverAddressStreamProvider(serverAddressStreamProvider); - } - - @Deprecated - @Override - public DnsServiceEndpointGroupBuilder dnsServerAddressStreamProvider( - DnsServerAddressStreamProvider dnsServerAddressStreamProvider) { - return (DnsServiceEndpointGroupBuilder) super.dnsServerAddressStreamProvider( - dnsServerAddressStreamProvider); - } - - @Override - public DnsServiceEndpointGroupBuilder maxPayloadSize(int maxPayloadSize) { - return (DnsServiceEndpointGroupBuilder) super.maxPayloadSize(maxPayloadSize); - } - - @Override - public DnsServiceEndpointGroupBuilder optResourceEnabled(boolean optResourceEnabled) { - return (DnsServiceEndpointGroupBuilder) super.optResourceEnabled(optResourceEnabled); - } - - @Override - public DnsServiceEndpointGroupBuilder hostsFileEntriesResolver( - HostsFileEntriesResolver hostsFileEntriesResolver) { - return (DnsServiceEndpointGroupBuilder) super.hostsFileEntriesResolver(hostsFileEntriesResolver); - } - - @Override - public DnsServiceEndpointGroupBuilder dnsQueryLifecycleObserverFactory( - DnsQueryLifecycleObserverFactory observerFactory) { - return (DnsServiceEndpointGroupBuilder) super.dnsQueryLifecycleObserverFactory(observerFactory); - } - - @Deprecated - @Override - public DnsServiceEndpointGroupBuilder disableDnsQueryMetrics() { - return (DnsServiceEndpointGroupBuilder) super.disableDnsQueryMetrics(); - } - - @Override - public DnsServiceEndpointGroupBuilder enableDnsQueryMetrics(boolean enable) { - return (DnsServiceEndpointGroupBuilder) super.enableDnsQueryMetrics(enable); - } - - @Override - public DnsServiceEndpointGroupBuilder searchDomains(String... searchDomains) { - return (DnsServiceEndpointGroupBuilder) super.searchDomains(searchDomains); - } - - @Override - public DnsServiceEndpointGroupBuilder searchDomains(Iterable searchDomains) { - return (DnsServiceEndpointGroupBuilder) super.searchDomains(searchDomains); - } - - @Override - public DnsServiceEndpointGroupBuilder ndots(int ndots) { - return (DnsServiceEndpointGroupBuilder) super.ndots(ndots); - } - - @Override - public DnsServiceEndpointGroupBuilder decodeIdn(boolean decodeIdn) { - return (DnsServiceEndpointGroupBuilder) super.decodeIdn(decodeIdn); - } - - @Override - public DnsServiceEndpointGroupBuilder meterRegistry(MeterRegistry meterRegistry) { - return (DnsServiceEndpointGroupBuilder) super.meterRegistry(meterRegistry); - } - - @Override - public DnsServiceEndpointGroupBuilder cacheSpec(String cacheSpec) { - return (DnsServiceEndpointGroupBuilder) super.cacheSpec(cacheSpec); - } - - @Override - public DnsServiceEndpointGroupBuilder ttl(int minTtl, int maxTtl) { - return (DnsServiceEndpointGroupBuilder) super.ttl(minTtl, maxTtl); - } - - @Override - public DnsServiceEndpointGroupBuilder negativeTtl(int negativeTtl) { - return (DnsServiceEndpointGroupBuilder) super.negativeTtl(negativeTtl); - } - - @Override - public DnsServiceEndpointGroupBuilder dnsCache(DnsCache dnsCache) { - return (DnsServiceEndpointGroupBuilder) super.dnsCache(dnsCache); - } - - @Override - public DnsServiceEndpointGroupBuilder allowEmptyEndpoints(boolean allowEmptyEndpoints) { - return (DnsServiceEndpointGroupBuilder) super.allowEmptyEndpoints(allowEmptyEndpoints); - } - - @Override - public DnsServiceEndpointGroupBuilder selectionTimeout(Duration selectionTimeout) { - return (DnsServiceEndpointGroupBuilder) super.selectionTimeout(selectionTimeout); - } - - @Override - public DnsServiceEndpointGroupBuilder selectionTimeoutMillis(long selectionTimeoutMillis) { - return (DnsServiceEndpointGroupBuilder) super.selectionTimeoutMillis(selectionTimeoutMillis); - } - - @Override - public DnsServiceEndpointGroupBuilder addDnsQueryListeners( - Iterable dnsQueryListeners) { - return (DnsServiceEndpointGroupBuilder) super.addDnsQueryListeners(dnsQueryListeners); - } - - @Override - public DnsServiceEndpointGroupBuilder addDnsQueryListeners(DnsQueryListener... dnsQueryListeners) { - return (DnsServiceEndpointGroupBuilder) super.addDnsQueryListeners(dnsQueryListeners); - } } diff --git a/core/src/main/java/com/linecorp/armeria/client/endpoint/dns/DnsTextEndpointGroupBuilder.java b/core/src/main/java/com/linecorp/armeria/client/endpoint/dns/DnsTextEndpointGroupBuilder.java index 84e33ae8ceb..c18de6d94f0 100644 --- a/core/src/main/java/com/linecorp/armeria/client/endpoint/dns/DnsTextEndpointGroupBuilder.java +++ b/core/src/main/java/com/linecorp/armeria/client/endpoint/dns/DnsTextEndpointGroupBuilder.java @@ -17,27 +17,18 @@ import static java.util.Objects.requireNonNull; -import java.net.InetSocketAddress; -import java.time.Duration; import java.util.function.Function; -import com.linecorp.armeria.client.DnsCache; import com.linecorp.armeria.client.Endpoint; -import com.linecorp.armeria.client.endpoint.EndpointSelectionStrategy; -import com.linecorp.armeria.client.retry.Backoff; import com.linecorp.armeria.common.annotation.Nullable; -import io.micrometer.core.instrument.MeterRegistry; import io.netty.channel.EventLoop; -import io.netty.resolver.HostsFileEntriesResolver; -import io.netty.resolver.dns.DnsQueryLifecycleObserverFactory; -import io.netty.resolver.dns.DnsServerAddressStreamProvider; /** * Builds a new {@link DnsTextEndpointGroup} that sources its {@link Endpoint} list from the {@code TXT} * DNS records of a certain hostname. */ -public final class DnsTextEndpointGroupBuilder extends DnsEndpointGroupBuilder { +public final class DnsTextEndpointGroupBuilder extends DnsEndpointGroupBuilder { private final Function mapping; @@ -56,188 +47,4 @@ public DnsTextEndpointGroup build() { eventLoop, backoff(), minTtl(), maxTtl(), hostname(), mapping, dnsQueryListeners()); } - - // Override the return type of the chaining methods in the DnsEndpointGroupBuilder. - - @Override - public DnsTextEndpointGroupBuilder eventLoop(EventLoop eventLoop) { - return (DnsTextEndpointGroupBuilder) super.eventLoop(eventLoop); - } - - @Override - public DnsTextEndpointGroupBuilder backoff(Backoff backoff) { - return (DnsTextEndpointGroupBuilder) super.backoff(backoff); - } - - @Override - public DnsTextEndpointGroupBuilder selectionStrategy(EndpointSelectionStrategy selectionStrategy) { - return (DnsTextEndpointGroupBuilder) super.selectionStrategy(selectionStrategy); - } - - // Override the return type of the chaining methods in the AbstractDnsResolverBuilder. - - @Override - public DnsTextEndpointGroupBuilder traceEnabled(boolean traceEnabled) { - return (DnsTextEndpointGroupBuilder) super.traceEnabled(traceEnabled); - } - - @Override - public DnsTextEndpointGroupBuilder queryTimeout(Duration queryTimeout) { - return (DnsTextEndpointGroupBuilder) super.queryTimeout(queryTimeout); - } - - @Override - public DnsTextEndpointGroupBuilder queryTimeoutMillis(long queryTimeoutMillis) { - return (DnsTextEndpointGroupBuilder) super.queryTimeoutMillis(queryTimeoutMillis); - } - - @Override - public DnsTextEndpointGroupBuilder queryTimeoutForEachAttempt(Duration queryTimeoutForEachAttempt) { - return (DnsTextEndpointGroupBuilder) super.queryTimeoutForEachAttempt(queryTimeoutForEachAttempt); - } - - @Override - public DnsTextEndpointGroupBuilder queryTimeoutMillisForEachAttempt( - long queryTimeoutMillisForEachAttempt) { - return (DnsTextEndpointGroupBuilder) super.queryTimeoutMillisForEachAttempt( - queryTimeoutMillisForEachAttempt); - } - - @Override - public DnsTextEndpointGroupBuilder recursionDesired(boolean recursionDesired) { - return (DnsTextEndpointGroupBuilder) super.recursionDesired(recursionDesired); - } - - @Override - public DnsTextEndpointGroupBuilder maxQueriesPerResolve(int maxQueriesPerResolve) { - return (DnsTextEndpointGroupBuilder) super.maxQueriesPerResolve(maxQueriesPerResolve); - } - - @Override - public DnsTextEndpointGroupBuilder serverAddresses(InetSocketAddress... serverAddresses) { - return (DnsTextEndpointGroupBuilder) super.serverAddresses(serverAddresses); - } - - @Override - public DnsTextEndpointGroupBuilder serverAddresses(Iterable serverAddresses) { - return (DnsTextEndpointGroupBuilder) super.serverAddresses(serverAddresses); - } - - @Override - public DnsTextEndpointGroupBuilder serverAddressStreamProvider( - DnsServerAddressStreamProvider serverAddressStreamProvider) { - return (DnsTextEndpointGroupBuilder) super.serverAddressStreamProvider(serverAddressStreamProvider); - } - - @Deprecated - @Override - public DnsTextEndpointGroupBuilder dnsServerAddressStreamProvider( - DnsServerAddressStreamProvider dnsServerAddressStreamProvider) { - return (DnsTextEndpointGroupBuilder) super.dnsServerAddressStreamProvider( - dnsServerAddressStreamProvider); - } - - @Override - public DnsTextEndpointGroupBuilder maxPayloadSize(int maxPayloadSize) { - return (DnsTextEndpointGroupBuilder) super.maxPayloadSize(maxPayloadSize); - } - - @Override - public DnsTextEndpointGroupBuilder optResourceEnabled(boolean optResourceEnabled) { - return (DnsTextEndpointGroupBuilder) super.optResourceEnabled(optResourceEnabled); - } - - @Override - public DnsTextEndpointGroupBuilder hostsFileEntriesResolver( - HostsFileEntriesResolver hostsFileEntriesResolver) { - return (DnsTextEndpointGroupBuilder) super.hostsFileEntriesResolver(hostsFileEntriesResolver); - } - - @Override - public DnsTextEndpointGroupBuilder dnsQueryLifecycleObserverFactory( - DnsQueryLifecycleObserverFactory observerFactory) { - return (DnsTextEndpointGroupBuilder) super.dnsQueryLifecycleObserverFactory(observerFactory); - } - - @Deprecated - @Override - public DnsTextEndpointGroupBuilder disableDnsQueryMetrics() { - return (DnsTextEndpointGroupBuilder) super.disableDnsQueryMetrics(); - } - - @Override - public DnsTextEndpointGroupBuilder enableDnsQueryMetrics(boolean enable) { - return (DnsTextEndpointGroupBuilder) super.enableDnsQueryMetrics(enable); - } - - @Override - public DnsTextEndpointGroupBuilder searchDomains(String... searchDomains) { - return (DnsTextEndpointGroupBuilder) super.searchDomains(searchDomains); - } - - @Override - public DnsTextEndpointGroupBuilder searchDomains(Iterable searchDomains) { - return (DnsTextEndpointGroupBuilder) super.searchDomains(searchDomains); - } - - @Override - public DnsTextEndpointGroupBuilder ndots(int ndots) { - return (DnsTextEndpointGroupBuilder) super.ndots(ndots); - } - - @Override - public DnsTextEndpointGroupBuilder decodeIdn(boolean decodeIdn) { - return (DnsTextEndpointGroupBuilder) super.decodeIdn(decodeIdn); - } - - @Override - public DnsTextEndpointGroupBuilder meterRegistry(MeterRegistry meterRegistry) { - return (DnsTextEndpointGroupBuilder) super.meterRegistry(meterRegistry); - } - - @Override - public DnsTextEndpointGroupBuilder cacheSpec(String cacheSpec) { - return (DnsTextEndpointGroupBuilder) super.cacheSpec(cacheSpec); - } - - @Override - public DnsTextEndpointGroupBuilder ttl(int minTtl, int maxTtl) { - return (DnsTextEndpointGroupBuilder) super.ttl(minTtl, maxTtl); - } - - @Override - public DnsTextEndpointGroupBuilder negativeTtl(int negativeTtl) { - return (DnsTextEndpointGroupBuilder) super.negativeTtl(negativeTtl); - } - - @Override - public DnsTextEndpointGroupBuilder dnsCache(DnsCache dnsCache) { - return (DnsTextEndpointGroupBuilder) super.dnsCache(dnsCache); - } - - @Override - public DnsTextEndpointGroupBuilder allowEmptyEndpoints(boolean allowEmptyEndpoints) { - return (DnsTextEndpointGroupBuilder) super.allowEmptyEndpoints(allowEmptyEndpoints); - } - - @Override - public DnsTextEndpointGroupBuilder selectionTimeout(Duration selectionTimeout) { - return (DnsTextEndpointGroupBuilder) super.selectionTimeout(selectionTimeout); - } - - @Override - public DnsTextEndpointGroupBuilder selectionTimeoutMillis(long selectionTimeoutMillis) { - return (DnsTextEndpointGroupBuilder) super.selectionTimeoutMillis(selectionTimeoutMillis); - } - - @Override - public DnsTextEndpointGroupBuilder addDnsQueryListeners( - Iterable dnsQueryListeners) { - return (DnsTextEndpointGroupBuilder) super.addDnsQueryListeners(dnsQueryListeners); - } - - @Override - public DnsTextEndpointGroupBuilder addDnsQueryListeners(DnsQueryListener... dnsQueryListeners) { - return (DnsTextEndpointGroupBuilder) super.addDnsQueryListeners(dnsQueryListeners); - } } diff --git a/core/src/main/java/com/linecorp/armeria/client/endpoint/healthcheck/AbstractHealthCheckedEndpointGroupBuilder.java b/core/src/main/java/com/linecorp/armeria/client/endpoint/healthcheck/AbstractHealthCheckedEndpointGroupBuilder.java index f42748a2577..17d78f9b58d 100644 --- a/core/src/main/java/com/linecorp/armeria/client/endpoint/healthcheck/AbstractHealthCheckedEndpointGroupBuilder.java +++ b/core/src/main/java/com/linecorp/armeria/client/endpoint/healthcheck/AbstractHealthCheckedEndpointGroupBuilder.java @@ -46,7 +46,9 @@ /** * A skeletal builder implementation for creating a new {@link HealthCheckedEndpointGroup}. */ -public abstract class AbstractHealthCheckedEndpointGroupBuilder extends AbstractDynamicEndpointGroupBuilder { +public abstract class AbstractHealthCheckedEndpointGroupBuilder + > + extends AbstractDynamicEndpointGroupBuilder { static final Backoff DEFAULT_HEALTH_CHECK_RETRY_BACKOFF = Backoff.fixed(3000).withJitter(0.2); @@ -79,17 +81,17 @@ protected AbstractHealthCheckedEndpointGroupBuilder(EndpointGroup delegate) { * same as the {@link ClientFactory} used when creating a {@link Client} stub using the * {@link EndpointGroup}. */ - public AbstractHealthCheckedEndpointGroupBuilder clientFactory(ClientFactory clientFactory) { + public SELF clientFactory(ClientFactory clientFactory) { clientOptionsBuilder.factory(requireNonNull(clientFactory, "clientFactory")); - return this; + return self(); } /** * Sets the {@link SessionProtocol} to be used when making health check requests. */ - public AbstractHealthCheckedEndpointGroupBuilder protocol(SessionProtocol protocol) { + public SELF protocol(SessionProtocol protocol) { this.protocol = requireNonNull(protocol, "protocol"); - return this; + return self(); } /** @@ -97,17 +99,17 @@ public AbstractHealthCheckedEndpointGroupBuilder protocol(SessionProtocol protoc * specified by {@link EndpointGroup}'s {@link Endpoint}s. This property is useful when your * server listens to health check requests on a different port. */ - public AbstractHealthCheckedEndpointGroupBuilder port(int port) { + public SELF port(int port) { checkArgument(port > 0 && port <= 65535, "port: %s (expected: 1-65535)", port); this.port = port; - return this; + return self(); } /** * Sets the interval between health check requests. Must be positive. */ - public AbstractHealthCheckedEndpointGroupBuilder retryInterval(Duration retryInterval) { + public SELF retryInterval(Duration retryInterval) { requireNonNull(retryInterval, "retryInterval"); checkArgument(!retryInterval.isNegative() && !retryInterval.isZero(), "retryInterval: %s (expected: > 0)", retryInterval); @@ -117,7 +119,7 @@ public AbstractHealthCheckedEndpointGroupBuilder retryInterval(Duration retryInt /** * Sets the interval between health check requests in milliseconds. Must be positive. */ - public AbstractHealthCheckedEndpointGroupBuilder retryIntervalMillis(long retryIntervalMillis) { + public SELF retryIntervalMillis(long retryIntervalMillis) { checkArgument(retryIntervalMillis > 0, "retryIntervalMillis: %s (expected: > 0)", retryIntervalMillis); return retryBackoff(Backoff.fixed(retryIntervalMillis).withJitter(0.2)); @@ -126,9 +128,9 @@ public AbstractHealthCheckedEndpointGroupBuilder retryIntervalMillis(long retryI /** * Sets the backoff between health check requests. */ - public AbstractHealthCheckedEndpointGroupBuilder retryBackoff(Backoff retryBackoff) { + public SELF retryBackoff(Backoff retryBackoff) { this.retryBackoff = requireNonNull(retryBackoff, "retryBackoff"); - return this; + return self(); } /** @@ -141,9 +143,9 @@ public AbstractHealthCheckedEndpointGroupBuilder retryBackoff(Backoff retryBacko * builder.clientOptions(myClient.options()); * } */ - public AbstractHealthCheckedEndpointGroupBuilder clientOptions(ClientOptions clientOptions) { + public SELF clientOptions(ClientOptions clientOptions) { clientOptionsBuilder.options(requireNonNull(clientOptions, "clientOptions")); - return this; + return self(); } /** @@ -156,19 +158,18 @@ public AbstractHealthCheckedEndpointGroupBuilder clientOptions(ClientOptions cli * }); * } */ - public AbstractHealthCheckedEndpointGroupBuilder withClientOptions( - Function configurator) { + public SELF withClientOptions(Function configurator) { final ClientOptionsBuilder newBuilder = requireNonNull(configurator, "configurator").apply(clientOptionsBuilder); checkState(newBuilder != null, "configurator returned null."); clientOptionsBuilder = newBuilder; - return this; + return self(); } /** * Sets the maximum endpoint ratio of target selected candidates. */ - public AbstractHealthCheckedEndpointGroupBuilder maxEndpointRatio(double maxEndpointRatio) { + public SELF maxEndpointRatio(double maxEndpointRatio) { if (maxEndpointCount != null) { throw new IllegalArgumentException("Maximum endpoint count is already set."); } @@ -178,13 +179,13 @@ public AbstractHealthCheckedEndpointGroupBuilder maxEndpointRatio(double maxEndp maxEndpointRatio); this.maxEndpointRatio = maxEndpointRatio; - return this; + return self(); } /** * Sets the maximum endpoint count of target selected candidates. */ - public AbstractHealthCheckedEndpointGroupBuilder maxEndpointCount(int maxEndpointCount) { + public SELF maxEndpointCount(int maxEndpointCount) { if (maxEndpointRatio != null) { throw new IllegalArgumentException("Maximum endpoint ratio is already set."); } @@ -192,21 +193,16 @@ public AbstractHealthCheckedEndpointGroupBuilder maxEndpointCount(int maxEndpoin checkArgument(maxEndpointCount > 0, "maxEndpointCount: %s (expected: > 0)", maxEndpointCount); this.maxEndpointCount = maxEndpointCount; - return this; + return self(); } /** * Sets the {@link AuthToken} header using {@link HttpHeaderNames#AUTHORIZATION}. */ - public AbstractHealthCheckedEndpointGroupBuilder auth(AuthToken token) { + public SELF auth(AuthToken token) { requireNonNull(token, "token"); clientOptionsBuilder.auth(token); - return this; - } - - @Override - public AbstractHealthCheckedEndpointGroupBuilder allowEmptyEndpoints(boolean allowEmptyEndpoints) { - return (AbstractHealthCheckedEndpointGroupBuilder) super.allowEmptyEndpoints(allowEmptyEndpoints); + return self(); } /** @@ -241,7 +237,7 @@ public AbstractHealthCheckedEndpointGroupBuilder allowEmptyEndpoints(boolean all */ @UnstableApi @Override - public AbstractHealthCheckedEndpointGroupBuilder selectionTimeout(Duration selectionTimeout) { + public SELF selectionTimeout(Duration selectionTimeout) { return selectionTimeout(selectionTimeout, selectionTimeout); } @@ -279,8 +275,7 @@ public AbstractHealthCheckedEndpointGroupBuilder selectionTimeout(Duration selec * default. */ @UnstableApi - public AbstractHealthCheckedEndpointGroupBuilder selectionTimeout(Duration initialSelectionTimeout, - Duration selectionTimeout) { + public SELF selectionTimeout(Duration initialSelectionTimeout, Duration selectionTimeout) { requireNonNull(initialSelectionTimeout, "initialSelectionTimeout"); requireNonNull(selectionTimeout, "selectionTimeout"); return selectionTimeoutMillis(initialSelectionTimeout.toMillis(), selectionTimeout.toMillis()); @@ -319,7 +314,7 @@ public AbstractHealthCheckedEndpointGroupBuilder selectionTimeout(Duration initi */ @UnstableApi @Override - public AbstractHealthCheckedEndpointGroupBuilder selectionTimeoutMillis(long selectionTimeoutMillis) { + public SELF selectionTimeoutMillis(long selectionTimeoutMillis) { return selectionTimeoutMillis(selectionTimeoutMillis, selectionTimeoutMillis); } @@ -357,8 +352,7 @@ public AbstractHealthCheckedEndpointGroupBuilder selectionTimeoutMillis(long sel * default. */ @UnstableApi - public AbstractHealthCheckedEndpointGroupBuilder selectionTimeoutMillis(long initialSelectionTimeoutMillis, - long selectionTimeoutMillis) { + public SELF selectionTimeoutMillis(long initialSelectionTimeoutMillis, long selectionTimeoutMillis) { checkArgument(selectionTimeoutMillis >= 0, "selectionTimeoutMillis: %s (expected: >= 0)", selectionTimeoutMillis); checkArgument(initialSelectionTimeoutMillis >= 0, "initialSelectionTimeoutMillis: %s (expected: >= 0)", @@ -371,7 +365,7 @@ public AbstractHealthCheckedEndpointGroupBuilder selectionTimeoutMillis(long ini } this.initialSelectionTimeoutMillis = initialSelectionTimeoutMillis; this.selectionTimeoutMillis = selectionTimeoutMillis; - return this; + return self(); } /** diff --git a/core/src/main/java/com/linecorp/armeria/client/endpoint/healthcheck/HealthCheckedEndpointGroupBuilder.java b/core/src/main/java/com/linecorp/armeria/client/endpoint/healthcheck/HealthCheckedEndpointGroupBuilder.java index c4fc6f87df1..f18fcbcd618 100644 --- a/core/src/main/java/com/linecorp/armeria/client/endpoint/healthcheck/HealthCheckedEndpointGroupBuilder.java +++ b/core/src/main/java/com/linecorp/armeria/client/endpoint/healthcheck/HealthCheckedEndpointGroupBuilder.java @@ -18,23 +18,17 @@ import static java.util.Objects.requireNonNull; -import java.time.Duration; import java.util.function.Function; -import com.linecorp.armeria.client.ClientFactory; -import com.linecorp.armeria.client.ClientOptions; -import com.linecorp.armeria.client.ClientOptionsBuilder; import com.linecorp.armeria.client.Endpoint; import com.linecorp.armeria.client.endpoint.EndpointGroup; -import com.linecorp.armeria.client.retry.Backoff; -import com.linecorp.armeria.common.SessionProtocol; -import com.linecorp.armeria.common.auth.AuthToken; import com.linecorp.armeria.common.util.AsyncCloseable; /** * A builder for creating a new {@link HealthCheckedEndpointGroup} that sends HTTP health check requests. */ -public final class HealthCheckedEndpointGroupBuilder extends AbstractHealthCheckedEndpointGroupBuilder { +public final class HealthCheckedEndpointGroupBuilder + extends AbstractHealthCheckedEndpointGroupBuilder { private final String path; private boolean useGet; @@ -61,96 +55,11 @@ public HealthCheckedEndpointGroupBuilder useGet(boolean useGet) { return this; } - @Override - public HealthCheckedEndpointGroupBuilder clientFactory(ClientFactory clientFactory) { - return (HealthCheckedEndpointGroupBuilder) super.clientFactory(clientFactory); - } - - @Override - public HealthCheckedEndpointGroupBuilder protocol(SessionProtocol protocol) { - return (HealthCheckedEndpointGroupBuilder) super.protocol(protocol); - } - - @Override - public HealthCheckedEndpointGroupBuilder port(int port) { - return (HealthCheckedEndpointGroupBuilder) super.port(port); - } - - @Override - public HealthCheckedEndpointGroupBuilder retryInterval(Duration retryInterval) { - return (HealthCheckedEndpointGroupBuilder) super.retryInterval(retryInterval); - } - - @Override - public HealthCheckedEndpointGroupBuilder retryIntervalMillis(long retryIntervalMillis) { - return (HealthCheckedEndpointGroupBuilder) super.retryIntervalMillis(retryIntervalMillis); - } - - @Override - public HealthCheckedEndpointGroupBuilder retryBackoff(Backoff retryBackoff) { - return (HealthCheckedEndpointGroupBuilder) super.retryBackoff(retryBackoff); - } - - @Override - public HealthCheckedEndpointGroupBuilder clientOptions(ClientOptions options) { - return (HealthCheckedEndpointGroupBuilder) super.clientOptions(options); - } - - @Override - public HealthCheckedEndpointGroupBuilder withClientOptions( - Function configurator) { - return (HealthCheckedEndpointGroupBuilder) super.withClientOptions(configurator); - } - @Override protected Function newCheckerFactory() { return new HttpHealthCheckerFactory(path, useGet); } - @Override - public HealthCheckedEndpointGroupBuilder maxEndpointRatio(double maxEndpointRatio) { - return (HealthCheckedEndpointGroupBuilder) super.maxEndpointRatio(maxEndpointRatio); - } - - @Override - public HealthCheckedEndpointGroupBuilder maxEndpointCount(int maxEndpointCount) { - return (HealthCheckedEndpointGroupBuilder) super.maxEndpointCount(maxEndpointCount); - } - - @Override - public HealthCheckedEndpointGroupBuilder auth(AuthToken token) { - return (HealthCheckedEndpointGroupBuilder) super.auth(token); - } - - @Override - public HealthCheckedEndpointGroupBuilder allowEmptyEndpoints(boolean allowEmptyEndpoints) { - return (HealthCheckedEndpointGroupBuilder) super.allowEmptyEndpoints(allowEmptyEndpoints); - } - - @Override - public HealthCheckedEndpointGroupBuilder selectionTimeout(Duration selectionTimeout) { - return (HealthCheckedEndpointGroupBuilder) super.selectionTimeout(selectionTimeout); - } - - @Override - public HealthCheckedEndpointGroupBuilder selectionTimeout(Duration initialSelectionTimeout, - Duration selectionTimeout) { - return (HealthCheckedEndpointGroupBuilder) super.selectionTimeout(initialSelectionTimeout, - selectionTimeout); - } - - @Override - public HealthCheckedEndpointGroupBuilder selectionTimeoutMillis(long selectionTimeoutMillis) { - return (HealthCheckedEndpointGroupBuilder) super.selectionTimeoutMillis(selectionTimeoutMillis); - } - - @Override - public HealthCheckedEndpointGroupBuilder selectionTimeoutMillis(long initialSelectionTimeoutMillis, - long selectionTimeoutMillis) { - return (HealthCheckedEndpointGroupBuilder) super.selectionTimeoutMillis(initialSelectionTimeoutMillis, - selectionTimeoutMillis); - } - private static class HttpHealthCheckerFactory implements Function { private final String path; diff --git a/core/src/main/java/com/linecorp/armeria/client/retry/RetryRuleBuilder.java b/core/src/main/java/com/linecorp/armeria/client/retry/RetryRuleBuilder.java index 3d72de0e40f..c56bce40aef 100644 --- a/core/src/main/java/com/linecorp/armeria/client/retry/RetryRuleBuilder.java +++ b/core/src/main/java/com/linecorp/armeria/client/retry/RetryRuleBuilder.java @@ -20,7 +20,6 @@ import static com.linecorp.armeria.client.retry.RetryRuleUtil.NEXT_DECISION; import static java.util.Objects.requireNonNull; -import java.time.Duration; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; import java.util.function.BiFunction; @@ -28,13 +27,7 @@ import com.linecorp.armeria.client.AbstractRuleBuilder; import com.linecorp.armeria.client.ClientRequestContext; -import com.linecorp.armeria.client.UnprocessedRequestException; -import com.linecorp.armeria.common.HttpHeaders; -import com.linecorp.armeria.common.HttpStatus; -import com.linecorp.armeria.common.HttpStatusClass; import com.linecorp.armeria.common.RequestHeaders; -import com.linecorp.armeria.common.ResponseHeaders; -import com.linecorp.armeria.common.TimeoutException; import com.linecorp.armeria.common.annotation.Nullable; import com.linecorp.armeria.common.util.UnmodifiableFuture; import com.linecorp.armeria.internal.client.AbstractRuleBuilderUtil; @@ -42,7 +35,7 @@ /** * A builder for creating a new {@link RetryRule}. */ -public final class RetryRuleBuilder extends AbstractRuleBuilder { +public final class RetryRuleBuilder extends AbstractRuleBuilder { RetryRuleBuilder(BiPredicate requestHeadersFilter) { super(requestHeadersFilter); @@ -106,148 +99,4 @@ public boolean requiresResponseTrailers() { } }; } - - // Override the return type of the chaining methods in the superclass. - - /** - * Adds the specified {@code responseHeadersFilter} for a {@link RetryRule} which will retry - * if the {@code responseHeadersFilter} returns {@code true}. - */ - @Override - public RetryRuleBuilder onResponseHeaders( - BiPredicate responseHeadersFilter) { - return (RetryRuleBuilder) super.onResponseHeaders(responseHeadersFilter); - } - - /** - * Adds the specified {@code responseTrailersFilter} for a {@link RetryRuleWithContent} which will retry - * if the {@code responseTrailersFilter} returns {@code true}. Note that using this method makes the entire - * response buffered, which may lead to excessive memory usage. - */ - @Override - public RetryRuleBuilder onResponseTrailers( - BiPredicate responseTrailersFilter) { - return (RetryRuleBuilder) super.onResponseTrailers(responseTrailersFilter); - } - - /** - * Adds the specified {@code grpcTrailersFilter} for a {@link RetryRuleWithContent} which will retry - * if the {@code grpcTrailersFilter} returns {@code true}. Note that using this method makes the entire - * response buffered, which may lead to excessive memory usage. - */ - @Override - public RetryRuleBuilder onGrpcTrailers( - BiPredicate grpcTrailersFilter) { - return (RetryRuleBuilder) super.onGrpcTrailers(grpcTrailersFilter); - } - - /** - * Adds the specified {@link HttpStatusClass}es for a {@link RetryRule} which will retry - * if a class of the response status is one of the specified {@link HttpStatusClass}es. - */ - @Override - public RetryRuleBuilder onStatusClass(HttpStatusClass... statusClasses) { - return (RetryRuleBuilder) super.onStatusClass(statusClasses); - } - - /** - * Adds the specified {@link HttpStatusClass}es for a {@link RetryRule} which will retry - * if a class of the response status is one of the specified {@link HttpStatusClass}es. - */ - @Override - public RetryRuleBuilder onStatusClass(Iterable statusClasses) { - return (RetryRuleBuilder) super.onStatusClass(statusClasses); - } - - /** - * Adds the {@link HttpStatusClass#SERVER_ERROR} for a {@link RetryRule} which will retry - * if a class of the response status is {@link HttpStatusClass#SERVER_ERROR}. - */ - @Override - public RetryRuleBuilder onServerErrorStatus() { - return (RetryRuleBuilder) super.onServerErrorStatus(); - } - - /** - * Adds the specified {@link HttpStatus}es for a {@link RetryRule} which will retry - * if a response status is one of the specified {@link HttpStatus}es. - */ - @Override - public RetryRuleBuilder onStatus(HttpStatus... statuses) { - return (RetryRuleBuilder) super.onStatus(statuses); - } - - /** - * Adds the specified {@link HttpStatus}es for a {@link RetryRule} which will retry - * if a response status is one of the specified {@link HttpStatus}es. - */ - @Override - public RetryRuleBuilder onStatus(Iterable statuses) { - return (RetryRuleBuilder) super.onStatus(statuses); - } - - /** - * Adds the specified {@code statusFilter} for a {@link RetryRule} which will retry - * if a response status matches the specified {@code statusFilter}. - */ - @Override - public RetryRuleBuilder onStatus( - BiPredicate statusFilter) { - return (RetryRuleBuilder) super.onStatus(statusFilter); - } - - /** - * Adds the specified exception type for a {@link RetryRule} which will retry - * if an {@link Exception} is raised and it is an instance of the specified {@code exception}. - */ - @Override - public RetryRuleBuilder onException(Class exception) { - return (RetryRuleBuilder) super.onException(exception); - } - - /** - * Adds the specified {@code exceptionFilter} for a {@link RetryRule} which will retry - * if an {@link Exception} is raised and the specified {@code exceptionFilter} returns {@code true}. - */ - @Override - public RetryRuleBuilder onException( - BiPredicate exceptionFilter) { - return (RetryRuleBuilder) super.onException(exceptionFilter); - } - - /** - * Makes a {@link RetryRule} retry on any {@link Exception}. - */ - @Override - public RetryRuleBuilder onException() { - return (RetryRuleBuilder) super.onException(); - } - - /** - * Makes a {@link RetryRule} retry on a {@link TimeoutException}. - */ - @Override - public RetryRuleBuilder onTimeoutException() { - return (RetryRuleBuilder) super.onTimeoutException(); - } - - /** - * Makes a {@link RetryRule} retry on an {@link UnprocessedRequestException} which means that the request - * has not been processed by the server. Therefore, you can safely retry the request without worrying about - * the idempotency of the request. - */ - @Override - public RetryRuleBuilder onUnprocessed() { - return (RetryRuleBuilder) super.onUnprocessed(); - } - - /** - * Adds the specified {@code totalDurationFilter} for a {@link RetryRule} which will retry - * if the {@code totalDurationFilter} returns {@code true}. - */ - @Override - public RetryRuleBuilder onTotalDuration( - BiPredicate totalDurationFilter) { - return (RetryRuleBuilder) super.onTotalDuration(totalDurationFilter); - } } diff --git a/core/src/main/java/com/linecorp/armeria/client/retry/RetryRuleWithContentBuilder.java b/core/src/main/java/com/linecorp/armeria/client/retry/RetryRuleWithContentBuilder.java index 9e07901aa3c..746103b191b 100644 --- a/core/src/main/java/com/linecorp/armeria/client/retry/RetryRuleWithContentBuilder.java +++ b/core/src/main/java/com/linecorp/armeria/client/retry/RetryRuleWithContentBuilder.java @@ -19,43 +19,27 @@ import static com.linecorp.armeria.client.retry.RetryRuleUtil.NEXT_DECISION; import static java.util.Objects.requireNonNull; -import java.time.Duration; import java.util.concurrent.CompletionStage; import java.util.function.BiFunction; import java.util.function.BiPredicate; import com.linecorp.armeria.client.AbstractRuleWithContentBuilder; import com.linecorp.armeria.client.ClientRequestContext; -import com.linecorp.armeria.client.UnprocessedRequestException; -import com.linecorp.armeria.common.HttpHeaders; -import com.linecorp.armeria.common.HttpStatus; -import com.linecorp.armeria.common.HttpStatusClass; import com.linecorp.armeria.common.RequestHeaders; import com.linecorp.armeria.common.Response; -import com.linecorp.armeria.common.ResponseHeaders; import com.linecorp.armeria.internal.client.AbstractRuleBuilderUtil; /** * A builder for creating a new {@link RetryRuleWithContent}. */ -public final class RetryRuleWithContentBuilder extends AbstractRuleWithContentBuilder { +public final class RetryRuleWithContentBuilder + extends AbstractRuleWithContentBuilder, T> { RetryRuleWithContentBuilder( BiPredicate requestHeadersFilter) { super(requestHeadersFilter); } - /** - * Adds the specified {@code responseFilter} for a {@link RetryRuleWithContent} which will retry - * if the specified {@code responseFilter} completes with {@code true}. - */ - @Override - public RetryRuleWithContentBuilder onResponse( - BiFunction> responseFilter) { - return (RetryRuleWithContentBuilder) super.onResponse(responseFilter); - } - /** * Sets the {@linkplain Backoff#ofDefault() default backoff} and * returns a newly created {@link RetryRuleWithContent}. @@ -115,160 +99,4 @@ RetryRuleWithContent build(RetryDecision decision) { }; return RetryRuleUtil.orElse(first, second); } - - // Override the return type of the chaining methods in the superclass. - - /** - * Adds the specified {@code responseHeadersFilter} for a {@link RetryRuleWithContent} which will retry - * if the {@code responseHeadersFilter} returns {@code true}. - */ - @SuppressWarnings("unchecked") - @Override - public RetryRuleWithContentBuilder onResponseHeaders( - BiPredicate responseHeadersFilter) { - return (RetryRuleWithContentBuilder) super.onResponseHeaders(responseHeadersFilter); - } - - /** - * Adds the specified {@code responseTrailersFilter} for a {@link RetryRuleWithContent} which will retry - * if the {@code responseTrailersFilter} returns {@code true}. Note that using this method makes the entire - * response buffered, which may lead to excessive memory usage. - */ - @SuppressWarnings("unchecked") - @Override - public RetryRuleWithContentBuilder onResponseTrailers( - BiPredicate responseTrailersFilter) { - return (RetryRuleWithContentBuilder) super.onResponseTrailers(responseTrailersFilter); - } - - /** - * Adds the specified {@code grpcTrailersFilter} for a {@link RetryRuleWithContent} which will retry - * if the {@code grpcTrailersFilter} returns {@code true}. Note that using this method makes the entire - * response buffered, which may lead to excessive memory usage. - */ - @SuppressWarnings("unchecked") - @Override - public RetryRuleWithContentBuilder onGrpcTrailers( - BiPredicate grpcTrailersFilter) { - return (RetryRuleWithContentBuilder) super.onGrpcTrailers(grpcTrailersFilter); - } - - /** - * Adds the specified {@link HttpStatusClass}es for a {@link RetryRuleWithContent} which will retry - * if a class of the response status is one of the specified {@link HttpStatusClass}es. - */ - @SuppressWarnings("unchecked") - @Override - public RetryRuleWithContentBuilder onStatusClass(HttpStatusClass... statusClasses) { - return (RetryRuleWithContentBuilder) super.onStatusClass(statusClasses); - } - - /** - * Adds the specified {@link HttpStatusClass}es for a {@link RetryRuleWithContent} which will retry - * if a class of the response status is one of the specified {@link HttpStatusClass}es. - */ - @SuppressWarnings("unchecked") - @Override - public RetryRuleWithContentBuilder onStatusClass(Iterable statusClasses) { - return (RetryRuleWithContentBuilder) super.onStatusClass(statusClasses); - } - - /** - * Adds the {@link HttpStatusClass#SERVER_ERROR} for a {@link RetryRuleWithContent} which will retry - * if a class of the response status is {@link HttpStatusClass#SERVER_ERROR}. - */ - @SuppressWarnings("unchecked") - @Override - public RetryRuleWithContentBuilder onServerErrorStatus() { - return (RetryRuleWithContentBuilder) super.onServerErrorStatus(); - } - - /** - * Adds the specified {@link HttpStatus}es for a {@link RetryRuleWithContent} which will retry - * if a response status is one of the specified {@link HttpStatus}es. - */ - @SuppressWarnings("unchecked") - @Override - public RetryRuleWithContentBuilder onStatus(HttpStatus... statuses) { - return (RetryRuleWithContentBuilder) super.onStatus(statuses); - } - - /** - * Adds the specified {@link HttpStatus}es for a {@link RetryRuleWithContent} which will retry - * if a response status is one of the specified {@link HttpStatus}es. - */ - @SuppressWarnings("unchecked") - @Override - public RetryRuleWithContentBuilder onStatus(Iterable statuses) { - return (RetryRuleWithContentBuilder) super.onStatus(statuses); - } - - /** - * Adds the specified {@code statusFilter} for a {@link RetryRuleWithContent} which will retry - * if a response status matches the specified {@code statusFilter}. - */ - @SuppressWarnings("unchecked") - @Override - public RetryRuleWithContentBuilder onStatus( - BiPredicate statusFilter) { - return (RetryRuleWithContentBuilder) super.onStatus(statusFilter); - } - - /** - * Adds the specified exception type for a {@link RetryRuleWithContent} which will retry - * if an {@link Exception} is raised and it is an instance of the specified {@code exception}. - */ - @SuppressWarnings("unchecked") - @Override - public RetryRuleWithContentBuilder onException(Class exception) { - return (RetryRuleWithContentBuilder) super.onException(exception); - } - - /** - * Adds the specified {@code exceptionFilter} for a {@link RetryRuleWithContent} which will retry - * if an {@link Exception} is raised and the specified {@code exceptionFilter} returns {@code true}. - */ - @SuppressWarnings("unchecked") - @Override - public RetryRuleWithContentBuilder onException( - BiPredicate exceptionFilter) { - return (RetryRuleWithContentBuilder) super.onException(exceptionFilter); - } - - /** - * Makes a {@link RetryRuleWithContent} retry on any {@link Exception}. - */ - @SuppressWarnings("unchecked") - @Override - public RetryRuleWithContentBuilder onException() { - return (RetryRuleWithContentBuilder) super.onException(); - } - - @SuppressWarnings("unchecked") - @Override - public RetryRuleWithContentBuilder onTimeoutException() { - return (RetryRuleWithContentBuilder) super.onTimeoutException(); - } - - /** - * Makes a {@link RetryRuleWithContent} retry on an {@link UnprocessedRequestException} which means that - * the request has not been processed by the server. - * Therefore, you can safely retry the request without worrying about the idempotency of the request. - */ - @SuppressWarnings("unchecked") - @Override - public RetryRuleWithContentBuilder onUnprocessed() { - return (RetryRuleWithContentBuilder) super.onUnprocessed(); - } - - /** - * Adds the specified {@code responseDurationFilter} for a {@link RetryRuleWithContent} which will retry - * if the {@code responseDurationFilter} returns {@code true}. - */ - @SuppressWarnings("unchecked") - @Override - public RetryRuleWithContentBuilder onTotalDuration( - BiPredicate totalDurationFilter) { - return (RetryRuleWithContentBuilder) super.onTotalDuration(totalDurationFilter); - } } diff --git a/core/src/main/java/com/linecorp/armeria/common/logging/AbstractHeadersSanitizerBuilder.java b/core/src/main/java/com/linecorp/armeria/common/logging/AbstractHeadersSanitizerBuilder.java index b320d831322..bc43a5598af 100644 --- a/core/src/main/java/com/linecorp/armeria/common/logging/AbstractHeadersSanitizerBuilder.java +++ b/core/src/main/java/com/linecorp/armeria/common/logging/AbstractHeadersSanitizerBuilder.java @@ -32,7 +32,7 @@ /** * A skeletal builder implementation for {@link HeadersSanitizer}. */ -abstract class AbstractHeadersSanitizerBuilder { +abstract class AbstractHeadersSanitizerBuilder, T> { // Referenced from: // - https://docs.rs/tower-http/latest/tower_http/sensitive_headers/index.html @@ -47,10 +47,15 @@ abstract class AbstractHeadersSanitizerBuilder { private HeaderMaskingFunction maskingFunction = HeaderMaskingFunction.of(); + @SuppressWarnings("unchecked") + final SELF self() { + return (SELF) this; + } + /** * Adds the headers to mask before logging. */ - public AbstractHeadersSanitizerBuilder sensitiveHeaders(CharSequence... headers) { + public SELF sensitiveHeaders(CharSequence... headers) { requireNonNull(headers, "headers"); return sensitiveHeaders(ImmutableSet.copyOf(headers)); } @@ -58,13 +63,13 @@ public AbstractHeadersSanitizerBuilder sensitiveHeaders(CharSequence... heade /** * Adds the headers to mask before logging. */ - public AbstractHeadersSanitizerBuilder sensitiveHeaders(Iterable headers) { + public SELF sensitiveHeaders(Iterable headers) { requireNonNull(headers, "headers"); if (sensitiveHeaders == null) { sensitiveHeaders = new HashSet<>(); } headers.forEach(header -> sensitiveHeaders.add(AsciiString.of(header).toLowerCase())); - return this; + return self(); } final Set sensitiveHeaders() { @@ -90,9 +95,9 @@ final Set sensitiveHeaders() { * } * } */ - public AbstractHeadersSanitizerBuilder maskingFunction(HeaderMaskingFunction maskingFunction) { + public SELF maskingFunction(HeaderMaskingFunction maskingFunction) { this.maskingFunction = requireNonNull(maskingFunction, "maskingFunction"); - return this; + return self(); } /** diff --git a/core/src/main/java/com/linecorp/armeria/common/logging/AbstractLogFormatterBuilder.java b/core/src/main/java/com/linecorp/armeria/common/logging/AbstractLogFormatterBuilder.java index 0ffd2e070ed..33d77e8885e 100644 --- a/core/src/main/java/com/linecorp/armeria/common/logging/AbstractLogFormatterBuilder.java +++ b/core/src/main/java/com/linecorp/armeria/common/logging/AbstractLogFormatterBuilder.java @@ -28,7 +28,7 @@ /** * A skeletal builder implementation for {@link LogFormatter}. */ -abstract class AbstractLogFormatterBuilder> { +abstract class AbstractLogFormatterBuilder, T> { @Nullable private HeadersSanitizer requestHeadersSanitizer; diff --git a/core/src/main/java/com/linecorp/armeria/common/logging/JsonHeadersSanitizerBuilder.java b/core/src/main/java/com/linecorp/armeria/common/logging/JsonHeadersSanitizerBuilder.java index a86dba1d324..48a70be0737 100644 --- a/core/src/main/java/com/linecorp/armeria/common/logging/JsonHeadersSanitizerBuilder.java +++ b/core/src/main/java/com/linecorp/armeria/common/logging/JsonHeadersSanitizerBuilder.java @@ -27,26 +27,12 @@ /** * A builder implementation for JSON {@link HeadersSanitizer}. */ -public final class JsonHeadersSanitizerBuilder extends AbstractHeadersSanitizerBuilder { +public final class JsonHeadersSanitizerBuilder + extends AbstractHeadersSanitizerBuilder { @Nullable private ObjectMapper objectMapper; - @Override - public JsonHeadersSanitizerBuilder sensitiveHeaders(CharSequence... headers) { - return (JsonHeadersSanitizerBuilder) super.sensitiveHeaders(headers); - } - - @Override - public JsonHeadersSanitizerBuilder sensitiveHeaders(Iterable headers) { - return (JsonHeadersSanitizerBuilder) super.sensitiveHeaders(headers); - } - - @Override - public JsonHeadersSanitizerBuilder maskingFunction(HeaderMaskingFunction maskingFunction) { - return (JsonHeadersSanitizerBuilder) super.maskingFunction(maskingFunction); - } - /** * Sets the {@link ObjectMapper} that will be used to convert headers into a {@link JsonNode}. */ diff --git a/core/src/main/java/com/linecorp/armeria/common/logging/JsonLogFormatterBuilder.java b/core/src/main/java/com/linecorp/armeria/common/logging/JsonLogFormatterBuilder.java index 4516b3338c2..4f89e2939a4 100644 --- a/core/src/main/java/com/linecorp/armeria/common/logging/JsonLogFormatterBuilder.java +++ b/core/src/main/java/com/linecorp/armeria/common/logging/JsonLogFormatterBuilder.java @@ -34,7 +34,7 @@ */ @UnstableApi public final class JsonLogFormatterBuilder - extends AbstractLogFormatterBuilder { + extends AbstractLogFormatterBuilder { @Nullable private ObjectMapper objectMapper; diff --git a/core/src/main/java/com/linecorp/armeria/common/logging/TextHeadersSanitizerBuilder.java b/core/src/main/java/com/linecorp/armeria/common/logging/TextHeadersSanitizerBuilder.java index 73db6727dbf..cd2ec89f059 100644 --- a/core/src/main/java/com/linecorp/armeria/common/logging/TextHeadersSanitizerBuilder.java +++ b/core/src/main/java/com/linecorp/armeria/common/logging/TextHeadersSanitizerBuilder.java @@ -19,22 +19,8 @@ /** * A builder implementation for Text {@link HeadersSanitizer}. */ -public final class TextHeadersSanitizerBuilder extends AbstractHeadersSanitizerBuilder { - - @Override - public TextHeadersSanitizerBuilder sensitiveHeaders(CharSequence... headers) { - return (TextHeadersSanitizerBuilder) super.sensitiveHeaders(headers); - } - - @Override - public TextHeadersSanitizerBuilder sensitiveHeaders(Iterable headers) { - return (TextHeadersSanitizerBuilder) super.sensitiveHeaders(headers); - } - - @Override - public TextHeadersSanitizerBuilder maskingFunction(HeaderMaskingFunction maskingFunction) { - return (TextHeadersSanitizerBuilder) super.maskingFunction(maskingFunction); - } +public final class TextHeadersSanitizerBuilder + extends AbstractHeadersSanitizerBuilder { /** * Returns a newly created text {@link HeadersSanitizer} based on the properties of this builder. diff --git a/core/src/main/java/com/linecorp/armeria/common/logging/TextLogFormatterBuilder.java b/core/src/main/java/com/linecorp/armeria/common/logging/TextLogFormatterBuilder.java index e07afd35a95..8de8f51aaad 100644 --- a/core/src/main/java/com/linecorp/armeria/common/logging/TextLogFormatterBuilder.java +++ b/core/src/main/java/com/linecorp/armeria/common/logging/TextLogFormatterBuilder.java @@ -28,7 +28,7 @@ */ @UnstableApi public final class TextLogFormatterBuilder - extends AbstractLogFormatterBuilder { + extends AbstractLogFormatterBuilder { private boolean includeContext = true; diff --git a/core/src/main/java/com/linecorp/armeria/server/AbstractContextPathAnnotatedServiceConfigSetters.java b/core/src/main/java/com/linecorp/armeria/server/AbstractContextPathAnnotatedServiceConfigSetters.java index 4b2a0d3e42c..55be27575ea 100644 --- a/core/src/main/java/com/linecorp/armeria/server/AbstractContextPathAnnotatedServiceConfigSetters.java +++ b/core/src/main/java/com/linecorp/armeria/server/AbstractContextPathAnnotatedServiceConfigSetters.java @@ -21,10 +21,10 @@ import java.util.Set; abstract class AbstractContextPathAnnotatedServiceConfigSetters - , - SELF extends AbstractContextPathAnnotatedServiceConfigSetters> + , + T extends AbstractContextPathServicesBuilder> extends AbstractAnnotatedServiceConfigSetters< - AbstractContextPathAnnotatedServiceConfigSetters> { + AbstractContextPathAnnotatedServiceConfigSetters> { private final T builder; private final Set contextPaths; diff --git a/core/src/main/java/com/linecorp/armeria/server/AbstractContextPathDecoratingBindingBuilder.java b/core/src/main/java/com/linecorp/armeria/server/AbstractContextPathDecoratingBindingBuilder.java index 345782370a1..82cce6e12c0 100644 --- a/core/src/main/java/com/linecorp/armeria/server/AbstractContextPathDecoratingBindingBuilder.java +++ b/core/src/main/java/com/linecorp/armeria/server/AbstractContextPathDecoratingBindingBuilder.java @@ -22,8 +22,9 @@ import com.linecorp.armeria.internal.server.RouteDecoratingService; -abstract class AbstractContextPathDecoratingBindingBuilder, - SELF extends AbstractContextPathDecoratingBindingBuilder> +abstract class AbstractContextPathDecoratingBindingBuilder + , + T extends AbstractContextPathServicesBuilder> extends AbstractBindingBuilder { private final T builder; diff --git a/core/src/main/java/com/linecorp/armeria/server/AbstractContextPathServiceBindingBuilder.java b/core/src/main/java/com/linecorp/armeria/server/AbstractContextPathServiceBindingBuilder.java index 963b8449216..99a022bffbb 100644 --- a/core/src/main/java/com/linecorp/armeria/server/AbstractContextPathServiceBindingBuilder.java +++ b/core/src/main/java/com/linecorp/armeria/server/AbstractContextPathServiceBindingBuilder.java @@ -18,9 +18,10 @@ import static java.util.Objects.requireNonNull; -abstract class AbstractContextPathServiceBindingBuilder, - SELF extends AbstractContextPathServiceBindingBuilder> - extends AbstractServiceBindingBuilder> { +abstract class AbstractContextPathServiceBindingBuilder + , + T extends AbstractContextPathServicesBuilder> + extends AbstractServiceBindingBuilder> { private final T contextPathServicesBuilder; diff --git a/core/src/main/java/com/linecorp/armeria/server/AbstractContextPathServicesBuilder.java b/core/src/main/java/com/linecorp/armeria/server/AbstractContextPathServicesBuilder.java index d9e86c4f1df..b61159cf6ed 100644 --- a/core/src/main/java/com/linecorp/armeria/server/AbstractContextPathServicesBuilder.java +++ b/core/src/main/java/com/linecorp/armeria/server/AbstractContextPathServicesBuilder.java @@ -33,9 +33,8 @@ import com.linecorp.armeria.server.annotation.RequestConverterFunction; import com.linecorp.armeria.server.annotation.ResponseConverterFunction; -abstract class AbstractContextPathServicesBuilder, - SELF extends AbstractContextPathServicesBuilder> - implements ServiceConfigsBuilder { +abstract class AbstractContextPathServicesBuilder, + T extends ServiceConfigsBuilder> implements ServiceConfigsBuilder { private final Set contextPaths; private final T parent; diff --git a/core/src/main/java/com/linecorp/armeria/server/ContextPathAnnotatedServiceConfigSetters.java b/core/src/main/java/com/linecorp/armeria/server/ContextPathAnnotatedServiceConfigSetters.java index d6f84fc62c7..d212c4f51f4 100644 --- a/core/src/main/java/com/linecorp/armeria/server/ContextPathAnnotatedServiceConfigSetters.java +++ b/core/src/main/java/com/linecorp/armeria/server/ContextPathAnnotatedServiceConfigSetters.java @@ -25,8 +25,8 @@ */ @UnstableApi public final class ContextPathAnnotatedServiceConfigSetters - extends AbstractContextPathAnnotatedServiceConfigSetters { + extends AbstractContextPathAnnotatedServiceConfigSetters { ContextPathAnnotatedServiceConfigSetters(ContextPathServicesBuilder builder) { super(builder); diff --git a/core/src/main/java/com/linecorp/armeria/server/ContextPathDecoratingBindingBuilder.java b/core/src/main/java/com/linecorp/armeria/server/ContextPathDecoratingBindingBuilder.java index a0b9558d16c..2b7a3b3004d 100644 --- a/core/src/main/java/com/linecorp/armeria/server/ContextPathDecoratingBindingBuilder.java +++ b/core/src/main/java/com/linecorp/armeria/server/ContextPathDecoratingBindingBuilder.java @@ -38,8 +38,8 @@ */ @UnstableApi public final class ContextPathDecoratingBindingBuilder - extends AbstractContextPathDecoratingBindingBuilder { + extends AbstractContextPathDecoratingBindingBuilder { ContextPathDecoratingBindingBuilder(ContextPathServicesBuilder builder) { super(builder); diff --git a/core/src/main/java/com/linecorp/armeria/server/ContextPathServiceBindingBuilder.java b/core/src/main/java/com/linecorp/armeria/server/ContextPathServiceBindingBuilder.java index f060bbe08ca..b91611298d0 100644 --- a/core/src/main/java/com/linecorp/armeria/server/ContextPathServiceBindingBuilder.java +++ b/core/src/main/java/com/linecorp/armeria/server/ContextPathServiceBindingBuilder.java @@ -35,8 +35,8 @@ */ @UnstableApi public final class ContextPathServiceBindingBuilder - extends AbstractContextPathServiceBindingBuilder { + extends AbstractContextPathServiceBindingBuilder { ContextPathServiceBindingBuilder(ContextPathServicesBuilder builder) { super(builder); diff --git a/core/src/main/java/com/linecorp/armeria/server/ContextPathServicesBuilder.java b/core/src/main/java/com/linecorp/armeria/server/ContextPathServicesBuilder.java index ebd1f4d216d..607a8472660 100644 --- a/core/src/main/java/com/linecorp/armeria/server/ContextPathServicesBuilder.java +++ b/core/src/main/java/com/linecorp/armeria/server/ContextPathServicesBuilder.java @@ -39,7 +39,7 @@ */ @UnstableApi public final class ContextPathServicesBuilder - extends AbstractContextPathServicesBuilder { + extends AbstractContextPathServicesBuilder { ContextPathServicesBuilder(ServerBuilder parent, VirtualHostBuilder virtualHostBuilder, Set contextPaths) { diff --git a/core/src/main/java/com/linecorp/armeria/server/VirtualHostContextPathAnnotatedServiceConfigSetters.java b/core/src/main/java/com/linecorp/armeria/server/VirtualHostContextPathAnnotatedServiceConfigSetters.java index 24e9c834cc3..d5101565639 100644 --- a/core/src/main/java/com/linecorp/armeria/server/VirtualHostContextPathAnnotatedServiceConfigSetters.java +++ b/core/src/main/java/com/linecorp/armeria/server/VirtualHostContextPathAnnotatedServiceConfigSetters.java @@ -25,8 +25,8 @@ */ @UnstableApi public final class VirtualHostContextPathAnnotatedServiceConfigSetters - extends AbstractContextPathAnnotatedServiceConfigSetters { + extends AbstractContextPathAnnotatedServiceConfigSetters< + VirtualHostContextPathAnnotatedServiceConfigSetters, VirtualHostContextPathServicesBuilder> { VirtualHostContextPathAnnotatedServiceConfigSetters(VirtualHostContextPathServicesBuilder builder) { super(builder); diff --git a/core/src/main/java/com/linecorp/armeria/server/VirtualHostContextPathDecoratingBindingBuilder.java b/core/src/main/java/com/linecorp/armeria/server/VirtualHostContextPathDecoratingBindingBuilder.java index a91f051b121..16c889d2138 100644 --- a/core/src/main/java/com/linecorp/armeria/server/VirtualHostContextPathDecoratingBindingBuilder.java +++ b/core/src/main/java/com/linecorp/armeria/server/VirtualHostContextPathDecoratingBindingBuilder.java @@ -43,8 +43,8 @@ */ @UnstableApi public final class VirtualHostContextPathDecoratingBindingBuilder - extends AbstractContextPathDecoratingBindingBuilder { + extends AbstractContextPathDecoratingBindingBuilder { VirtualHostContextPathDecoratingBindingBuilder(VirtualHostContextPathServicesBuilder builder) { super(builder); diff --git a/core/src/main/java/com/linecorp/armeria/server/VirtualHostContextPathServiceBindingBuilder.java b/core/src/main/java/com/linecorp/armeria/server/VirtualHostContextPathServiceBindingBuilder.java index bae2c515256..65edbcd007b 100644 --- a/core/src/main/java/com/linecorp/armeria/server/VirtualHostContextPathServiceBindingBuilder.java +++ b/core/src/main/java/com/linecorp/armeria/server/VirtualHostContextPathServiceBindingBuilder.java @@ -36,8 +36,8 @@ */ @UnstableApi public final class VirtualHostContextPathServiceBindingBuilder - extends AbstractContextPathServiceBindingBuilder { + extends AbstractContextPathServiceBindingBuilder { VirtualHostContextPathServiceBindingBuilder(VirtualHostContextPathServicesBuilder builder) { super(builder); diff --git a/core/src/main/java/com/linecorp/armeria/server/VirtualHostContextPathServicesBuilder.java b/core/src/main/java/com/linecorp/armeria/server/VirtualHostContextPathServicesBuilder.java index 229e45f243c..8763320042e 100644 --- a/core/src/main/java/com/linecorp/armeria/server/VirtualHostContextPathServicesBuilder.java +++ b/core/src/main/java/com/linecorp/armeria/server/VirtualHostContextPathServicesBuilder.java @@ -40,7 +40,7 @@ */ @UnstableApi public final class VirtualHostContextPathServicesBuilder - extends AbstractContextPathServicesBuilder { + extends AbstractContextPathServicesBuilder { VirtualHostContextPathServicesBuilder(VirtualHostBuilder parent, VirtualHostBuilder virtualHostBuilder, Set contextPaths) { diff --git a/core/src/test/java/com/linecorp/armeria/client/endpoint/dns/DnsEndpointGroupBuilderTest.java b/core/src/test/java/com/linecorp/armeria/client/endpoint/dns/DnsEndpointGroupBuilderTest.java index 67c8f8b2b10..8b1d81ebf53 100644 --- a/core/src/test/java/com/linecorp/armeria/client/endpoint/dns/DnsEndpointGroupBuilderTest.java +++ b/core/src/test/java/com/linecorp/armeria/client/endpoint/dns/DnsEndpointGroupBuilderTest.java @@ -22,9 +22,6 @@ import org.junit.jupiter.api.Test; -import com.linecorp.armeria.client.endpoint.EndpointSelectionStrategy; -import com.linecorp.armeria.client.retry.Backoff; - import io.netty.channel.DefaultEventLoop; import io.netty.channel.EventLoop; import io.netty.channel.nio.NioEventLoopGroup; @@ -92,10 +89,10 @@ void serverAddresses() { @Test void allowEmptyEndpoints() { - final DnsEndpointGroupBuilder builder0 = new Builder("foo.com").allowEmptyEndpoints(false); + final DnsEndpointGroupBuilder builder0 = new Builder("foo.com").allowEmptyEndpoints(false); assertThat(builder0.shouldAllowEmptyEndpoints()).isFalse(); - final DnsEndpointGroupBuilder builder1 = new Builder("foo.com").allowEmptyEndpoints(true); + final DnsEndpointGroupBuilder builder1 = new Builder("foo.com").allowEmptyEndpoints(true); assertThat(builder1.shouldAllowEmptyEndpoints()).isTrue(); } @@ -103,16 +100,11 @@ private static Builder builder() { return new Builder("foo.com"); } - private static final class Builder extends DnsEndpointGroupBuilder { + private static final class Builder extends DnsEndpointGroupBuilder { Builder(String hostname) { super(hostname); } - @Override - public Builder eventLoop(EventLoop eventLoop) { - return (Builder) super.eventLoop(eventLoop); - } - int minTtl0() { return minTtl(); } @@ -121,33 +113,8 @@ int maxTtl0() { return maxTtl(); } - @Override - public Builder ttl(int minTtl, int maxTtl) { - return (Builder) super.ttl(minTtl, maxTtl); - } - DnsServerAddressStreamProvider serverAddressStreamProvider0() { return serverAddressStreamProvider(); } - - @Override - public Builder serverAddresses(InetSocketAddress... serverAddresses) { - return (Builder) super.serverAddresses(serverAddresses); - } - - @Override - public Builder serverAddresses(Iterable serverAddresses) { - return (Builder) super.serverAddresses(serverAddresses); - } - - @Override - public Builder backoff(Backoff backoff) { - return (Builder) super.backoff(backoff); - } - - @Override - public Builder selectionStrategy(EndpointSelectionStrategy selectionStrategy) { - return (Builder) super.selectionStrategy(selectionStrategy); - } } } diff --git a/core/src/test/java/com/linecorp/armeria/internal/client/AbstractRuleBuilderTest.java b/core/src/test/java/com/linecorp/armeria/internal/client/AbstractRuleBuilderTest.java deleted file mode 100644 index b9c06046a9c..00000000000 --- a/core/src/test/java/com/linecorp/armeria/internal/client/AbstractRuleBuilderTest.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2020 LINE Corporation - * - * LINE Corporation licenses this file to you under the Apache License, - * version 2.0 (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at: - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ - -package com.linecorp.armeria.internal.client; - -import static com.google.common.collect.ImmutableList.toImmutableList; -import static org.assertj.core.api.Assertions.assertThat; - -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.function.Predicate; - -import org.junit.jupiter.api.Test; -import org.junit.platform.commons.util.ReflectionUtils; - -import com.google.common.collect.ImmutableMap; - -import com.linecorp.armeria.client.AbstractRuleBuilder; -import com.linecorp.armeria.client.circuitbreaker.CircuitBreakerRule; -import com.linecorp.armeria.client.circuitbreaker.CircuitBreakerRuleBuilder; -import com.linecorp.armeria.client.retry.RetryRule; -import com.linecorp.armeria.client.retry.RetryRuleBuilder; - -class AbstractRuleBuilderTest { - - @Test - void checkStaticMethods() { - final Map, Class> classes = - ImmutableMap.of( - RetryRule.class, RetryRuleBuilder.class, - CircuitBreakerRule.class, CircuitBreakerRuleBuilder.class); - - classes.forEach((rule, builder) -> { - final List builderMethods = - ReflectionUtils.findMethods(builder, - method -> !Modifier.isStatic(method.getModifiers()) && - Modifier.isPublic(method.getModifiers()) && - method.getName().startsWith("on") && - !"onResponseHeaders".equals(method.getName()) && - !"onResponseTrailers".equals(method.getName()) && - !"onGrpcTrailers".equals(method.getName()) && - !"onUnprocessed".equals(method.getName()) && - !"onTotalDuration".equals(method.getName()) && - !method.isVarArgs()); - - final List ruleMethods = - ReflectionUtils.findMethods(rule, - method -> Modifier.isStatic(method.getModifiers()) && - Modifier.isPublic(method.getModifiers()) && - method.getName().startsWith("on")); - assertThat(builderMethods).isNotEmpty(); - for (Method builderMethod : builderMethods) { - final Predicate predicate = ruleMethod -> - ruleMethod.getName().equals(builderMethod.getName()) && - Arrays.equals(ruleMethod.getParameterTypes(), builderMethod.getParameterTypes()); - - assertThat(ruleMethods.stream().filter(predicate).collect(toImmutableList())).hasSize(1); - } - }); - } -} diff --git a/eureka/src/main/java/com/linecorp/armeria/client/eureka/EurekaEndpointGroupBuilder.java b/eureka/src/main/java/com/linecorp/armeria/client/eureka/EurekaEndpointGroupBuilder.java index 6f254901fe1..1013f83bdd2 100644 --- a/eureka/src/main/java/com/linecorp/armeria/client/eureka/EurekaEndpointGroupBuilder.java +++ b/eureka/src/main/java/com/linecorp/armeria/client/eureka/EurekaEndpointGroupBuilder.java @@ -65,7 +65,7 @@ * Builds a {@link EurekaEndpointGroup}. */ public final class EurekaEndpointGroupBuilder extends AbstractWebClientBuilder - implements DynamicEndpointGroupSetters { + implements DynamicEndpointGroupSetters { private static final long DEFAULT_REGISTRY_FETCH_INTERVAL_MILLIS = 30000; @@ -465,7 +465,8 @@ public EurekaEndpointGroupBuilder selectionTimeoutMillis(long selectionTimeoutMi * EurekaEndpointGroupBuilder can't extend AbstractDynamicEndpointGroupBuilder because it already extends * EurekaEndpointGroupBuilder. */ - private static class DynamicEndpointGroupBuilder extends AbstractDynamicEndpointGroupBuilder { + private static class DynamicEndpointGroupBuilder + extends AbstractDynamicEndpointGroupBuilder { DynamicEndpointGroupBuilder() { super(Flags.defaultResponseTimeoutMillis()); diff --git a/it/builders/src/test/java/com/linecorp/armeria/OverriddenBuilderMethodsReturnTypeTest.java b/it/builders/src/test/java/com/linecorp/armeria/OverriddenBuilderMethodsReturnTypeTest.java index eaa4af62e37..2c2f76a95e4 100644 --- a/it/builders/src/test/java/com/linecorp/armeria/OverriddenBuilderMethodsReturnTypeTest.java +++ b/it/builders/src/test/java/com/linecorp/armeria/OverriddenBuilderMethodsReturnTypeTest.java @@ -65,7 +65,36 @@ void methodChaining() { "VirtualHostDecoratingServiceBindingBuilder", "VirtualHostServiceBindingBuilder", "ChainedCorsPolicyBuilder", - "CorsPolicyBuilder"); + "CorsPolicyBuilder", + "ConsulEndpointGroupBuilde", + "AbstractDnsResolverBuilder", + "AbstractRuleBuilder", + "AbstractRuleWithContentBuilder", + "DnsResolverGroupBuilder", + "AbstractCircuitBreakerMappingBuilder", + "CircuitBreakerMappingBuilder", + "CircuitBreakerRuleBuilder", + "CircuitBreakerRuleWithContentBuilder", + "AbstractDynamicEndpointGroupBuilder", + "DynamicEndpointGroupBuilder", + "DynamicEndpointGroupSetters", + "DnsAddressEndpointGroupBuilder", + "DnsEndpointGroupBuilder", + "DnsServiceEndpointGroupBuilder", + "DnsTextEndpointGroupBuilder", + "AbstractHealthCheckedEndpointGroupBuilder", + "HealthCheckedEndpointGroupBuilder", + "RetryRuleBuilder", + "RetryRuleWithContentBuilder", + "AbstractHeadersSanitizerBuilder", + "JsonHeadersSanitizerBuilder", + "TextHeadersSanitizerBuilder", + "EurekaEndpointGroupBuilder", + "KubernetesEndpointGroupBuilder", + "Resilience4jCircuitBreakerMappingBuilder", + "ZooKeeperEndpointGroupBuilder", + "AbstractCuratorFrameworkBuilder", + "ZooKeeperUpdatingListenerBuilder"); final String packageName = "com.linecorp.armeria"; findAllClasses(packageName).stream() .map(ReflectionUtils::forName) diff --git a/kubernetes/src/main/java/com/linecorp/armeria/client/kubernetes/endpoints/KubernetesEndpointGroupBuilder.java b/kubernetes/src/main/java/com/linecorp/armeria/client/kubernetes/endpoints/KubernetesEndpointGroupBuilder.java index 18f7ed174c3..3ee32bf9e72 100644 --- a/kubernetes/src/main/java/com/linecorp/armeria/client/kubernetes/endpoints/KubernetesEndpointGroupBuilder.java +++ b/kubernetes/src/main/java/com/linecorp/armeria/client/kubernetes/endpoints/KubernetesEndpointGroupBuilder.java @@ -19,7 +19,6 @@ import static com.google.common.base.Preconditions.checkState; import static java.util.Objects.requireNonNull; -import java.time.Duration; import java.util.function.Predicate; import com.google.common.base.Strings; @@ -38,7 +37,8 @@ * A builder for creating a new {@link KubernetesEndpointGroup}. */ @UnstableApi -public final class KubernetesEndpointGroupBuilder extends AbstractDynamicEndpointGroupBuilder { +public final class KubernetesEndpointGroupBuilder + extends AbstractDynamicEndpointGroupBuilder { private final KubernetesClient kubernetesClient; private final boolean autoClose; @@ -109,25 +109,6 @@ public KubernetesEndpointGroupBuilder selectionStrategy(EndpointSelectionStrateg return this; } - /** - * Sets whether to allow an empty {@link Endpoint} list. - * If unspecified, the default is {@code false} that disallows an empty {@link Endpoint} list. - */ - @Override - public KubernetesEndpointGroupBuilder allowEmptyEndpoints(boolean allowEmptyEndpoints) { - return (KubernetesEndpointGroupBuilder) super.allowEmptyEndpoints(allowEmptyEndpoints); - } - - @Override - public KubernetesEndpointGroupBuilder selectionTimeout(Duration selectionTimeout) { - return (KubernetesEndpointGroupBuilder) super.selectionTimeout(selectionTimeout); - } - - @Override - public KubernetesEndpointGroupBuilder selectionTimeoutMillis(long selectionTimeoutMillis) { - return (KubernetesEndpointGroupBuilder) super.selectionTimeoutMillis(selectionTimeoutMillis); - } - /** * Returns a newly-created {@link KubernetesEndpointGroup} based on the properties of this builder. */ diff --git a/resilience4j2/src/main/java/com/linecorp/armeria/resilience4j/circuitbreaker/client/Resilience4jCircuitBreakerMappingBuilder.java b/resilience4j2/src/main/java/com/linecorp/armeria/resilience4j/circuitbreaker/client/Resilience4jCircuitBreakerMappingBuilder.java index c438a4b42c3..a0b2ff87a1a 100644 --- a/resilience4j2/src/main/java/com/linecorp/armeria/resilience4j/circuitbreaker/client/Resilience4jCircuitBreakerMappingBuilder.java +++ b/resilience4j2/src/main/java/com/linecorp/armeria/resilience4j/circuitbreaker/client/Resilience4jCircuitBreakerMappingBuilder.java @@ -30,26 +30,12 @@ * based on a combination of host, method and path. */ @UnstableApi -public final class Resilience4jCircuitBreakerMappingBuilder extends AbstractCircuitBreakerMappingBuilder { +public final class Resilience4jCircuitBreakerMappingBuilder + extends AbstractCircuitBreakerMappingBuilder { private CircuitBreakerRegistry registry = CircuitBreakerRegistry.ofDefaults(); private Resilience4jCircuitBreakerFactory factory = Resilience4jCircuitBreakerFactory.of(); - @Override - public Resilience4jCircuitBreakerMappingBuilder perHost() { - return (Resilience4jCircuitBreakerMappingBuilder) super.perHost(); - } - - @Override - public Resilience4jCircuitBreakerMappingBuilder perMethod() { - return (Resilience4jCircuitBreakerMappingBuilder) super.perMethod(); - } - - @Override - public Resilience4jCircuitBreakerMappingBuilder perPath() { - return (Resilience4jCircuitBreakerMappingBuilder) super.perPath(); - } - /** * The {@link CircuitBreakerRegistry} from which {@link CircuitBreaker} instances will be * created by default. diff --git a/zookeeper3/src/main/java/com/linecorp/armeria/client/zookeeper/ZooKeeperEndpointGroupBuilder.java b/zookeeper3/src/main/java/com/linecorp/armeria/client/zookeeper/ZooKeeperEndpointGroupBuilder.java index f8b615a65a2..a0d8fd08e28 100644 --- a/zookeeper3/src/main/java/com/linecorp/armeria/client/zookeeper/ZooKeeperEndpointGroupBuilder.java +++ b/zookeeper3/src/main/java/com/linecorp/armeria/client/zookeeper/ZooKeeperEndpointGroupBuilder.java @@ -18,10 +18,8 @@ import static java.util.Objects.requireNonNull; import java.time.Duration; -import java.util.function.Consumer; import org.apache.curator.framework.CuratorFramework; -import org.apache.curator.framework.CuratorFrameworkFactory.Builder; import com.linecorp.armeria.client.Endpoint; import com.linecorp.armeria.client.endpoint.AbstractDynamicEndpointGroupBuilder; @@ -33,8 +31,9 @@ /** * Builds a {@link ZooKeeperEndpointGroup}. */ -public final class ZooKeeperEndpointGroupBuilder extends AbstractCuratorFrameworkBuilder - implements DynamicEndpointGroupSetters { +public final class ZooKeeperEndpointGroupBuilder + extends AbstractCuratorFrameworkBuilder + implements DynamicEndpointGroupSetters { private final DynamicEndpointGroupBuilder dynamicEndpointGroupBuilder = new DynamicEndpointGroupBuilder(); private final ZooKeeperDiscoverySpec spec; @@ -71,33 +70,6 @@ public ZooKeeperEndpointGroup build() { client, znodePath(), spec, internalClient); } - // Override the return type of the chaining methods in the superclass. - - @Override - public ZooKeeperEndpointGroupBuilder connectTimeout(Duration connectTimeout) { - return (ZooKeeperEndpointGroupBuilder) super.connectTimeout(connectTimeout); - } - - @Override - public ZooKeeperEndpointGroupBuilder connectTimeoutMillis(long connectTimeoutMillis) { - return (ZooKeeperEndpointGroupBuilder) super.connectTimeoutMillis(connectTimeoutMillis); - } - - @Override - public ZooKeeperEndpointGroupBuilder sessionTimeout(Duration sessionTimeout) { - return (ZooKeeperEndpointGroupBuilder) super.sessionTimeout(sessionTimeout); - } - - @Override - public ZooKeeperEndpointGroupBuilder sessionTimeoutMillis(long sessionTimeoutMillis) { - return (ZooKeeperEndpointGroupBuilder) super.sessionTimeoutMillis(sessionTimeoutMillis); - } - - @Override - public ZooKeeperEndpointGroupBuilder customizer(Consumer customizer) { - return (ZooKeeperEndpointGroupBuilder) super.customizer(customizer); - } - @Override public ZooKeeperEndpointGroupBuilder allowEmptyEndpoints(boolean allowEmptyEndpoints) { dynamicEndpointGroupBuilder.allowEmptyEndpoints(allowEmptyEndpoints); @@ -131,7 +103,8 @@ public ZooKeeperEndpointGroupBuilder selectionTimeoutMillis(long selectionTimeou * ZooKeeperEndpointGroupBuilder can't extend AbstractDynamicEndpointGroupBuilder because it already extends * AbstractCuratorFrameworkBuilder. */ - private static class DynamicEndpointGroupBuilder extends AbstractDynamicEndpointGroupBuilder { + private static class DynamicEndpointGroupBuilder + extends AbstractDynamicEndpointGroupBuilder { protected DynamicEndpointGroupBuilder() { super(Flags.defaultResponseTimeoutMillis()); } diff --git a/zookeeper3/src/main/java/com/linecorp/armeria/common/zookeeper/AbstractCuratorFrameworkBuilder.java b/zookeeper3/src/main/java/com/linecorp/armeria/common/zookeeper/AbstractCuratorFrameworkBuilder.java index e86e9afc88c..e85d508df5f 100644 --- a/zookeeper3/src/main/java/com/linecorp/armeria/common/zookeeper/AbstractCuratorFrameworkBuilder.java +++ b/zookeeper3/src/main/java/com/linecorp/armeria/common/zookeeper/AbstractCuratorFrameworkBuilder.java @@ -39,7 +39,7 @@ * A skeletal builder implementation for {@link CuratorFramework}. */ @UnstableApi -public class AbstractCuratorFrameworkBuilder { +public class AbstractCuratorFrameworkBuilder> { private static final int DEFAULT_CONNECT_TIMEOUT_MILLIS = 1000; private static final int DEFAULT_SESSION_TIMEOUT_MILLIS = 10000; @@ -97,6 +97,11 @@ protected final String znodePath() { return znodePath; } + @SuppressWarnings("unchecked") + final SELF self() { + return (SELF) this; + } + /** * Sets the specified connect timeout. {@value DEFAULT_CONNECT_TIMEOUT_MILLIS} ms is used by default. * @@ -105,7 +110,7 @@ protected final String znodePath() { * @throws IllegalStateException if this builder was created with an existing {@link CuratorFramework} * instance. */ - public AbstractCuratorFrameworkBuilder connectTimeout(Duration connectTimeout) { + public SELF connectTimeout(Duration connectTimeout) { requireNonNull(connectTimeout, "connectTimeout"); checkArgument(!connectTimeout.isZero() && !connectTimeout.isNegative(), "connectTimeout: %s (expected: > 0)", connectTimeout); @@ -121,12 +126,12 @@ public AbstractCuratorFrameworkBuilder connectTimeout(Duration connectTimeout) { * @throws IllegalStateException if this builder was created with an existing {@link CuratorFramework} * instance. */ - public AbstractCuratorFrameworkBuilder connectTimeoutMillis(long connectTimeoutMillis) { + public SELF connectTimeoutMillis(long connectTimeoutMillis) { checkArgument(connectTimeoutMillis > 0, "connectTimeoutMillis: %s (expected: > 0)", connectTimeoutMillis); ensureInternalClient(); customizer(builder -> builder.connectionTimeoutMs(Ints.saturatedCast(connectTimeoutMillis))); - return this; + return self(); } /** @@ -137,7 +142,7 @@ public AbstractCuratorFrameworkBuilder connectTimeoutMillis(long connectTimeoutM * @throws IllegalStateException if this builder was created with an existing {@link CuratorFramework} * instance. */ - public AbstractCuratorFrameworkBuilder sessionTimeout(Duration sessionTimeout) { + public SELF sessionTimeout(Duration sessionTimeout) { requireNonNull(sessionTimeout, "sessionTimeout"); checkArgument(!sessionTimeout.isZero() && !sessionTimeout.isNegative(), "sessionTimeout: %s (expected: > 0)", sessionTimeout); @@ -152,12 +157,12 @@ public AbstractCuratorFrameworkBuilder sessionTimeout(Duration sessionTimeout) { * @throws IllegalStateException if this builder was created with an existing {@link CuratorFramework} * instance. */ - public AbstractCuratorFrameworkBuilder sessionTimeoutMillis(long sessionTimeoutMillis) { + public SELF sessionTimeoutMillis(long sessionTimeoutMillis) { checkArgument(sessionTimeoutMillis > 0, "sessionTimeoutMillis: %s (expected: > 0)", sessionTimeoutMillis); ensureInternalClient(); customizer(builder -> builder.sessionTimeoutMs(Ints.saturatedCast(sessionTimeoutMillis))); - return this; + return self(); } /** @@ -166,11 +171,11 @@ public AbstractCuratorFrameworkBuilder sessionTimeoutMillis(long sessionTimeoutM * @throws IllegalStateException if this builder was created with an existing {@link CuratorFramework} * instance. */ - public AbstractCuratorFrameworkBuilder customizer( + public SELF customizer( Consumer customizer) { ensureInternalClient(); customizers.add(requireNonNull(customizer, "customizer")); - return this; + return self(); } /** diff --git a/zookeeper3/src/main/java/com/linecorp/armeria/server/zookeeper/ZooKeeperUpdatingListenerBuilder.java b/zookeeper3/src/main/java/com/linecorp/armeria/server/zookeeper/ZooKeeperUpdatingListenerBuilder.java index c8b43ee11d4..503384261a3 100644 --- a/zookeeper3/src/main/java/com/linecorp/armeria/server/zookeeper/ZooKeeperUpdatingListenerBuilder.java +++ b/zookeeper3/src/main/java/com/linecorp/armeria/server/zookeeper/ZooKeeperUpdatingListenerBuilder.java @@ -18,10 +18,8 @@ import static java.util.Objects.requireNonNull; import java.time.Duration; -import java.util.function.Consumer; import org.apache.curator.framework.CuratorFramework; -import org.apache.curator.framework.CuratorFrameworkFactory.Builder; import com.linecorp.armeria.common.zookeeper.AbstractCuratorFrameworkBuilder; import com.linecorp.armeria.server.Server; @@ -54,7 +52,8 @@ * sb.serverListener(listener); * } * */ -public final class ZooKeeperUpdatingListenerBuilder extends AbstractCuratorFrameworkBuilder { +public final class ZooKeeperUpdatingListenerBuilder + extends AbstractCuratorFrameworkBuilder { private final ZooKeeperRegistrationSpec spec; @@ -93,31 +92,4 @@ public ZooKeeperUpdatingListener build() { return new ZooKeeperUpdatingListener(client, znodePath(), spec, internalClient); } - - // Override the return type of the chaining methods in the superclass. - - @Override - public ZooKeeperUpdatingListenerBuilder connectTimeout(Duration connectTimeout) { - return (ZooKeeperUpdatingListenerBuilder) super.connectTimeout(connectTimeout); - } - - @Override - public ZooKeeperUpdatingListenerBuilder connectTimeoutMillis(long connectTimeoutMillis) { - return (ZooKeeperUpdatingListenerBuilder) super.connectTimeoutMillis(connectTimeoutMillis); - } - - @Override - public ZooKeeperUpdatingListenerBuilder sessionTimeout(Duration sessionTimeout) { - return (ZooKeeperUpdatingListenerBuilder) super.sessionTimeout(sessionTimeout); - } - - @Override - public ZooKeeperUpdatingListenerBuilder sessionTimeoutMillis(long sessionTimeoutMillis) { - return (ZooKeeperUpdatingListenerBuilder) super.sessionTimeoutMillis(sessionTimeoutMillis); - } - - @Override - public ZooKeeperUpdatingListenerBuilder customizer(Consumer customizer) { - return (ZooKeeperUpdatingListenerBuilder) super.customizer(customizer); - } }