mirror of https://github.com/grpc/grpc-java.git
Implemented a Bootstrapper class which reads a local bootstrap file.
This commit is contained in:
parent
4309c4339e
commit
27ec907e68
|
|
@ -26,11 +26,18 @@ dependencies {
|
|||
compile project(':grpc-protobuf'),
|
||||
project(':grpc-stub'),
|
||||
project(':grpc-core'),
|
||||
project(':grpc-services')
|
||||
project(':grpc-services'),
|
||||
project(':grpc-auth')
|
||||
compile (libraries.protobuf_util) {
|
||||
// prefer 26.0-android from libraries instead of 20.0
|
||||
exclude group: 'com.google.guava', module: 'guava'
|
||||
}
|
||||
compile (libraries.google_auth_oauth2_http) {
|
||||
// prefer 26.0-android from libraries instead of 25.1-android
|
||||
exclude group: 'com.google.guava', module: 'guava'
|
||||
// prefer 0.19.2 from libraries instead of 0.18.0
|
||||
exclude group: 'io.opencensus', module: 'opencensus-api'
|
||||
}
|
||||
|
||||
testCompile project(':grpc-core').sourceSets.test.output
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
* Copyright 2019 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.auth.oauth2.ComputeEngineCredentials;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.protobuf.InvalidProtocolBufferException;
|
||||
import com.google.protobuf.util.JsonFormat;
|
||||
import io.envoyproxy.envoy.api.v2.core.ApiConfigSource;
|
||||
import io.envoyproxy.envoy.api.v2.core.ApiConfigSource.ApiType;
|
||||
import io.envoyproxy.envoy.api.v2.core.Node;
|
||||
import io.grpc.CallCredentials;
|
||||
import io.grpc.auth.MoreCallCredentials;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
/**
|
||||
* Loads configuration information to bootstrap xDS load balancer.
|
||||
*/
|
||||
@Immutable
|
||||
abstract class Bootstrapper {
|
||||
|
||||
private static final String BOOTSTRAP_PATH_SYS_ENV_VAR = "GRPC_XDS_BOOTSTRAP";
|
||||
private static volatile Exception failToBootstrapException;
|
||||
private static volatile Bootstrapper DEFAULT_INSTANCE;
|
||||
|
||||
static Bootstrapper getInstance() throws Exception {
|
||||
if (DEFAULT_INSTANCE == null && failToBootstrapException == null) {
|
||||
synchronized (Bootstrapper.class) {
|
||||
if (DEFAULT_INSTANCE == null && failToBootstrapException == null) {
|
||||
try {
|
||||
DEFAULT_INSTANCE = new FileBasedBootstrapper();
|
||||
} catch (Exception e) {
|
||||
failToBootstrapException = e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (DEFAULT_INSTANCE == null) {
|
||||
throw failToBootstrapException;
|
||||
}
|
||||
return DEFAULT_INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the canonical name of the traffic director to be connected to.
|
||||
*/
|
||||
abstract String getBalancerName();
|
||||
|
||||
/**
|
||||
* Returns a {@link Node} message with project/network metadata in it to be included in
|
||||
* xDS requests.
|
||||
*/
|
||||
abstract Node getNode();
|
||||
|
||||
/**
|
||||
* Returns the credentials to use when communicating with the xDS server.
|
||||
*/
|
||||
abstract CallCredentials getCallCredentials();
|
||||
|
||||
@VisibleForTesting
|
||||
static final class FileBasedBootstrapper extends Bootstrapper {
|
||||
|
||||
private final String balancerName;
|
||||
private final Node node;
|
||||
// TODO(chengyuanzhang): Add configuration for call credentials loaded from bootstrap file.
|
||||
// hard-coded for alpha release.
|
||||
|
||||
private FileBasedBootstrapper() throws IOException {
|
||||
this(Bootstrapper.readConfig());
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
FileBasedBootstrapper(Bootstrap bootstrapConfig) {
|
||||
ApiConfigSource serverConfig = bootstrapConfig.getXdsServer();
|
||||
if (!serverConfig.getApiType().equals(ApiType.GRPC)) {
|
||||
throw new RuntimeException("Unexpected api type: " + serverConfig.getApiType().toString());
|
||||
}
|
||||
if (serverConfig.getGrpcServicesCount() != 1) {
|
||||
throw new RuntimeException(
|
||||
"Unexpected number of gRPC services: expected: 1, actual: "
|
||||
+ serverConfig.getGrpcServicesCount());
|
||||
}
|
||||
balancerName = serverConfig.getGrpcServices(0).getGoogleGrpc().getTargetUri();
|
||||
node = bootstrapConfig.getNode();
|
||||
}
|
||||
|
||||
@Override
|
||||
String getBalancerName() {
|
||||
return balancerName;
|
||||
}
|
||||
|
||||
@Override
|
||||
Node getNode() {
|
||||
return node;
|
||||
}
|
||||
|
||||
@Override
|
||||
CallCredentials getCallCredentials() {
|
||||
return MoreCallCredentials.from(ComputeEngineCredentials.create());
|
||||
}
|
||||
}
|
||||
|
||||
private static Bootstrap readConfig() throws IOException {
|
||||
String filePath = System.getenv(BOOTSTRAP_PATH_SYS_ENV_VAR);
|
||||
if (filePath == null) {
|
||||
throw new RuntimeException("Environment variable "
|
||||
+ BOOTSTRAP_PATH_SYS_ENV_VAR + " not found.");
|
||||
}
|
||||
return parseConfig(new String(Files.readAllBytes(Paths.get(filePath)), "UTF-8"));
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static Bootstrap parseConfig(String rawData) throws InvalidProtocolBufferException {
|
||||
Bootstrap.Builder bootstrapBuilder = Bootstrap.newBuilder();
|
||||
JsonFormat.parser().merge(rawData, bootstrapBuilder);
|
||||
return bootstrapBuilder.build();
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue