Skip to content

Commit 26a94c9

Browse files
committed
Merge remote-tracking branch 'origin/master' into authorityverifyokhttp
2 parents ecbf7b7 + 86b9529 commit 26a94c9

File tree

77 files changed

+651
-207
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

77 files changed

+651
-207
lines changed

.github/workflows/testing.yml

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -79,14 +79,9 @@ jobs:
7979
runs-on: ubuntu-latest
8080
strategy:
8181
matrix:
82-
include:
83-
# Test with and without bzlmod. Bazel 6 doesn't support bzlmod, so use Bazel 7 instead
84-
- bazel: 6.0.0
85-
bzlmod: false
86-
- bazel: 7.0.0
87-
bzlmod: true
82+
bzlmod: [true, false]
8883
env:
89-
USE_BAZEL_VERSION: ${{ matrix.bazel }}
84+
USE_BAZEL_VERSION: 7.0.0
9085

9186
steps:
9287
- uses: actions/checkout@v4

alts/build.gradle

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,11 @@ dependencies {
4444
classifier = "linux-x86_64"
4545
}
4646
}
47-
signature libraries.signature.java
47+
signature (libraries.signature.java) {
48+
artifact {
49+
extension = "signature"
50+
}
51+
}
4852
}
4953

5054
configureProtoCompilation()

api/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,6 @@ java_library(
1313
artifact("com.google.errorprone:error_prone_annotations"),
1414
artifact("com.google.guava:failureaccess"), # future transitive dep of Guava. See #5214
1515
artifact("com.google.guava:guava"),
16+
artifact("org.codehaus.mojo:animal-sniffer-annotations"),
1617
],
1718
)

