Skip to content

Commit e1d7c5f

Browse files
committed
googleapis: Add RFC 3986 URI support.
1 parent 3deabb2 commit e1d7c5f

File tree

5 files changed

+108
-16
lines changed

5 files changed

+108
-16
lines changed

googleapis/src/main/java/io/grpc/googleapis/GoogleCloudToProdExperimentalNameResolverProvider.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import io.grpc.NameResolver;
2121
import io.grpc.NameResolver.Args;
2222
import io.grpc.NameResolverProvider;
23+
import io.grpc.Uri;
2324
import java.net.URI;
2425

2526
/**
@@ -35,6 +36,11 @@ public NameResolver newNameResolver(URI targetUri, Args args) {
3536
return delegate.newNameResolver(targetUri, args);
3637
}
3738

39+
@Override
40+
public NameResolver newNameResolver(Uri targetUri, Args args) {
41+
return delegate.newNameResolver(targetUri, args);
42+
}
43+
3844
@Override
3945
public String getDefaultScheme() {
4046
return delegate.getDefaultScheme();

googleapis/src/main/java/io/grpc/googleapis/GoogleCloudToProdNameResolver.java

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import io.grpc.NameResolverRegistry;
3030
import io.grpc.Status;
3131
import io.grpc.SynchronizationContext;
32+
import io.grpc.Uri;
3233
import io.grpc.alts.InternalCheckGcpEnvironment;
3334
import io.grpc.internal.GrpcUtil;
3435
import io.grpc.internal.SharedResourceHolder;
@@ -49,6 +50,7 @@
4950
import java.net.URISyntaxException;
5051
import java.net.URL;
5152
import java.nio.charset.StandardCharsets;
53+
import java.util.List;
5254
import java.util.Random;
5355
import java.util.concurrent.Executor;
5456
import java.util.logging.Level;
@@ -117,6 +119,7 @@ private static synchronized BootstrapInfo getBootstrapInfo()
117119
@VisibleForTesting
118120
GoogleCloudToProdNameResolver(URI targetUri, Args args, Resource<Executor> executorResource,
119121
NameResolver.Factory nameResolverFactory) {
122+
// TODO(jdcormie): Remove after io.grpc.Uri migration.
120123
this.executorResource = checkNotNull(executorResource, "executorResource");
121124
String targetPath = checkNotNull(checkNotNull(targetUri, "targetUri").getPath(), "targetPath");
122125
Preconditions.checkArgument(
@@ -141,6 +144,45 @@ private static synchronized BootstrapInfo getBootstrapInfo()
141144
usingExecutorResource = executor == null;
142145
}
143146

147+
GoogleCloudToProdNameResolver(Uri targetUri, Args args, Resource<Executor> executorResource) {
148+
this(targetUri, args, executorResource, NameResolverRegistry.getDefaultRegistry().asFactory());
149+
}
150+
151+
@VisibleForTesting
152+
GoogleCloudToProdNameResolver(
153+
Uri targetUri,
154+
Args args,
155+
Resource<Executor> executorResource,
156+
NameResolver.Factory nameResolverFactory) {
157+
this.executorResource = checkNotNull(executorResource, "executorResource");
158+
Preconditions.checkArgument(
159+
targetUri.isPathAbsolute(),
160+
"the path component of the target (%s) must start with '/'",
161+
targetUri);
162+
List<String> pathSegments = targetUri.getPathSegments();
163+
Preconditions.checkArgument(
164+
pathSegments.size() == 1,
165+
"the path component of the target (%s) must have exactly one segment",
166+
targetUri);
167+
authority = GrpcUtil.checkAuthority(pathSegments.get(0));
168+
syncContext = checkNotNull(args, "args").getSynchronizationContext();
169+
Uri.Builder modifiedTargetBuilder = targetUri.toBuilder().setScheme(schemeOverride);
170+
if (schemeOverride.equals("xds")) {
171+
modifiedTargetBuilder.setRawAuthority(C2P_AUTHORITY).build();
172+
args =
173+
args.toBuilder()
174+
.setArg(XdsNameResolverProvider.XDS_CLIENT_SUPPLIER, () -> xdsClient)
175+
.build();
176+
}
177+
targetUri = modifiedTargetBuilder.build();
178+
target = targetUri.toString();
179+
metricRecorder = args.getMetricRecorder();
180+
delegate =
181+
checkNotNull(nameResolverFactory, "nameResolverFactory").newNameResolver(targetUri, args);
182+
executor = args.getOffloadExecutor();
183+
usingExecutorResource = executor == null;
184+
}
185+
144186
@Override
145187
public String getServiceAuthority() {
146188
return authority;

googleapis/src/main/java/io/grpc/googleapis/GoogleCloudToProdNameResolverProvider.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import io.grpc.NameResolver;
2222
import io.grpc.NameResolver.Args;
2323
import io.grpc.NameResolverProvider;
24+
import io.grpc.Uri;
2425
import io.grpc.internal.GrpcUtil;
2526
import java.net.InetSocketAddress;
2627
import java.net.SocketAddress;
@@ -48,6 +49,16 @@ public GoogleCloudToProdNameResolverProvider() {
4849

4950
@Override
5051
public NameResolver newNameResolver(URI targetUri, Args args) {
52+
// TODO(jdcormie): Remove after io.grpc.Uri migration is complete.
53+
if (scheme.equals(targetUri.getScheme())) {
54+
return new GoogleCloudToProdNameResolver(
55+
targetUri, args, GrpcUtil.SHARED_CHANNEL_EXECUTOR);
56+
}
57+
return null;
58+
}
59+
60+
@Override
61+
public NameResolver newNameResolver(Uri targetUri, Args args) {
5162
if (scheme.equals(targetUri.getScheme())) {
5263
return new GoogleCloudToProdNameResolver(
5364
targetUri, args, GrpcUtil.SHARED_CHANNEL_EXECUTOR);

googleapis/src/test/java/io/grpc/googleapis/GoogleCloudToProdNameResolverProviderTest.java

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,20 +23,23 @@
2323
import io.grpc.ChannelLogger;
2424
import io.grpc.InternalServiceProviders;
2525
import io.grpc.NameResolver;
26+
import io.grpc.NameResolver.Args;
2627
import io.grpc.NameResolver.ServiceConfigParser;
2728
import io.grpc.NameResolverProvider;
2829
import io.grpc.SynchronizationContext;
30+
import io.grpc.Uri;
2931
import io.grpc.internal.FakeClock;
3032
import io.grpc.internal.GrpcUtil;
3133
import java.net.URI;
34+
import java.util.Arrays;
3235
import org.junit.Test;
3336
import org.junit.runner.RunWith;
34-
import org.junit.runners.JUnit4;
37+
import org.junit.runners.Parameterized;
38+
import org.junit.runners.Parameterized.Parameter;
39+
import org.junit.runners.Parameterized.Parameters;
3540

36-
/**
37-
* Unit tests for {@link GoogleCloudToProdNameResolverProvider}.
38-
*/
39-
@RunWith(JUnit4.class)
41+
/** Unit tests for {@link GoogleCloudToProdNameResolverProvider}. */
42+
@RunWith(Parameterized.class)
4043
public class GoogleCloudToProdNameResolverProviderTest {
4144
private final SynchronizationContext syncContext = new SynchronizationContext(
4245
new Thread.UncaughtExceptionHandler() {
@@ -59,6 +62,13 @@ public void uncaughtException(Thread t, Throwable e) {
5962
private GoogleCloudToProdNameResolverProvider provider =
6063
new GoogleCloudToProdNameResolverProvider();
6164

65+
@Parameters(name = "enableRfc3986UrisParam={0}")
66+
public static Iterable<Object[]> data() {
67+
return Arrays.asList(new Object[][] {{true}, {false}});
68+
}
69+
70+
@Parameter public boolean enableRfc3986UrisParam;
71+
6272
@Test
6373
public void provided() {
6474
for (NameResolverProvider current
@@ -84,16 +94,24 @@ NameResolverProvider.class, getClass().getClassLoader())) {
8494
}
8595

8696
@Test
87-
public void newNameResolver() {
88-
assertThat(provider
89-
.newNameResolver(URI.create("google-c2p:///foo.googleapis.com"), args))
97+
public void shouldProvideNameResolverOfExpectedType() {
98+
assertThat(newNameResolver(provider, "google-c2p:///foo.googleapis.com", args))
9099
.isInstanceOf(GoogleCloudToProdNameResolver.class);
91100
}
92101

93102
@Test
94-
public void experimentalNewNameResolver() {
95-
assertThat(new GoogleCloudToProdExperimentalNameResolverProvider()
96-
.newNameResolver(URI.create("google-c2p-experimental:///foo.googleapis.com"), args))
103+
public void shouldProvideExperimentalNameResolverOfExpectedType() {
104+
assertThat(
105+
newNameResolver(
106+
new GoogleCloudToProdExperimentalNameResolverProvider(),
107+
"google-c2p-experimental:///foo.googleapis.com",
108+
args))
97109
.isInstanceOf(GoogleCloudToProdNameResolver.class);
98110
}
111+
112+
private NameResolver newNameResolver(NameResolverProvider provider, String uri, Args args) {
113+
return enableRfc3986UrisParam
114+
? provider.newNameResolver(Uri.create(uri), args)
115+
: provider.newNameResolver(URI.create(uri), args);
116+
}
99117
}

googleapis/src/test/java/io/grpc/googleapis/GoogleCloudToProdNameResolverTest.java

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import io.grpc.Status;
3535
import io.grpc.Status.Code;
3636
import io.grpc.SynchronizationContext;
37+
import io.grpc.Uri;
3738
import io.grpc.googleapis.GoogleCloudToProdNameResolver.HttpConnectionProvider;
3839
import io.grpc.internal.FakeClock;
3940
import io.grpc.internal.GrpcUtil;
@@ -43,6 +44,7 @@
4344
import java.net.HttpURLConnection;
4445
import java.net.URI;
4546
import java.nio.charset.StandardCharsets;
47+
import java.util.Arrays;
4648
import java.util.HashMap;
4749
import java.util.List;
4850
import java.util.Map;
@@ -53,20 +55,22 @@
5355
import org.junit.Rule;
5456
import org.junit.Test;
5557
import org.junit.runner.RunWith;
56-
import org.junit.runners.JUnit4;
58+
import org.junit.runners.Parameterized;
59+
import org.junit.runners.Parameterized.Parameter;
60+
import org.junit.runners.Parameterized.Parameters;
5761
import org.mockito.ArgumentCaptor;
5862
import org.mockito.Captor;
5963
import org.mockito.Mock;
6064
import org.mockito.junit.MockitoJUnit;
6165
import org.mockito.junit.MockitoRule;
6266

63-
@RunWith(JUnit4.class)
67+
@RunWith(Parameterized.class)
6468
public class GoogleCloudToProdNameResolverTest {
6569

6670
@Rule
6771
public final MockitoRule mocks = MockitoJUnit.rule();
6872

69-
private static final URI TARGET_URI = URI.create("google-c2p:///googleapis.com");
73+
private static final String TARGET_URI = "google-c2p:///googleapis.com";
7074
private static final String ZONE = "us-central1-a";
7175
private static final int DEFAULT_PORT = 887;
7276

@@ -108,6 +112,13 @@ public void close(Executor instance) {}
108112
private GoogleCloudToProdNameResolver resolver;
109113
private String responseToIpV6 = "1:1:1";
110114

115+
@Parameters(name = "enableRfc3986UrisParam={0}")
116+
public static Iterable<Object[]> data() {
117+
return Arrays.asList(new Object[][] {{true}, {false}});
118+
}
119+
120+
@Parameter public boolean enableRfc3986UrisParam;
121+
111122
@Before
112123
public void setUp() {
113124
nsRegistry.register(new FakeNsProvider("dns"));
@@ -149,8 +160,12 @@ public void tearDown() {
149160
}
150161

151162
private void createResolver() {
152-
resolver = new GoogleCloudToProdNameResolver(
153-
TARGET_URI, args, fakeExecutorResource, nsRegistry.asFactory());
163+
resolver =
164+
enableRfc3986UrisParam
165+
? new GoogleCloudToProdNameResolver(
166+
Uri.create(TARGET_URI), args, fakeExecutorResource, nsRegistry.asFactory())
167+
: new GoogleCloudToProdNameResolver(
168+
URI.create(TARGET_URI), args, fakeExecutorResource, nsRegistry.asFactory());
154169
}
155170

156171
@Test

0 commit comments

Comments
 (0)