Skip to content

Commit

Permalink
Move XdsChannelFactory to its own file and improve tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
voidzcy committed Sep 8, 2020
1 parent 20c6338 commit aaa9be9
Show file tree
Hide file tree
Showing 2 changed files with 189 additions and 0 deletions.
89 changes: 89 additions & 0 deletions xds/src/main/java/io/grpc/xds/XdsChannelFactory.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/*
* 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.base.Preconditions.checkArgument;

import com.google.common.annotations.VisibleForTesting;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import io.grpc.alts.GoogleDefaultChannelBuilder;
import io.grpc.xds.Bootstrapper.ChannelCreds;
import io.grpc.xds.Bootstrapper.ServerInfo;
import io.grpc.xds.XdsClient.XdsChannel;
import io.grpc.xds.XdsLogger.XdsLogLevel;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
* Factory for creating channels to xDS severs.
*/
abstract class XdsChannelFactory {
@VisibleForTesting
static boolean experimentalV3SupportEnvVar = Boolean.parseBoolean(
System.getenv("GRPC_XDS_EXPERIMENTAL_V3_SUPPORT"));

private static final String XDS_V3_SERVER_FEATURE = "xds_v3";
private static final XdsChannelFactory DEFAULT_INSTANCE = new XdsChannelFactory() {
/**
* Creates a channel to the first server in the given list.
*/
@Override
XdsChannel createChannel(List<ServerInfo> servers) throws XdsInitializationException {
checkArgument(!servers.isEmpty(), "No management server provided.");
XdsLogger logger = XdsLogger.withPrefix("xds-client-channel-factory");
ServerInfo serverInfo = servers.get(0);
String serverUri = serverInfo.getServerUri();
logger.log(XdsLogLevel.INFO, "Creating channel to {0}", serverUri);
List<ChannelCreds> channelCredsList = serverInfo.getChannelCredentials();
ManagedChannelBuilder<?> channelBuilder = null;
// Use the first supported channel credentials configuration.
// Currently, only "google_default" is supported.
for (ChannelCreds creds : channelCredsList) {
if (creds.getType().equals("google_default")) {
logger.log(XdsLogLevel.INFO, "Using channel credentials: google_default");
channelBuilder = GoogleDefaultChannelBuilder.forTarget(serverUri);
break;
}
}
if (channelBuilder == null) {
logger.log(XdsLogLevel.INFO, "Using default channel credentials");
channelBuilder = ManagedChannelBuilder.forTarget(serverUri);
}

ManagedChannel channel = channelBuilder
.keepAliveTime(5, TimeUnit.MINUTES)
.build();
boolean useProtocolV3 = experimentalV3SupportEnvVar
&& serverInfo.getServerFeatures().contains(XDS_V3_SERVER_FEATURE);

return new XdsChannel(channel, useProtocolV3);
}
};

static XdsChannelFactory getInstance() {
return DEFAULT_INSTANCE;
}

/**
* Creates a channel to one of the provided management servers.
*
* @throws XdsInitializationException if failed to create a channel with the given list of
* servers.
*/
abstract XdsChannel createChannel(List<ServerInfo> servers) throws XdsInitializationException;
}
100 changes: 100 additions & 0 deletions xds/src/test/java/io/grpc/xds/XdsChannelFactoryTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/*
* 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 io.grpc.xds.Bootstrapper.ChannelCreds;
import io.grpc.xds.Bootstrapper.ServerInfo;
import io.grpc.xds.XdsClient.XdsChannel;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/**
* Tests for {@link XdsChannelFactory}.
*/
@RunWith(JUnit4.class)
public class XdsChannelFactoryTest {

private final XdsChannelFactory channelFactory = XdsChannelFactory.getInstance();
private final List<XdsChannel> channels = new ArrayList<>();
private ServerInfo server1; // google_default
private ServerInfo server2; // plaintext, v3
private ServerInfo server3; // unsupported

@Before
public void setUp() {
ChannelCreds tls = new ChannelCreds("tls", null);
ChannelCreds googleDefault = new ChannelCreds("google_default", null);
ChannelCreds insecure = new ChannelCreds("insecure", null);
ChannelCreds unsupported = new ChannelCreds("unsupported", null);
server1 = new ServerInfo("server1.com", Collections.singletonList(googleDefault),
Collections.<String>emptyList());
server2 = new ServerInfo("server2.com", Collections.singletonList(insecure),
Collections.singletonList("xds_v3"));
server3 = new ServerInfo("server4.com", Collections.singletonList(unsupported),
Collections.<String>emptyList());
}

@After
public void tearDown() {
for (XdsChannel channel : channels) {
channel.getManagedChannel().shutdown();
}
}

@Test
public void failToCreateChannel_unsupportedChannelCreds() {
try {
createChannel(server3);
fail("Should have thrown");
} catch (XdsInitializationException expected) {
}
}

@Test
public void defaultUseV2ProtocolL() throws XdsInitializationException {
XdsChannel channel = createChannel(server1);
assertThat(channel.isUseProtocolV3()).isFalse();
}

@Test
public void supportServerFeature_v3Protocol() throws XdsInitializationException {
boolean originalV3SupportEnvVar = XdsChannelFactory.experimentalV3SupportEnvVar;
XdsChannelFactory.experimentalV3SupportEnvVar = true;
try {
XdsChannel channel = createChannel(server2);
assertThat(channel.isUseProtocolV3()).isTrue();
} finally {
XdsChannelFactory.experimentalV3SupportEnvVar = originalV3SupportEnvVar;
}
}

private XdsChannel createChannel(ServerInfo... servers) throws XdsInitializationException {
XdsChannel channel = channelFactory.createChannel(Arrays.asList(servers));
channels.add(channel);
return channel;
}
}

0 comments on commit aaa9be9

Please sign in to comment.