api/build.gradle

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ tasks.named("jar").configure {
3636
dependencies {
3737
compileOnly sourceSets.context.output
3838
api libraries.jsr305,
39+
libraries.animalsniffer.annotations,
3940
libraries.errorprone.annotations
4041
implementation libraries.guava
4142

@@ -48,8 +49,18 @@ dependencies {
4849
testImplementation project(':grpc-testing')
4950
testImplementation libraries.guava.testlib
5051

51-
signature libraries.signature.java
52-
signature libraries.signature.android
52+
signature (libraries.signature.java) {
53+
artifact {
54+
extension = "signature"
55+
}
56+
}
57+
// TODO: Temporarily disabled until StatusException is fixed.
58+
// Context: https://github.com/grpc/grpc-java/pull/11066
59+
//signature (libraries.signature.android) {
60+
// artifact {
61+
// extension = "signature"
62+
// }
63+
//}
5364
}
5465

5566
tasks.named("javadoc").configure {

api/src/main/java/io/grpc/ForwardingChannelBuilder2.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,12 @@ protected T addMetricSink(MetricSink metricSink) {
263263
return thisT();
264264
}
265265

266+
@Override
267+
public <X> T setNameResolverArg(NameResolver.Args.Key<X> key, X value) {
268+
delegate().setNameResolverArg(key, value);
269+
return thisT();
270+
}
271+
266272
/**
267273
* Returns the {@link ManagedChannel} built by the delegate by default. Overriding method can
268274
* return different value.

api/src/main/java/io/grpc/ManagedChannelBuilder.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -633,6 +633,23 @@ protected T addMetricSink(MetricSink metricSink) {
633633
throw new UnsupportedOperationException();
634634
}
635635

636+
/**
637+
* Provides a "custom" argument for the {@link NameResolver}, if applicable, replacing any 'value'
638+
* previously provided for 'key'.
639+
*
640+
* <p>NB: If the selected {@link NameResolver} does not understand 'key', or target URI resolution
641+
* isn't needed at all, your custom argument will be silently ignored.
642+
*
643+
* <p>See {@link NameResolver.Args#getArg(NameResolver.Args.Key)} for more.
644+
*
645+
* @param key identifies the argument in a type-safe manner
646+
* @param value the argument itself
647+
* @return this
648+
*/
649+
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/1770")
650+
public <X> T setNameResolverArg(NameResolver.Args.Key<X> key, X value) {
651+
throw new UnsupportedOperationException();
652+
}
636653

637654
/**
638655
* Builds a channel using the given parameters.

api/src/main/java/io/grpc/NameResolver.java

Lines changed: 100 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,13 @@
2828
import java.lang.annotation.RetentionPolicy;
2929
import java.net.URI;
3030
import java.util.Collections;
31+
import java.util.IdentityHashMap;
3132
import java.util.List;
3233
import java.util.Map;
3334
import java.util.concurrent.Executor;
3435
import java.util.concurrent.ScheduledExecutorService;
3536
import javax.annotation.Nullable;
37+
import javax.annotation.concurrent.Immutable;
3638
import javax.annotation.concurrent.ThreadSafe;
3739

3840
/**
@@ -276,7 +278,12 @@ public Status onResult2(ResolutionResult resolutionResult) {
276278
/**
277279
* Information that a {@link Factory} uses to create a {@link NameResolver}.
278280
*
279-
* <p>Note this class doesn't override neither {@code equals()} nor {@code hashCode()}.
281+
* <p>Args applicable to all {@link NameResolver}s are defined here using ordinary setters and
282+
* getters. This container can also hold externally-defined "custom" args that aren't so widely
283+
* useful or that would be inappropriate dependencies for this low level API. See {@link
284+
* Args#getArg} for more.
285+
*
286+
* <p>Note this class overrides neither {@code equals()} nor {@code hashCode()}.
280287
*
281288
* @since 1.21.0
282289
*/
@@ -291,26 +298,20 @@ public static final class Args {
291298
@Nullable private final Executor executor;
292299
@Nullable private final String overrideAuthority;
293300
@Nullable private final MetricRecorder metricRecorder;
301+
@Nullable private final IdentityHashMap<Key<?>, Object> customArgs;
294302

295-
private Args(
296-
Integer defaultPort,
297-
ProxyDetector proxyDetector,
298-
SynchronizationContext syncContext,
299-
ServiceConfigParser serviceConfigParser,
300-
@Nullable ScheduledExecutorService scheduledExecutorService,
301-
@Nullable ChannelLogger channelLogger,
302-
@Nullable Executor executor,
303-
@Nullable String overrideAuthority,
304-
@Nullable MetricRecorder metricRecorder) {
305-
this.defaultPort = checkNotNull(defaultPort, "defaultPort not set");
306-
this.proxyDetector = checkNotNull(proxyDetector, "proxyDetector not set");
307-
this.syncContext = checkNotNull(syncContext, "syncContext not set");
308-
this.serviceConfigParser = checkNotNull(serviceConfigParser, "serviceConfigParser not set");
309-
this.scheduledExecutorService = scheduledExecutorService;
310-
this.channelLogger = channelLogger;
311-
this.executor = executor;
312-
this.overrideAuthority = overrideAuthority;
313-
this.metricRecorder = metricRecorder;
303+
private Args(Builder builder) {
304+
this.defaultPort = checkNotNull(builder.defaultPort, "defaultPort not set");
305+
this.proxyDetector = checkNotNull(builder.proxyDetector, "proxyDetector not set");
306+
this.syncContext = checkNotNull(builder.syncContext, "syncContext not set");
307+
this.serviceConfigParser =
308+
checkNotNull(builder.serviceConfigParser, "serviceConfigParser not set");
309+
this.scheduledExecutorService = builder.scheduledExecutorService;
310+
this.channelLogger = builder.channelLogger;
311+
this.executor = builder.executor;
312+
this.overrideAuthority = builder.overrideAuthority;
313+
this.metricRecorder = builder.metricRecorder;
314+
this.customArgs = cloneCustomArgs(builder.customArgs);
314315
}
315316

316317
/**
@@ -319,6 +320,7 @@ private Args(
319320
*
320321
* @since 1.21.0
321322
*/
323+
// <p>TODO: Only meaningful for InetSocketAddress producers. Make this a custom arg?
322324
public int getDefaultPort() {
323325
return defaultPort;
324326
}
@@ -371,6 +373,30 @@ public ServiceConfigParser getServiceConfigParser() {
371373
return serviceConfigParser;
372374
}
373375

376+
/**
377+
* Returns the value of a custom arg named 'key', or {@code null} if it's not set.
378+
*
379+
* <p>While ordinary {@link Args} should be universally useful and meaningful, custom arguments
380+
* can apply just to resolvers of a certain URI scheme, just to resolvers producing a particular
381+
* type of {@link java.net.SocketAddress}, or even an individual {@link NameResolver} subclass.
382+
* Custom args are identified by an instance of {@link Args.Key} which should be a constant
383+
* defined in a java package and class appropriate for the argument's scope.
384+
*
385+
* <p>{@link Args} are normally reserved for information in *support* of name resolution, not
386+
* the name to be resolved itself. However, there are rare cases where all or part of the target
387+
* name can't be represented by any standard URI scheme or can't be encoded as a String at all.
388+
* Custom args, in contrast, can hold arbitrary Java types, making them a useful work around in
389+
* these cases.
390+
*
391+
* <p>Custom args can also be used simply to avoid adding inappropriate deps to the low level
392+
* io.grpc package.
393+
*/
394+
@SuppressWarnings("unchecked") // Cast is safe because all put()s go through the setArg() API.
395+
@Nullable
396+
public <T> T getArg(Key<T> key) {
397+
return customArgs != null ? (T) customArgs.get(key) : null;
398+
}
399+
374400
/**
375401
* Returns the {@link ChannelLogger} for the Channel served by this NameResolver.
376402
*
@@ -424,6 +450,7 @@ public String toString() {
424450
.add("proxyDetector", proxyDetector)
425451
.add("syncContext", syncContext)
426452
.add("serviceConfigParser", serviceConfigParser)
453+
.add("customArgs", customArgs)
427454
.add("scheduledExecutorService", scheduledExecutorService)
428455
.add("channelLogger", channelLogger)
429456
.add("executor", executor)
@@ -448,6 +475,7 @@ public Builder toBuilder() {
448475
builder.setOffloadExecutor(executor);
449476
builder.setOverrideAuthority(overrideAuthority);
450477
builder.setMetricRecorder(metricRecorder);
478+
builder.customArgs = cloneCustomArgs(customArgs);
451479
return builder;
452480
}
453481

@@ -475,6 +503,7 @@ public static final class Builder {
475503
private Executor executor;
476504
private String overrideAuthority;
477505
private MetricRecorder metricRecorder;
506+
private IdentityHashMap<Key<?>, Object> customArgs;
478507

479508
Builder() {
480509
}
@@ -561,6 +590,17 @@ public Builder setOverrideAuthority(String authority) {
561590
return this;
562591
}
563592

593+
/** See {@link Args#getArg(Key)}. */
594+
public <T> Builder setArg(Key<T> key, T value) {
595+
checkNotNull(key, "key");
596+
checkNotNull(value, "value");
597+
if (customArgs == null) {
598+
customArgs = new IdentityHashMap<>();
599+
}
600+
customArgs.put(key, value);
601+
return this;
602+
}
603+
564604
/**
565605
* See {@link Args#getMetricRecorder()}. This is an optional field.
566606
*/
@@ -575,11 +615,40 @@ public Builder setMetricRecorder(MetricRecorder metricRecorder) {
575615
* @since 1.21.0
576616
*/
577617
public Args build() {
578-
return
579-
new Args(
580-
defaultPort, proxyDetector, syncContext, serviceConfigParser,
581-
scheduledExecutorService, channelLogger, executor, overrideAuthority,
582-
metricRecorder);
618+
return new Args(this);
619+
}
620+
}
621+
622+
/**
623+
* Identifies an externally-defined custom argument that can be stored in {@link Args}.
624+
*
625+
* <p>Uses reference equality so keys should be defined as global constants.
626+
*
627+
* @param <T> type of values that can be stored under this key
628+
*/
629+
@Immutable
630+
@SuppressWarnings("UnusedTypeParameter")
631+
public static final class Key<T> {
632+
private final String debugString;
633+
634+
private Key(String debugString) {
635+
this.debugString = debugString;
636+
}
637+
638+
@Override
639+
public String toString() {
640+
return debugString;
641+
}
642+
643+
/**
644+
* Creates a new instance of {@link Key}.
645+
*
646+
* @param debugString a string used to describe the key, used for debugging.
647+
* @param <T> Key type
648+
* @return a new instance of Key
649+
*/
650+
public static <T> Key<T> create(String debugString) {
651+
return new Key<>(debugString);
583652
}
584653
}
585654
}
@@ -877,4 +946,10 @@ public String toString() {
877946
}
878947
}
879948
}
949+
950+
@Nullable
951+
private static IdentityHashMap<Args.Key<?>, Object> cloneCustomArgs(
952+
@Nullable IdentityHashMap<Args.Key<?>, Object> customArgs) {
953+
return customArgs != null ? new IdentityHashMap<>(customArgs) : null;
954+
}
880955
}

api/src/main/java/io/grpc/TimeUtils.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,12 @@
1717
package io.grpc;
1818

1919
import java.time.Duration;
20+
import org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement;
2021

2122
final class TimeUtils {
2223
private TimeUtils() {}
2324

25+
@IgnoreJRERequirement
2426
static long convertToNanos(Duration duration) {
2527
try {
2628
return duration.toNanos();

api/src/test/java/io/grpc/CallOptionsTest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import io.grpc.internal.SerializingExecutor;
3535
import java.time.Duration;
3636
import java.util.concurrent.Executor;
37+
import org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement;
3738
import org.junit.Test;
3839
import org.junit.runner.RunWith;
3940
import org.junit.runners.JUnit4;
@@ -152,6 +153,7 @@ public void withDeadlineAfter() {
152153
}
153154

154155
@Test
156+
@IgnoreJRERequirement
155157
public void withDeadlineAfterDuration() {
156158
Deadline actual = CallOptions.DEFAULT.withDeadlineAfter(Duration.ofMinutes(1L)).getDeadline();
157159
Deadline expected = Deadline.after(1, MINUTES);

api/src/test/java/io/grpc/NameResolverTest.java

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,13 @@ public class NameResolverTest {
4747
private static final List<EquivalentAddressGroup> ADDRESSES =
4848
Collections.singletonList(
4949
new EquivalentAddressGroup(new FakeSocketAddress("fake-address-1"), Attributes.EMPTY));
50-
private static final Attributes.Key<String> YOLO_KEY = Attributes.Key.create("yolo");
51-
private static Attributes ATTRIBUTES = Attributes.newBuilder()
52-
.set(YOLO_KEY, "To be, or not to be?").build();
50+
private static final Attributes.Key<String> YOLO_ATTR_KEY = Attributes.Key.create("yolo");
51+
private static Attributes ATTRIBUTES =
52+
Attributes.newBuilder().set(YOLO_ATTR_KEY, "To be, or not to be?").build();
53+
private static final NameResolver.Args.Key<Integer> FOO_ARG_KEY =
54+
NameResolver.Args.Key.create("foo");
55+
private static final NameResolver.Args.Key<Integer> BAR_ARG_KEY =
56+
NameResolver.Args.Key.create("bar");
5357
private static ConfigOrError CONFIG = ConfigOrError.fromConfig("foo");
5458

5559
@Rule
@@ -65,6 +69,7 @@ public class NameResolverTest {
6569
private final Executor executor = Executors.newSingleThreadExecutor();
6670
private final String overrideAuthority = "grpc.io";
6771
private final MetricRecorder metricRecorder = new MetricRecorder() {};
72+
private final int customArgValue = 42;
6873
@Mock NameResolver.Listener mockListener;
6974

7075
@Test
@@ -79,6 +84,8 @@ public void args() {
7984
assertThat(args.getOffloadExecutor()).isSameInstanceAs(executor);
8085
assertThat(args.getOverrideAuthority()).isSameInstanceAs(overrideAuthority);
8186
assertThat(args.getMetricRecorder()).isSameInstanceAs(metricRecorder);
87+
assertThat(args.getArg(FOO_ARG_KEY)).isEqualTo(customArgValue);
88+
assertThat(args.getArg(BAR_ARG_KEY)).isNull();
8289

8390
NameResolver.Args args2 = args.toBuilder().build();
8491
assertThat(args2.getDefaultPort()).isEqualTo(defaultPort);
@@ -90,6 +97,8 @@ public void args() {
9097
assertThat(args2.getOffloadExecutor()).isSameInstanceAs(executor);
9198
assertThat(args2.getOverrideAuthority()).isSameInstanceAs(overrideAuthority);
9299
assertThat(args.getMetricRecorder()).isSameInstanceAs(metricRecorder);
100+
assertThat(args.getArg(FOO_ARG_KEY)).isEqualTo(customArgValue);
101+
assertThat(args.getArg(BAR_ARG_KEY)).isNull();
93102

94103
assertThat(args2).isNotSameInstanceAs(args);
95104
assertThat(args2).isNotEqualTo(args);
@@ -106,6 +115,7 @@ private NameResolver.Args createArgs() {
106115
.setOffloadExecutor(executor)
107116
.setOverrideAuthority(overrideAuthority)
108117
.setMetricRecorder(metricRecorder)
118+
.setArg(FOO_ARG_KEY, customArgValue)
109119
.build();
110120
}
111121

0 commit comments

Comments
 (0)