Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: generate JSON service config based on gRPC service config #73

Merged
merged 14 commits into from
Oct 25, 2019
Merged
6 changes: 4 additions & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ jobs:
- run:
name: Run baseline tests
command: |
sudo npm link
npm link
npm test
environment:
NPM_CONFIG_PREFIX: /tmp/.npm-global
- run:
name: Run showcase test for js users
command: |
Expand All @@ -41,7 +43,7 @@ jobs:
npm install
npm test
- run:
name: Run unit tests
name: Run unit tests of the generated library
command: |
cd .test-out-showcase/
npm test
Expand Down
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"codecov": "c8 --reporter=lcov mocha build/test/unit && c8 report",
"lint": "gts check",
"clean": "gts clean",
"compile-protos": "pbjs -p node_modules/google-gax/protos -t static-module -o pbjs-genfiles/plugin.js google/protobuf/compiler/plugin.proto google/api/annotations.proto google/api/client.proto google/longrunning/operations.proto && pbts pbjs-genfiles/plugin.js -o pbjs-genfiles/plugin.d.ts",
"compile-protos": "pbjs -p protos -p node_modules/google-gax/protos -t static-module -o pbjs-genfiles/plugin.js google/protobuf/compiler/plugin.proto google/api/annotations.proto google/api/client.proto google/longrunning/operations.proto service_config.proto && pbts pbjs-genfiles/plugin.js -o pbjs-genfiles/plugin.d.ts",
"compile": "tsc -p . && cp -r typescript/test/protos build/test/",
"fix": "gts fix",
"prepare": "npm run compile-protos && npm run compile",
Expand All @@ -35,12 +35,12 @@
},
"homepage": "https://github.com/googleapis/gapic-generator-typescript#readme",
"devDependencies": {
"@types/command-line-args": "^5.0.0",
"@types/fs-extra": "^8.0.1",
"@types/get-stdin": "^5.0.1",
"@types/mocha": "^5.2.7",
"@types/mocha": "^5.2.5",
"@types/node": "^11.13.22",
"@types/nunjucks": "^3.1.0",
"@types/object-hash": "^1.3.0",
"@types/rimraf": "^2.0.2",
"assert-rejects": "^1.0.0",
"c8": "^5.0.4",
Expand All @@ -58,11 +58,11 @@
"dependencies": {
"@types/fs-extra": "^8.0.1",
"@types/yargs": "^13.0.3",
"command-line-args": "^5.0.2",
"file-system": "^2.2.2",
"fs-extra": "^8.1.0",
"get-stdin": "^7.0.0",
"nunjucks": "^3.1.3",
"object-hash": "^2.0.0",
"protobufjs": "^6.8.8",
"yargs": "^14.2.0"
}
Expand Down
324 changes: 324 additions & 0 deletions protos/service_config.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,324 @@
// Copyright 2016 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.

// A ServiceConfig is supplied when a service is deployed. It mostly contains
// parameters for how clients that connect to the service should behave (for
// example, the load balancing policy to use to pick between service replicas).
//
// The configuration options provided here act as overrides to automatically
// chosen option values. Service owners should be conservative in specifying
// options as the system is likely to choose better values for these options in
// the vast majority of cases. In other words, please specify a configuration
// option only if you really have to, and avoid copy-paste inclusion of configs.

syntax = "proto3";

package grpc.service_config;

import "google/protobuf/duration.proto";
import "google/protobuf/wrappers.proto";
import "google/rpc/code.proto";

option java_package = "io.grpc.serviceconfig";
option java_multiple_files = true;
option java_outer_classname = "ServiceConfigProto";

// Configuration for a method.
message MethodConfig {
// The names of the methods to which this configuration applies. There must
// be at least one name. Each name entry must be unique across the entire
// ClientConfig. If the 'method' field is empty, then this MethodConfig
// specifies the defaults for all methods for the specified service.
//
// For example, let's say that the service config contains the following
// MethodConfig entries:
//
// method_config { name { service: "MyService" } ... }
// method_config { name { service: "MyService" method: "Foo" } ... }
//
// For a request for MyService/Foo, we will use the second entry, because it
// exactly matches the service and method name.
// For a request for MyService/Bar, we will use the first entry, because it
// provides the default for all methods of MyService.
message Name {
string service = 1; // Required. Includes proto package name.
string method = 2;
}
repeated Name name = 1;

// Whether RPCs sent to this method should wait until the connection is
// ready by default. If false, the RPC will abort immediately if there is
// a transient failure connecting to the server. Otherwise, gRPC will
// attempt to connect until the deadline is exceeded.
//
// The value specified via the gRPC client API will override the value
// set here. However, note that setting the value in the client API will
// also affect transient errors encountered during name resolution, which
// cannot be caught by the value here, since the service config is
// obtained by the gRPC client via name resolution.
google.protobuf.BoolValue wait_for_ready = 2;

// The default timeout in seconds for RPCs sent to this method. This can be
// overridden in code. If no reply is received in the specified amount of
// time, the request is aborted and a DEADLINE_EXCEEDED error status
// is returned to the caller.
//
// The actual deadline used will be the minimum of the value specified here
// and the value set by the application via the gRPC client API. If either
// one is not set, then the other will be used. If neither is set, then the
// request has no deadline.
google.protobuf.Duration timeout = 3;

// The maximum allowed payload size for an individual request or object in a
// stream (client->server) in bytes. The size which is measured is the
// serialized payload after per-message compression (but before stream
// compression) in bytes. This applies both to streaming and non-streaming
// requests.
//
// The actual value used is the minumum of the value specified here and the
// value set by the application via the gRPC client API. If either one is
// not set, then the other will be used. If neither is set, then the
// built-in default is used.
//
// If a client attempts to send an object larger than this value, it will not
// be sent and the client will see a ClientError.
// Note that 0 is a valid value, meaning that the request message
// must be empty.
google.protobuf.UInt32Value max_request_message_bytes = 4;

// The maximum allowed payload size for an individual response or object in a
// stream (server->client) in bytes. The size which is measured is the
// serialized payload after per-message compression (but before stream
// compression) in bytes. This applies both to streaming and non-streaming
// requests.
//
// The actual value used is the minumum of the value specified here and the
// value set by the application via the gRPC client API. If either one is
// not set, then the other will be used. If neither is set, then the
// built-in default is used.
//
// If a server attempts to send an object larger than this value, it will not
// be sent, and a ServerError will be sent to the client instead.
// Note that 0 is a valid value, meaning that the response message
// must be empty.
google.protobuf.UInt32Value max_response_message_bytes = 5;

// The retry policy for outgoing RPCs.
message RetryPolicy {
// The maximum number of RPC attempts, including the original attempt.
//
// This field is required and must be greater than 1.
// Any value greater than 5 will be treated as if it were 5.
uint32 max_attempts = 1;

// Exponential backoff parameters. The initial retry attempt will occur at
// random(0, initial_backoff). In general, the nth attempt will occur at
// random(0,
// min(initial_backoff*backoff_multiplier**(n-1), max_backoff)).
// Required. Must be greater than zero.
google.protobuf.Duration initial_backoff = 2;
// Required. Must be greater than zero.
google.protobuf.Duration max_backoff = 3;
float backoff_multiplier = 4; // Required. Must be greater than zero.

// The set of status codes which may be retried.
//
// This field is required and must be non-empty.
repeated google.rpc.Code retryable_status_codes = 5;
}

// The hedging policy for outgoing RPCs. Hedged RPCs may execute more than
// once on the server, so only idempotent methods should specify a hedging
// policy.
message HedgingPolicy {
// The hedging policy will send up to max_requests RPCs.
// This number represents the total number of all attempts, including
// the original attempt.
//
// This field is required and must be greater than 1.
// Any value greater than 5 will be treated as if it were 5.
uint32 max_attempts = 1;

// The first RPC will be sent immediately, but the max_requests-1 subsequent
// hedged RPCs will be sent at intervals of every hedging_delay. Set this
// to 0 to immediately send all max_requests RPCs.
google.protobuf.Duration hedging_delay = 2;

// The set of status codes which indicate other hedged RPCs may still
// succeed. If a non-fatal status code is returned by the server, hedged
// RPCs will continue. Otherwise, outstanding requests will be canceled and
// the error returned to the client application layer.
//
// This field is optional.
repeated google.rpc.Code non_fatal_status_codes = 3;
}

// Only one of retry_policy or hedging_policy may be set. If neither is set,
// RPCs will not be retried or hedged.
oneof retry_or_hedging_policy {
RetryPolicy retry_policy = 6;
HedgingPolicy hedging_policy = 7;
}
}

// Configuration for pick_first LB policy.
message PickFirstConfig {}

// Configuration for round_robin LB policy.
message RoundRobinConfig {}

// Configuration for grpclb LB policy.
message GrpcLbConfig {
// Optional. What LB policy to use for routing between the backend
// addresses. If unset, defaults to round_robin.
// Currently, the only supported values are round_robin and pick_first.
// Note that this will be used both in balancer mode and in fallback mode.
// Multiple LB policies can be specified; clients will iterate through
// the list in order and stop at the first policy that they support.
repeated LoadBalancingConfig child_policy = 1;
}

// Configuration for xds LB policy.
message XdsConfig {
// Required. Name of balancer to connect to.
string balancer_name = 1;
// Optional. What LB policy to use for intra-locality routing.
// If unset, will use whatever algorithm is specified by the balancer.
// Multiple LB policies can be specified; clients will iterate through
// the list in order and stop at the first policy that they support.
repeated LoadBalancingConfig child_policy = 2;
// Optional. What LB policy to use in fallback mode. If not
// specified, defaults to round_robin.
// Multiple LB policies can be specified; clients will iterate through
// the list in order and stop at the first policy that they support.
repeated LoadBalancingConfig fallback_policy = 3;
}

// Selects LB policy and provides corresponding configuration.
//
// In general, all instances of this field should be repeated.
// Clients will iterate through the list in order and stop at the first
// policy that they support. This allows the service config to specify
// custom policies that may not be known to all clients.
message LoadBalancingConfig {
// Exactly one LB policy may be configured.
oneof policy {
// For each new LB policy supported by gRPC, a new field must be added
// here. The field's name must be the LB policy name and its type is a
// message that provides whatever configuration parameters are needed
// by the LB policy. The configuration message will be passed to the
// LB policy when it is instantiated on the client.
//
// If the LB policy does not require any configuration parameters, the
// message for that LB policy may be empty.
//
// Note that if an LB policy contains another nested LB policy
// (e.g., a gslb policy picks the cluster and then delegates to
// a round_robin policy to pick the backend within that cluster), its
// configuration message may include a nested instance of the
// LoadBalancingConfig message to configure the nested LB policy.

PickFirstConfig pick_first = 4 [json_name = "pick_first"];

RoundRobinConfig round_robin = 1 [json_name = "round_robin"];

// gRPC lookaside load balancing.
// This will eventually be deprecated by the new xDS-based local
// balancing policy.
GrpcLbConfig grpclb = 3;

// EXPERIMENTAL -- DO NOT USE
// xDS-based load balancing.
// The policy is known as xds_experimental while it is under development.
// It will be renamed to xds once it is ready for public use.
XdsConfig xds = 2;
// TODO(rekarthik): Deprecate this field after the xds policy
// is ready for public use.
XdsConfig xds_experimental = 5 [json_name = "xds_experimental"];

// Next available ID: 6
}
}

// A ServiceConfig represents information about a service but is not specific to
// any name resolver.
message ServiceConfig {
// Load balancing policy.
//
// Note that load_balancing_policy is deprecated in favor of
// load_balancing_config; the former will be used only if the latter
// is unset.
//
// If no LB policy is configured here, then the default is pick_first.
// If the policy name is set via the client API, that value overrides
// the value specified here.
//
// If the deprecated load_balancing_policy field is used, note that if the
// resolver returns at least one balancer address (as opposed to backend
// addresses), gRPC will use grpclb (see
// https://github.com/grpc/grpc/blob/master/doc/load-balancing.md),
// regardless of what policy is configured here. However, if the resolver
// returns at least one backend address in addition to the balancer
// address(es), the client may fall back to the requested policy if it
// is unable to reach any of the grpclb load balancers.
enum LoadBalancingPolicy {
UNSPECIFIED = 0;
ROUND_ROBIN = 1;
}
LoadBalancingPolicy load_balancing_policy = 1 [deprecated = true];
// Multiple LB policies can be specified; clients will iterate through
// the list in order and stop at the first policy that they support. If none
// are supported, the service config is considered invalid.
repeated LoadBalancingConfig load_balancing_config = 4;

// Per-method configuration.
repeated MethodConfig method_config = 2;

// If a RetryThrottlingPolicy is provided, gRPC will automatically throttle
// retry attempts and hedged RPCs when the client's ratio of failures to
// successes exceeds a threshold.
//
// For each server name, the gRPC client will maintain a token_count which is
// initially set to max_tokens. Every outgoing RPC (regardless of service or
// method invoked) will change token_count as follows:
//
// - Every failed RPC will decrement the token_count by 1.
// - Every successful RPC will increment the token_count by token_ratio.
//
// If token_count is less than or equal to max_tokens / 2, then RPCs will not
// be retried and hedged RPCs will not be sent.
message RetryThrottlingPolicy {
// The number of tokens starts at max_tokens. The token_count will always be
// between 0 and max_tokens.
//
// This field is required and must be greater than zero.
uint32 max_tokens = 1;

// The amount of tokens to add on each successful RPC. Typically this will
// be some number between 0 and 1, e.g., 0.1.
//
// This field is required and must be greater than zero. Up to 3 decimal
// places are supported.
float token_ratio = 2;
}
RetryThrottlingPolicy retry_throttling = 3;

message HealthCheckConfig {
// Service name to use in the health-checking request.
google.protobuf.StringValue service_name = 1;
}
HealthCheckConfig health_check_config = 5;

// next available tag: 6
}
Loading