mirror of https://github.com/grpc/grpc-java.git
xds: Support custom credentials using XdsCredentialsRegistry (#8924)
Currently the credentials used for xDS communications is hardcoded in the BootstrapperImpl. The bootstrap config chooses one of the possible hardcoded credential. This commit adds support for a credential plugin which allows users to register custom credentials through XdsCredentialProviders. gRPC will automatically discover the implementations via Java's SPI mechanism Bootstrapper will use XdsCredentialRegistry to retrieve the list of supported credentials. The current hardcoded list of credentials(google_default, insecure and tls) are registered by default to keep the behavior as is.
This commit is contained in:
parent
cda0e9d996
commit
d3f7dc0059
|
|
@ -21,10 +21,7 @@ import com.google.common.base.Strings;
|
|||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import io.grpc.ChannelCredentials;
|
||||
import io.grpc.InsecureChannelCredentials;
|
||||
import io.grpc.InternalLogId;
|
||||
import io.grpc.TlsChannelCredentials;
|
||||
import io.grpc.alts.GoogleDefaultChannelCredentials;
|
||||
import io.grpc.internal.GrpcUtil;
|
||||
import io.grpc.internal.GrpcUtil.GrpcBuildVersion;
|
||||
import io.grpc.internal.JsonParser;
|
||||
|
|
@ -327,14 +324,15 @@ class BootstrapperImpl extends Bootstrapper {
|
|||
throw new XdsInitializationException(
|
||||
"Invalid bootstrap: server " + serverUri + " with 'channel_creds' type unspecified");
|
||||
}
|
||||
switch (type) {
|
||||
case "google_default":
|
||||
return GoogleDefaultChannelCredentials.create();
|
||||
case "insecure":
|
||||
return InsecureChannelCredentials.create();
|
||||
case "tls":
|
||||
return TlsChannelCredentials.create();
|
||||
default:
|
||||
XdsCredentialsProvider provider = XdsCredentialsRegistry.getDefaultRegistry()
|
||||
.getProvider(type);
|
||||
if (provider != null) {
|
||||
Map<String, ?> config = JsonUtil.getObject(channelCreds, "config");
|
||||
if (config == null) {
|
||||
config = ImmutableMap.of();
|
||||
}
|
||||
|
||||
return provider.newChannelCredentials(config);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Copyright 2022 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 io.grpc.ChannelCredentials;
|
||||
import io.grpc.Internal;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Provider of credentials which can be consumed by clients for xds communications. The actual
|
||||
* credential to be used for a particular xds communication will be chosen based on the bootstrap
|
||||
* configuration.
|
||||
*
|
||||
* <p>Implementations can be automatically discovered by gRPC via Java's SPI mechanism. For
|
||||
* automatic discovery, the implementation must have a zero-argument constructor and include
|
||||
* a resource named {@code META-INF/services/io.grpc.xds.XdsCredentialsProvider} in their JAR. The
|
||||
* file's contents should be the implementation's class name.
|
||||
* Implementations that need arguments in their constructor can be manually registered by
|
||||
* {@link XdsCredentialsRegistry#register}.
|
||||
*
|
||||
* <p>Implementations <em>should not</em> throw. If they do, it may interrupt class loading. If
|
||||
* exceptions may reasonably occur for implementation-specific reasons, implementations should
|
||||
* generally handle the exception gracefully and return {@code false} from {@link #isAvailable()}.
|
||||
*/
|
||||
@Internal
|
||||
public abstract class XdsCredentialsProvider {
|
||||
/**
|
||||
* Creates a {@link ChannelCredentials} from the given jsonConfig, or
|
||||
* {@code null} if the given config is invalid. The provider is free to ignore
|
||||
* the config if it's not needed for producing the channel credentials.
|
||||
*
|
||||
* @param jsonConfig json config that can be consumed by the provider to create
|
||||
* the channel credentials
|
||||
*
|
||||
*/
|
||||
protected abstract ChannelCredentials newChannelCredentials(Map<String, ?> jsonConfig);
|
||||
|
||||
/**
|
||||
* Returns the xDS credential name associated with this provider which makes it selectable
|
||||
* via {@link XdsCredentialsRegistry#getProvider}. This is called only when the class is loaded.
|
||||
* It shouldn't change, and there is no point doing so.
|
||||
*/
|
||||
protected abstract String getName();
|
||||
|
||||
/**
|
||||
* Whether this provider is available for use, taking the current environment
|
||||
* into consideration.
|
||||
* If {@code false}, {@link #newChannelCredentials} is not safe to be called.
|
||||
*/
|
||||
public abstract boolean isAvailable();
|
||||
|
||||
/**
|
||||
* A priority, from 0 to 10 that this provider should be used, taking the
|
||||
* current environment into consideration.
|
||||
* 5 should be considered the default, and then tweaked based on
|
||||
* environment detection. A priority of 0 does not imply that the provider
|
||||
* wouldn't work; just that it should be last in line.
|
||||
*/
|
||||
public abstract int priority();
|
||||
}
|
||||
|
|
@ -0,0 +1,189 @@
|
|||
/*
|
||||
* Copyright 2022 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 static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import io.grpc.InternalServiceProviders;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.concurrent.GuardedBy;
|
||||
import javax.annotation.concurrent.ThreadSafe;
|
||||
|
||||
/**
|
||||
* Registry of {@link XdsCredentialsProvider}s. The {@link #getDefaultRegistry default
|
||||
* instance} loads providers at runtime through the Java service provider mechanism.
|
||||
*/
|
||||
@ThreadSafe
|
||||
final class XdsCredentialsRegistry {
|
||||
private static final Logger logger = Logger.getLogger(XdsCredentialsRegistry.class.getName());
|
||||
private static XdsCredentialsRegistry instance;
|
||||
|
||||
@GuardedBy("this")
|
||||
private final LinkedHashSet<XdsCredentialsProvider> allProviders = new LinkedHashSet<>();
|
||||
|
||||
/**
|
||||
* Generated from {@code allProviders}. Is mapping from scheme key to the
|
||||
* highest priority {@link XdsCredentialsProvider}.
|
||||
* Is replaced instead of mutating.
|
||||
*/
|
||||
@GuardedBy("this")
|
||||
private ImmutableMap<String, XdsCredentialsProvider> effectiveProviders = ImmutableMap.of();
|
||||
|
||||
/**
|
||||
* Register a provider.
|
||||
*
|
||||
* <p>If the provider's {@link XdsCredentialsProvider#isAvailable isAvailable()}
|
||||
* returns {@code false}, this method will throw {@link IllegalArgumentException}.
|
||||
*
|
||||
* <p>Providers will be used in priority order. In case of ties, providers are used
|
||||
* in registration order.
|
||||
*/
|
||||
public synchronized void register(XdsCredentialsProvider provider) {
|
||||
addProvider(provider);
|
||||
refreshProviders();
|
||||
}
|
||||
|
||||
private synchronized void addProvider(XdsCredentialsProvider provider) {
|
||||
checkArgument(provider.isAvailable(), "isAvailable() returned false");
|
||||
allProviders.add(provider);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deregisters a provider. No-op if the provider is not in the registry.
|
||||
*
|
||||
* @param provider the provider that was added to the register via
|
||||
* {@link #register}.
|
||||
*/
|
||||
public synchronized void deregister(XdsCredentialsProvider provider) {
|
||||
allProviders.remove(provider);
|
||||
refreshProviders();
|
||||
}
|
||||
|
||||
private synchronized void refreshProviders() {
|
||||
Map<String, XdsCredentialsProvider> refreshedProviders = new HashMap<>();
|
||||
int maxPriority = Integer.MIN_VALUE;
|
||||
// We prefer first-registered providers.
|
||||
for (XdsCredentialsProvider provider : allProviders) {
|
||||
String credsName = provider.getName();
|
||||
XdsCredentialsProvider existing = refreshedProviders.get(credsName);
|
||||
if (existing == null || existing.priority() < provider.priority()) {
|
||||
refreshedProviders.put(credsName, provider);
|
||||
}
|
||||
if (maxPriority < provider.priority()) {
|
||||
maxPriority = provider.priority();
|
||||
}
|
||||
}
|
||||
effectiveProviders = ImmutableMap.copyOf(refreshedProviders);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default registry that loads providers via the Java service loader
|
||||
* mechanism.
|
||||
*/
|
||||
public static synchronized XdsCredentialsRegistry getDefaultRegistry() {
|
||||
if (instance == null) {
|
||||
List<XdsCredentialsProvider> providerList = InternalServiceProviders.loadAll(
|
||||
XdsCredentialsProvider.class,
|
||||
getHardCodedClasses(),
|
||||
XdsCredentialsProvider.class.getClassLoader(),
|
||||
new XdsCredentialsProviderPriorityAccessor());
|
||||
if (providerList.isEmpty()) {
|
||||
logger.warning("No XdsCredsRegistry found via ServiceLoader, including for GoogleDefault, "
|
||||
+ "TLS and Insecure. This is probably due to a broken build.");
|
||||
}
|
||||
instance = new XdsCredentialsRegistry();
|
||||
for (XdsCredentialsProvider provider : providerList) {
|
||||
logger.fine("Service loader found " + provider);
|
||||
if (provider.isAvailable()) {
|
||||
instance.addProvider(provider);
|
||||
}
|
||||
}
|
||||
instance.refreshProviders();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns effective providers map from scheme to the highest priority
|
||||
* XdsCredsProvider of that scheme.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
synchronized Map<String, XdsCredentialsProvider> providers() {
|
||||
return effectiveProviders;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the effective provider for the given xds credential name, or {@code null} if no
|
||||
* suitable provider can be found.
|
||||
* Each provider declares its name via {@link XdsCredentialsProvider#getName}.
|
||||
*/
|
||||
@Nullable
|
||||
public synchronized XdsCredentialsProvider getProvider(String name) {
|
||||
return effectiveProviders.get(checkNotNull(name, "name"));
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static List<Class<?>> getHardCodedClasses() {
|
||||
// Class.forName(String) is used to remove the need for ProGuard configuration. Note that
|
||||
// ProGuard does not detect usages of Class.forName(String, boolean, ClassLoader):
|
||||
// https://sourceforge.net/p/proguard/bugs/418/
|
||||
ArrayList<Class<?>> list = new ArrayList<>();
|
||||
try {
|
||||
list.add(Class.forName("io.grpc.xds.internal.GoogleDefaultXdsCredentialsProvider"));
|
||||
} catch (ClassNotFoundException e) {
|
||||
logger.log(Level.WARNING, "Unable to find GoogleDefaultXdsCredentialsProvider", e);
|
||||
}
|
||||
|
||||
try {
|
||||
list.add(Class.forName("io.grpc.xds.internal.InsecureXdsCredentialsProvider"));
|
||||
} catch (ClassNotFoundException e) {
|
||||
logger.log(Level.WARNING, "Unable to find InsecureXdsCredentialsProvider", e);
|
||||
}
|
||||
|
||||
try {
|
||||
list.add(Class.forName("io.grpc.xds.internal.TlsXdsCredentialsProvider"));
|
||||
} catch (ClassNotFoundException e) {
|
||||
logger.log(Level.WARNING, "Unable to find TlsXdsCredentialsProvider", e);
|
||||
}
|
||||
|
||||
return Collections.unmodifiableList(list);
|
||||
}
|
||||
|
||||
private static final class XdsCredentialsProviderPriorityAccessor
|
||||
implements InternalServiceProviders.PriorityAccessor<XdsCredentialsProvider> {
|
||||
@Override
|
||||
public boolean isAvailable(XdsCredentialsProvider provider) {
|
||||
return provider.isAvailable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPriority(XdsCredentialsProvider provider) {
|
||||
return provider.priority();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright 2022 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.internal;
|
||||
|
||||
import io.grpc.ChannelCredentials;
|
||||
import io.grpc.alts.GoogleDefaultChannelCredentials;
|
||||
import io.grpc.xds.XdsCredentialsProvider;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A wrapper class that supports {@link GoogleDefaultChannelCredentials} for
|
||||
* Xds by implementing {@link XdsCredentialsProvider}.
|
||||
*/
|
||||
public final class GoogleDefaultXdsCredentialsProvider extends XdsCredentialsProvider {
|
||||
private static final String CREDS_NAME = "google_default";
|
||||
|
||||
@Override
|
||||
protected ChannelCredentials newChannelCredentials(Map<String, ?> jsonConfig) {
|
||||
return GoogleDefaultChannelCredentials.create();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getName() {
|
||||
return CREDS_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int priority() {
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright 2022 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.internal;
|
||||
|
||||
import io.grpc.ChannelCredentials;
|
||||
import io.grpc.InsecureChannelCredentials;
|
||||
import io.grpc.xds.XdsCredentialsProvider;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A wrapper class that supports {@link InsecureChannelCredentials} for Xds
|
||||
* by implementing {@link XdsCredentialsProvider}.
|
||||
*/
|
||||
public final class InsecureXdsCredentialsProvider extends XdsCredentialsProvider {
|
||||
private static final String CREDS_NAME = "insecure";
|
||||
|
||||
@Override
|
||||
protected ChannelCredentials newChannelCredentials(Map<String, ?> jsonConfig) {
|
||||
return InsecureChannelCredentials.create();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getName() {
|
||||
return CREDS_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int priority() {
|
||||
return 5;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright 2022 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.internal;
|
||||
|
||||
import io.grpc.ChannelCredentials;
|
||||
import io.grpc.TlsChannelCredentials;
|
||||
import io.grpc.xds.XdsCredentialsProvider;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A wrapper class that supports {@link TlsChannelCredentials} for Xds
|
||||
* by implementing {@link XdsCredentialsProvider}.
|
||||
*/
|
||||
public final class TlsXdsCredentialsProvider extends XdsCredentialsProvider {
|
||||
private static final String CREDS_NAME = "tls";
|
||||
|
||||
@Override
|
||||
protected ChannelCredentials newChannelCredentials(Map<String, ?> jsonConfig) {
|
||||
return TlsChannelCredentials.create();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getName() {
|
||||
return CREDS_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int priority() {
|
||||
return 5;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
io.grpc.xds.internal.GoogleDefaultXdsCredentialsProvider
|
||||
io.grpc.xds.internal.InsecureXdsCredentialsProvider
|
||||
io.grpc.xds.internal.TlsXdsCredentialsProvider
|
||||
|
|
@ -0,0 +1,213 @@
|
|||
/*
|
||||
* Copyright 2022 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.assertEquals;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import io.grpc.ChannelCredentials;
|
||||
import io.grpc.xds.XdsCredentialsProvider;
|
||||
import io.grpc.xds.XdsCredentialsRegistry;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
|
||||
/** Unit tests for {@link XdsCredentialsRegistry}. */
|
||||
@RunWith(JUnit4.class)
|
||||
public class XdsCredentialsRegistryTest {
|
||||
|
||||
@Test
|
||||
public void register_unavailableProviderThrows() {
|
||||
XdsCredentialsRegistry reg = new XdsCredentialsRegistry();
|
||||
try {
|
||||
reg.register(new BaseCredsProvider(false, 5, "creds"));
|
||||
fail("Should throw");
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertThat(e).hasMessageThat().contains("isAvailable() returned false");
|
||||
}
|
||||
assertThat(reg.providers()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deregister() {
|
||||
XdsCredentialsRegistry reg = new XdsCredentialsRegistry();
|
||||
String credsName = "sampleCredsName";
|
||||
XdsCredentialsProvider p1 = new BaseCredsProvider(true, 5, credsName);
|
||||
XdsCredentialsProvider p2 = new BaseCredsProvider(true, 5, credsName);
|
||||
XdsCredentialsProvider p3 = new BaseCredsProvider(true, 5, credsName);
|
||||
reg.register(p1);
|
||||
reg.register(p2);
|
||||
reg.register(p3);
|
||||
assertThat(reg.getProvider(credsName)).isSameInstanceAs(p1);
|
||||
reg.deregister(p2);
|
||||
assertThat(reg.getProvider(credsName)).isSameInstanceAs(p1);
|
||||
reg.deregister(p1);
|
||||
assertThat(reg.getProvider(credsName)).isSameInstanceAs(p3);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void provider_sorted() {
|
||||
XdsCredentialsRegistry reg = new XdsCredentialsRegistry();
|
||||
String credsName = "sampleCredsName";
|
||||
XdsCredentialsProvider p1 = new BaseCredsProvider(true, 5, credsName);
|
||||
XdsCredentialsProvider p2 = new BaseCredsProvider(true, 3, credsName);
|
||||
XdsCredentialsProvider p3 = new BaseCredsProvider(true, 8, credsName);
|
||||
XdsCredentialsProvider p4 = new BaseCredsProvider(true, 3, credsName);
|
||||
XdsCredentialsProvider p5 = new BaseCredsProvider(true, 8, credsName);
|
||||
reg.register(p1);
|
||||
reg.register(p2);
|
||||
reg.register(p3);
|
||||
reg.register(p4);
|
||||
reg.register(p5);
|
||||
assertThat(reg.getProvider(credsName)).isSameInstanceAs(p3);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void channelCredentials_successful() {
|
||||
XdsCredentialsRegistry registry = new XdsCredentialsRegistry();
|
||||
String credsName = "sampleCredsName";
|
||||
|
||||
registry.register(
|
||||
new BaseCredsProvider(true, 5, credsName) {
|
||||
@Override
|
||||
public ChannelCredentials newChannelCredentials(Map<String, ?> config) {
|
||||
return new SampleChannelCredentials(config);
|
||||
}
|
||||
});
|
||||
|
||||
Map<String, String> sampleConfig = ImmutableMap.of("a", "b");
|
||||
ChannelCredentials creds = registry.providers().get(credsName)
|
||||
.newChannelCredentials(sampleConfig);
|
||||
assertSame(SampleChannelCredentials.class, creds.getClass());
|
||||
assertEquals(sampleConfig, ((SampleChannelCredentials)creds).getConfig());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void channelCredentials_multiSuccessful() {
|
||||
XdsCredentialsRegistry registry = new XdsCredentialsRegistry();
|
||||
String credsName1 = "sampleCreds1";
|
||||
String credsName2 = "sampleCreds2";
|
||||
registry.register(
|
||||
new BaseCredsProvider(true, 5, credsName1) {
|
||||
@Override
|
||||
public ChannelCredentials newChannelCredentials(Map<String, ?> config) {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
registry.register(
|
||||
new BaseCredsProvider(true, 7, credsName2) {
|
||||
@Override
|
||||
public ChannelCredentials newChannelCredentials(Map<String, ?> config) {
|
||||
return new SampleChannelCredentials(config);
|
||||
}
|
||||
});
|
||||
|
||||
assertThat(registry.getProvider(credsName1).newChannelCredentials(null)).isNull();
|
||||
assertThat(registry.getProvider(credsName1).getName()).isEqualTo(credsName1);
|
||||
assertThat(registry.getProvider(credsName2).newChannelCredentials(null)).isNotNull();
|
||||
assertThat(registry.getProvider(credsName2).getName()).isEqualTo(credsName2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultRegistry_providers() {
|
||||
Map<String, XdsCredentialsProvider> providers =
|
||||
XdsCredentialsRegistry.getDefaultRegistry().providers();
|
||||
assertThat(providers).hasSize(3);
|
||||
assertThat(providers.get("google_default").getClass())
|
||||
.isEqualTo(io.grpc.xds.internal.GoogleDefaultXdsCredentialsProvider.class);
|
||||
assertThat(providers.get("insecure").getClass())
|
||||
.isEqualTo(io.grpc.xds.internal.InsecureXdsCredentialsProvider.class);
|
||||
assertThat(providers.get("tls").getClass())
|
||||
.isEqualTo(io.grpc.xds.internal.TlsXdsCredentialsProvider.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getClassesViaHardcoded_classesPresent() throws Exception {
|
||||
List<Class<?>> classes = XdsCredentialsRegistry.getHardCodedClasses();
|
||||
assertThat(classes).containsExactly(
|
||||
io.grpc.xds.internal.GoogleDefaultXdsCredentialsProvider.class,
|
||||
io.grpc.xds.internal.InsecureXdsCredentialsProvider.class,
|
||||
io.grpc.xds.internal.TlsXdsCredentialsProvider.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getProvider_null() {
|
||||
try {
|
||||
XdsCredentialsRegistry.getDefaultRegistry().getProvider(null);
|
||||
fail("Should throw");
|
||||
} catch (NullPointerException e) {
|
||||
assertThat(e).hasMessageThat().contains("name");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class BaseCredsProvider extends XdsCredentialsProvider {
|
||||
private final boolean isAvailable;
|
||||
private final int priority;
|
||||
private final String name;
|
||||
|
||||
public BaseCredsProvider(boolean isAvailable, int priority, String name) {
|
||||
this.isAvailable = isAvailable;
|
||||
this.priority = priority;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return isAvailable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int priority() {
|
||||
return priority;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelCredentials newChannelCredentials(Map<String, ?> config) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
private static class SampleChannelCredentials extends ChannelCredentials {
|
||||
private final Map<String, ?> config;
|
||||
|
||||
SampleChannelCredentials(Map<String, ?> config) {
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
public Map<String, ?> getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelCredentials withoutBearerTokens() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright 2022 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.internal;
|
||||
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import io.grpc.CompositeChannelCredentials;
|
||||
import io.grpc.InternalServiceProviders;
|
||||
import io.grpc.xds.XdsCredentialsProvider;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
|
||||
/** Unit tests for {@link GoogleDefaultXdsCredentialsProvider}. */
|
||||
@RunWith(JUnit4.class)
|
||||
public class GoogleDefaultXdsCredentialsProviderTest {
|
||||
private GoogleDefaultXdsCredentialsProvider provider = new GoogleDefaultXdsCredentialsProvider();
|
||||
|
||||
@Test
|
||||
public void provided() {
|
||||
for (XdsCredentialsProvider current
|
||||
: InternalServiceProviders.getCandidatesViaServiceLoader(
|
||||
XdsCredentialsProvider.class, getClass().getClassLoader())) {
|
||||
if (current instanceof GoogleDefaultXdsCredentialsProvider) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
fail("ServiceLoader unable to load GoogleDefaultXdsCredentialsProvider");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isAvailable() {
|
||||
assertTrue(provider.isAvailable());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void channelCredentials() {
|
||||
assertSame(CompositeChannelCredentials.class,
|
||||
provider.newChannelCredentials(null).getClass());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright 2022 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.internal;
|
||||
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import io.grpc.InsecureChannelCredentials;
|
||||
import io.grpc.InternalServiceProviders;
|
||||
import io.grpc.xds.XdsCredentialsProvider;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
|
||||
/** Unit tests for {@link InsecureXdsCredentialsProvider}. */
|
||||
@RunWith(JUnit4.class)
|
||||
public class InsecureXdsCredentialsProviderTest {
|
||||
private InsecureXdsCredentialsProvider provider = new InsecureXdsCredentialsProvider();
|
||||
|
||||
@Test
|
||||
public void provided() {
|
||||
for (XdsCredentialsProvider current
|
||||
: InternalServiceProviders.getCandidatesViaServiceLoader(
|
||||
XdsCredentialsProvider.class, getClass().getClassLoader())) {
|
||||
if (current instanceof InsecureXdsCredentialsProvider) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
fail("ServiceLoader unable to load InsecureXdsCredentialsProvider");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isAvailable() {
|
||||
assertTrue(provider.isAvailable());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void channelCredentials() {
|
||||
assertSame(InsecureChannelCredentials.class,
|
||||
provider.newChannelCredentials(null).getClass());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright 2022 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.internal;
|
||||
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import io.grpc.InternalServiceProviders;
|
||||
import io.grpc.TlsChannelCredentials;
|
||||
import io.grpc.xds.XdsCredentialsProvider;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
|
||||
/** Unit tests for {@link TlsXdsCredentialsProvider}. */
|
||||
@RunWith(JUnit4.class)
|
||||
public class TlsXdsCredentialsProviderTest {
|
||||
private TlsXdsCredentialsProvider provider = new TlsXdsCredentialsProvider();
|
||||
|
||||
@Test
|
||||
public void provided() {
|
||||
for (XdsCredentialsProvider current
|
||||
: InternalServiceProviders.getCandidatesViaServiceLoader(
|
||||
XdsCredentialsProvider.class, getClass().getClassLoader())) {
|
||||
if (current instanceof TlsXdsCredentialsProvider) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
fail("ServiceLoader unable to load TlsXdsCredentialsProvider");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isAvailable() {
|
||||
assertTrue(provider.isAvailable());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void channelCredentials() {
|
||||
assertSame(TlsChannelCredentials.class,
|
||||
provider.newChannelCredentials(null).getClass());
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue