xds: migrating XdsNameResolver to "xds" scheme

Change "xds-experimenal" scheme to "xds" and add a deprecated provider with "xds-experimenal" scheme for keeping current users' tests working.
This commit is contained in:
ZHANG Dapeng 2020-04-07 11:52:41 -07:00 committed by GitHub
parent d88f0f19ec
commit 5c31dc6d71
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 204 additions and 10 deletions

View File

@ -27,6 +27,6 @@ JAVA_OPTS=-Djava.util.logging.config.file=grpc-java/buildscripts/xds_logging.pro
--gcp_suffix=$(date '+%s') \
--verbose \
--client_cmd="grpc-java/interop-testing/build/install/grpc-interop-testing/bin/xds-test-client \
--server=xds-experimental:///{server_uri} \
--server=xds:///{server_uri} \
--stats_port={stats_port} \
--qps={qps}"

View File

@ -0,0 +1,75 @@
/*
* Copyright 2020 The gRPC Authors
*
* Licensed 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
*
* http://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 io.grpc.xds;
import com.google.common.base.Preconditions;
import io.grpc.Internal;
import io.grpc.NameResolver;
import io.grpc.NameResolver.Args;
import io.grpc.NameResolverProvider;
import io.grpc.internal.ExponentialBackoffPolicy;
import io.grpc.internal.GrpcUtil;
import io.grpc.xds.XdsClient.XdsChannelFactory;
import java.net.URI;
/** A deprecated provider for {@link XdsNameResolver}. */
// TODO(zdapeng): remove this class once it's not needed for interop testing.
@Deprecated
@Internal
public final class XdsExperimentalNameResolverProvider extends NameResolverProvider {
private static final String SCHEME = "xds-experimental";
@Override
public NameResolver newNameResolver(URI targetUri, Args args) {
if (SCHEME.equals(targetUri.getScheme())) {
String targetPath = Preconditions.checkNotNull(targetUri.getPath(), "targetPath");
Preconditions.checkArgument(
targetPath.startsWith("/"),
"the path component (%s) of the target (%s) must start with '/'",
targetPath,
targetUri);
String name = targetPath.substring(1);
return
new XdsNameResolver(
name,
args,
new ExponentialBackoffPolicy.Provider(),
GrpcUtil.STOPWATCH_SUPPLIER,
XdsChannelFactory.getInstance(),
Bootstrapper.getInstance());
}
return null;
}
@Override
public String getDefaultScheme() {
return SCHEME;
}
@Override
protected boolean isAvailable() {
return true;
}
@Override
protected int priority() {
// Set priority value to be < 5 as we still want DNS resolver to be the primary default
// resolver.
return 4;
}
}

View File

@ -28,17 +28,17 @@ import java.net.URI;
/**
* A provider for {@link XdsNameResolver}.
*
* <p>It resolves a target URI whose scheme is {@code "xds-experimental"}. The authority of the
* <p>It resolves a target URI whose scheme is {@code "xds"}. The authority of the
* target URI is never used for current release. The path of the target URI, excluding the leading
* slash {@code '/'}, will indicate the name to use in the VHDS query.
*
* <p>This class should not be directly referenced in code. The resolver should be accessed
* through {@link io.grpc.NameResolverRegistry} with the URI scheme "xds-experimental".
* through {@link io.grpc.NameResolverRegistry} with the URI scheme "xds".
*/
@Internal
public final class XdsNameResolverProvider extends NameResolverProvider {
private static final String SCHEME = "xds-experimental";
private static final String SCHEME = "xds";
@Override
public XdsNameResolver newNameResolver(URI targetUri, Args args) {

View File

@ -1 +1,2 @@
io.grpc.xds.XdsNameResolverProvider
io.grpc.xds.XdsExperimentalNameResolverProvider

View File

@ -0,0 +1,118 @@
/*
* Copyright 2020 The gRPC Authors
*
* Licensed 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
*
* http://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 io.grpc.xds;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
import io.grpc.ChannelLogger;
import io.grpc.InternalServiceProviders;
import io.grpc.NameResolver;
import io.grpc.NameResolver.ServiceConfigParser;
import io.grpc.NameResolverProvider;
import io.grpc.SynchronizationContext;
import io.grpc.internal.FakeClock;
import io.grpc.internal.GrpcUtil;
import java.net.URI;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
/** Unit tests for {@link XdsExperimentalNameResolverProvider}. */
@Deprecated
@RunWith(JUnit4.class)
public class XdsExperimentalNameResolverProviderTest {
private final SynchronizationContext syncContext = new SynchronizationContext(
new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable e) {
throw new AssertionError(e);
}
});
private final FakeClock fakeClock = new FakeClock();
private final NameResolver.Args args = NameResolver.Args.newBuilder()
.setDefaultPort(8080)
.setProxyDetector(GrpcUtil.NOOP_PROXY_DETECTOR)
.setSynchronizationContext(syncContext)
.setServiceConfigParser(mock(ServiceConfigParser.class))
.setScheduledExecutorService(fakeClock.getScheduledExecutorService())
.setChannelLogger(mock(ChannelLogger.class))
.build();
private XdsExperimentalNameResolverProvider provider = new XdsExperimentalNameResolverProvider();
@Test
public void provided() {
for (NameResolverProvider current
: InternalServiceProviders.getCandidatesViaServiceLoader(
NameResolverProvider.class, getClass().getClassLoader())) {
if (current instanceof XdsExperimentalNameResolverProvider) {
return;
}
}
fail("XdsExperimentalNameResolverProvider not registered");
}
@Test
public void isAvailable() {
assertThat(provider.isAvailable()).isTrue();
}
@Test
public void newNameResolver() {
assertThat(
provider.newNameResolver(URI.create("xds-experimental://1.1.1.1/foo.googleapis.com"), args))
.isInstanceOf(XdsNameResolver.class);
assertThat(
provider.newNameResolver(URI.create("xds-experimental:///foo.googleapis.com"), args))
.isInstanceOf(XdsNameResolver.class);
assertThat(
provider.newNameResolver(URI.create("notxds-experimental://1.1.1.1/foo.googleapis.com"),
args))
.isNull();
}
@Test
public void validName_withAuthority() {
NameResolver resolver =
provider.newNameResolver(
URI.create("xds-experimental://trafficdirector.google.com/foo.googleapis.com"), args);
assertThat(resolver).isNotNull();
assertThat(resolver.getServiceAuthority()).isEqualTo("foo.googleapis.com");
}
@Test
public void validName_noAuthority() {
NameResolver resolver =
provider.newNameResolver(URI.create("xds-experimental:///foo.googleapis.com"), args);
assertThat(resolver).isNotNull();
assertThat(resolver.getServiceAuthority()).isEqualTo("foo.googleapis.com");
}
@Test
public void invalidName_hostnameContainsUnderscore() {
URI uri = URI.create("xds-experimental:///foo_bar.googleapis.com");
try {
provider.newNameResolver(uri, args);
fail("Expected IllegalArgumentException");
} catch (IllegalArgumentException e) {
// Expected
}
}
}

View File

@ -76,13 +76,13 @@ public class XdsNameResolverProviderTest {
@Test
public void newNameResolver() {
assertThat(
provider.newNameResolver(URI.create("xds-experimental://1.1.1.1/foo.googleapis.com"), args))
provider.newNameResolver(URI.create("xds://1.1.1.1/foo.googleapis.com"), args))
.isInstanceOf(XdsNameResolver.class);
assertThat(
provider.newNameResolver(URI.create("xds-experimental:///foo.googleapis.com"), args))
provider.newNameResolver(URI.create("xds:///foo.googleapis.com"), args))
.isInstanceOf(XdsNameResolver.class);
assertThat(
provider.newNameResolver(URI.create("notxds-experimental://1.1.1.1/foo.googleapis.com"),
provider.newNameResolver(URI.create("notxds://1.1.1.1/foo.googleapis.com"),
args))
.isNull();
}
@ -91,7 +91,7 @@ public class XdsNameResolverProviderTest {
public void validName_withAuthority() {
XdsNameResolver resolver =
provider.newNameResolver(
URI.create("xds-experimental://trafficdirector.google.com/foo.googleapis.com"), args);
URI.create("xds://trafficdirector.google.com/foo.googleapis.com"), args);
assertThat(resolver).isNotNull();
assertThat(resolver.getServiceAuthority()).isEqualTo("foo.googleapis.com");
}
@ -99,14 +99,14 @@ public class XdsNameResolverProviderTest {
@Test
public void validName_noAuthority() {
XdsNameResolver resolver =
provider.newNameResolver(URI.create("xds-experimental:///foo.googleapis.com"), args);
provider.newNameResolver(URI.create("xds:///foo.googleapis.com"), args);
assertThat(resolver).isNotNull();
assertThat(resolver.getServiceAuthority()).isEqualTo("foo.googleapis.com");
}
@Test
public void invalidName_hostnameContainsUnderscore() {
URI uri = URI.create("xds-experimental:///foo_bar.googleapis.com");
URI uri = URI.create("xds:///foo_bar.googleapis.com");
try {
provider.newNameResolver(uri, args);
fail("Expected IllegalArgumentException");