mirror of https://github.com/grpc/grpc-java.git
Compare commits
6 Commits
Author | SHA1 | Date |
---|---|---|
|
cf78406950 | |
|
33af0a75fd | |
|
19c9b998b1 | |
|
752a045f10 | |
|
ef09d94fe8 | |
|
c37fb181a4 |
|
@ -2,7 +2,7 @@ module(
|
|||
name = "grpc-java",
|
||||
compatibility_level = 0,
|
||||
repo_name = "io_grpc_grpc_java",
|
||||
version = "1.66.0-SNAPSHOT", # CURRENT_GRPC_VERSION
|
||||
version = "1.66.0", # CURRENT_GRPC_VERSION
|
||||
)
|
||||
|
||||
# GRPC_DEPS_START
|
||||
|
|
36
README.md
36
README.md
|
@ -44,8 +44,8 @@ For a guided tour, take a look at the [quick start
|
|||
guide](https://grpc.io/docs/languages/java/quickstart) or the more explanatory [gRPC
|
||||
basics](https://grpc.io/docs/languages/java/basics).
|
||||
|
||||
The [examples](https://github.com/grpc/grpc-java/tree/v1.65.0/examples) and the
|
||||
[Android example](https://github.com/grpc/grpc-java/tree/v1.65.0/examples/android)
|
||||
The [examples](https://github.com/grpc/grpc-java/tree/v1.66.0/examples) and the
|
||||
[Android example](https://github.com/grpc/grpc-java/tree/v1.66.0/examples/android)
|
||||
are standalone projects that showcase the usage of gRPC.
|
||||
|
||||
Download
|
||||
|
@ -56,18 +56,18 @@ Download [the JARs][]. Or for Maven with non-Android, add to your `pom.xml`:
|
|||
<dependency>
|
||||
<groupId>io.grpc</groupId>
|
||||
<artifactId>grpc-netty-shaded</artifactId>
|
||||
<version>1.65.0</version>
|
||||
<version>1.66.0</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.grpc</groupId>
|
||||
<artifactId>grpc-protobuf</artifactId>
|
||||
<version>1.65.0</version>
|
||||
<version>1.66.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.grpc</groupId>
|
||||
<artifactId>grpc-stub</artifactId>
|
||||
<version>1.65.0</version>
|
||||
<version>1.66.0</version>
|
||||
</dependency>
|
||||
<dependency> <!-- necessary for Java 9+ -->
|
||||
<groupId>org.apache.tomcat</groupId>
|
||||
|
@ -79,18 +79,18 @@ Download [the JARs][]. Or for Maven with non-Android, add to your `pom.xml`:
|
|||
|
||||
Or for Gradle with non-Android, add to your dependencies:
|
||||
```gradle
|
||||
runtimeOnly 'io.grpc:grpc-netty-shaded:1.65.0'
|
||||
implementation 'io.grpc:grpc-protobuf:1.65.0'
|
||||
implementation 'io.grpc:grpc-stub:1.65.0'
|
||||
runtimeOnly 'io.grpc:grpc-netty-shaded:1.66.0'
|
||||
implementation 'io.grpc:grpc-protobuf:1.66.0'
|
||||
implementation 'io.grpc:grpc-stub:1.66.0'
|
||||
compileOnly 'org.apache.tomcat:annotations-api:6.0.53' // necessary for Java 9+
|
||||
```
|
||||
|
||||
For Android client, use `grpc-okhttp` instead of `grpc-netty-shaded` and
|
||||
`grpc-protobuf-lite` instead of `grpc-protobuf`:
|
||||
```gradle
|
||||
implementation 'io.grpc:grpc-okhttp:1.65.0'
|
||||
implementation 'io.grpc:grpc-protobuf-lite:1.65.0'
|
||||
implementation 'io.grpc:grpc-stub:1.65.0'
|
||||
implementation 'io.grpc:grpc-okhttp:1.66.0'
|
||||
implementation 'io.grpc:grpc-protobuf-lite:1.66.0'
|
||||
implementation 'io.grpc:grpc-stub:1.66.0'
|
||||
compileOnly 'org.apache.tomcat:annotations-api:6.0.53' // necessary for Java 9+
|
||||
```
|
||||
|
||||
|
@ -99,7 +99,7 @@ For [Bazel](https://bazel.build), you can either
|
|||
(with the GAVs from above), or use `@io_grpc_grpc_java//api` et al (see below).
|
||||
|
||||
[the JARs]:
|
||||
https://search.maven.org/search?q=g:io.grpc%20AND%20v:1.65.0
|
||||
https://search.maven.org/search?q=g:io.grpc%20AND%20v:1.66.0
|
||||
|
||||
Development snapshots are available in [Sonatypes's snapshot
|
||||
repository](https://oss.sonatype.org/content/repositories/snapshots/).
|
||||
|
@ -129,9 +129,9 @@ For protobuf-based codegen integrated with the Maven build system, you can use
|
|||
<artifactId>protobuf-maven-plugin</artifactId>
|
||||
<version>0.6.1</version>
|
||||
<configuration>
|
||||
<protocArtifact>com.google.protobuf:protoc:3.25.1:exe:${os.detected.classifier}</protocArtifact>
|
||||
<protocArtifact>com.google.protobuf:protoc:3.25.3:exe:${os.detected.classifier}</protocArtifact>
|
||||
<pluginId>grpc-java</pluginId>
|
||||
<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.65.0:exe:${os.detected.classifier}</pluginArtifact>
|
||||
<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.66.0:exe:${os.detected.classifier}</pluginArtifact>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
|
@ -157,11 +157,11 @@ plugins {
|
|||
|
||||
protobuf {
|
||||
protoc {
|
||||
artifact = "com.google.protobuf:protoc:3.25.1"
|
||||
artifact = "com.google.protobuf:protoc:3.25.3"
|
||||
}
|
||||
plugins {
|
||||
grpc {
|
||||
artifact = 'io.grpc:protoc-gen-grpc-java:1.65.0'
|
||||
artifact = 'io.grpc:protoc-gen-grpc-java:1.66.0'
|
||||
}
|
||||
}
|
||||
generateProtoTasks {
|
||||
|
@ -190,11 +190,11 @@ plugins {
|
|||
|
||||
protobuf {
|
||||
protoc {
|
||||
artifact = "com.google.protobuf:protoc:3.25.1"
|
||||
artifact = "com.google.protobuf:protoc:3.25.3"
|
||||
}
|
||||
plugins {
|
||||
grpc {
|
||||
artifact = 'io.grpc:protoc-gen-grpc-java:1.65.0'
|
||||
artifact = 'io.grpc:protoc-gen-grpc-java:1.66.0'
|
||||
}
|
||||
}
|
||||
generateProtoTasks {
|
||||
|
|
|
@ -246,16 +246,6 @@ public abstract class NameResolver {
|
|||
*/
|
||||
@Override
|
||||
public abstract void onError(Status error);
|
||||
|
||||
/**
|
||||
* Handles updates on resolved addresses and attributes.
|
||||
*
|
||||
* @param resolutionResult the resolved server addresses, attributes, and Service Config.
|
||||
* @since 1.66
|
||||
*/
|
||||
public Status onResult2(ResolutionResult resolutionResult) {
|
||||
throw new UnsupportedOperationException("Not implemented.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -21,7 +21,7 @@ subprojects {
|
|||
apply plugin: "net.ltgt.errorprone"
|
||||
|
||||
group = "io.grpc"
|
||||
version = "1.66.0-SNAPSHOT" // CURRENT_GRPC_VERSION
|
||||
version = "1.66.0" // CURRENT_GRPC_VERSION
|
||||
|
||||
repositories {
|
||||
maven { // The google mirror is less flaky than mavenCentral()
|
||||
|
|
|
@ -8,7 +8,7 @@ import static io.grpc.MethodDescriptor.generateFullMethodName;
|
|||
* </pre>
|
||||
*/
|
||||
@javax.annotation.Generated(
|
||||
value = "by gRPC proto compiler (version 1.66.0-SNAPSHOT)",
|
||||
value = "by gRPC proto compiler (version 1.66.0)",
|
||||
comments = "Source: grpc/testing/compiler/test.proto")
|
||||
@io.grpc.stub.annotations.GrpcGenerated
|
||||
@java.lang.Deprecated
|
||||
|
|
|
@ -8,7 +8,7 @@ import static io.grpc.MethodDescriptor.generateFullMethodName;
|
|||
* </pre>
|
||||
*/
|
||||
@javax.annotation.Generated(
|
||||
value = "by gRPC proto compiler (version 1.66.0-SNAPSHOT)",
|
||||
value = "by gRPC proto compiler (version 1.66.0)",
|
||||
comments = "Source: grpc/testing/compiler/test.proto")
|
||||
@io.grpc.stub.annotations.GrpcGenerated
|
||||
public final class TestServiceGrpc {
|
||||
|
|
|
@ -330,9 +330,7 @@ public class DnsNameResolver extends NameResolver {
|
|||
resolutionResultBuilder.setAttributes(result.attributes);
|
||||
}
|
||||
}
|
||||
syncContext.execute(() -> {
|
||||
savedListener.onResult2(resolutionResultBuilder.build());
|
||||
});
|
||||
savedListener.onResult(resolutionResultBuilder.build());
|
||||
} catch (IOException e) {
|
||||
savedListener.onError(
|
||||
Status.UNAVAILABLE.withDescription("Unable to resolve host " + host).withCause(e));
|
||||
|
|
|
@ -219,7 +219,7 @@ public final class GrpcUtil {
|
|||
|
||||
public static final Splitter ACCEPT_ENCODING_SPLITTER = Splitter.on(',').trimResults();
|
||||
|
||||
public static final String IMPLEMENTATION_VERSION = "1.66.0-SNAPSHOT"; // CURRENT_GRPC_VERSION
|
||||
public static final String IMPLEMENTATION_VERSION = "1.66.0"; // CURRENT_GRPC_VERSION
|
||||
|
||||
/**
|
||||
* The default timeout in nanos for a keepalive ping request.
|
||||
|
|
|
@ -1673,24 +1673,11 @@ final class ManagedChannelImpl extends ManagedChannel implements
|
|||
public void onResult(final ResolutionResult resolutionResult) {
|
||||
final class NamesResolved implements Runnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Status status = onResult2(resolutionResult);
|
||||
ResolutionResultListener resolutionResultListener = resolutionResult.getAttributes()
|
||||
.get(RetryingNameResolver.RESOLUTION_RESULT_LISTENER_KEY);
|
||||
resolutionResultListener.resolutionAttempted(status);
|
||||
}
|
||||
}
|
||||
|
||||
syncContext.execute(new NamesResolved());
|
||||
}
|
||||
|
||||
@SuppressWarnings("ReferenceEquality")
|
||||
@Override
|
||||
public Status onResult2(final ResolutionResult resolutionResult) {
|
||||
syncContext.throwIfNotInThisSynchronizationContext();
|
||||
public void run() {
|
||||
if (ManagedChannelImpl.this.nameResolver != resolver) {
|
||||
return Status.OK;
|
||||
return;
|
||||
}
|
||||
|
||||
List<EquivalentAddressGroup> servers = resolutionResult.getAddresses();
|
||||
|
@ -1706,6 +1693,8 @@ final class ManagedChannelImpl extends ManagedChannel implements
|
|||
}
|
||||
|
||||
ConfigOrError configOrError = resolutionResult.getServiceConfig();
|
||||
ResolutionResultListener resolutionResultListener = resolutionResult.getAttributes()
|
||||
.get(RetryingNameResolver.RESOLUTION_RESULT_LISTENER_KEY);
|
||||
InternalConfigSelector resolvedConfigSelector =
|
||||
resolutionResult.getAttributes().get(InternalConfigSelector.KEY);
|
||||
ManagedChannelServiceConfig validServiceConfig =
|
||||
|
@ -1762,7 +1751,10 @@ final class ManagedChannelImpl extends ManagedChannel implements
|
|||
// we later check for these error codes when investigating pick results in
|
||||
// GrpcUtil.getTransportFromPickResult().
|
||||
onError(configOrError.getError());
|
||||
return configOrError.getError();
|
||||
if (resolutionResultListener != null) {
|
||||
resolutionResultListener.resolutionAttempted(configOrError.getError());
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
effectiveServiceConfig = lastServiceConfig;
|
||||
}
|
||||
|
@ -1806,14 +1798,21 @@ final class ManagedChannelImpl extends ManagedChannel implements
|
|||
}
|
||||
Attributes attributes = attrBuilder.build();
|
||||
|
||||
return helper.lb.tryAcceptResolvedAddresses(
|
||||
Status addressAcceptanceStatus = helper.lb.tryAcceptResolvedAddresses(
|
||||
ResolvedAddresses.newBuilder()
|
||||
.setAddresses(servers)
|
||||
.setAttributes(attributes)
|
||||
.setLoadBalancingPolicyConfig(effectiveServiceConfig.getLoadBalancingConfig())
|
||||
.build());
|
||||
// If a listener is provided, let it know if the addresses were accepted.
|
||||
if (resolutionResultListener != null) {
|
||||
resolutionResultListener.resolutionAttempted(addressAcceptanceStatus);
|
||||
}
|
||||
return Status.OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
syncContext.execute(new NamesResolved());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -95,24 +95,12 @@ final class RetryingNameResolver extends ForwardingNameResolver {
|
|||
"RetryingNameResolver can only be used once to wrap a NameResolver");
|
||||
}
|
||||
|
||||
// To have retry behavior for name resolvers that haven't migrated to onResult2.
|
||||
delegateListener.onResult(resolutionResult.toBuilder().setAttributes(
|
||||
resolutionResult.getAttributes().toBuilder()
|
||||
.set(RESOLUTION_RESULT_LISTENER_KEY, new ResolutionResultListener()).build())
|
||||
.build());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Status onResult2(ResolutionResult resolutionResult) {
|
||||
Status status = delegateListener.onResult2(resolutionResult);
|
||||
if (status.isOk()) {
|
||||
retryScheduler.reset();
|
||||
} else {
|
||||
retryScheduler.schedule(new DelayedNameResolverRefresh());
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Status error) {
|
||||
delegateListener.onError(error);
|
||||
|
|
|
@ -26,6 +26,7 @@ import static org.junit.Assert.assertTrue;
|
|||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.isA;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.times;
|
||||
|
@ -225,7 +226,13 @@ public class DnsNameResolverTest {
|
|||
System.getProperty(DnsNameResolver.NETWORKADDRESS_CACHE_TTL_PROPERTY);
|
||||
|
||||
// By default the mock listener processes the result successfully.
|
||||
when(mockListener.onResult2(isA(ResolutionResult.class))).thenReturn(Status.OK);
|
||||
doAnswer(invocation -> {
|
||||
ResolutionResult result = invocation.getArgument(0);
|
||||
syncContext.execute(
|
||||
() -> result.getAttributes().get(RetryingNameResolver.RESOLUTION_RESULT_LISTENER_KEY)
|
||||
.resolutionAttempted(Status.OK));
|
||||
return null;
|
||||
}).when(mockListener).onResult(isA(ResolutionResult.class));
|
||||
}
|
||||
|
||||
@After
|
||||
|
@ -312,13 +319,13 @@ public class DnsNameResolverTest {
|
|||
|
||||
resolver.start(mockListener);
|
||||
assertEquals(1, fakeExecutor.runDueTasks());
|
||||
verify(mockListener).onResult2(resultCaptor.capture());
|
||||
verify(mockListener).onResult(resultCaptor.capture());
|
||||
assertAnswerMatches(answer1, 81, resultCaptor.getValue());
|
||||
assertEquals(0, fakeClock.numPendingTasks());
|
||||
|
||||
resolver.refresh();
|
||||
assertEquals(1, fakeExecutor.runDueTasks());
|
||||
verify(mockListener, times(2)).onResult2(resultCaptor.capture());
|
||||
verify(mockListener, times(2)).onResult(resultCaptor.capture());
|
||||
assertAnswerMatches(answer2, 81, resultCaptor.getValue());
|
||||
assertEquals(0, fakeClock.numPendingTasks());
|
||||
assertEquals(0, fakeExecutor.numPendingTasks());
|
||||
|
@ -340,7 +347,7 @@ public class DnsNameResolverTest {
|
|||
|
||||
resolver.start(mockListener);
|
||||
assertEquals(1, fakeExecutor.runDueTasks());
|
||||
verify(mockListener).onResult2(resultCaptor.capture());
|
||||
verify(mockListener).onResult(resultCaptor.capture());
|
||||
assertAnswerMatches(answer, 81, resultCaptor.getValue());
|
||||
assertEquals(0, fakeClock.numPendingTasks());
|
||||
assertEquals(0, fakeExecutor.numPendingTasks());
|
||||
|
@ -382,7 +389,7 @@ public class DnsNameResolverTest {
|
|||
|
||||
resolver.start(mockListener);
|
||||
assertEquals(0, fakeExecutor.runDueTasks());
|
||||
verify(mockListener).onResult2(resultCaptor.capture());
|
||||
verify(mockListener).onResult(resultCaptor.capture());
|
||||
assertAnswerMatches(answer, 81, resultCaptor.getValue());
|
||||
assertEquals(0, fakeClock.numPendingTasks());
|
||||
assertEquals(0, fakeExecutor.numPendingTasks());
|
||||
|
@ -411,7 +418,7 @@ public class DnsNameResolverTest {
|
|||
|
||||
resolver.start(mockListener);
|
||||
assertEquals(1, fakeExecutor.runDueTasks());
|
||||
verify(mockListener).onResult2(resultCaptor.capture());
|
||||
verify(mockListener).onResult(resultCaptor.capture());
|
||||
assertAnswerMatches(answer1, 81, resultCaptor.getValue());
|
||||
assertEquals(0, fakeClock.numPendingTasks());
|
||||
|
||||
|
@ -445,7 +452,7 @@ public class DnsNameResolverTest {
|
|||
|
||||
resolver.start(mockListener);
|
||||
assertEquals(1, fakeExecutor.runDueTasks());
|
||||
verify(mockListener).onResult2(resultCaptor.capture());
|
||||
verify(mockListener).onResult(resultCaptor.capture());
|
||||
assertAnswerMatches(answer, 81, resultCaptor.getValue());
|
||||
assertEquals(0, fakeClock.numPendingTasks());
|
||||
|
||||
|
@ -480,14 +487,14 @@ public class DnsNameResolverTest {
|
|||
|
||||
resolver.start(mockListener);
|
||||
assertEquals(1, fakeExecutor.runDueTasks());
|
||||
verify(mockListener).onResult2(resultCaptor.capture());
|
||||
verify(mockListener).onResult(resultCaptor.capture());
|
||||
assertAnswerMatches(answer1, 81, resultCaptor.getValue());
|
||||
assertEquals(0, fakeClock.numPendingTasks());
|
||||
|
||||
fakeTicker.advance(ttl + 1, TimeUnit.SECONDS);
|
||||
resolver.refresh();
|
||||
assertEquals(1, fakeExecutor.runDueTasks());
|
||||
verify(mockListener, times(2)).onResult2(resultCaptor.capture());
|
||||
verify(mockListener, times(2)).onResult(resultCaptor.capture());
|
||||
assertAnswerMatches(answer2, 81, resultCaptor.getValue());
|
||||
assertEquals(0, fakeClock.numPendingTasks());
|
||||
assertEquals(0, fakeExecutor.numPendingTasks());
|
||||
|
@ -524,7 +531,7 @@ public class DnsNameResolverTest {
|
|||
|
||||
resolver.start(mockListener);
|
||||
assertEquals(1, fakeExecutor.runDueTasks());
|
||||
verify(mockListener).onResult2(resultCaptor.capture());
|
||||
verify(mockListener).onResult(resultCaptor.capture());
|
||||
assertAnswerMatches(answer1, 81, resultCaptor.getValue());
|
||||
assertEquals(0, fakeClock.numPendingTasks());
|
||||
|
||||
|
@ -537,7 +544,7 @@ public class DnsNameResolverTest {
|
|||
fakeTicker.advance(1, TimeUnit.SECONDS);
|
||||
resolver.refresh();
|
||||
assertEquals(1, fakeExecutor.runDueTasks());
|
||||
verify(mockListener, times(2)).onResult2(resultCaptor.capture());
|
||||
verify(mockListener, times(2)).onResult(resultCaptor.capture());
|
||||
assertAnswerMatches(answer2, 81, resultCaptor.getValue());
|
||||
assertEquals(0, fakeClock.numPendingTasks());
|
||||
assertEquals(0, fakeExecutor.numPendingTasks());
|
||||
|
@ -568,7 +575,7 @@ public class DnsNameResolverTest {
|
|||
assertThat(fakeExecutor.runDueTasks()).isEqualTo(1);
|
||||
|
||||
ArgumentCaptor<ResolutionResult> ac = ArgumentCaptor.forClass(ResolutionResult.class);
|
||||
verify(mockListener).onResult2(ac.capture());
|
||||
verify(mockListener).onResult(ac.capture());
|
||||
verifyNoMoreInteractions(mockListener);
|
||||
assertThat(ac.getValue().getAddresses()).isEmpty();
|
||||
assertThat(ac.getValue().getServiceConfig()).isNull();
|
||||
|
@ -581,7 +588,12 @@ public class DnsNameResolverTest {
|
|||
// Load balancer rejects the empty addresses.
|
||||
@Test
|
||||
public void resolve_emptyResult_notAccepted() throws Exception {
|
||||
when(mockListener.onResult2(isA(ResolutionResult.class))).thenReturn(Status.UNAVAILABLE);
|
||||
doAnswer(invocation -> {
|
||||
ResolutionResult result = invocation.getArgument(0);
|
||||
result.getAttributes().get(RetryingNameResolver.RESOLUTION_RESULT_LISTENER_KEY)
|
||||
.resolutionAttempted(Status.UNAVAILABLE);
|
||||
return null;
|
||||
}).when(mockListener).onResult(isA(ResolutionResult.class));
|
||||
|
||||
DnsNameResolver.enableTxt = true;
|
||||
RetryingNameResolver resolver = newResolver("dns:///addr.fake:1234", 443);
|
||||
|
@ -602,7 +614,7 @@ public class DnsNameResolverTest {
|
|||
syncContext.execute(() -> assertThat(fakeExecutor.runDueTasks()).isEqualTo(1));
|
||||
|
||||
ArgumentCaptor<ResolutionResult> ac = ArgumentCaptor.forClass(ResolutionResult.class);
|
||||
verify(mockListener).onResult2(ac.capture());
|
||||
verify(mockListener).onResult(ac.capture());
|
||||
verifyNoMoreInteractions(mockListener);
|
||||
assertThat(ac.getValue().getAddresses()).isEmpty();
|
||||
assertThat(ac.getValue().getServiceConfig()).isNull();
|
||||
|
@ -628,7 +640,7 @@ public class DnsNameResolverTest {
|
|||
dnsResolver.setResourceResolver(null);
|
||||
resolver.start(mockListener);
|
||||
assertEquals(1, fakeExecutor.runDueTasks());
|
||||
verify(mockListener).onResult2(resultCaptor.capture());
|
||||
verify(mockListener).onResult(resultCaptor.capture());
|
||||
ResolutionResult result = resultCaptor.getValue();
|
||||
InetSocketAddress resolvedBackendAddr =
|
||||
(InetSocketAddress) Iterables.getOnlyElement(
|
||||
|
@ -700,7 +712,7 @@ public class DnsNameResolverTest {
|
|||
|
||||
resolver.start(mockListener);
|
||||
assertEquals(1, fakeExecutor.runDueTasks());
|
||||
verify(mockListener).onResult2(resultCaptor.capture());
|
||||
verify(mockListener).onResult(resultCaptor.capture());
|
||||
ResolutionResult result = resultCaptor.getValue();
|
||||
InetSocketAddress resolvedBackendAddr =
|
||||
(InetSocketAddress) Iterables.getOnlyElement(
|
||||
|
@ -758,7 +770,7 @@ public class DnsNameResolverTest {
|
|||
dnsResolver.setResourceResolver(mockResourceResolver);
|
||||
resolver.start(mockListener);
|
||||
assertEquals(1, fakeExecutor.runDueTasks());
|
||||
verify(mockListener).onResult2(resultCaptor.capture());
|
||||
verify(mockListener).onResult(resultCaptor.capture());
|
||||
ResolutionResult result = resultCaptor.getValue();
|
||||
InetSocketAddress resolvedBackendAddr =
|
||||
(InetSocketAddress) Iterables.getOnlyElement(
|
||||
|
@ -790,7 +802,7 @@ public class DnsNameResolverTest {
|
|||
dnsResolver.setResourceResolver(mockResourceResolver);
|
||||
resolver.start(mockListener);
|
||||
assertEquals(1, fakeExecutor.runDueTasks());
|
||||
verify(mockListener).onResult2(resultCaptor.capture());
|
||||
verify(mockListener).onResult(resultCaptor.capture());
|
||||
ResolutionResult result = resultCaptor.getValue();
|
||||
InetSocketAddress resolvedBackendAddr =
|
||||
(InetSocketAddress) Iterables.getOnlyElement(
|
||||
|
@ -858,7 +870,7 @@ public class DnsNameResolverTest {
|
|||
resolver.start(mockListener);
|
||||
assertEquals(1, fakeExecutor.runDueTasks());
|
||||
|
||||
verify(mockListener).onResult2(resultCaptor.capture());
|
||||
verify(mockListener).onResult(resultCaptor.capture());
|
||||
List<EquivalentAddressGroup> result = resultCaptor.getValue().getAddresses();
|
||||
assertThat(result).hasSize(1);
|
||||
EquivalentAddressGroup eag = result.get(0);
|
||||
|
|
|
@ -1054,79 +1054,6 @@ public class ManagedChannelImplTest {
|
|||
verifyNoMoreInteractions(mockLoadBalancer);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noMoreCallbackAfterLoadBalancerShutdown_configError() throws InterruptedException {
|
||||
FakeNameResolverFactory nameResolverFactory =
|
||||
new FakeNameResolverFactory.Builder(expectedUri)
|
||||
.setServers(Collections.singletonList(new EquivalentAddressGroup(socketAddress)))
|
||||
.build();
|
||||
channelBuilder.nameResolverFactory(nameResolverFactory);
|
||||
Status resolutionError = Status.UNAVAILABLE.withDescription("Resolution failed");
|
||||
createChannel();
|
||||
|
||||
FakeNameResolverFactory.FakeNameResolver resolver = nameResolverFactory.resolvers.get(0);
|
||||
verify(mockLoadBalancerProvider).newLoadBalancer(any(Helper.class));
|
||||
verify(mockLoadBalancer).acceptResolvedAddresses(resolvedAddressCaptor.capture());
|
||||
assertThat(resolvedAddressCaptor.getValue().getAddresses()).containsExactly(addressGroup);
|
||||
|
||||
SubchannelStateListener stateListener1 = mock(SubchannelStateListener.class);
|
||||
SubchannelStateListener stateListener2 = mock(SubchannelStateListener.class);
|
||||
Subchannel subchannel1 =
|
||||
createSubchannelSafely(helper, addressGroup, Attributes.EMPTY, stateListener1);
|
||||
Subchannel subchannel2 =
|
||||
createSubchannelSafely(helper, addressGroup, Attributes.EMPTY, stateListener2);
|
||||
requestConnectionSafely(helper, subchannel1);
|
||||
requestConnectionSafely(helper, subchannel2);
|
||||
verify(mockTransportFactory, times(2))
|
||||
.newClientTransport(
|
||||
any(SocketAddress.class), any(ClientTransportOptions.class), any(ChannelLogger.class));
|
||||
MockClientTransportInfo transportInfo1 = transports.poll();
|
||||
MockClientTransportInfo transportInfo2 = transports.poll();
|
||||
|
||||
// LoadBalancer receives all sorts of callbacks
|
||||
transportInfo1.listener.transportReady();
|
||||
|
||||
verify(stateListener1, times(2)).onSubchannelState(stateInfoCaptor.capture());
|
||||
assertSame(CONNECTING, stateInfoCaptor.getAllValues().get(0).getState());
|
||||
assertSame(READY, stateInfoCaptor.getAllValues().get(1).getState());
|
||||
|
||||
verify(stateListener2).onSubchannelState(stateInfoCaptor.capture());
|
||||
assertSame(CONNECTING, stateInfoCaptor.getValue().getState());
|
||||
|
||||
resolver.listener.onError(resolutionError);
|
||||
verify(mockLoadBalancer).handleNameResolutionError(resolutionError);
|
||||
|
||||
verifyNoMoreInteractions(mockLoadBalancer);
|
||||
|
||||
channel.shutdown();
|
||||
verify(mockLoadBalancer).shutdown();
|
||||
verifyNoMoreInteractions(stateListener1, stateListener2);
|
||||
|
||||
// LoadBalancer will normally shutdown all subchannels
|
||||
shutdownSafely(helper, subchannel1);
|
||||
shutdownSafely(helper, subchannel2);
|
||||
|
||||
// Since subchannels are shutdown, SubchannelStateListeners will only get SHUTDOWN regardless of
|
||||
// the transport states.
|
||||
transportInfo1.listener.transportShutdown(Status.UNAVAILABLE);
|
||||
transportInfo2.listener.transportReady();
|
||||
verify(stateListener1).onSubchannelState(ConnectivityStateInfo.forNonError(SHUTDOWN));
|
||||
verify(stateListener2).onSubchannelState(ConnectivityStateInfo.forNonError(SHUTDOWN));
|
||||
verifyNoMoreInteractions(stateListener1, stateListener2);
|
||||
|
||||
// No more callback should be delivered to LoadBalancer after it's shut down
|
||||
resolver.listener.onResult(
|
||||
ResolutionResult.newBuilder()
|
||||
.setAddresses(new ArrayList<>())
|
||||
.setServiceConfig(
|
||||
ConfigOrError.fromError(Status.UNAVAILABLE.withDescription("Resolution failed")))
|
||||
.build());
|
||||
Thread.sleep(1100);
|
||||
assertThat(timer.getPendingTasks()).isEmpty();
|
||||
resolver.resolved();
|
||||
verifyNoMoreInteractions(mockLoadBalancer);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void interceptor() throws Exception {
|
||||
final AtomicLong atomic = new AtomicLong();
|
||||
|
@ -3211,48 +3138,6 @@ public class ManagedChannelImplTest {
|
|||
assertThat(getStats(channel).channelTrace.events).hasSize(prevSize + 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void channelTracing_nameResolvedEvent_zeorAndNonzeroBackends_usesListener2onResult2()
|
||||
throws Exception {
|
||||
timer.forwardNanos(1234);
|
||||
channelBuilder.maxTraceEvents(10);
|
||||
List<EquivalentAddressGroup> servers = new ArrayList<>();
|
||||
servers.add(new EquivalentAddressGroup(socketAddress));
|
||||
FakeNameResolverFactory nameResolverFactory =
|
||||
new FakeNameResolverFactory.Builder(expectedUri).setServers(servers).build();
|
||||
channelBuilder.nameResolverFactory(nameResolverFactory);
|
||||
createChannel();
|
||||
|
||||
int prevSize = getStats(channel).channelTrace.events.size();
|
||||
ResolutionResult resolutionResult1 = ResolutionResult.newBuilder()
|
||||
.setAddresses(Collections.singletonList(
|
||||
new EquivalentAddressGroup(
|
||||
Arrays.asList(new SocketAddress() {}, new SocketAddress() {}))))
|
||||
.build();
|
||||
|
||||
channel.syncContext.execute(
|
||||
() -> nameResolverFactory.resolvers.get(0).listener.onResult2(resolutionResult1));
|
||||
assertThat(getStats(channel).channelTrace.events).hasSize(prevSize);
|
||||
|
||||
prevSize = getStats(channel).channelTrace.events.size();
|
||||
nameResolverFactory.resolvers.get(0).listener.onError(Status.INTERNAL);
|
||||
assertThat(getStats(channel).channelTrace.events).hasSize(prevSize + 1);
|
||||
|
||||
prevSize = getStats(channel).channelTrace.events.size();
|
||||
nameResolverFactory.resolvers.get(0).listener.onError(Status.INTERNAL);
|
||||
assertThat(getStats(channel).channelTrace.events).hasSize(prevSize);
|
||||
|
||||
prevSize = getStats(channel).channelTrace.events.size();
|
||||
ResolutionResult resolutionResult2 = ResolutionResult.newBuilder()
|
||||
.setAddresses(Collections.singletonList(
|
||||
new EquivalentAddressGroup(
|
||||
Arrays.asList(new SocketAddress() {}, new SocketAddress() {}))))
|
||||
.build();
|
||||
channel.syncContext.execute(
|
||||
() -> nameResolverFactory.resolvers.get(0).listener.onResult2(resolutionResult2));
|
||||
assertThat(getStats(channel).channelTrace.events).hasSize(prevSize + 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void channelTracing_serviceConfigChange() throws Exception {
|
||||
timer.forwardNanos(1234);
|
||||
|
@ -3312,69 +3197,6 @@ public class ManagedChannelImplTest {
|
|||
.build());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void channelTracing_serviceConfigChange_usesListener2OnResult2() throws Exception {
|
||||
timer.forwardNanos(1234);
|
||||
channelBuilder.maxTraceEvents(10);
|
||||
List<EquivalentAddressGroup> servers = new ArrayList<>();
|
||||
servers.add(new EquivalentAddressGroup(socketAddress));
|
||||
FakeNameResolverFactory nameResolverFactory =
|
||||
new FakeNameResolverFactory.Builder(expectedUri).setServers(servers).build();
|
||||
channelBuilder.nameResolverFactory(nameResolverFactory);
|
||||
createChannel();
|
||||
|
||||
int prevSize = getStats(channel).channelTrace.events.size();
|
||||
ManagedChannelServiceConfig mcsc1 = createManagedChannelServiceConfig(
|
||||
ImmutableMap.<String, Object>of(),
|
||||
new PolicySelection(
|
||||
mockLoadBalancerProvider, null));
|
||||
ResolutionResult resolutionResult1 = ResolutionResult.newBuilder()
|
||||
.setAddresses(Collections.singletonList(
|
||||
new EquivalentAddressGroup(
|
||||
Arrays.asList(new SocketAddress() {}, new SocketAddress() {}))))
|
||||
.setServiceConfig(ConfigOrError.fromConfig(mcsc1))
|
||||
.build();
|
||||
|
||||
channel.syncContext.execute(() ->
|
||||
nameResolverFactory.resolvers.get(0).listener.onResult2(resolutionResult1));
|
||||
assertThat(getStats(channel).channelTrace.events).hasSize(prevSize + 1);
|
||||
assertThat(getStats(channel).channelTrace.events.get(prevSize))
|
||||
.isEqualTo(new ChannelTrace.Event.Builder()
|
||||
.setDescription("Service config changed")
|
||||
.setSeverity(ChannelTrace.Event.Severity.CT_INFO)
|
||||
.setTimestampNanos(timer.getTicker().read())
|
||||
.build());
|
||||
|
||||
prevSize = getStats(channel).channelTrace.events.size();
|
||||
ResolutionResult resolutionResult2 = ResolutionResult.newBuilder().setAddresses(
|
||||
Collections.singletonList(
|
||||
new EquivalentAddressGroup(
|
||||
Arrays.asList(new SocketAddress() {}, new SocketAddress() {}))))
|
||||
.setServiceConfig(ConfigOrError.fromConfig(mcsc1))
|
||||
.build();
|
||||
channel.syncContext.execute(() ->
|
||||
nameResolverFactory.resolvers.get(0).listener.onResult(resolutionResult2));
|
||||
assertThat(getStats(channel).channelTrace.events).hasSize(prevSize);
|
||||
|
||||
prevSize = getStats(channel).channelTrace.events.size();
|
||||
timer.forwardNanos(1234);
|
||||
ResolutionResult resolutionResult3 = ResolutionResult.newBuilder()
|
||||
.setAddresses(Collections.singletonList(
|
||||
new EquivalentAddressGroup(
|
||||
Arrays.asList(new SocketAddress() {}, new SocketAddress() {}))))
|
||||
.setServiceConfig(ConfigOrError.fromConfig(ManagedChannelServiceConfig.empty()))
|
||||
.build();
|
||||
channel.syncContext.execute(() ->
|
||||
nameResolverFactory.resolvers.get(0).listener.onResult(resolutionResult3));
|
||||
assertThat(getStats(channel).channelTrace.events).hasSize(prevSize + 1);
|
||||
assertThat(getStats(channel).channelTrace.events.get(prevSize))
|
||||
.isEqualTo(new ChannelTrace.Event.Builder()
|
||||
.setDescription("Service config changed")
|
||||
.setSeverity(ChannelTrace.Event.Severity.CT_INFO)
|
||||
.setTimestampNanos(timer.getTicker().read())
|
||||
.build());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void channelTracing_stateChangeEvent() throws Exception {
|
||||
channelBuilder.maxTraceEvents(10);
|
||||
|
@ -4035,120 +3857,6 @@ public class ManagedChannelImplTest {
|
|||
mychannel.shutdownNow();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void badServiceConfigIsRecoverable_usesListener2OnResult2() throws Exception {
|
||||
final List<EquivalentAddressGroup> addresses =
|
||||
ImmutableList.of(new EquivalentAddressGroup(new SocketAddress() {}));
|
||||
final class FakeNameResolver extends NameResolver {
|
||||
Listener2 listener;
|
||||
private final SynchronizationContext syncContext;
|
||||
|
||||
FakeNameResolver(Args args) {
|
||||
this.syncContext = args.getSynchronizationContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServiceAuthority() {
|
||||
return "also fake";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(Listener2 listener) {
|
||||
this.listener = listener;
|
||||
syncContext.execute(() ->
|
||||
listener.onResult2(
|
||||
ResolutionResult.newBuilder()
|
||||
.setAddresses(addresses)
|
||||
.setServiceConfig(
|
||||
ConfigOrError.fromError(
|
||||
Status.INTERNAL.withDescription("kaboom is invalid")))
|
||||
.build()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() {}
|
||||
}
|
||||
|
||||
final class FakeNameResolverFactory2 extends NameResolver.Factory {
|
||||
FakeNameResolver resolver;
|
||||
ManagedChannelImpl managedChannel;
|
||||
SynchronizationContext syncContext;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public NameResolver newNameResolver(URI targetUri, NameResolver.Args args) {
|
||||
syncContext = args.getSynchronizationContext();
|
||||
return (resolver = new FakeNameResolver(args));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDefaultScheme() {
|
||||
return "fake";
|
||||
}
|
||||
}
|
||||
|
||||
FakeNameResolverFactory2 factory = new FakeNameResolverFactory2();
|
||||
|
||||
ManagedChannelImplBuilder customBuilder = new ManagedChannelImplBuilder(TARGET,
|
||||
new ClientTransportFactoryBuilder() {
|
||||
@Override
|
||||
public ClientTransportFactory buildClientTransportFactory() {
|
||||
return mockTransportFactory;
|
||||
}
|
||||
},
|
||||
null);
|
||||
when(mockTransportFactory.getSupportedSocketAddressTypes()).thenReturn(Collections.singleton(
|
||||
InetSocketAddress.class));
|
||||
customBuilder.executorPool = executorPool;
|
||||
customBuilder.channelz = channelz;
|
||||
ManagedChannel mychannel = customBuilder.nameResolverFactory(factory).build();
|
||||
|
||||
ClientCall<Void, Void> call1 =
|
||||
mychannel.newCall(TestMethodDescriptors.voidMethod(), CallOptions.DEFAULT);
|
||||
ListenableFuture<Void> future1 = ClientCalls.futureUnaryCall(call1, null);
|
||||
executor.runDueTasks();
|
||||
try {
|
||||
future1.get(1, TimeUnit.SECONDS);
|
||||
Assert.fail();
|
||||
} catch (ExecutionException e) {
|
||||
assertThat(Throwables.getStackTraceAsString(e.getCause())).contains("kaboom");
|
||||
}
|
||||
|
||||
// ok the service config is bad, let's fix it.
|
||||
Map<String, Object> rawServiceConfig =
|
||||
parseConfig("{\"loadBalancingConfig\": [{\"round_robin\": {}}]}");
|
||||
Object fakeLbConfig = new Object();
|
||||
PolicySelection lbConfigs =
|
||||
new PolicySelection(
|
||||
mockLoadBalancerProvider, fakeLbConfig);
|
||||
mockLoadBalancerProvider.parseLoadBalancingPolicyConfig(rawServiceConfig);
|
||||
ManagedChannelServiceConfig managedChannelServiceConfig =
|
||||
createManagedChannelServiceConfig(rawServiceConfig, lbConfigs);
|
||||
factory.syncContext.execute(() ->
|
||||
factory.resolver.listener.onResult2(
|
||||
ResolutionResult.newBuilder()
|
||||
.setAddresses(addresses)
|
||||
.setServiceConfig(ConfigOrError.fromConfig(managedChannelServiceConfig))
|
||||
.build()));
|
||||
|
||||
ClientCall<Void, Void> call2 = mychannel.newCall(
|
||||
TestMethodDescriptors.voidMethod(),
|
||||
CallOptions.DEFAULT.withDeadlineAfter(5, TimeUnit.SECONDS));
|
||||
ListenableFuture<Void> future2 = ClientCalls.futureUnaryCall(call2, null);
|
||||
|
||||
timer.forwardTime(1234, TimeUnit.SECONDS);
|
||||
|
||||
executor.runDueTasks();
|
||||
try {
|
||||
future2.get();
|
||||
Assert.fail();
|
||||
} catch (ExecutionException e) {
|
||||
assertThat(Throwables.getStackTraceAsString(e.getCause())).contains("deadline");
|
||||
}
|
||||
|
||||
mychannel.shutdownNow();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nameResolverArgsPropagation() {
|
||||
final AtomicReference<NameResolver.Args> capturedArgs = new AtomicReference<>();
|
||||
|
@ -4810,7 +4518,7 @@ public class ManagedChannelImplTest {
|
|||
}
|
||||
assertEquals(DEFAULT_PORT, args.getDefaultPort());
|
||||
FakeNameResolverFactory.FakeNameResolver resolver =
|
||||
new FakeNameResolverFactory.FakeNameResolver(targetUri, error, args);
|
||||
new FakeNameResolverFactory.FakeNameResolver(targetUri, error);
|
||||
resolvers.add(resolver);
|
||||
return resolver;
|
||||
}
|
||||
|
@ -4838,16 +4546,14 @@ public class ManagedChannelImplTest {
|
|||
|
||||
final class FakeNameResolver extends NameResolver {
|
||||
final URI targetUri;
|
||||
final SynchronizationContext syncContext;
|
||||
Listener2 listener;
|
||||
boolean shutdown;
|
||||
int refreshCalled;
|
||||
Status error;
|
||||
|
||||
FakeNameResolver(URI targetUri, Status error, Args args) {
|
||||
FakeNameResolver(URI targetUri, Status error) {
|
||||
this.targetUri = targetUri;
|
||||
this.error = error;
|
||||
syncContext = args.getSynchronizationContext();
|
||||
}
|
||||
|
||||
@Override public String getServiceAuthority() {
|
||||
|
@ -4879,7 +4585,7 @@ public class ManagedChannelImplTest {
|
|||
if (configOrError != null) {
|
||||
builder.setServiceConfig(configOrError);
|
||||
}
|
||||
syncContext.execute(() -> listener.onResult(builder.build()));
|
||||
listener.onResult(builder.build());
|
||||
}
|
||||
|
||||
@Override public void shutdown() {
|
||||
|
|
|
@ -21,7 +21,6 @@ import static org.junit.Assert.fail;
|
|||
import static org.mockito.ArgumentMatchers.isA;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import io.grpc.NameResolver;
|
||||
import io.grpc.NameResolver.Listener2;
|
||||
|
@ -80,7 +79,7 @@ public class RetryingNameResolverTest {
|
|||
// Make sure the ResolutionResultListener callback is added to the ResolutionResult attributes,
|
||||
// and the retry scheduler is reset since the name resolution was successful.
|
||||
@Test
|
||||
public void onResult_success() {
|
||||
public void onResult_sucess() {
|
||||
retryingNameResolver.start(mockListener);
|
||||
verify(mockNameResolver).start(listenerCaptor.capture());
|
||||
|
||||
|
@ -95,18 +94,6 @@ public class RetryingNameResolverTest {
|
|||
verify(mockRetryScheduler).reset();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onResult2_sucesss() {
|
||||
when(mockListener.onResult2(isA(ResolutionResult.class))).thenReturn(Status.OK);
|
||||
retryingNameResolver.start(mockListener);
|
||||
verify(mockNameResolver).start(listenerCaptor.capture());
|
||||
|
||||
assertThat(listenerCaptor.getValue().onResult2(ResolutionResult.newBuilder().build()))
|
||||
.isEqualTo(Status.OK);
|
||||
|
||||
verify(mockRetryScheduler).reset();
|
||||
}
|
||||
|
||||
// Make sure the ResolutionResultListener callback is added to the ResolutionResult attributes,
|
||||
// and that a retry gets scheduled when the resolution results are rejected.
|
||||
@Test
|
||||
|
@ -125,19 +112,6 @@ public class RetryingNameResolverTest {
|
|||
verify(mockRetryScheduler).schedule(isA(Runnable.class));
|
||||
}
|
||||
|
||||
// Make sure that a retry gets scheduled when the resolution results are rejected.
|
||||
@Test
|
||||
public void onResult2_failure() {
|
||||
when(mockListener.onResult2(isA(ResolutionResult.class))).thenReturn(Status.UNAVAILABLE);
|
||||
retryingNameResolver.start(mockListener);
|
||||
verify(mockNameResolver).start(listenerCaptor.capture());
|
||||
|
||||
assertThat(listenerCaptor.getValue().onResult2(ResolutionResult.newBuilder().build()))
|
||||
.isEqualTo(Status.UNAVAILABLE);
|
||||
|
||||
verify(mockRetryScheduler).schedule(isA(Runnable.class));
|
||||
}
|
||||
|
||||
// Wrapping a NameResolver more than once is a misconfiguration.
|
||||
@Test
|
||||
public void onResult_failure_doubleWrapped() {
|
||||
|
|
|
@ -34,7 +34,7 @@ android {
|
|||
protobuf {
|
||||
protoc { artifact = 'com.google.protobuf:protoc:3.25.1' }
|
||||
plugins {
|
||||
grpc { artifact = 'io.grpc:protoc-gen-grpc-java:1.66.0-SNAPSHOT' // CURRENT_GRPC_VERSION
|
||||
grpc { artifact = 'io.grpc:protoc-gen-grpc-java:1.66.0' // CURRENT_GRPC_VERSION
|
||||
}
|
||||
}
|
||||
generateProtoTasks {
|
||||
|
@ -54,12 +54,12 @@ dependencies {
|
|||
implementation 'androidx.appcompat:appcompat:1.0.0'
|
||||
|
||||
// You need to build grpc-java to obtain these libraries below.
|
||||
implementation 'io.grpc:grpc-okhttp:1.66.0-SNAPSHOT' // CURRENT_GRPC_VERSION
|
||||
implementation 'io.grpc:grpc-protobuf-lite:1.66.0-SNAPSHOT' // CURRENT_GRPC_VERSION
|
||||
implementation 'io.grpc:grpc-stub:1.66.0-SNAPSHOT' // CURRENT_GRPC_VERSION
|
||||
implementation 'io.grpc:grpc-okhttp:1.66.0' // CURRENT_GRPC_VERSION
|
||||
implementation 'io.grpc:grpc-protobuf-lite:1.66.0' // CURRENT_GRPC_VERSION
|
||||
implementation 'io.grpc:grpc-stub:1.66.0' // CURRENT_GRPC_VERSION
|
||||
implementation 'org.apache.tomcat:annotations-api:6.0.53'
|
||||
|
||||
testImplementation 'junit:junit:4.13.2'
|
||||
testImplementation 'com.google.truth:truth:1.1.5'
|
||||
testImplementation 'io.grpc:grpc-testing:1.66.0-SNAPSHOT' // CURRENT_GRPC_VERSION
|
||||
testImplementation 'io.grpc:grpc-testing:1.66.0' // CURRENT_GRPC_VERSION
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ android {
|
|||
protobuf {
|
||||
protoc { artifact = 'com.google.protobuf:protoc:3.25.1' }
|
||||
plugins {
|
||||
grpc { artifact = 'io.grpc:protoc-gen-grpc-java:1.66.0-SNAPSHOT' // CURRENT_GRPC_VERSION
|
||||
grpc { artifact = 'io.grpc:protoc-gen-grpc-java:1.66.0' // CURRENT_GRPC_VERSION
|
||||
}
|
||||
}
|
||||
generateProtoTasks {
|
||||
|
@ -52,8 +52,8 @@ dependencies {
|
|||
implementation 'androidx.appcompat:appcompat:1.0.0'
|
||||
|
||||
// You need to build grpc-java to obtain these libraries below.
|
||||
implementation 'io.grpc:grpc-okhttp:1.66.0-SNAPSHOT' // CURRENT_GRPC_VERSION
|
||||
implementation 'io.grpc:grpc-protobuf-lite:1.66.0-SNAPSHOT' // CURRENT_GRPC_VERSION
|
||||
implementation 'io.grpc:grpc-stub:1.66.0-SNAPSHOT' // CURRENT_GRPC_VERSION
|
||||
implementation 'io.grpc:grpc-okhttp:1.66.0' // CURRENT_GRPC_VERSION
|
||||
implementation 'io.grpc:grpc-protobuf-lite:1.66.0' // CURRENT_GRPC_VERSION
|
||||
implementation 'io.grpc:grpc-stub:1.66.0' // CURRENT_GRPC_VERSION
|
||||
implementation 'org.apache.tomcat:annotations-api:6.0.53'
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ android {
|
|||
protobuf {
|
||||
protoc { artifact = 'com.google.protobuf:protoc:3.25.1' }
|
||||
plugins {
|
||||
grpc { artifact = 'io.grpc:protoc-gen-grpc-java:1.66.0-SNAPSHOT' // CURRENT_GRPC_VERSION
|
||||
grpc { artifact = 'io.grpc:protoc-gen-grpc-java:1.66.0' // CURRENT_GRPC_VERSION
|
||||
}
|
||||
}
|
||||
generateProtoTasks {
|
||||
|
@ -52,8 +52,8 @@ dependencies {
|
|||
implementation 'androidx.appcompat:appcompat:1.0.0'
|
||||
|
||||
// You need to build grpc-java to obtain these libraries below.
|
||||
implementation 'io.grpc:grpc-okhttp:1.66.0-SNAPSHOT' // CURRENT_GRPC_VERSION
|
||||
implementation 'io.grpc:grpc-protobuf-lite:1.66.0-SNAPSHOT' // CURRENT_GRPC_VERSION
|
||||
implementation 'io.grpc:grpc-stub:1.66.0-SNAPSHOT' // CURRENT_GRPC_VERSION
|
||||
implementation 'io.grpc:grpc-okhttp:1.66.0' // CURRENT_GRPC_VERSION
|
||||
implementation 'io.grpc:grpc-protobuf-lite:1.66.0' // CURRENT_GRPC_VERSION
|
||||
implementation 'io.grpc:grpc-stub:1.66.0' // CURRENT_GRPC_VERSION
|
||||
implementation 'org.apache.tomcat:annotations-api:6.0.53'
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ android {
|
|||
protobuf {
|
||||
protoc { artifact = 'com.google.protobuf:protoc:3.25.1' }
|
||||
plugins {
|
||||
grpc { artifact = 'io.grpc:protoc-gen-grpc-java:1.66.0-SNAPSHOT' // CURRENT_GRPC_VERSION
|
||||
grpc { artifact = 'io.grpc:protoc-gen-grpc-java:1.66.0' // CURRENT_GRPC_VERSION
|
||||
}
|
||||
}
|
||||
generateProtoTasks {
|
||||
|
@ -53,8 +53,8 @@ dependencies {
|
|||
implementation 'androidx.appcompat:appcompat:1.0.0'
|
||||
|
||||
// You need to build grpc-java to obtain these libraries below.
|
||||
implementation 'io.grpc:grpc-okhttp:1.66.0-SNAPSHOT' // CURRENT_GRPC_VERSION
|
||||
implementation 'io.grpc:grpc-protobuf-lite:1.66.0-SNAPSHOT' // CURRENT_GRPC_VERSION
|
||||
implementation 'io.grpc:grpc-stub:1.66.0-SNAPSHOT' // CURRENT_GRPC_VERSION
|
||||
implementation 'io.grpc:grpc-okhttp:1.66.0' // CURRENT_GRPC_VERSION
|
||||
implementation 'io.grpc:grpc-protobuf-lite:1.66.0' // CURRENT_GRPC_VERSION
|
||||
implementation 'io.grpc:grpc-stub:1.66.0' // CURRENT_GRPC_VERSION
|
||||
implementation 'org.apache.tomcat:annotations-api:6.0.53'
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ java {
|
|||
|
||||
// Feel free to delete the comment at the next line. It is just for safely
|
||||
// updating the version in our release process.
|
||||
def grpcVersion = '1.66.0-SNAPSHOT' // CURRENT_GRPC_VERSION
|
||||
def grpcVersion = '1.66.0' // CURRENT_GRPC_VERSION
|
||||
def protobufVersion = '3.25.3'
|
||||
def protocVersion = protobufVersion
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ java {
|
|||
|
||||
// Feel free to delete the comment at the next line. It is just for safely
|
||||
// updating the version in our release process.
|
||||
def grpcVersion = '1.66.0-SNAPSHOT' // CURRENT_GRPC_VERSION
|
||||
def grpcVersion = '1.66.0' // CURRENT_GRPC_VERSION
|
||||
def protocVersion = '3.25.3'
|
||||
|
||||
dependencies {
|
||||
|
|
|
@ -25,7 +25,7 @@ java {
|
|||
|
||||
// Feel free to delete the comment at the next line. It is just for safely
|
||||
// updating the version in our release process.
|
||||
def grpcVersion = '1.66.0-SNAPSHOT' // CURRENT_GRPC_VERSION
|
||||
def grpcVersion = '1.66.0' // CURRENT_GRPC_VERSION
|
||||
def protobufVersion = '3.25.3'
|
||||
|
||||
dependencies {
|
||||
|
|
|
@ -6,13 +6,13 @@
|
|||
<packaging>jar</packaging>
|
||||
<!-- Feel free to delete the comment at the end of these lines. It is just
|
||||
for safely updating the version in our release process. -->
|
||||
<version>1.66.0-SNAPSHOT</version><!-- CURRENT_GRPC_VERSION -->
|
||||
<version>1.66.0</version><!-- CURRENT_GRPC_VERSION -->
|
||||
<name>example-debug</name>
|
||||
<url>https://github.com/grpc/grpc-java</url>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<grpc.version>1.66.0-SNAPSHOT</grpc.version><!-- CURRENT_GRPC_VERSION -->
|
||||
<grpc.version>1.66.0</grpc.version><!-- CURRENT_GRPC_VERSION -->
|
||||
<protoc.version>3.25.3</protoc.version>
|
||||
<!-- required for jdk9 -->
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
|
|
|
@ -24,7 +24,7 @@ java {
|
|||
|
||||
// Feel free to delete the comment at the next line. It is just for safely
|
||||
// updating the version in our release process.
|
||||
def grpcVersion = '1.66.0-SNAPSHOT' // CURRENT_GRPC_VERSION
|
||||
def grpcVersion = '1.66.0' // CURRENT_GRPC_VERSION
|
||||
def protobufVersion = '3.25.3'
|
||||
def protocVersion = protobufVersion
|
||||
|
||||
|
|
|
@ -6,13 +6,13 @@
|
|||
<packaging>jar</packaging>
|
||||
<!-- Feel free to delete the comment at the end of these lines. It is just
|
||||
for safely updating the version in our release process. -->
|
||||
<version>1.66.0-SNAPSHOT</version><!-- CURRENT_GRPC_VERSION -->
|
||||
<version>1.66.0</version><!-- CURRENT_GRPC_VERSION -->
|
||||
<name>example-gauth</name>
|
||||
<url>https://github.com/grpc/grpc-java</url>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<grpc.version>1.66.0-SNAPSHOT</grpc.version><!-- CURRENT_GRPC_VERSION -->
|
||||
<grpc.version>1.66.0</grpc.version><!-- CURRENT_GRPC_VERSION -->
|
||||
<protobuf.version>3.25.3</protobuf.version>
|
||||
<!-- required for jdk9 -->
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
|
|
|
@ -25,7 +25,7 @@ java {
|
|||
|
||||
// Feel free to delete the comment at the next line. It is just for safely
|
||||
// updating the version in our release process.
|
||||
def grpcVersion = '1.66.0-SNAPSHOT' // CURRENT_GRPC_VERSION
|
||||
def grpcVersion = '1.66.0' // CURRENT_GRPC_VERSION
|
||||
def protocVersion = '3.25.3'
|
||||
def openTelemetryVersion = '1.40.0'
|
||||
def openTelemetryPrometheusVersion = '1.40.0-alpha'
|
||||
|
|
|
@ -25,7 +25,7 @@ java {
|
|||
|
||||
// Feel free to delete the comment at the next line. It is just for safely
|
||||
// updating the version in our release process.
|
||||
def grpcVersion = '1.66.0-SNAPSHOT' // CURRENT_GRPC_VERSION
|
||||
def grpcVersion = '1.66.0' // CURRENT_GRPC_VERSION
|
||||
def protocVersion = '3.25.3'
|
||||
|
||||
dependencies {
|
||||
|
|
|
@ -23,7 +23,7 @@ java {
|
|||
|
||||
// Feel free to delete the comment at the next line. It is just for safely
|
||||
// updating the version in our release process.
|
||||
def grpcVersion = '1.66.0-SNAPSHOT' // CURRENT_GRPC_VERSION
|
||||
def grpcVersion = '1.66.0' // CURRENT_GRPC_VERSION
|
||||
def protobufVersion = '3.25.3'
|
||||
|
||||
dependencies {
|
||||
|
|
|
@ -6,13 +6,13 @@
|
|||
<packaging>jar</packaging>
|
||||
<!-- Feel free to delete the comment at the end of these lines. It is just
|
||||
for safely updating the version in our release process. -->
|
||||
<version>1.66.0-SNAPSHOT</version><!-- CURRENT_GRPC_VERSION -->
|
||||
<version>1.66.0</version><!-- CURRENT_GRPC_VERSION -->
|
||||
<name>example-hostname</name>
|
||||
<url>https://github.com/grpc/grpc-java</url>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<grpc.version>1.66.0-SNAPSHOT</grpc.version><!-- CURRENT_GRPC_VERSION -->
|
||||
<grpc.version>1.66.0</grpc.version><!-- CURRENT_GRPC_VERSION -->
|
||||
<protoc.version>3.25.3</protoc.version>
|
||||
<!-- required for jdk9 -->
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
|
|
|
@ -23,7 +23,7 @@ java {
|
|||
|
||||
// Feel free to delete the comment at the next line. It is just for safely
|
||||
// updating the version in our release process.
|
||||
def grpcVersion = '1.66.0-SNAPSHOT' // CURRENT_GRPC_VERSION
|
||||
def grpcVersion = '1.66.0' // CURRENT_GRPC_VERSION
|
||||
def protobufVersion = '3.25.3'
|
||||
def protocVersion = protobufVersion
|
||||
|
||||
|
|
|
@ -7,13 +7,13 @@
|
|||
<packaging>jar</packaging>
|
||||
<!-- Feel free to delete the comment at the end of these lines. It is just
|
||||
for safely updating the version in our release process. -->
|
||||
<version>1.66.0-SNAPSHOT</version><!-- CURRENT_GRPC_VERSION -->
|
||||
<version>1.66.0</version><!-- CURRENT_GRPC_VERSION -->
|
||||
<name>example-jwt-auth</name>
|
||||
<url>https://github.com/grpc/grpc-java</url>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<grpc.version>1.66.0-SNAPSHOT</grpc.version><!-- CURRENT_GRPC_VERSION -->
|
||||
<grpc.version>1.66.0</grpc.version><!-- CURRENT_GRPC_VERSION -->
|
||||
<protobuf.version>3.25.3</protobuf.version>
|
||||
<protoc.version>3.25.3</protoc.version>
|
||||
<!-- required for jdk9 -->
|
||||
|
|
|
@ -23,7 +23,7 @@ java {
|
|||
|
||||
// Feel free to delete the comment at the next line. It is just for safely
|
||||
// updating the version in our release process.
|
||||
def grpcVersion = '1.66.0-SNAPSHOT' // CURRENT_GRPC_VERSION
|
||||
def grpcVersion = '1.66.0' // CURRENT_GRPC_VERSION
|
||||
def protobufVersion = '3.25.3'
|
||||
def protocVersion = protobufVersion
|
||||
|
||||
|
|
|
@ -7,13 +7,13 @@
|
|||
<packaging>jar</packaging>
|
||||
<!-- Feel free to delete the comment at the end of these lines. It is just
|
||||
for safely updating the version in our release process. -->
|
||||
<version>1.66.0-SNAPSHOT</version><!-- CURRENT_GRPC_VERSION -->
|
||||
<version>1.66.0</version><!-- CURRENT_GRPC_VERSION -->
|
||||
<name>example-oauth</name>
|
||||
<url>https://github.com/grpc/grpc-java</url>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<grpc.version>1.66.0-SNAPSHOT</grpc.version><!-- CURRENT_GRPC_VERSION -->
|
||||
<grpc.version>1.66.0</grpc.version><!-- CURRENT_GRPC_VERSION -->
|
||||
<protobuf.version>3.25.3</protobuf.version>
|
||||
<protoc.version>3.25.3</protoc.version>
|
||||
<!-- required for jdk9 -->
|
||||
|
|
|
@ -24,7 +24,7 @@ java {
|
|||
|
||||
// Feel free to delete the comment at the next line. It is just for safely
|
||||
// updating the version in our release process.
|
||||
def grpcVersion = '1.66.0-SNAPSHOT' // CURRENT_GRPC_VERSION
|
||||
def grpcVersion = '1.66.0' // CURRENT_GRPC_VERSION
|
||||
def protocVersion = '3.25.3'
|
||||
def openTelemetryVersion = '1.40.0'
|
||||
def openTelemetryPrometheusVersion = '1.40.0-alpha'
|
||||
|
|
|
@ -18,7 +18,7 @@ java {
|
|||
targetCompatibility = JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
def grpcVersion = '1.66.0-SNAPSHOT' // CURRENT_GRPC_VERSION
|
||||
def grpcVersion = '1.66.0' // CURRENT_GRPC_VERSION
|
||||
def protocVersion = '3.25.3'
|
||||
|
||||
dependencies {
|
||||
|
|
|
@ -18,7 +18,7 @@ java {
|
|||
targetCompatibility = JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
def grpcVersion = '1.66.0-SNAPSHOT' // CURRENT_GRPC_VERSION
|
||||
def grpcVersion = '1.66.0' // CURRENT_GRPC_VERSION
|
||||
def protocVersion = '3.25.3'
|
||||
|
||||
dependencies {
|
||||
|
|
|
@ -16,7 +16,7 @@ java {
|
|||
targetCompatibility = JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
def grpcVersion = '1.66.0-SNAPSHOT' // CURRENT_GRPC_VERSION
|
||||
def grpcVersion = '1.66.0' // CURRENT_GRPC_VERSION
|
||||
def protocVersion = '3.25.3'
|
||||
|
||||
dependencies {
|
||||
|
|
|
@ -24,7 +24,7 @@ java {
|
|||
|
||||
// Feel free to delete the comment at the next line. It is just for safely
|
||||
// updating the version in our release process.
|
||||
def grpcVersion = '1.66.0-SNAPSHOT' // CURRENT_GRPC_VERSION
|
||||
def grpcVersion = '1.66.0' // CURRENT_GRPC_VERSION
|
||||
def protocVersion = '3.25.3'
|
||||
|
||||
dependencies {
|
||||
|
|
|
@ -6,13 +6,13 @@
|
|||
<packaging>jar</packaging>
|
||||
<!-- Feel free to delete the comment at the end of these lines. It is just
|
||||
for safely updating the version in our release process. -->
|
||||
<version>1.66.0-SNAPSHOT</version><!-- CURRENT_GRPC_VERSION -->
|
||||
<version>1.66.0</version><!-- CURRENT_GRPC_VERSION -->
|
||||
<name>example-tls</name>
|
||||
<url>https://github.com/grpc/grpc-java</url>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<grpc.version>1.66.0-SNAPSHOT</grpc.version><!-- CURRENT_GRPC_VERSION -->
|
||||
<grpc.version>1.66.0</grpc.version><!-- CURRENT_GRPC_VERSION -->
|
||||
<protoc.version>3.25.3</protoc.version>
|
||||
<!-- required for jdk9 -->
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
|
|
|
@ -23,7 +23,7 @@ java {
|
|||
|
||||
// Feel free to delete the comment at the next line. It is just for safely
|
||||
// updating the version in our release process.
|
||||
def grpcVersion = '1.66.0-SNAPSHOT' // CURRENT_GRPC_VERSION
|
||||
def grpcVersion = '1.66.0' // CURRENT_GRPC_VERSION
|
||||
def protocVersion = '3.25.3'
|
||||
|
||||
dependencies {
|
||||
|
|
|
@ -6,13 +6,13 @@
|
|||
<packaging>jar</packaging>
|
||||
<!-- Feel free to delete the comment at the end of these lines. It is just
|
||||
for safely updating the version in our release process. -->
|
||||
<version>1.66.0-SNAPSHOT</version><!-- CURRENT_GRPC_VERSION -->
|
||||
<version>1.66.0</version><!-- CURRENT_GRPC_VERSION -->
|
||||
<name>examples</name>
|
||||
<url>https://github.com/grpc/grpc-java</url>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<grpc.version>1.66.0-SNAPSHOT</grpc.version><!-- CURRENT_GRPC_VERSION -->
|
||||
<grpc.version>1.66.0</grpc.version><!-- CURRENT_GRPC_VERSION -->
|
||||
<protobuf.version>3.25.3</protobuf.version>
|
||||
<protoc.version>3.25.3</protoc.version>
|
||||
<!-- required for JDK 8 -->
|
||||
|
|
|
@ -152,7 +152,7 @@ public class GrpclbNameResolverTest {
|
|||
resolver.start(mockListener);
|
||||
assertThat(fakeClock.runDueTasks()).isEqualTo(1);
|
||||
|
||||
verify(mockListener).onResult2(resultCaptor.capture());
|
||||
verify(mockListener).onResult(resultCaptor.capture());
|
||||
ResolutionResult result = resultCaptor.getValue();
|
||||
assertThat(result.getAddresses()).isEmpty();
|
||||
assertThat(result.getAttributes()).isEqualTo(Attributes.EMPTY);
|
||||
|
@ -192,7 +192,7 @@ public class GrpclbNameResolverTest {
|
|||
|
||||
resolver.start(mockListener);
|
||||
assertThat(fakeClock.runDueTasks()).isEqualTo(1);
|
||||
verify(mockListener).onResult2(resultCaptor.capture());
|
||||
verify(mockListener).onResult(resultCaptor.capture());
|
||||
ResolutionResult result = resultCaptor.getValue();
|
||||
InetSocketAddress resolvedBackendAddr =
|
||||
(InetSocketAddress) Iterables.getOnlyElement(
|
||||
|
@ -225,7 +225,7 @@ public class GrpclbNameResolverTest {
|
|||
|
||||
resolver.start(mockListener);
|
||||
assertThat(fakeClock.runDueTasks()).isEqualTo(1);
|
||||
verify(mockListener).onResult2(resultCaptor.capture());
|
||||
verify(mockListener).onResult(resultCaptor.capture());
|
||||
ResolutionResult result = resultCaptor.getValue();
|
||||
assertThat(result.getAddresses())
|
||||
.containsExactly(
|
||||
|
@ -272,7 +272,7 @@ public class GrpclbNameResolverTest {
|
|||
|
||||
resolver.start(mockListener);
|
||||
assertThat(fakeClock.runDueTasks()).isEqualTo(1);
|
||||
verify(mockListener).onResult2(resultCaptor.capture());
|
||||
verify(mockListener).onResult(resultCaptor.capture());
|
||||
ResolutionResult result = resultCaptor.getValue();
|
||||
assertThat(result.getAddresses()).isEmpty();
|
||||
EquivalentAddressGroup resolvedBalancerAddr =
|
||||
|
@ -306,7 +306,7 @@ public class GrpclbNameResolverTest {
|
|||
|
||||
resolver.start(mockListener);
|
||||
assertThat(fakeClock.runDueTasks()).isEqualTo(1);
|
||||
verify(mockListener).onResult2(resultCaptor.capture());
|
||||
verify(mockListener).onResult(resultCaptor.capture());
|
||||
ResolutionResult result = resultCaptor.getValue();
|
||||
|
||||
InetSocketAddress resolvedBackendAddr =
|
||||
|
|
|
@ -152,8 +152,14 @@ final class ControlPlaneClient {
|
|||
startRpcStream();
|
||||
}
|
||||
Collection<String> resources = resourceStore.getSubscribedResources(serverInfo, resourceType);
|
||||
if (resources != null) {
|
||||
if (resources == null) {
|
||||
resources = Collections.emptyList();
|
||||
}
|
||||
adsStream.sendDiscoveryRequest(resourceType, resources);
|
||||
if (resources.isEmpty()) {
|
||||
// The resource type no longer has subscribing resources; clean up references to it
|
||||
versions.remove(resourceType);
|
||||
adsStream.respNonces.remove(resourceType);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -281,7 +281,7 @@ public final class XdsClientImpl extends XdsClient implements XdsResponseHandler
|
|||
@SuppressWarnings("unchecked")
|
||||
public void run() {
|
||||
ResourceSubscriber<T> subscriber =
|
||||
(ResourceSubscriber<T>) resourceSubscribers.get(type).get(resourceName);;
|
||||
(ResourceSubscriber<T>) resourceSubscribers.get(type).get(resourceName);
|
||||
subscriber.removeWatcher(watcher);
|
||||
if (!subscriber.isWatched()) {
|
||||
subscriber.cancelResourceWatch();
|
||||
|
|
|
@ -133,6 +133,7 @@ import org.mockito.invocation.InvocationOnMock;
|
|||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
import org.mockito.stubbing.Answer;
|
||||
import org.mockito.verification.VerificationMode;
|
||||
|
||||
/**
|
||||
* Tests for {@link XdsClientImpl}.
|
||||
|
@ -2757,6 +2758,37 @@ public abstract class GrpcXdsClientImplTestBase {
|
|||
verifySubscribedResourcesMetadataSizes(0, 0, 0, 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void edsCleanupNonceAfterUnsubscription() {
|
||||
Assume.assumeFalse(ignoreResourceDeletion());
|
||||
|
||||
// Suppose we have an EDS subscription A.1
|
||||
xdsClient.watchXdsResource(XdsEndpointResource.getInstance(), "A.1", edsResourceWatcher);
|
||||
DiscoveryRpcCall call = resourceDiscoveryCalls.poll();
|
||||
assertThat(call).isNotNull();
|
||||
call.verifyRequest(EDS, "A.1", "", "", NODE);
|
||||
|
||||
// EDS -> {A.1}, version 1
|
||||
List<Message> dropOverloads = ImmutableList.of();
|
||||
List<Message> endpointsV1 = ImmutableList.of(lbEndpointHealthy);
|
||||
ImmutableMap<String, Any> resourcesV1 = ImmutableMap.of(
|
||||
"A.1", Any.pack(mf.buildClusterLoadAssignment("A.1", endpointsV1, dropOverloads)));
|
||||
call.sendResponse(EDS, resourcesV1.values().asList(), VERSION_1, "0000");
|
||||
// {A.1} -> ACK, version 1
|
||||
call.verifyRequest(EDS, "A.1", VERSION_1, "0000", NODE);
|
||||
verify(edsResourceWatcher, times(1)).onChanged(any());
|
||||
|
||||
// trigger an EDS resource unsubscription.
|
||||
xdsClient.cancelXdsResourceWatch(XdsEndpointResource.getInstance(), "A.1", edsResourceWatcher);
|
||||
verifySubscribedResourcesMetadataSizes(0, 0, 0, 0);
|
||||
call.verifyRequest(EDS, Arrays.asList(), VERSION_1, "0000", NODE);
|
||||
|
||||
// When re-subscribing, the version and nonce were properly forgotten, so the request is the
|
||||
// same as the initial request
|
||||
xdsClient.watchXdsResource(XdsEndpointResource.getInstance(), "A.1", edsResourceWatcher);
|
||||
call.verifyRequest(EDS, "A.1", "", "", NODE, Mockito.timeout(2000).times(2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void edsResponseErrorHandling_allResourcesFailedUnpack() {
|
||||
DiscoveryRpcCall call = startResourceWatcher(XdsEndpointResource.getInstance(), EDS_RESOURCE,
|
||||
|
@ -3787,10 +3819,22 @@ public abstract class GrpcXdsClientImplTestBase {
|
|||
|
||||
protected void verifyRequest(
|
||||
XdsResourceType<?> type, List<String> resources, String versionInfo, String nonce,
|
||||
Node node) {
|
||||
Node node, VerificationMode verificationMode) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
protected void verifyRequest(
|
||||
XdsResourceType<?> type, List<String> resources, String versionInfo, String nonce,
|
||||
Node node) {
|
||||
verifyRequest(type, resources, versionInfo, nonce, node, Mockito.timeout(2000));
|
||||
}
|
||||
|
||||
protected void verifyRequest(
|
||||
XdsResourceType<?> type, String resource, String versionInfo, String nonce,
|
||||
Node node, VerificationMode verificationMode) {
|
||||
verifyRequest(type, ImmutableList.of(resource), versionInfo, nonce, node, verificationMode);
|
||||
}
|
||||
|
||||
protected void verifyRequest(
|
||||
XdsResourceType<?> type, String resource, String versionInfo, String nonce, Node node) {
|
||||
verifyRequest(type, ImmutableList.of(resource), versionInfo, nonce, node);
|
||||
|
|
|
@ -118,6 +118,7 @@ import org.junit.runners.Parameterized.Parameters;
|
|||
import org.mockito.ArgumentMatcher;
|
||||
import org.mockito.InOrder;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.verification.VerificationMode;
|
||||
|
||||
/**
|
||||
* Tests for {@link XdsClientImpl} with protocol version v3.
|
||||
|
@ -205,8 +206,8 @@ public class GrpcXdsClientImplV3Test extends GrpcXdsClientImplTestBase {
|
|||
@Override
|
||||
protected void verifyRequest(
|
||||
XdsResourceType<?> type, List<String> resources, String versionInfo, String nonce,
|
||||
EnvoyProtoData.Node node) {
|
||||
verify(requestObserver, Mockito.timeout(2000)).onNext(argThat(new DiscoveryRequestMatcher(
|
||||
EnvoyProtoData.Node node, VerificationMode verificationMode) {
|
||||
verify(requestObserver, verificationMode).onNext(argThat(new DiscoveryRequestMatcher(
|
||||
node.toEnvoyProtoNode(), versionInfo, resources, type.typeUrl(), nonce, null, null)));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue