diff --git a/.gitignore b/.gitignore index 77180e3..34c36b5 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,8 @@ bazel-testlogs # Java files *.exe + +# Logs files +*.ERROR* +*.INFO* +*.WARNING* \ No newline at end of file diff --git a/BUILD.bazel b/BUILD.bazel index 3ded010..49c9a49 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -13,6 +13,6 @@ buildifier( # gazelle:exclude third_party # gazelle:exclude vendor # gazelle:exclude _output -# gazelle:prefix github.com/binchencoder/skylb-apiv2 +# gazelle:prefix github.com/binchencoder/skylb-api gazelle(name = "gazelle") diff --git a/WORKSPACE b/WORKSPACE index f5732c1..5eb3d84 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -1,4 +1,4 @@ -workspace(name = "com_github_binchencoder_skylb_apiv2") +workspace(name = "com_github_binchencoder_skylb_api") load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository") diff --git a/balancer/BUILD.bazel b/balancer/BUILD.bazel new file mode 100644 index 0000000..0c3c51d --- /dev/null +++ b/balancer/BUILD.bazel @@ -0,0 +1,49 @@ +package(default_visibility = ["//visibility:public"]) + +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "go_default_library", + srcs = glob( + ["*.go"], + exclude = ["*_test.go"], + ), + importpath = "github.com/binchencoder/skylb-api/balancer", + deps = [ + "//internal/health:go_default_library", + "@com_github_binchencoder_letsgo//grpc:go_default_library", + "@com_github_binchencoder_letsgo//hashring:go_default_library", + "@com_github_golang_glog//:go_default_library", + "@org_golang_x_net//context:go_default_library", + "@org_golang_google_grpc//:go_default_library", + "@org_golang_google_grpc//codes:go_default_library", + "@org_golang_google_grpc//grpclog:go_default_library", + ], +) + +# TODO(chenbin) 2019/08/17 +# ERROR: /skylb-api/balancer/BUILD:28:1: in go_test rule //balancer:small_tests: +# target '@org_golang_google_grpc//internal/leakcheck:go_default_library' is not visible from target '//balancer:small_tests'. +# Check the visibility declaration of the former target if you think the dependency is legitimate +# go_test( +# name = "small_tests", +# size = "small", +# srcs = [ +# "roundrobin_test.go", +# ], +# embed = [ +# ":go_default_library", +# ], +# deps = [ +# "@org_golang_google_grpc//:go_default_library", +# "@org_golang_google_grpc//balancer/roundrobin:go_default_library", +# "@org_golang_google_grpc//codes:go_default_library", +# "@org_golang_google_grpc//grpclog/glogger:go_default_library", +# "@org_golang_google_grpc//internal/leakcheck:go_default_library", +# "@org_golang_google_grpc//peer:go_default_library", +# "@org_golang_google_grpc//resolver:go_default_library", +# "@org_golang_google_grpc//resolver/manual:go_default_library", +# "@org_golang_google_grpc//status:go_default_library", +# "@org_golang_google_grpc//test/grpc_testing:go_default_library", +# ], +# ) diff --git a/balancer/debug.go b/balancer/debug.go new file mode 100644 index 0000000..b323c63 --- /dev/null +++ b/balancer/debug.go @@ -0,0 +1,13 @@ +package balancer + +import ( + "time" +) + +// DebugBalancer defines the grpc load balancer which prints debug info. +type DebugBalancer interface { + // StartDebugPrint starts printing debug info. + StartDebugPrint(interval time.Duration) + // StopDebugPrint stops printing debug info. + StopDebugPrint() +} diff --git a/client/BUILD.bazel b/client/BUILD.bazel new file mode 100644 index 0000000..0a7e8c1 --- /dev/null +++ b/client/BUILD.bazel @@ -0,0 +1,21 @@ +package(default_visibility = ["//visibility:public"]) + +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = glob( + ["*.go"], + exclude = ["*_test.go"], + ), + importpath = "github.com/binchencoder/skylb-api/client", + deps = [ + "//proto:go_default_library", + "//client/option:go_default_library", + "//internal/skylb:go_default_library", + "//naming:go_default_library", + "@com_github_binchencoder_gateway_proto//data:go_default_library", + "@com_github_binchencoder_letsgo//flags:go_default_library", + "@org_golang_google_grpc//:go_default_library", + ], +) diff --git a/client/client.go b/client/client.go new file mode 100644 index 0000000..cf0e8bf --- /dev/null +++ b/client/client.go @@ -0,0 +1,90 @@ +package client + +import ( + "flag" + + "google.golang.org/grpc" + + vexpb "github.com/binchencoder/gateway-proto/data" + "github.com/binchencoder/letsgo/flags" + "github.com/binchencoder/skylb-api/internal/skylb" + "github.com/binchencoder/skylb-api/naming" + pb "github.com/binchencoder/skylb-api/proto" +) + +const ( + DefaultNameSpace = "default" + DefaultPortName = "grpc" +) + +var ( + DebugSvcEndpoints = flags.StringMap{} +) + +func init() { + flag.Var(&DebugSvcEndpoints, "debug-svc-endpoint", "The debug service endpoint. If not empty, disable SkyLB resolving for that service.") +} + +// ServiceCli defines the interface through which the client app obtains +// gRPC load balancing support from SkyLB. +type ServiceCli interface { + // Resolve resolves a service spec. + // It needs to be called for every service used by the client. + Resolve(spec *pb.ServiceSpec, opts ...grpc.DialOption) + + // EnableHistogram enables historgram in client api metrics. + // + // Even if there are multiple ServiceCli instances, EnableHistogram + // only needs to be called once, on any of those instances. + EnableHistogram() + + // EnableFailFast makes service client doesn't wait for service to become + // available in Start(). + EnableFailFast() + + // AddUnaryInterceptor adds a unary client interceptor to the client. + AddUnaryInterceptor(incept grpc.UnaryClientInterceptor) + + // Start starts the service resolver and returns the grpc connection for + // each service through the callback function. + // + // Start can only be called once for each ServiceCli instance in the whole + // lifecycle of an application. + Start(callback func(spec *pb.ServiceSpec, conn *grpc.ClientConn)) + + // Shutdown turns the service client down. After shutdown, all grpc.Balancer + // objects returned from Resolve() call can not be used any more. + Shutdown() +} + +// NewServiceSpec returns a new ServiceSpec struct with the given parameters. +func NewServiceSpec(namespace string, serviceId vexpb.ServiceId, portName string) *pb.ServiceSpec { + if namespace == "" { + namespace = DefaultNameSpace + } + if portName == "" { + portName = DefaultPortName + } + serviceName, err := naming.ServiceIdToName(serviceId) + if err != nil { + panic("Unknown service ID.") + } + + return &pb.ServiceSpec{ + Namespace: namespace, + ServiceName: serviceName, + PortName: portName, + } +} + +// NewDefaultServiceSpec returns a new ServiceSpec struct with the default +// namespace and default port name. +func NewDefaultServiceSpec(serviceId vexpb.ServiceId) *pb.ServiceSpec { + return NewServiceSpec(DefaultNameSpace, serviceId, DefaultPortName) +} + +// NewServiceCli returns a new service client. NewServiceCli() should be called +// once in the whole lifecycle of an application. +func NewServiceCli(clientServiceId vexpb.ServiceId) ServiceCli { + return skylb.NewServiceClient(clientServiceId, map[string]string(DebugSvcEndpoints)) +} diff --git a/client/example_test.go b/client/example_test.go new file mode 100644 index 0000000..2168ded --- /dev/null +++ b/client/example_test.go @@ -0,0 +1,36 @@ +package client + +import ( + "google.golang.org/grpc" + + vexpb "github.com/binchencoder/gateway-proto/data" + pb "github.com/binchencoder/skylb-api/proto" +) + +func ExampleNewServiceLocator() { + // Create a service client. + cli := NewServiceCli(vexpb.ServiceId_SHARED_TEST_CLIENT_SERVICE) + + // Resolve services. + // grpcHandler := handlers.NewGrpcLoadBalanceHandler( + // NewDefaultServiceSpec(vexpb.ServiceId_SHARED_TEST_SERVER_SERVICE), + // func(conn *grpc.ClientConn) { + // // hold the connecton for use later. + // }, + // ) + // sl.Resolve(grpcHandler) + + cli.Resolve(NewDefaultServiceSpec(vexpb.ServiceId_SHARED_TEST_SERVER_SERVICE), grpc.WithBalancerName("")) + + // Start the locator. + // sl.Start() + + cli.Start(func(spec *pb.ServiceSpec, conn *grpc.ClientConn) { + // hold the connecton for use later. + }) + + // Use the connection to create grpc clients. + + // Shutdown before exit. + cli.Shutdown() +} diff --git a/client/option/BUILD b/client/option/BUILD new file mode 100644 index 0000000..9171d7d --- /dev/null +++ b/client/option/BUILD @@ -0,0 +1,19 @@ +package(default_visibility = ["//visibility:public"]) + +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = glob( + ["*.go"], + exclude = ["*_test.go"], + ), + importpath = "github.com/binchencoder/skylb-api/client/option", + deps = [ + "//proto:go_default_library", + "@com_github_binchencoder_gateway_proto//data:go_default_library", + "@com_github_opentracing_opentracing_go//:go_default_library", + "@org_golang_google_grpc//:go_default_library", + "@org_golang_google_grpc//resolver:go_default_library", + ], +) diff --git a/client/option/options.go b/client/option/options.go new file mode 100644 index 0000000..fa6d541 --- /dev/null +++ b/client/option/options.go @@ -0,0 +1,79 @@ +package option + +import ( + "errors" + + vexpb "github.com/binchencoder/gateway-proto/data" + pb "github.com/binchencoder/skylb-api/proto" + "google.golang.org/grpc/resolver" +) + +var ( + ErrBalancerNameMatchMiss = errors.New("balancer name match miss") +) + +// SkyLbKeeper defines the interface for a SkyLB keeper. +type SkyLbKeeper interface { + // ResisterService registers the service with the given spec to the keeper + RegisterService(spec *pb.ServiceSpec) + + // RegisterServiceCliConn registers the service resolver.ClientConn + // with the given spec to the keeper + RegisterServiceCliConn(spec *pb.ServiceSpec, cliConn resolver.ClientConn) + + // Start starts the keeper with the given client service ID and name. + Start(csId vexpb.ServiceId, csName string, resolveFullEps bool) + + // Shutdown shuts down the keeper. + Shutdown() + + // WaitUntilReady blocks the caller until the keeper receives the initial + // endpoints for all service specs. + WaitUntilReady() +} + +// LoadBalanceHandler defines the interface to handle the notification logic +// for different clients in SkyLB API load balancing. +// type LoadBalanceHandler interface { +// // Returns the service spec for this handler. +// ServiceSpec() *pb.ServiceSpec + +// // BeforeResolve is called before SkyLB API resolves the given spec. +// BeforeResolve(spec *pb.ServiceSpec, ropts *ResolveOptions) + +// // AfterResolve is called after SkyLB API resolved the given spec. +// AfterResolve(spec *pb.ServiceSpec, csId vexpb.ServiceId, csName string, keeper SkyLbKeeper, tracer opentracing.Tracer, failFast bool) + +// // OnShutdown is called when the SkyLB API is shutting down. +// OnShutdown() +// } + +// // BalancerCreator is a function which get a grpc Balancer. +// type BalancerCreator func(balancerName string) balancer.Builder + +// ResolveOptions configure a resolve call. +// type ResolveOptions struct { +// balancerCreator BalancerCreator +// } + +// BalancerCreator returns the load balancer creator. +// func (ropts *ResolveOptions) BalancerCreator() BalancerCreator { +// return ropts.balancerCreator +// } + +// ResolveOption configures how we set up the resolve call. +// type ResolveOption func(*ResolveOptions) + +// WithBalancerCreator returns a ResolveOption which sets a load balancer creator. +// func WithBalancerCreator(balancerName string) ResolveOption { +// builder := balancer.Get(balancerName) +// if nil == builder { +// panic(ErrNoBalancer) +// } + +// return func(o *ResolveOptions) { +// o.balancerCreator = bc +// } + +// return grpc.WithDefaultServiceConfig(`{"loadBalancingConfig": [{"round_robin":{}}]}`) +// } diff --git a/cmd/skytest/BUILD.bazel b/cmd/skytest/BUILD.bazel new file mode 100644 index 0000000..3c803d9 --- /dev/null +++ b/cmd/skytest/BUILD.bazel @@ -0,0 +1,56 @@ +load("@bazel_tools//tools/build_defs/pkg:pkg.bzl", "pkg_tar") +# load("@io_bazel_rules_docker//docker:docker.bzl", "docker_build") +load("@io_bazel_rules_go//go:def.bzl", "go_binary") + +go_binary( + name = "skytest-client", + srcs = ["client.go"], + deps = [ + "//client:go_default_library", + "//cmd/skytest/proto:go_default_library", + "//proto:go_default_library", + "@com_github_binchencoder_letsgo//:go_default_library", + "@com_github_binchencoder_gateway_proto//data:go_default_library", + "@com_github_golang_glog//:go_default_library", + "@com_github_prometheus_client_golang//prometheus:go_default_library", + "@org_golang_x_net//context:go_default_library", + "@org_golang_google_grpc//:go_default_library", + "@org_golang_google_grpc//health/grpc_health_v1:go_default_library", + ], +) + +go_binary( + name = "skytest-server", + srcs = ["server.go"], + deps = [ + "//client:go_default_library", + "//cmd/skytest/proto:go_default_library", + "//server:go_default_library", + "@com_github_binchencoder_letsgo//:go_default_library", + "@com_github_binchencoder_gateway_proto//data:go_default_library", + "@com_github_golang_glog//:go_default_library", + "@com_github_prometheus_client_golang//prometheus:go_default_library", + "@org_golang_x_net//context:go_default_library", + "@org_golang_google_grpc//:go_default_library", + ], +) + +# pkg_tar( +# name = "binary", +# srcs = [ +# ":skytest-client", +# ":skytest-server", +# ], +# package_dir = "/skylb", +# ) + +# docker_build( +# name = "latest", +# base = "//bld_tools/docker/ubuntu:base", +# cmd = "/skylb/start.sh", +# repository = "harbor.binchencoder.ltd", +# tag = "skylb/skytest", +# tars = [ +# ":binary", +# ], +# ) diff --git a/cmd/skytest/README.md b/cmd/skytest/README.md new file mode 100644 index 0000000..8544881 --- /dev/null +++ b/cmd/skytest/README.md @@ -0,0 +1,58 @@ +# Overrview + +sklb-apiv2/cmd/skytest 是一个测试skylb api的程序 + +## Build the skytest + +#### build gRPC server + +```shell +bazel build cmd/skytest:skytest-server +``` + +#### build gRPC client + +```skytest +bazel build cmd/skytest:skytest-client +``` + +## Run the skytest + +#### 确定先启动skylb + +``` +skylb/bazel-bin/cmd/skylb/linux_amd64_stripped/skylb --etcd-endpoints="http://localhost:2377" -alsologtostderr -v=2 +``` + +#### start gRPC server + +1. 注册到skylbserver + +``` +skylb-apiv2/bazel-bin/cmd/skytest/skytest-server_/skytest-server -within-k8s=true -port=18000 -skylb-endpoints="127.0.0.1:1900" -alsologtostderr -v=2 -log_dir=. +``` + +2. 不注册到skylbserver +``` +skylb-apiv2/bazel-bin/cmd/skytest/skytest-server_/skytest-server -port=18000 -alsologtostderr -v=2 -log_dir=. + +skylb-apiv2/bazel-bin/cmd/skytest/skytest-server_/skytest-server -port=18001 -alsologtostderr -v=2 -log_dir=. + +skylb-apiv2/bazel-bin/cmd/skytest/skytest-server_/skytest-server -port=18002 -alsologtostderr -v=2 -log_dir=. +``` + +#### start gRPC client + +1. 直连 + +```shell +skylb-apiv2/bazel-bin/cmd/skytest/skytest-client_/skytest-client -debug-svc-endpoint=shared-test-server-service=localhost:18000,localhost:18001,localhost:18002 -alsologtostderr +``` + +2. 连skylb + +```shell +skylb-apiv2/bazel-bin/cmd/skytest/skytest-client_/skytest-client -skylb-endpoints="127.0.0.1:1900" -alsologtostderr -v=2 -log_dir=. +``` + + \ No newline at end of file diff --git a/cmd/skytest/client.go b/cmd/skytest/client.go new file mode 100644 index 0000000..0b4f5e1 --- /dev/null +++ b/cmd/skytest/client.go @@ -0,0 +1,96 @@ +package main + +import ( + "flag" + "fmt" + "os" + "time" + + "github.com/golang/glog" + prom "github.com/prometheus/client_golang/prometheus" + "golang.org/x/net/context" + "google.golang.org/grpc" + hpb "google.golang.org/grpc/health/grpc_health_v1" + + vexpb "github.com/binchencoder/gateway-proto/data" + "github.com/binchencoder/letsgo" + skylb "github.com/binchencoder/skylb-api/client" + pb "github.com/binchencoder/skylb-api/cmd/skytest/proto" + skypb "github.com/binchencoder/skylb-api/proto" +) + +var ( + nBatchRequest = flag.Int("n-batch-request", 10000, "The number of batched request") + requestSleep = flag.Duration("request-sleep", 100*time.Millisecond, "The sleep time after each request") + requestTimeout = flag.Duration("request-timeout", 100*time.Millisecond, "The timeout of each request") + + spec = skylb.NewServiceSpec(skylb.DefaultNameSpace, vexpb.ServiceId_SHARED_TEST_SERVER_SERVICE, skylb.DefaultPortName) + + grpcFailCount = prom.NewCounter( + prom.CounterOpts{ + Namespace: "skytest", + Subsystem: "client", + Name: "grpc_call_failure", + Help: "The number of failed gRPC calls.", + }, + ) +) + +func startSkylb(sid vexpb.ServiceId) (skylb.ServiceCli, pb.SkytestClient, hpb.HealthClient) { + skycli := skylb.NewServiceCli(vexpb.ServiceId_SHARED_TEST_CLIENT_SERVICE) + skycli.Resolve(skylb.NewServiceSpec(skylb.DefaultNameSpace, sid, skylb.DefaultPortName), + grpc.WithDefaultServiceConfig(`{"loadBalancingConfig": [{"round_robin": {}}]}`)) + skycli.EnableHistogram() + var cli pb.SkytestClient + var healthCli hpb.HealthClient + skycli.Start(func(spec *skypb.ServiceSpec, conn *grpc.ClientConn) { + cli = pb.NewSkytestClient(conn) + healthCli = hpb.NewHealthClient(conn) + }) + return skycli, cli, healthCli +} + +func usage() { + fmt.Println(`Skytest gRPC client. + +Usage: + skytest-client [options] + +Options:`) + + flag.PrintDefaults() + os.Exit(2) +} + +func main() { + letsgo.Init(letsgo.FlagUsage(usage)) + + testClient() +} + +func testClient() { + sl, cli, healthCli := startSkylb(vexpb.ServiceId_SHARED_TEST_SERVER_SERVICE) + for { + for i := 0; i < *nBatchRequest; i++ { + req := pb.GreetingRequest{ + Name: fmt.Sprintf("John Doe %d", time.Now().Second()), + } + ctx, cancel := context.WithTimeout(context.Background(), *requestTimeout) + _, err := cli.Greeting(ctx, &req, grpc.FailFast(false)) + if err != nil { + cancel() + glog.Errorf("Failed to greet service, %v \n", err) + grpcFailCount.Inc() + time.Sleep(*requestTimeout) + continue + } + + // glog.Infof("Greeting resp: %v \n", resp) + + healthCli.Check(context.Background(), &hpb.HealthCheckRequest{}) + time.Sleep(*requestSleep) + } + } + + sl.Shutdown() +} diff --git a/cmd/skytest/grpc.go b/cmd/skytest/grpc.go new file mode 100644 index 0000000..281453b --- /dev/null +++ b/cmd/skytest/grpc.go @@ -0,0 +1,53 @@ +package main + +import ( + "context" + "flag" + "fmt" + "time" + + "github.com/golang/glog" + "google.golang.org/grpc" + + pb "github.com/binchencoder/skylb-api/cmd/skytest/proto" +) + +var ( + grpcEndpoint = flag.String("grpc-endpoint", "192.168.221.104:18000", "The gRPC server endpoint") + timeout = flag.Duration("timeout", time.Second, "The timeout to call gRPC service") +) + +func main() { + flag.Parse() + + for { + testDirectGrpc() + time.Sleep(100 * time.Millisecond) + } +} + +func testDirectGrpc() { + conn, err := grpc.Dial(*grpcEndpoint, grpc.WithInsecure()) + if err != nil { + glog.Fatalf("fail to dial: %v", err) + } + defer conn.Close() + + cli := pb.NewSkytestClient(conn) + + req := pb.GreetingRequest{ + Name: fmt.Sprintf("John Doe %d", time.Now().Second()), + } + ctx, cancel := context.WithTimeout(context.Background(), *timeout) + // fuyc: "cancel" may not be used on all execution paths. Safely ignore + // warnings from "go tool vet". + resp, err := cli.Greeting(ctx, &req, grpc.FailFast(false)) + if err != nil { + cancel() + glog.Errorf("Failed to greet service, %v", err) + fmt.Printf("Failed to greet service, %v", err) + time.Sleep(100 * time.Millisecond) + return + } + fmt.Printf("Demo Reply: %s\n", resp.Greeting) +} diff --git a/cmd/skytest/proto/BUILD.bazel b/cmd/skytest/proto/BUILD.bazel new file mode 100644 index 0000000..b56ddce --- /dev/null +++ b/cmd/skytest/proto/BUILD.bazel @@ -0,0 +1,70 @@ +package( + default_visibility = ["//visibility:public"], +) + +load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") + +proto_library( + name = "api_proto", + srcs = ["api.proto"], +) + +go_proto_library( + name = "api_go_proto", + compilers = [ + "@io_bazel_rules_go//proto:go_grpc", + ], + importpath = "github.com/binchencoder/skylb-api/cmd/skytest/proto", + proto = ":api_proto", +) + +go_library( + name = "go_default_library", + embed = [ + ":api_go_proto", + ], + importpath = "github.com/binchencoder/skylb-api/cmd/skytest/proto", + deps = [ + "@com_github_golang_protobuf//proto:go_default_library", + "@org_golang_x_net//context:go_default_library", + "@org_golang_google_grpc//:go_default_library", + ], +) + +java_proto_library( + name = "api_java_proto", + deps = [ + ":api_proto", + ], +) + +# java_lite_proto_library( +# name = "api_java_lite_proto", +# deps = [ +# ":api_proto", +# ], +# ) + +# genproto_java( +# name = "skytest_src", +# srcs = ["api.proto"], +# has_service = 1, +# deps = [ +# "@com_github_binchencoder_ease_gateway//httpoptions:options_proto", +# "@binchencoder_third_party_go//vendor/github.com/google/protobuf/src/google/protobuf:protos_java", +# "@com_github_binchencoder_gateway_proto//data:data_srcjar", +# ], +# ) + +# java_library( +# name = "skytest", +# # srcs = [":api_proto"], +# runtime_deps = [ +# ":api_java_proto", +# ], +# deps = [ +# # "@com_github_binchencoder_ease_gateway//httpoptions", +# "//vendor/github.com/binchencoder/third-party-java/dependencies/lib:grpc-1.18.0", +# ], +# ) diff --git a/cmd/skytest/proto/api.pb.go b/cmd/skytest/proto/api.pb.go new file mode 100755 index 0000000..2adba47 --- /dev/null +++ b/cmd/skytest/proto/api.pb.go @@ -0,0 +1,308 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.27.1 +// protoc v3.19.4 +// source: cmd/skytest/proto/api.proto + +package proto + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type GreetingRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Age int32 `protobuf:"varint,2,opt,name=age,proto3" json:"age,omitempty"` +} + +func (x *GreetingRequest) Reset() { + *x = GreetingRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_cmd_skytest_proto_api_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GreetingRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GreetingRequest) ProtoMessage() {} + +func (x *GreetingRequest) ProtoReflect() protoreflect.Message { + mi := &file_cmd_skytest_proto_api_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GreetingRequest.ProtoReflect.Descriptor instead. +func (*GreetingRequest) Descriptor() ([]byte, []int) { + return file_cmd_skytest_proto_api_proto_rawDescGZIP(), []int{0} +} + +func (x *GreetingRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *GreetingRequest) GetAge() int32 { + if x != nil { + return x.Age + } + return 0 +} + +type GreetingResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Greeting string `protobuf:"bytes,1,opt,name=greeting,proto3" json:"greeting,omitempty"` +} + +func (x *GreetingResponse) Reset() { + *x = GreetingResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_cmd_skytest_proto_api_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GreetingResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GreetingResponse) ProtoMessage() {} + +func (x *GreetingResponse) ProtoReflect() protoreflect.Message { + mi := &file_cmd_skytest_proto_api_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GreetingResponse.ProtoReflect.Descriptor instead. +func (*GreetingResponse) Descriptor() ([]byte, []int) { + return file_cmd_skytest_proto_api_proto_rawDescGZIP(), []int{1} +} + +func (x *GreetingResponse) GetGreeting() string { + if x != nil { + return x.Greeting + } + return "" +} + +var File_cmd_skytest_proto_api_proto protoreflect.FileDescriptor + +var file_cmd_skytest_proto_api_proto_rawDesc = []byte{ + 0x0a, 0x1b, 0x63, 0x6d, 0x64, 0x2f, 0x73, 0x6b, 0x79, 0x74, 0x65, 0x73, 0x74, 0x2f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2f, 0x61, 0x70, 0x69, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x05, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x37, 0x0a, 0x0f, 0x47, 0x72, 0x65, 0x65, 0x74, 0x69, 0x6e, 0x67, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x61, + 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x61, 0x67, 0x65, 0x22, 0x2e, 0x0a, + 0x10, 0x47, 0x72, 0x65, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x67, 0x72, 0x65, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x67, 0x72, 0x65, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x32, 0x46, 0x0a, + 0x07, 0x53, 0x6b, 0x79, 0x74, 0x65, 0x73, 0x74, 0x12, 0x3b, 0x0a, 0x08, 0x47, 0x72, 0x65, 0x65, + 0x74, 0x69, 0x6e, 0x67, 0x12, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x72, 0x65, + 0x65, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x72, 0x65, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x37, 0x0a, 0x24, 0x63, 0x6f, 0x6d, 0x2e, 0x62, 0x69, 0x6e, + 0x63, 0x68, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x73, 0x6b, 0x79, 0x6c, 0x62, 0x2e, + 0x73, 0x6b, 0x79, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x42, 0x0d, 0x53, + 0x6b, 0x79, 0x74, 0x65, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x50, 0x00, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_cmd_skytest_proto_api_proto_rawDescOnce sync.Once + file_cmd_skytest_proto_api_proto_rawDescData = file_cmd_skytest_proto_api_proto_rawDesc +) + +func file_cmd_skytest_proto_api_proto_rawDescGZIP() []byte { + file_cmd_skytest_proto_api_proto_rawDescOnce.Do(func() { + file_cmd_skytest_proto_api_proto_rawDescData = protoimpl.X.CompressGZIP(file_cmd_skytest_proto_api_proto_rawDescData) + }) + return file_cmd_skytest_proto_api_proto_rawDescData +} + +var file_cmd_skytest_proto_api_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_cmd_skytest_proto_api_proto_goTypes = []interface{}{ + (*GreetingRequest)(nil), // 0: proto.GreetingRequest + (*GreetingResponse)(nil), // 1: proto.GreetingResponse +} +var file_cmd_skytest_proto_api_proto_depIdxs = []int32{ + 0, // 0: proto.Skytest.Greeting:input_type -> proto.GreetingRequest + 1, // 1: proto.Skytest.Greeting:output_type -> proto.GreetingResponse + 1, // [1:2] is the sub-list for method output_type + 0, // [0:1] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_cmd_skytest_proto_api_proto_init() } +func file_cmd_skytest_proto_api_proto_init() { + if File_cmd_skytest_proto_api_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_cmd_skytest_proto_api_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GreetingRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_cmd_skytest_proto_api_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GreetingResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_cmd_skytest_proto_api_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_cmd_skytest_proto_api_proto_goTypes, + DependencyIndexes: file_cmd_skytest_proto_api_proto_depIdxs, + MessageInfos: file_cmd_skytest_proto_api_proto_msgTypes, + }.Build() + File_cmd_skytest_proto_api_proto = out.File + file_cmd_skytest_proto_api_proto_rawDesc = nil + file_cmd_skytest_proto_api_proto_goTypes = nil + file_cmd_skytest_proto_api_proto_depIdxs = nil +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConnInterface + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion6 + +// SkytestClient is the client API for Skytest service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type SkytestClient interface { + Greeting(ctx context.Context, in *GreetingRequest, opts ...grpc.CallOption) (*GreetingResponse, error) +} + +type skytestClient struct { + cc grpc.ClientConnInterface +} + +func NewSkytestClient(cc grpc.ClientConnInterface) SkytestClient { + return &skytestClient{cc} +} + +func (c *skytestClient) Greeting(ctx context.Context, in *GreetingRequest, opts ...grpc.CallOption) (*GreetingResponse, error) { + out := new(GreetingResponse) + err := c.cc.Invoke(ctx, "/proto.Skytest/Greeting", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// SkytestServer is the server API for Skytest service. +type SkytestServer interface { + Greeting(context.Context, *GreetingRequest) (*GreetingResponse, error) +} + +// UnimplementedSkytestServer can be embedded to have forward compatible implementations. +type UnimplementedSkytestServer struct { +} + +func (*UnimplementedSkytestServer) Greeting(context.Context, *GreetingRequest) (*GreetingResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Greeting not implemented") +} + +func RegisterSkytestServer(s *grpc.Server, srv SkytestServer) { + s.RegisterService(&_Skytest_serviceDesc, srv) +} + +func _Skytest_Greeting_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GreetingRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SkytestServer).Greeting(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.Skytest/Greeting", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SkytestServer).Greeting(ctx, req.(*GreetingRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _Skytest_serviceDesc = grpc.ServiceDesc{ + ServiceName: "proto.Skytest", + HandlerType: (*SkytestServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Greeting", + Handler: _Skytest_Greeting_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "cmd/skytest/proto/api.proto", +} diff --git a/cmd/skytest/proto/api.proto b/cmd/skytest/proto/api.proto new file mode 100644 index 0000000..3e6dcef --- /dev/null +++ b/cmd/skytest/proto/api.proto @@ -0,0 +1,23 @@ +syntax = "proto3"; + +package proto; + +option java_multiple_files = false; +option java_outer_classname = "SkytestProtos"; +option java_package = "com.binchencoder.skylb.skytest.proto"; + +// The request message to be greeted. +message GreetingRequest { + string name = 1; + int32 age = 2; +} + +// The response message to greet the requester. +message GreetingResponse { + string greeting = 1; +} + +// The gRPC service definition for skytest. +service Skytest { + rpc Greeting (GreetingRequest) returns (GreetingResponse); +} diff --git a/cmd/skytest/server.go b/cmd/skytest/server.go new file mode 100644 index 0000000..471e739 --- /dev/null +++ b/cmd/skytest/server.go @@ -0,0 +1,110 @@ +package main + +import ( + "flag" + "fmt" + "math/rand" + "os" + "time" + + "github.com/golang/glog" + "golang.org/x/net/context" + "google.golang.org/grpc" + + vexpb "github.com/binchencoder/gateway-proto/data" + "github.com/binchencoder/letsgo" + cli "github.com/binchencoder/skylb-api/client" + pb "github.com/binchencoder/skylb-api/cmd/skytest/proto" + skylb "github.com/binchencoder/skylb-api/server" +) + +var ( + host = flag.String("host", "localhost", "The host") + port = flag.Int("port", 18000, "The gRPC port of the server") + scrapeAddr = flag.String("scrape-addr", "0.0.0.0:18001", "The prometheus scrape port") +) + +var ( + letterRunes = []rune("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") + token string + myServiceId vexpb.ServiceId +) + +func init() { + rand.Seed(time.Now().UnixNano()) + token = randString(20) + fmt.Printf("I am %s \n", token) +} + +func usage() { + fmt.Println(`Skytest gRPC server. + +Usage: + skytest-server [options] + +Options:`) + + flag.PrintDefaults() + os.Exit(2) +} + +func main() { + letsgo.Init(letsgo.FlagUsage(usage)) + + // if *host == "" { + // glog.Fatalf("Flag --host is required.") + // } + + // go registerFakeServices() + // go registerPrometheus() + + myServiceId = vexpb.ServiceId_SHARED_TEST_SERVER_SERVICE + skylb.Register(myServiceId, cli.DefaultPortName, *port) + // skylb.EnableHistogram() + + addr := fmt.Sprintf("%s:%d", *host, *port) + glog.Infof("Starting gRPC service at %s\n", addr) + skylb.Start(addr, func(s *grpc.Server) error { + pb.RegisterSkytestServer(s, &greetingServer{}) + return nil + }) +} + +// func registerFakeServices() { +// for k := range vexpb.ServiceId_name { +// if k > 1000 && k < 220000 { +// glog.Infof("Registered service %d", k) +// spec := skycli.NewServiceSpec(skycli.DefaultNameSpace, vexpb.ServiceId(k), "grpc") +// go skylb.StartSkylbReportLoadWithFixedHost(spec, *host, *port) +// } +// } +// } + +// func registerPrometheus() { +// http.Handle("/_/metrics", prometheus.UninstrumentedHandler()) +// if err := http.ListenAndServe(*scrapeAddr, nil); err != nil { +// log.Fatal("ListenServerError:", err) +// } +// } + +func randString(n int) string { + b := make([]rune, n) + for i := range b { + b[i] = letterRunes[rand.Intn(len(letterRunes))] + } + return string(b) +} + +type greetingServer struct { +} + +func (greetingServer) Greeting(ctx context.Context, req *pb.GreetingRequest) (*pb.GreetingResponse, error) { + glog.Infof("getting request from client, name %s", req.Name) + + time.Sleep(time.Duration(10+rand.Intn(40)) * time.Millisecond) + + g := pb.GreetingResponse{ + Greeting: fmt.Sprintf("Hello %s <- %s@:%d", req.Name, token, *port), + } + return &g, nil +} diff --git a/go.mod b/go.mod index 8d19dd0..9e307ff 100644 --- a/go.mod +++ b/go.mod @@ -1,26 +1,58 @@ -module github.com/binchencoder/skylb-apiv2 +module github.com/binchencoder/skylb-api go 1.17 require ( - github.com/binchencoder/ease-gateway v0.0.4 github.com/binchencoder/gateway-proto v0.0.5 github.com/binchencoder/letsgo v0.0.3 - github.com/coreos/bbolt v1.3.5 // indirect - github.com/coreos/etcd v3.3.13+incompatible - github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b - github.com/golang/protobuf v1.4.2 +) + +require ( + github.com/golang/glog v1.0.0 github.com/grpc-ecosystem/go-grpc-middleware v1.2.0 - github.com/grpc-ecosystem/grpc-gateway/v2 v2.9.0 github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 - github.com/mwitkow/grpc-proxy v0.0.0-20181017164139-0f1106ef9c76 - github.com/opentracing/opentracing-go v1.2.0 github.com/prometheus/client_golang v1.7.1 - github.com/smartystreets/goconvey v1.6.4 github.com/soheilhy/cmux v0.1.4 - github.com/stretchr/testify v1.6.1 golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd google.golang.org/grpc v1.45.0 + google.golang.org/protobuf v1.27.1 +) + +require ( + github.com/VividCortex/gohistogram v1.0.0 // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/cenkalti/backoff v2.2.1+incompatible // indirect + github.com/cespare/xxhash/v2 v2.1.1 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/go-kit/kit v0.10.0 // indirect + github.com/golang/protobuf v1.5.2 // indirect + github.com/google/uuid v1.1.2 // indirect + github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 // indirect + github.com/jtolds/gls v4.20.0+incompatible // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect + github.com/opentracing/opentracing-go v1.2.0 // indirect + github.com/pborman/uuid v1.2.0 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/prometheus/client_model v0.2.0 // indirect + github.com/prometheus/common v0.10.0 // indirect + github.com/prometheus/procfs v0.1.3 // indirect + github.com/smartystreets/assertions v1.0.1 // indirect + github.com/stretchr/objx v0.2.0 // indirect + github.com/uber/jaeger-client-go v2.24.0+incompatible // indirect + github.com/uber/jaeger-lib v2.2.0+incompatible // indirect + golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e // indirect + golang.org/x/text v0.3.7 // indirect + gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 // indirect +) + +require ( + github.com/google/go-cmp v0.5.7 // indirect + github.com/smartystreets/goconvey v1.6.4 + github.com/stretchr/testify v1.7.1 + go.uber.org/atomic v1.6.0 // indirect + google.golang.org/genproto v0.0.0-20220314164441-57ef72a4c106 // indirect + google.golang.org/grpc/examples v0.0.0-20200630190442-3de8449f8555 // indirect ) replace ( diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..0fb26d1 --- /dev/null +++ b/go.sum @@ -0,0 +1,504 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= +github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= +github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= +github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= +github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= +github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= +github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/binchencoder/gateway-proto v0.0.5 h1:2oh9Y8/qlMX1K3m73XDMU9U3mA06WMkLmJrMi4nFlCc= +github.com/binchencoder/gateway-proto v0.0.5/go.mod h1:853l4bAOm0Gt8XrDy+9obeKRlBLwP4HAk9tVYbgnSmU= +github.com/binchencoder/letsgo v0.0.3 h1:hEDDOeGdX9R/JPYMdVo9N/9iQa5BeBLluTssrNYy/ng= +github.com/binchencoder/letsgo v0.0.3/go.mod h1:WbqNFa5gFsogqe3gtycvPYswprKV7eGJIxScwQhAg44= +github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= +github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= +github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= +github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd h1:qMd81Ts1T2OTKmB4acZcyKaMtRnY5Y44NuXGX2GFJ1w= +github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= +github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= +github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= +github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= +github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.10.0 h1:dXFJfIHVvUcpSgDOV+Ne6t7jXri8Tfv2uOLHUZ2XNuo= +github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ= +github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= +github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= +github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= +github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-middleware v1.2.0 h1:0IKlLyQ3Hs9nDaiK5cSHAGmcQEIC8l2Ts1u6x5Dfrqg= +github.com/grpc-ecosystem/go-grpc-middleware v1.2.0/go.mod h1:mJzapYve32yjrKlk9GbyCZHuPgZsrbyIbyKhSzOpg6s= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 h1:MJG/KsmcqMwFAkh8mTnAwhyKoB+sTAnY4CACC110tbU= +github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645/go.mod h1:6iZfnjpejD4L/4DwD7NryNaJyCQdzwWwH2MWhCA90Kw= +github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= +github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= +github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= +github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= +github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= +github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= +github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= +github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= +github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= +github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= +github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= +github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= +github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= +github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= +github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= +github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= +github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= +github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g= +github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= +github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= +github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= +github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= +github.com/prometheus/client_golang v1.7.1 h1:NTGy1Ja9pByO+xAeH/qiWnLrKtr3hJPNjaVUwnjpdpA= +github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= +github.com/prometheus/common v0.10.0 h1:RyRA7RzGXQZiW+tGMr7sxa85G1z0yOpM1qq5c8lNawc= +github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= +github.com/prometheus/procfs v0.1.3 h1:F0+tqvhOksq22sc6iCHF5WGlWjdwj92p0udFh1VFBS8= +github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/assertions v1.0.1 h1:voD4ITNjPL5jjBfgR/r8fPIIBrliWrWHeiJApdr3r4w= +github.com/smartystreets/assertions v1.0.1/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= +github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= +github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= +github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/uber/jaeger-client-go v2.24.0+incompatible h1:CGchgJcHsDd2jWnaL4XngByMrXoGHh3n8oCqAKx0uMo= +github.com/uber/jaeger-client-go v2.24.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= +github.com/uber/jaeger-lib v2.2.0+incompatible h1:MxZXOiR2JuoANZ3J6DE/U0kSFv/eJ/GfSYVCjK7dyaw= +github.com/uber/jaeger-lib v2.2.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= +github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= +go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= +go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk= +go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd h1:O7DYs+zxREGLKzKoMQrtrEacpb0ZVXA5rIwylE2Xchk= +golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200103221440-774c71fcf114 h1:DnSr2mCsxyCE6ZgIkmcWUQY2R5cH/6wL7eIxEmQOMSE= +golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200624020401-64a14ca9d1ad/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20220314164441-57ef72a4c106 h1:ErU+UA6wxadoU8nWrsy5MZUVBs75K17zUCsUCIfrXCE= +google.golang.org/genproto v0.0.0-20220314164441-57ef72a4c106/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= +google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.45.0 h1:NEpgUqV3Z+ZjkqMsxMg11IaDrXY4RY6CQukSGK0uI1M= +google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= +google.golang.org/grpc/examples v0.0.0-20200630190442-3de8449f8555 h1:B6/wMqTY7mM93BBu0wfiO67B9+bcv4oQQsdrcijjfzA= +google.golang.org/grpc/examples v0.0.0-20200630190442-3de8449f8555/go.mod h1:5j1uub0jRGhRiSghIlrThmBUgcgLXOVJQ/l1getT4uo= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= +sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= +upper.io/db.v3 v3.7.1+incompatible/go.mod h1:FgTdD24eBjJAbPKsQSiHUNgXjOR4Lub3u1UMHSIh82Y= diff --git a/internal/flags/BUILD.bazel b/internal/flags/BUILD.bazel index 6816d18..4b0da81 100644 --- a/internal/flags/BUILD.bazel +++ b/internal/flags/BUILD.bazel @@ -5,5 +5,5 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") go_library( name = "go_default_library", srcs = ["flags.go"], - importpath = "github.com/binchencoder/skylb-apiv2/internal/flags", + importpath = "github.com/binchencoder/skylb-api/internal/flags", ) diff --git a/internal/health/BUILD.bazel b/internal/health/BUILD.bazel new file mode 100644 index 0000000..6a85d3f --- /dev/null +++ b/internal/health/BUILD.bazel @@ -0,0 +1,38 @@ +package(default_visibility = ["//visibility:public"]) + +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "go_default_library", + srcs = [ + "ctx.go", + "health.go", + ], + importpath = "github.com/binchencoder/skylb-api/internal/health", + deps = [ + "@com_github_binchencoder_letsgo//hashring:go_default_library", + "@com_github_golang_glog//:go_default_library", + "@com_github_prometheus_client_golang//prometheus:go_default_library", + "@org_golang_x_net//context:go_default_library", + "@org_golang_google_grpc//:go_default_library", + "@org_golang_google_grpc//balancer:go_default_library", + "@org_golang_google_grpc//codes:go_default_library", + "@org_golang_google_grpc//health/grpc_health_v1:go_default_library", + "@org_golang_google_grpc//status:go_default_library", + ], +) + +go_test( + name = "small_tests", + size = "small", + srcs = [ + "ctx_test.go", + ], + embed = [ + ":go_default_library", + ], + deps = [ + "@com_github_smartystreets_goconvey//convey:go_default_library", + "@org_golang_x_net//context:go_default_library", + ], +) diff --git a/internal/health/ctx.go b/internal/health/ctx.go new file mode 100644 index 0000000..867bf49 --- /dev/null +++ b/internal/health/ctx.go @@ -0,0 +1,23 @@ +package health + +import "golang.org/x/net/context" + +const ( + reqTypeHealthCheck = 1 +) + +type requestTypeKey struct{} + +// withHealthCheck returns a copy of parent context in which +// the health check is set. +func withHealthCheck(parent context.Context) context.Context { + return context.WithValue(parent, requestTypeKey{}, reqTypeHealthCheck) +} + +// IsHealthCheck returns true if the request is a gRPC health check. +func IsHealthCheck(ctx context.Context) bool { + if reqType, ok := ctx.Value(requestTypeKey{}).(int); ok { + return reqType == reqTypeHealthCheck + } + return false +} diff --git a/internal/health/ctx_test.go b/internal/health/ctx_test.go new file mode 100644 index 0000000..ea2973e --- /dev/null +++ b/internal/health/ctx_test.go @@ -0,0 +1,16 @@ +package health + +import ( + "testing" + + . "github.com/smartystreets/goconvey/convey" + "golang.org/x/net/context" +) + +func TestHealthCheckContext(t *testing.T) { + Convey("Create a health check context", t, func() { + ctx := withHealthCheck(context.Background()) + So(IsHealthCheck(ctx), ShouldBeTrue) + So(IsHealthCheck(context.Background()), ShouldBeFalse) + }) +} diff --git a/internal/health/health.go b/internal/health/health.go new file mode 100644 index 0000000..a78901f --- /dev/null +++ b/internal/health/health.go @@ -0,0 +1,143 @@ +package health + +import ( + "flag" + "time" + + "github.com/golang/glog" + prom "github.com/prometheus/client_golang/prometheus" + + "golang.org/x/net/context" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + hpb "google.golang.org/grpc/health/grpc_health_v1" + "google.golang.org/grpc/status" + + "github.com/binchencoder/letsgo/hashring" + "google.golang.org/grpc/balancer" +) + +var ( + healthCheckInterval = flag.Duration("health-check-interval", time.Minute, "The interval of health checking") + HealthCheckTimeout = flag.Duration("health-check-timeout", 2000*time.Millisecond, "The timeout for health checking") + + healthCheckCounts = prom.NewCounterVec( + prom.CounterOpts{ + Namespace: "skylb", + Subsystem: "client", + Name: "health_check_counts", + Help: "grpc health check counts.", + }, + []string{"code", "grpc_service"}, + ) + // to export + HealthCheckCounts = healthCheckCounts + + healthCheckSuccessGauge = prom.NewGaugeVec( + prom.GaugeOpts{ + Namespace: "skylb", + Subsystem: "client", + Name: "health_check_success_gauge", + Help: "grpc health check success gauge.", + }, + []string{"grpc_service"}, + ) + + healthCheckSuccessRate = prom.NewGaugeVec( + prom.GaugeOpts{ + Namespace: "skylb", + Subsystem: "client", + Name: "health_check_success_rate", + Help: "grpc health check success rate.", + }, + []string{"grpc_service"}, + ) + + healthCheckLatency = prom.NewHistogramVec( + prom.HistogramOpts{ + Namespace: "skylb", + Subsystem: "client", + Name: "health_check_latency", + Help: "grpc health check latency.", + Buckets: prom.DefBuckets, + }, + []string{"grpc_service"}, + ) + //to export + HealthCheckLatency = healthCheckLatency +) + +func init() { + prom.MustRegister(healthCheckCounts) + prom.MustRegister(healthCheckSuccessGauge) + prom.MustRegister(healthCheckSuccessRate) + prom.MustRegister(healthCheckLatency) +} + +type sizer interface { + Size() int +} + +// StartHealthCheck starts a goroutine to send health check requests +// to gRPC service. +func StartHealthCheck(conn *grpc.ClientConn, balancer balancer.Balancer, svc string) chan<- struct{} { + if _, ok := balancer.(sizer); !ok { + glog.Errorf("The load balancer didn't implement Size(), service %s", svc) + return nil + } + + stopCh := make(chan struct{}, 1) + + go func() { + cli := hpb.NewHealthClient(conn) + ticker := time.NewTicker(*healthCheckInterval) + req := hpb.HealthCheckRequest{ + Service: svc, + } + parent := withHealthCheck(context.Background()) + parent = hashring.WithHashKey(parent, "") // To avoid warning in services like authz. + for { + select { + case <-ticker.C: + size := balancer.(sizer).Size() + if size == 0 { + glog.Errorf("The load balancer has empty instances of service %s", svc) + healthCheckSuccessGauge.WithLabelValues(svc).Set(0) + healthCheckSuccessRate.WithLabelValues(svc).Set(0) + continue + } + glog.V(5).Infof("Sending health check for %d instances of service %s", size, svc) + + success := 0 + for i := 0; i < size; i++ { + start := time.Now() + ctx, _ := context.WithTimeout(parent, *HealthCheckTimeout) + if _, err := cli.Check(ctx, &req); err != nil { + healthCheckCounts.WithLabelValues(status.Code(err).String(), svc).Inc() + if !IsSafeError(err) { + glog.Errorf("Failed to send a health check for an instance of service %s: %v", svc, err) + continue + } + } + healthCheckLatency.WithLabelValues(svc).Observe(time.Since(start).Seconds()) + healthCheckCounts.WithLabelValues("OK", svc).Inc() + success++ + //time.Sleep(time.Second) // fuyc: uncomment to verify health check working in correct order. + } + healthCheckSuccessGauge.WithLabelValues(svc).Set(float64(success)) + healthCheckSuccessRate.WithLabelValues(svc).Set(float64(success) / float64(size)) + case <-stopCh: + glog.Infof("got stopCh") + ticker.Stop() + return + } + } + }() + + return stopCh +} + +func IsSafeError(err error) bool { + code := status.Code(err) + return codes.Unimplemented == code || codes.InvalidArgument == code || codes.NotFound == code +} diff --git a/internal/rpccli/BUILD.bazel b/internal/rpccli/BUILD.bazel index ebe9d4c..ac9742c 100644 --- a/internal/rpccli/BUILD.bazel +++ b/internal/rpccli/BUILD.bazel @@ -8,11 +8,12 @@ go_library( ["*.go"], exclude = ["*_test.go"], ), - importpath = "github.com/binchencoder/skylb-apiv2/internal/rpccli", + importpath = "github.com/binchencoder/skylb-api/internal/rpccli", deps = [ - "@com_github_binchencoder_letsgo//strings:go_default_library", "//internal/flags:go_default_library", "//proto:go_default_library", + "//resolver:go_default_library", + "@com_github_binchencoder_letsgo//strings:go_default_library", "@com_github_golang_glog//:go_default_library", "@org_golang_x_net//context:go_default_library", "@org_golang_google_grpc//:go_default_library", diff --git a/internal/rpccli/rpc.go b/internal/rpccli/rpc.go index 5b49f12..c7119bf 100644 --- a/internal/rpccli/rpc.go +++ b/internal/rpccli/rpc.go @@ -13,8 +13,9 @@ import ( "google.golang.org/grpc" "github.com/binchencoder/letsgo/strings" - "github.com/binchencoder/skylb-apiv2/internal/flags" - pb "github.com/binchencoder/skylb-apiv2/proto" + "github.com/binchencoder/skylb-api/internal/flags" + pb "github.com/binchencoder/skylb-api/proto" + "github.com/binchencoder/skylb-api/resolver" ) func init() { @@ -50,6 +51,7 @@ func NewGrpcClient(ctx context.Context) (pb.SkylbClient, error) { } glog.Infof("Resolved SkyLB instances %s", addrs) + // TODO(chenbin) 这里不要随机取 switch len(addrs) { case 0: return nil, fmt.Errorf("No SkyLB instances found") @@ -61,7 +63,8 @@ func NewGrpcClient(ctx context.Context) (pb.SkylbClient, error) { } glog.Infof("Connecting SkyLB instance %s on port %s", ep, port) - conn, err := grpc.Dial(fmt.Sprintf("%s:%s", ep, port), grpc.WithInsecure(), grpc.WithTimeout(time.Second), grpc.WithBlock()) + conn, err := grpc.Dial(resolver.DirectTarget(fmt.Sprintf("%s:%s", ep, port)), + grpc.WithInsecure(), grpc.WithTimeout(time.Second), grpc.WithBlock()) if err != nil { glog.Errorf("Failed to dial to SkyLB instance %s, %+v.", ep, err) return nil, err diff --git a/internal/skylb/BUILD.bazel b/internal/skylb/BUILD.bazel new file mode 100644 index 0000000..5e66ef7 --- /dev/null +++ b/internal/skylb/BUILD.bazel @@ -0,0 +1,57 @@ +package(default_visibility = ["//visibility:public"]) + +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "go_default_library", + srcs = glob( + ["*.go"], + exclude = ["*_test.go"], + ), + importpath = "github.com/binchencoder/skylb-api/internal/skylb", + deps = [ + "//balancer:go_default_library", + "//client/option:go_default_library", + "//internal/flags:go_default_library", + "//internal/flags/client:go_default_library", + "//internal/health:go_default_library", + "//internal/rpccli:go_default_library", + "//metrics:go_default_library", + "//naming:go_default_library", + "//proto:go_default_library", + "//resolver:go_default_library", + "@com_github_binchencoder_letsgo//grpc:go_default_library", + "@com_github_binchencoder_letsgo//sync:go_default_library", + "@com_github_binchencoder_gateway_proto//data:go_default_library", + "@com_github_golang_glog//:go_default_library", + "@com_github_grpc_ecosystem_grpc_opentracing//go/otgrpc:go_default_library", + "@com_github_prometheus_client_golang//prometheus:go_default_library", + "@org_golang_x_net//context:go_default_library", + "@org_golang_google_grpc//:go_default_library", + "@org_golang_google_grpc//codes:go_default_library", + "@org_golang_google_grpc//credentials/insecure:go_default_library", + "@org_golang_google_grpc//resolver:go_default_library", + "@org_golang_google_grpc//status:go_default_library", + ], +) + +go_test( + name = "tests", + size = "small", + srcs = glob( + ["*_test.go"] + ), + embed = [ + ":go_default_library", + ], + deps = [ + "//client/option:go_default_library", + "//proto:go_default_library", + "//testing:go_default_library", + "@com_github_opentracing_opentracing_go//:go_default_library", + "@com_github_smartystreets_goconvey//convey:go_default_library", + "@com_github_stretchr_testify//assert:go_default_library", + "@com_github_stretchr_testify//mock:go_default_library", + "@com_github_binchencoder_gateway_proto//data:go_default_library", + ], +) diff --git a/internal/skylb/client.go b/internal/skylb/client.go new file mode 100644 index 0000000..64395e2 --- /dev/null +++ b/internal/skylb/client.go @@ -0,0 +1,297 @@ +package skylb + +import ( + "fmt" + "strconv" + "strings" + "time" + + "github.com/golang/glog" + "github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc" + "golang.org/x/net/context" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" + + vexpb "github.com/binchencoder/gateway-proto/data" + jg "github.com/binchencoder/letsgo/grpc" + "github.com/binchencoder/skylb-api/client/option" + "github.com/binchencoder/skylb-api/internal/flags" + "github.com/binchencoder/skylb-api/metrics" + "github.com/binchencoder/skylb-api/naming" + pb "github.com/binchencoder/skylb-api/proto" + "github.com/binchencoder/skylb-api/resolver" + skyrs "github.com/binchencoder/skylb-api/resolver" +) + +var ( + withPrometheusHistogram = false +) + +// serviceClient implements interface skylb-api/client/ServiceClient. +type serviceClient struct { + clientServiceId vexpb.ServiceId + keeper option.SkyLbKeeper + specs []*pb.ServiceSpec + conns []*grpc.ClientConn + // lbs map[string]grpc.Balancer + healthCheckClosers []chan<- struct{} + dopts map[string][]grpc.DialOption + unaryInterceptors []grpc.UnaryClientInterceptor + failFast bool + skylbResolveCount int + + debugSvcEndpoints map[string]string + + resolveFullEps bool + started bool +} + +// Resolve resolves a service spec and returns a load balancer handle. +// It needs to be called for every service used by the client. +func (sc *serviceClient) Resolve(spec *pb.ServiceSpec, opts ...grpc.DialOption) { + dopts := []grpc.DialOption{} + for _, opt := range opts { + dopts = append(dopts, opt) + } + sc.dopts[spec.String()] = dopts + + sc.resolve(spec) +} + +func (sc *serviceClient) resolve(spec *pb.ServiceSpec) { + if ep, ok := sc.debugSvcEndpoints[spec.ServiceName]; ok { + // Debug mode, do not need to register service. + addrs := strings.Split(ep, ",") + // Check valid addrs + for _, addr := range addrs { + parts := strings.SplitN(addr, ":", 2) + if len(parts) != 2 { + panic(fmt.Sprintf("Service instance endpoint should in format host:port, got %s", ep)) + } + _, err := strconv.Atoi(parts[1]) + if err != nil { + panic(err) + } + } + } else { + sc.keeper.RegisterService(spec) + sc.skylbResolveCount++ + } + + sc.specs = append(sc.specs, spec) +} + +// EnableHistogram enables historgram in client api metrics. +// (This function doesn't have to be member method, but done so anyway +// in order to expose to interface ServiceCli) +func (sc *serviceClient) EnableHistogram() { + withPrometheusHistogram = true +} + +// EnableResolveFullEps enables to resolve full endpoints. +func (sc *serviceClient) EnableResolveFullEps() { + sc.resolveFullEps = true +} + +// DisableResolveFullEps disables resolving full endpoints. +func (sc *serviceClient) DisableResolveFullEps() { + sc.resolveFullEps = false +} + +// AddUnaryInterceptor adds a unary client interceptor to the client. +func (sc *serviceClient) AddUnaryInterceptor(incept grpc.UnaryClientInterceptor) { + sc.unaryInterceptors = append(sc.unaryInterceptors, incept) +} + +// Start starts the service resolver and returns the grpc connection for +// each service through the callback function. +// +// Start can only be called once in the whole lifecycle of an application. +func (sc *serviceClient) Start(callback func(spec *pb.ServiceSpec, conn *grpc.ClientConn)) { + csId := sc.clientServiceId + csName, err := naming.ServiceIdToName(csId) + + // Only be called once + if sc.started { + glog.Warningf("Service client[%s] has started", csName) + return + } + + glog.Infof("Starting service client[%s] with %d service specs to resolve.", + csName, sc.skylbResolveCount) + + if nil != err { + glog.V(1).Infof("Invalid caller service id %d\n", csId) + csName = fmt.Sprintf("!%d", csId) + } + + if sc.skylbResolveCount > 0 { + // Registers the skylb scheme to the resolver. + resolver.RegisterSkylbResolverBuilder(sc.keeper) + + go sc.keeper.Start(csId, csName, sc.resolveFullEps) + } + + for _, spec := range sc.specs { + specCopy := &pb.ServiceSpec{ + Namespace: spec.Namespace, + ServiceName: spec.ServiceName, + PortName: spec.PortName, + } + + options := sc.buildDialOptions(specCopy) + + var conn *grpc.ClientConn + var err error + for { + func() { + defer func() { + if p := recover(); p != nil { + err = fmt.Errorf("%v", p) + } + }() + + var target string + if addrs, ok := sc.debugSvcEndpoints[spec.ServiceName]; ok { + target = skyrs.DirectTarget(addrs) + } else { + target = skyrs.SkyLBTarget(spec) + } + conn, err = grpc.Dial(target, options...) + }() + + if err == nil { + break + } + + glog.Warningf("Failed to dial service %q, %v.", spec.ServiceName, err) + time.Sleep(*flags.SkylbRetryInterval) + } + + sc.conns = append(sc.conns, conn) + callback(spec, conn) + // if *cflags.EnableHealthCheck { + // closer := health.StartHealthCheck(conn, balancer, spec.ServiceName) + // if closer != nil { + // sc.healthCheckClosers = append(sc.healthCheckClosers, closer) + // } + // } + } + + if withPrometheusHistogram { + metrics.EnableClientHandlingTimeHistogram() + } + + if !sc.failFast && sc.skylbResolveCount > 0 { + sc.keeper.WaitUntilReady() + } + + sc.started = true +} + +func (sc *serviceClient) buildDialOptions(calledSpec *pb.ServiceSpec) []grpc.DialOption { + var options []grpc.DialOption + if ops, ok := sc.dopts[calledSpec.String()]; ok { + options = ops + } + + csId := sc.clientServiceId + csName, err := naming.ServiceIdToName(csId) + if nil != err { + glog.V(1).Infof("Invalid caller service id %d\n", csId) + csName = fmt.Sprintf("!%d", csId) + } + + tracer := jg.InitOpenTracing(getClientServiceName(sc.clientServiceId)) + openTracingInterceptor := otgrpc.OpenTracingClientInterceptor(tracer) + + metricsInterceptor := func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, + invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { + ctx2 := jg.WithServiceId(ctx, int(csId)) + return metrics.UnaryClientInterceptor(csName, calledSpec, ctx2, method, req, reply, cc, invoker, opts...) + } + + metadataInterceptor := func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, + invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { + return jg.ClientToMetadataInterceptor(csName, ctx, method, req, reply, cc, invoker, opts...) + } + + incepts := make([]grpc.UnaryClientInterceptor, 0, len(sc.unaryInterceptors)+3) + // openTracingInterceptor needs to be after + // ExpBackoffUnaryClientInterceptor so that retry request will + // have separate tracing. + incepts = append(incepts, metricsInterceptor, jg.ExpBackoffUnaryClientInterceptor, openTracingInterceptor) + incepts = append(incepts, sc.unaryInterceptors...) + // ClientToMetadataInterceptor needs to be the last. + incepts = append(incepts, metadataInterceptor) + + options = append(options, grpc.WithTransportCredentials(insecure.NewCredentials())) + + options = append(options, + grpc.WithUnaryInterceptor(jg.ChainUnaryClient(incepts...)), + grpc.WithStreamInterceptor(func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, + streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) { + ctx2 := jg.WithServiceId(ctx, int(csId)) + return metrics.StreamClientInterceptor(csName, calledSpec, ctx2, desc, cc, method, streamer, opts...) + }), + ) + + if sc.failFast { + options = append(options, + grpc.WithBlock(), + // TODO(fuyc): here use a relatively longer duration as dial timeout. + grpc.WithTimeout(*flags.SkylbRetryInterval*6), + ) + } + + return options +} + +// Shutdown turns the service client down. After shutdown all grpc.Balancer +// objects returned from Resolve() call can not be used any more. +func (sc *serviceClient) Shutdown() { + glog.V(3).Infof("Shutdown") + for _, closer := range sc.healthCheckClosers { + close(closer) + } + for _, conn := range sc.conns { + if nil != conn { + conn.Close() + } + } + sc.keeper.Shutdown() +} + +// EnableFailFast instructs the API framework to not wait all dependent +// services to be available. Here it only delegates the call to the keeper. +func (sc *serviceClient) EnableFailFast() { + glog.V(3).Infoln("FailFast is enabled") + sc.failFast = true +} + +func getClientServiceName(clientServiceId vexpb.ServiceId) string { + name, err := naming.ServiceIdToName(clientServiceId) + if nil != err { + glog.Errorf("Invalid client service id %d\n", clientServiceId) + return "unknownService" + } + + return name +} + +// NewServiceClient returns a new service client with the given debug service +// endpoints map. +func NewServiceClient(clientServiceId vexpb.ServiceId, dseps map[string]string) *serviceClient { + return &serviceClient{ + clientServiceId: clientServiceId, + keeper: NewSkyLbKeeper(), + specs: []*pb.ServiceSpec{}, + conns: []*grpc.ClientConn{}, + healthCheckClosers: []chan<- struct{}{}, + dopts: map[string][]grpc.DialOption{}, + unaryInterceptors: []grpc.UnaryClientInterceptor{}, + + debugSvcEndpoints: dseps, + resolveFullEps: true, + } +} diff --git a/internal/skylb/keeper.go b/internal/skylb/keeper.go new file mode 100644 index 0000000..f9c1f2c --- /dev/null +++ b/internal/skylb/keeper.go @@ -0,0 +1,291 @@ +package skylb + +import ( + "bytes" + "context" + "flag" + "fmt" + "io" + "time" + + vexpb "github.com/binchencoder/gateway-proto/data" + "github.com/binchencoder/letsgo/sync" + "github.com/binchencoder/skylb-api/internal/flags" + "github.com/binchencoder/skylb-api/internal/rpccli" + "github.com/binchencoder/skylb-api/metrics" + pb "github.com/binchencoder/skylb-api/proto" + "github.com/golang/glog" + prom "github.com/prometheus/client_golang/prometheus" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/resolver" + "google.golang.org/grpc/status" +) + +var ( + skylbAliveTimeout = flag.Duration("skylb-alive-timeout", 3*time.Minute, "The timeout duration to keep alive of the SkyLB endpoints updates. Recommended value is 3 times of the auto rectification interval") + + svcKeeperGauge = prom.NewGauge( + prom.GaugeOpts{ + Namespace: "skylb", + Subsystem: "client", + Name: "service_keeper_gauge", + Help: "Number of service keepers.", + }, + ) + svcKeeperRecvStreamGauge = prom.NewGauge( + prom.GaugeOpts{ + Namespace: "skylb", + Subsystem: "client", + Name: "service_keeper_recv_stream_gauge", + Help: "Number of service keepers receiving stream.", + }, + ) + svcWatcherUpdatesGauge = prom.NewGauge( + prom.GaugeOpts{ + Namespace: "skylb", + Subsystem: "client", + Name: "service_watcher_updates_gauge", + Help: "Number of unconsumed service watcher updates.", + }, + ) +) + +// type serviceEntry struct { +// spec *pb.ServiceSpec +// updateCh chan []*resolver.Address +// } + +// skyLbKeeper keeps connectivity to SkyLb instance. +type skyLbKeeper struct { + sync.RWLock + + services map[string]*pb.ServiceSpec + resolverCliConns map[string]resolver.ClientConn + readyCh chan struct{} + ready bool + cancel context.CancelFunc + stopped bool +} + +func init() { + prom.MustRegister(svcKeeperGauge) + prom.MustRegister(svcKeeperRecvStreamGauge) + prom.MustRegister(svcWatcherUpdatesGauge) +} + +func (sk *skyLbKeeper) RegisterService(spec *pb.ServiceSpec) { + key := calcServiceKey(spec) + sk.services[key] = spec +} + +func (sk *skyLbKeeper) RegisterServiceCliConn(spec *pb.ServiceSpec, cliConn resolver.ClientConn) { + key := calcServiceKey(spec) + sk.resolverCliConns[key] = cliConn + + glog.Infof("Registered to resolve service spec %s.%s on port name %q.", + spec.Namespace, spec.ServiceName, spec.PortName) +} + +func (sk *skyLbKeeper) Start(csId vexpb.ServiceId, csName string, resolveFullEps bool) { + svcKeeperGauge.Inc() + + glog.V(4).Infof("Starting SkyLB keeper for caller service ID %#v", csId) + if len(sk.services) == 0 { + svcKeeperGauge.Dec() + return + } + + req := pb.ResolveRequest{ + Services: []*pb.ServiceSpec{}, + CallerServiceId: csId, + CallerServiceName: csName, + ResolveFullEndpoints: resolveFullEps, + } + for _, s := range sk.services { + req.Services = append(req.Services, s) + } + + ctx, cancel := context.WithCancel(context.Background()) + sk.cancel = cancel + + for { + if err := sk.start(ctx, &req); err != nil { + if err == io.EOF { + glog.Info("SkyLB server closed the resolve stream.") + } + if st, ok := status.FromError(err); ok && st.Code() == codes.Canceled { + if sk.stopped { + break + } + } + } + time.Sleep(*flags.SkylbRetryInterval) + } + + svcKeeperGauge.Dec() +} + +func (sk *skyLbKeeper) start(ctx context.Context, req *pb.ResolveRequest) error { + ctxt, cancel := context.WithCancel(ctx) + skyCli, err := rpccli.NewGrpcClient(ctxt) + if err != nil { + glog.Errorf("Failed to create gRPC client to SkyLB, %+v, retry.", err) + return err + } + + stopCh := make(chan struct{}, 1) + + timer := time.NewTimer(*skylbAliveTimeout) + go func(cancel context.CancelFunc, stopCh <-chan struct{}) { + select { + case <-timer.C: + glog.V(4).Infof("Service keeper timeout to receive updates. Cancel and restart.") + metrics.SkylbAliveTimeoutCounts.Inc() + case <-stopCh: + glog.V(4).Infof("Service keeper is shutdown.") + if !timer.Stop() { + <-timer.C + } + } + cancel() + }(cancel, stopCh) + + glog.V(5).Infof("Resolving request: %+v", req) + rctx, _ := context.WithCancel(ctxt) + stream, err := skyCli.Resolve(rctx, req) + if err != nil { + glog.Errorf("Failed to call RPC Resolve, %+v, retry.", err) + close(stopCh) + return err + } + glog.Infoln("Established resolve stream to SkyLB.") + + // localEpsMap := make(map[string]map[string]struct{}) + + readyMap := map[string]struct{}{} + for { + resp, err := stream.Recv() + if err != nil { + close(stopCh) + cancel() + return err + } + + svcKeeperRecvStreamGauge.Inc() + + if !timer.Stop() { + <-timer.C + } + timer.Reset(*skylbAliveTimeout) + + var updates []resolver.Address + if svcEps := resp.GetSvcEndpoints(); svcEps != nil { + lenEps := len(svcEps.InstEndpoints) + svcName := svcEps.Spec.ServiceName + glog.V(2).Infof("Received %d endpoint(s) for service %s", lenEps, svcName) + metrics.RecordEndpointCount(svcName, lenEps) + + // localEps, ok := localEpsMap[svcEps.Spec.String()] + // if !ok { + // localEps = make(map[string]struct{}) + // localEpsMap[svcEps.Spec.String()] = localEps + // } + + // The response holds full endpoints, we need to calculate + // the deltas. + // eps := make(map[string]struct{}) + for _, ep := range svcEps.InstEndpoints { + addr := fmt.Sprintf("%s:%d", ep.Host, ep.Port) + // eps[addr] = struct{}{} + // if _, ok := localEps[addr]; !ok { + // up := resolver.Address{ + // Addr: addr, + // } + // if ep.Weight != 0 { + // up.Metadata = ep.Weight + // } + // updates = append(updates, up) + // localEps[addr] = struct{}{} + // } + + updates = append(updates, resolver.Address{ + Addr: addr, + }) + } + // for addr := range localEps { + // if _, ok := eps[addr]; !ok { + // up := resolver.Address{ + // Addr: addr, + // } + // updates = append(updates, up) + // delete(localEps, addr) + // } + // } + + if len(updates) == 0 { + svcKeeperRecvStreamGauge.Dec() + continue + } + + key := calcServiceKey(svcEps.Spec) + if !sk.ready { + if _, ok := readyMap[key]; !ok { + readyMap[key] = struct{}{} + if len(readyMap) == len(sk.services) { + close(sk.readyCh) + sk.ready = true + } + } + } + + if glog.V(3) { + var buf bytes.Buffer + for i, up := range updates { + if i > 0 { + (&buf).WriteString(", ") + } + (&buf).WriteString(fmt.Sprintf("[%+v]", up)) + } + glog.Infof("Received endpoints update for %s with value %+v.", key, buf.String()) + } + + if cliConn, ok := sk.resolverCliConns[key]; ok { + // glog.V(1).Infof("resolver.ClientConn#UpdateState, service:[%s], update: %+v \n", key, updates) + if err := cliConn.UpdateState(resolver.State{ + Addresses: updates, + }); err != nil { + cliConn.ReportError(err) + } + } else { + glog.Errorf("Nil resolver.ClientConn for key %s", key) + } + } + svcKeeperRecvStreamGauge.Dec() + } +} + +func (sk *skyLbKeeper) Shutdown() { + glog.V(3).Info("Shutting down keeper.") + sk.stopped = true + if sk.cancel != nil { + sk.cancel() + } + metrics.ClearEndpointCount() +} + +func (sk *skyLbKeeper) WaitUntilReady() { + <-sk.readyCh +} + +func calcServiceKey(spec *pb.ServiceSpec) string { + return fmt.Sprintf("%s.%s:%s", spec.Namespace, spec.ServiceName, spec.PortName) +} + +// NewSkyLbKeeper returns a new skylb keeper. +func NewSkyLbKeeper() *skyLbKeeper { + return &skyLbKeeper{ + resolverCliConns: make(map[string]resolver.ClientConn), + services: make(map[string]*pb.ServiceSpec), + readyCh: make(chan struct{}, 1), + } +} diff --git a/metrics/BUILD.bazel b/metrics/BUILD.bazel index 427b5b6..da59960 100644 --- a/metrics/BUILD.bazel +++ b/metrics/BUILD.bazel @@ -8,7 +8,7 @@ go_library( ["*.go"], exclude = ["*_test.go"], ), - importpath = "github.com/binchencoder/skylb-apiv2/metrics", + importpath = "github.com/binchencoder/skylb-api/metrics", deps = [ "@com_github_binchencoder_letsgo//grpc:go_default_library", "//proto:go_default_library", diff --git a/metrics/client.go b/metrics/client.go index fafebee..be30ba2 100644 --- a/metrics/client.go +++ b/metrics/client.go @@ -12,7 +12,7 @@ import ( "google.golang.org/grpc" "google.golang.org/grpc/codes" - pb "github.com/binchencoder/skylb-apiv2/proto" + pb "github.com/binchencoder/skylb-api/proto" ) // UnaryClientInterceptor is a gRPC client-side interceptor that provides Prometheus monitoring for Unary RPCs. diff --git a/metrics/client_reporter.go b/metrics/client_reporter.go index 19170c9..e87f757 100644 --- a/metrics/client_reporter.go +++ b/metrics/client_reporter.go @@ -9,7 +9,7 @@ import ( prom "github.com/prometheus/client_golang/prometheus" "google.golang.org/grpc/codes" - pb "github.com/binchencoder/skylb-apiv2/proto" + pb "github.com/binchencoder/skylb-api/proto" ) var ( diff --git a/metrics/server.go b/metrics/server.go index 8799961..1a350cc 100644 --- a/metrics/server.go +++ b/metrics/server.go @@ -11,7 +11,7 @@ import ( "google.golang.org/grpc" jgrpc "github.com/binchencoder/letsgo/grpc" - pb "github.com/binchencoder/skylb-apiv2/proto" + pb "github.com/binchencoder/skylb-api/proto" ) // PreregisterServices takes a gRPC server and pre-initializes all counters to 0. diff --git a/metrics/server_reporter.go b/metrics/server_reporter.go index 10bb6c2..4a2a32a 100644 --- a/metrics/server_reporter.go +++ b/metrics/server_reporter.go @@ -10,7 +10,7 @@ import ( "google.golang.org/grpc" "google.golang.org/grpc/codes" - pb "github.com/binchencoder/skylb-apiv2/proto" + pb "github.com/binchencoder/skylb-api/proto" ) type grpcType string diff --git a/naming/BUILD.bazel b/naming/BUILD.bazel new file mode 100644 index 0000000..a1537c8 --- /dev/null +++ b/naming/BUILD.bazel @@ -0,0 +1,34 @@ +package(default_visibility = ["//visibility:public"]) + +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "go_default_library", + srcs = glob( + ["*.go"], + exclude = ["*_test.go"], + ), + importpath = "github.com/binchencoder/skylb-api/naming", + deps = [ + "@com_github_binchencoder_gateway_proto//data:go_default_library", + ], +) + +go_test( + name = "naming_test", + size = "small", + srcs = glob(["*_test.go"]), + embed = [ + ":go_default_library", + ], + deps = [ + "@com_github_binchencoder_gateway_proto//data:go_default_library", + ], +) + +go_test( + name = "go_default_test", + srcs = ["naming_test.go"], + embed = [":go_default_library"], + deps = ["@com_github_binchencoder_gateway_proto//data:go_default_library"], +) diff --git a/naming/naming.go b/naming/naming.go new file mode 100644 index 0000000..1c4f9fc --- /dev/null +++ b/naming/naming.go @@ -0,0 +1,39 @@ +package naming + +import ( + "fmt" + "strings" + + dpb "github.com/binchencoder/gateway-proto/data" +) + +// ServiceIdToName converts service id to service name in +// standard string form. +func ServiceIdToName(serviceId dpb.ServiceId) (string, error) { + serviceName, ok := dpb.ServiceId_name[int32(serviceId)] + if ok { + return strings.ToLower(strings.Replace(serviceName, "_", "-", -1)), nil + } + return fmt.Sprintf("!%d", serviceId), fmt.Errorf("Invalid service id %d", serviceId) +} + +// ServiceNameToId converts service name in standard string form +// to service id. +func ServiceNameToId(serviceName string) (dpb.ServiceId, error) { + serviceId, ok := dpb.ServiceId_value[strings.ToUpper(strings.Replace(serviceName, "-", "_", -1))] + if ok { + return dpb.ServiceId(serviceId), nil + } + return dpb.ServiceId_SERVICE_NONE, fmt.Errorf("Invalid service name %s", serviceName) +} + +// ServiceNameToFolderName converts service name to folder name used +// in production repo. +func ServiceNameToFolderName(serviceName string) string { + return strings.ToLower(strings.Replace(serviceName, "_", "-", -1)) +} + +// FolderNameToServiceName converts folder name to service name. +func FolderNameToServiceName(folderName string) string { + return strings.ToUpper(strings.Replace(folderName, "-", "_", -1)) +} diff --git a/naming/naming_test.go b/naming/naming_test.go new file mode 100644 index 0000000..6487693 --- /dev/null +++ b/naming/naming_test.go @@ -0,0 +1,35 @@ +package naming + +import ( + "testing" + + dpb "github.com/binchencoder/gateway-proto/data" +) + +func TestToString(t *testing.T) { + vexillaryServiceName, err := ServiceIdToName(dpb.ServiceId_VEXILLARY_SERVICE) + if err != nil { + t.Error("Expect no error") + } + if vexillaryServiceName != "vexillary-service" { + t.Errorf("Expect 'vexillary-service' but got %s.", vexillaryServiceName) + } + + vexillaryServiceId, err := ServiceNameToId(vexillaryServiceName) + if err != nil { + t.Error("Expect no error") + } + if vexillaryServiceId != dpb.ServiceId_VEXILLARY_SERVICE { + t.Errorf("Expect 'ServiceId_VEXILLARY_SERVICE' but got %v.", vexillaryServiceId) + } + + vexillaryServiceName, err = ServiceIdToName(dpb.ServiceId(13131313)) // Some non-existent service id. + if err == nil { + t.Error("Expect error") + } + + vexillaryServiceId, err = ServiceNameToId("wrong-name") + if err == nil { + t.Error("Expect error") + } +} diff --git a/proto/BUILD.bazel b/proto/BUILD.bazel index b362940..e774022 100644 --- a/proto/BUILD.bazel +++ b/proto/BUILD.bazel @@ -16,7 +16,7 @@ go_proto_library( compilers = [ "@io_bazel_rules_go//proto:go_grpc", ], - importpath = "github.com/binchencoder/skylb-apiv2/proto", + importpath = "github.com/binchencoder/skylb-api/proto", proto = ":api_proto", deps = [ "@com_github_binchencoder_gateway_proto//data:data_go_proto", @@ -27,7 +27,7 @@ go_proto_library( go_library( name = "go_default_library", embed = [":api_go_proto"], - importpath = "github.com/binchencoder/skylb-apiv2/proto", + importpath = "github.com/binchencoder/skylb-api/proto", deps = [ "@com_github_golang_protobuf//proto:go_default_library", "@org_golang_x_net//context:go_default_library", diff --git a/proto/api.pb.go b/proto/api.pb.go new file mode 100755 index 0000000..3dfc306 --- /dev/null +++ b/proto/api.pb.go @@ -0,0 +1,1817 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.27.1 +// protoc v3.19.4 +// source: proto/api.proto + +package proto + +import ( + context "context" + data "github.com/binchencoder/gateway-proto/data" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type Operation int32 + +const ( + Operation_Add Operation = 0 + Operation_Delete Operation = 1 +) + +// Enum value maps for Operation. +var ( + Operation_name = map[int32]string{ + 0: "Add", + 1: "Delete", + } + Operation_value = map[string]int32{ + "Add": 0, + "Delete": 1, + } +) + +func (x Operation) Enum() *Operation { + p := new(Operation) + *p = x + return p +} + +func (x Operation) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Operation) Descriptor() protoreflect.EnumDescriptor { + return file_proto_api_proto_enumTypes[0].Descriptor() +} + +func (Operation) Type() protoreflect.EnumType { + return &file_proto_api_proto_enumTypes[0] +} + +func (x Operation) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Operation.Descriptor instead. +func (Operation) EnumDescriptor() ([]byte, []int) { + return file_proto_api_proto_rawDescGZIP(), []int{0} +} + +type ServiceSpec struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Namespace string `protobuf:"bytes,1,opt,name=namespace,proto3" json:"namespace,omitempty"` + ServiceName string `protobuf:"bytes,2,opt,name=service_name,json=serviceName,proto3" json:"service_name,omitempty"` + PortName string `protobuf:"bytes,3,opt,name=port_name,json=portName,proto3" json:"port_name,omitempty"` +} + +func (x *ServiceSpec) Reset() { + *x = ServiceSpec{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_api_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ServiceSpec) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServiceSpec) ProtoMessage() {} + +func (x *ServiceSpec) ProtoReflect() protoreflect.Message { + mi := &file_proto_api_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServiceSpec.ProtoReflect.Descriptor instead. +func (*ServiceSpec) Descriptor() ([]byte, []int) { + return file_proto_api_proto_rawDescGZIP(), []int{0} +} + +func (x *ServiceSpec) GetNamespace() string { + if x != nil { + return x.Namespace + } + return "" +} + +func (x *ServiceSpec) GetServiceName() string { + if x != nil { + return x.ServiceName + } + return "" +} + +func (x *ServiceSpec) GetPortName() string { + if x != nil { + return x.PortName + } + return "" +} + +type ResolveRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Services []*ServiceSpec `protobuf:"bytes,1,rep,name=services,proto3" json:"services,omitempty"` + CallerServiceId data.ServiceId `protobuf:"varint,2,opt,name=callerServiceId,proto3,enum=data.ServiceId" json:"callerServiceId,omitempty"` + CallerServiceName string `protobuf:"bytes,3,opt,name=callerServiceName,proto3" json:"callerServiceName,omitempty"` + ResolveFullEndpoints bool `protobuf:"varint,4,opt,name=resolve_full_endpoints,json=resolveFullEndpoints,proto3" json:"resolve_full_endpoints,omitempty"` +} + +func (x *ResolveRequest) Reset() { + *x = ResolveRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_api_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ResolveRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResolveRequest) ProtoMessage() {} + +func (x *ResolveRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_api_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ResolveRequest.ProtoReflect.Descriptor instead. +func (*ResolveRequest) Descriptor() ([]byte, []int) { + return file_proto_api_proto_rawDescGZIP(), []int{1} +} + +func (x *ResolveRequest) GetServices() []*ServiceSpec { + if x != nil { + return x.Services + } + return nil +} + +func (x *ResolveRequest) GetCallerServiceId() data.ServiceId { + if x != nil { + return x.CallerServiceId + } + return data.ServiceId(0) +} + +func (x *ResolveRequest) GetCallerServiceName() string { + if x != nil { + return x.CallerServiceName + } + return "" +} + +func (x *ResolveRequest) GetResolveFullEndpoints() bool { + if x != nil { + return x.ResolveFullEndpoints + } + return false +} + +type InstanceEndpoint struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Deprecated: Do not use. + Op Operation `protobuf:"varint,1,opt,name=op,proto3,enum=api.Operation" json:"op,omitempty"` + Host string `protobuf:"bytes,2,opt,name=host,proto3" json:"host,omitempty"` + Port int32 `protobuf:"varint,3,opt,name=port,proto3" json:"port,omitempty"` + Weight int32 `protobuf:"varint,4,opt,name=weight,proto3" json:"weight,omitempty"` +} + +func (x *InstanceEndpoint) Reset() { + *x = InstanceEndpoint{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_api_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *InstanceEndpoint) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*InstanceEndpoint) ProtoMessage() {} + +func (x *InstanceEndpoint) ProtoReflect() protoreflect.Message { + mi := &file_proto_api_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use InstanceEndpoint.ProtoReflect.Descriptor instead. +func (*InstanceEndpoint) Descriptor() ([]byte, []int) { + return file_proto_api_proto_rawDescGZIP(), []int{2} +} + +// Deprecated: Do not use. +func (x *InstanceEndpoint) GetOp() Operation { + if x != nil { + return x.Op + } + return Operation_Add +} + +func (x *InstanceEndpoint) GetHost() string { + if x != nil { + return x.Host + } + return "" +} + +func (x *InstanceEndpoint) GetPort() int32 { + if x != nil { + return x.Port + } + return 0 +} + +func (x *InstanceEndpoint) GetWeight() int32 { + if x != nil { + return x.Weight + } + return 0 +} + +type ServiceEndpoints struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Spec *ServiceSpec `protobuf:"bytes,1,opt,name=spec,proto3" json:"spec,omitempty"` + InstEndpoints []*InstanceEndpoint `protobuf:"bytes,2,rep,name=inst_endpoints,json=instEndpoints,proto3" json:"inst_endpoints,omitempty"` +} + +func (x *ServiceEndpoints) Reset() { + *x = ServiceEndpoints{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_api_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ServiceEndpoints) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServiceEndpoints) ProtoMessage() {} + +func (x *ServiceEndpoints) ProtoReflect() protoreflect.Message { + mi := &file_proto_api_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServiceEndpoints.ProtoReflect.Descriptor instead. +func (*ServiceEndpoints) Descriptor() ([]byte, []int) { + return file_proto_api_proto_rawDescGZIP(), []int{3} +} + +func (x *ServiceEndpoints) GetSpec() *ServiceSpec { + if x != nil { + return x.Spec + } + return nil +} + +func (x *ServiceEndpoints) GetInstEndpoints() []*InstanceEndpoint { + if x != nil { + return x.InstEndpoints + } + return nil +} + +type ResolveResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + SvcEndpoints *ServiceEndpoints `protobuf:"bytes,1,opt,name=svc_endpoints,json=svcEndpoints,proto3" json:"svc_endpoints,omitempty"` +} + +func (x *ResolveResponse) Reset() { + *x = ResolveResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_api_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ResolveResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResolveResponse) ProtoMessage() {} + +func (x *ResolveResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_api_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ResolveResponse.ProtoReflect.Descriptor instead. +func (*ResolveResponse) Descriptor() ([]byte, []int) { + return file_proto_api_proto_rawDescGZIP(), []int{4} +} + +func (x *ResolveResponse) GetSvcEndpoints() *ServiceEndpoints { + if x != nil { + return x.SvcEndpoints + } + return nil +} + +type ReportLoadRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Spec *ServiceSpec `protobuf:"bytes,1,opt,name=spec,proto3" json:"spec,omitempty"` + Port int32 `protobuf:"varint,2,opt,name=port,proto3" json:"port,omitempty"` + Weight int32 `protobuf:"varint,3,opt,name=weight,proto3" json:"weight,omitempty"` + FixedHost string `protobuf:"bytes,4,opt,name=fixed_host,json=fixedHost,proto3" json:"fixed_host,omitempty"` +} + +func (x *ReportLoadRequest) Reset() { + *x = ReportLoadRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_api_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ReportLoadRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ReportLoadRequest) ProtoMessage() {} + +func (x *ReportLoadRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_api_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ReportLoadRequest.ProtoReflect.Descriptor instead. +func (*ReportLoadRequest) Descriptor() ([]byte, []int) { + return file_proto_api_proto_rawDescGZIP(), []int{5} +} + +func (x *ReportLoadRequest) GetSpec() *ServiceSpec { + if x != nil { + return x.Spec + } + return nil +} + +func (x *ReportLoadRequest) GetPort() int32 { + if x != nil { + return x.Port + } + return 0 +} + +func (x *ReportLoadRequest) GetWeight() int32 { + if x != nil { + return x.Weight + } + return 0 +} + +func (x *ReportLoadRequest) GetFixedHost() string { + if x != nil { + return x.FixedHost + } + return "" +} + +type ReportLoadResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ReportLoadResponse) Reset() { + *x = ReportLoadResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_api_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ReportLoadResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ReportLoadResponse) ProtoMessage() {} + +func (x *ReportLoadResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_api_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ReportLoadResponse.ProtoReflect.Descriptor instead. +func (*ReportLoadResponse) Descriptor() ([]byte, []int) { + return file_proto_api_proto_rawDescGZIP(), []int{6} +} + +type CheckHealthInstruction struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *CheckHealthInstruction) Reset() { + *x = CheckHealthInstruction{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_api_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CheckHealthInstruction) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CheckHealthInstruction) ProtoMessage() {} + +func (x *CheckHealthInstruction) ProtoReflect() protoreflect.Message { + mi := &file_proto_api_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CheckHealthInstruction.ProtoReflect.Descriptor instead. +func (*CheckHealthInstruction) Descriptor() ([]byte, []int) { + return file_proto_api_proto_rawDescGZIP(), []int{7} +} + +type HealthInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Endpoint string `protobuf:"bytes,1,opt,name=endpoint,proto3" json:"endpoint,omitempty"` + Latency int32 `protobuf:"varint,2,opt,name=latency,proto3" json:"latency,omitempty"` +} + +func (x *HealthInfo) Reset() { + *x = HealthInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_api_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *HealthInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HealthInfo) ProtoMessage() {} + +func (x *HealthInfo) ProtoReflect() protoreflect.Message { + mi := &file_proto_api_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use HealthInfo.ProtoReflect.Descriptor instead. +func (*HealthInfo) Descriptor() ([]byte, []int) { + return file_proto_api_proto_rawDescGZIP(), []int{8} +} + +func (x *HealthInfo) GetEndpoint() string { + if x != nil { + return x.Endpoint + } + return "" +} + +func (x *HealthInfo) GetLatency() int32 { + if x != nil { + return x.Latency + } + return 0 +} + +type CheckHealthResult struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + HealthInfo []*HealthInfo `protobuf:"bytes,1,rep,name=health_info,json=healthInfo,proto3" json:"health_info,omitempty"` +} + +func (x *CheckHealthResult) Reset() { + *x = CheckHealthResult{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_api_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CheckHealthResult) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CheckHealthResult) ProtoMessage() {} + +func (x *CheckHealthResult) ProtoReflect() protoreflect.Message { + mi := &file_proto_api_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CheckHealthResult.ProtoReflect.Descriptor instead. +func (*CheckHealthResult) Descriptor() ([]byte, []int) { + return file_proto_api_proto_rawDescGZIP(), []int{9} +} + +func (x *CheckHealthResult) GetHealthInfo() []*HealthInfo { + if x != nil { + return x.HealthInfo + } + return nil +} + +type FetchInstancesInstruction struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *FetchInstancesInstruction) Reset() { + *x = FetchInstancesInstruction{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_api_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FetchInstancesInstruction) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FetchInstancesInstruction) ProtoMessage() {} + +func (x *FetchInstancesInstruction) ProtoReflect() protoreflect.Message { + mi := &file_proto_api_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FetchInstancesInstruction.ProtoReflect.Descriptor instead. +func (*FetchInstancesInstruction) Descriptor() ([]byte, []int) { + return file_proto_api_proto_rawDescGZIP(), []int{10} +} + +type FetchInstancesResult struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + SvcEndpoints *ServiceEndpoints `protobuf:"bytes,1,opt,name=svc_endpoints,json=svcEndpoints,proto3" json:"svc_endpoints,omitempty"` +} + +func (x *FetchInstancesResult) Reset() { + *x = FetchInstancesResult{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_api_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FetchInstancesResult) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FetchInstancesResult) ProtoMessage() {} + +func (x *FetchInstancesResult) ProtoReflect() protoreflect.Message { + mi := &file_proto_api_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FetchInstancesResult.ProtoReflect.Descriptor instead. +func (*FetchInstancesResult) Descriptor() ([]byte, []int) { + return file_proto_api_proto_rawDescGZIP(), []int{11} +} + +func (x *FetchInstancesResult) GetSvcEndpoints() *ServiceEndpoints { + if x != nil { + return x.SvcEndpoints + } + return nil +} + +type AddInstanceInstruction struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + SvcEndpoints *ServiceEndpoints `protobuf:"bytes,1,opt,name=svc_endpoints,json=svcEndpoints,proto3" json:"svc_endpoints,omitempty"` +} + +func (x *AddInstanceInstruction) Reset() { + *x = AddInstanceInstruction{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_api_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AddInstanceInstruction) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AddInstanceInstruction) ProtoMessage() {} + +func (x *AddInstanceInstruction) ProtoReflect() protoreflect.Message { + mi := &file_proto_api_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AddInstanceInstruction.ProtoReflect.Descriptor instead. +func (*AddInstanceInstruction) Descriptor() ([]byte, []int) { + return file_proto_api_proto_rawDescGZIP(), []int{12} +} + +func (x *AddInstanceInstruction) GetSvcEndpoints() *ServiceEndpoints { + if x != nil { + return x.SvcEndpoints + } + return nil +} + +type AddInstanceResult struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *AddInstanceResult) Reset() { + *x = AddInstanceResult{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_api_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AddInstanceResult) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AddInstanceResult) ProtoMessage() {} + +func (x *AddInstanceResult) ProtoReflect() protoreflect.Message { + mi := &file_proto_api_proto_msgTypes[13] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AddInstanceResult.ProtoReflect.Descriptor instead. +func (*AddInstanceResult) Descriptor() ([]byte, []int) { + return file_proto_api_proto_rawDescGZIP(), []int{13} +} + +type DeleteInstanceInstruction struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + SvcEndpoints *ServiceEndpoints `protobuf:"bytes,1,opt,name=svc_endpoints,json=svcEndpoints,proto3" json:"svc_endpoints,omitempty"` +} + +func (x *DeleteInstanceInstruction) Reset() { + *x = DeleteInstanceInstruction{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_api_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteInstanceInstruction) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteInstanceInstruction) ProtoMessage() {} + +func (x *DeleteInstanceInstruction) ProtoReflect() protoreflect.Message { + mi := &file_proto_api_proto_msgTypes[14] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteInstanceInstruction.ProtoReflect.Descriptor instead. +func (*DeleteInstanceInstruction) Descriptor() ([]byte, []int) { + return file_proto_api_proto_rawDescGZIP(), []int{14} +} + +func (x *DeleteInstanceInstruction) GetSvcEndpoints() *ServiceEndpoints { + if x != nil { + return x.SvcEndpoints + } + return nil +} + +type DeleteInstanceResult struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *DeleteInstanceResult) Reset() { + *x = DeleteInstanceResult{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_api_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteInstanceResult) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteInstanceResult) ProtoMessage() {} + +func (x *DeleteInstanceResult) ProtoReflect() protoreflect.Message { + mi := &file_proto_api_proto_msgTypes[15] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteInstanceResult.ProtoReflect.Descriptor instead. +func (*DeleteInstanceResult) Descriptor() ([]byte, []int) { + return file_proto_api_proto_rawDescGZIP(), []int{15} +} + +type DiagnoseRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to Instruction: + // *DiagnoseRequest_CheckHealth + // *DiagnoseRequest_FetchInstances + // *DiagnoseRequest_AddInstance + // *DiagnoseRequest_DeleteInstance + Instruction isDiagnoseRequest_Instruction `protobuf_oneof:"instruction"` +} + +func (x *DiagnoseRequest) Reset() { + *x = DiagnoseRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_api_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DiagnoseRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DiagnoseRequest) ProtoMessage() {} + +func (x *DiagnoseRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_api_proto_msgTypes[16] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DiagnoseRequest.ProtoReflect.Descriptor instead. +func (*DiagnoseRequest) Descriptor() ([]byte, []int) { + return file_proto_api_proto_rawDescGZIP(), []int{16} +} + +func (m *DiagnoseRequest) GetInstruction() isDiagnoseRequest_Instruction { + if m != nil { + return m.Instruction + } + return nil +} + +func (x *DiagnoseRequest) GetCheckHealth() *CheckHealthInstruction { + if x, ok := x.GetInstruction().(*DiagnoseRequest_CheckHealth); ok { + return x.CheckHealth + } + return nil +} + +func (x *DiagnoseRequest) GetFetchInstances() *FetchInstancesInstruction { + if x, ok := x.GetInstruction().(*DiagnoseRequest_FetchInstances); ok { + return x.FetchInstances + } + return nil +} + +func (x *DiagnoseRequest) GetAddInstance() *AddInstanceInstruction { + if x, ok := x.GetInstruction().(*DiagnoseRequest_AddInstance); ok { + return x.AddInstance + } + return nil +} + +func (x *DiagnoseRequest) GetDeleteInstance() *DeleteInstanceInstruction { + if x, ok := x.GetInstruction().(*DiagnoseRequest_DeleteInstance); ok { + return x.DeleteInstance + } + return nil +} + +type isDiagnoseRequest_Instruction interface { + isDiagnoseRequest_Instruction() +} + +type DiagnoseRequest_CheckHealth struct { + CheckHealth *CheckHealthInstruction `protobuf:"bytes,1,opt,name=check_health,json=checkHealth,proto3,oneof"` +} + +type DiagnoseRequest_FetchInstances struct { + FetchInstances *FetchInstancesInstruction `protobuf:"bytes,2,opt,name=fetch_instances,json=fetchInstances,proto3,oneof"` +} + +type DiagnoseRequest_AddInstance struct { + AddInstance *AddInstanceInstruction `protobuf:"bytes,3,opt,name=add_instance,json=addInstance,proto3,oneof"` +} + +type DiagnoseRequest_DeleteInstance struct { + DeleteInstance *DeleteInstanceInstruction `protobuf:"bytes,4,opt,name=delete_instance,json=deleteInstance,proto3,oneof"` +} + +func (*DiagnoseRequest_CheckHealth) isDiagnoseRequest_Instruction() {} + +func (*DiagnoseRequest_FetchInstances) isDiagnoseRequest_Instruction() {} + +func (*DiagnoseRequest_AddInstance) isDiagnoseRequest_Instruction() {} + +func (*DiagnoseRequest_DeleteInstance) isDiagnoseRequest_Instruction() {} + +type DiagnoseResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to Result: + // *DiagnoseResponse_CheckHealth + // *DiagnoseResponse_FetchInstances + // *DiagnoseResponse_AddInstance + // *DiagnoseResponse_DeleteInstance + Result isDiagnoseResponse_Result `protobuf_oneof:"result"` +} + +func (x *DiagnoseResponse) Reset() { + *x = DiagnoseResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_api_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DiagnoseResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DiagnoseResponse) ProtoMessage() {} + +func (x *DiagnoseResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_api_proto_msgTypes[17] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DiagnoseResponse.ProtoReflect.Descriptor instead. +func (*DiagnoseResponse) Descriptor() ([]byte, []int) { + return file_proto_api_proto_rawDescGZIP(), []int{17} +} + +func (m *DiagnoseResponse) GetResult() isDiagnoseResponse_Result { + if m != nil { + return m.Result + } + return nil +} + +func (x *DiagnoseResponse) GetCheckHealth() *CheckHealthResult { + if x, ok := x.GetResult().(*DiagnoseResponse_CheckHealth); ok { + return x.CheckHealth + } + return nil +} + +func (x *DiagnoseResponse) GetFetchInstances() *FetchInstancesResult { + if x, ok := x.GetResult().(*DiagnoseResponse_FetchInstances); ok { + return x.FetchInstances + } + return nil +} + +func (x *DiagnoseResponse) GetAddInstance() *AddInstanceResult { + if x, ok := x.GetResult().(*DiagnoseResponse_AddInstance); ok { + return x.AddInstance + } + return nil +} + +func (x *DiagnoseResponse) GetDeleteInstance() *DeleteInstanceResult { + if x, ok := x.GetResult().(*DiagnoseResponse_DeleteInstance); ok { + return x.DeleteInstance + } + return nil +} + +type isDiagnoseResponse_Result interface { + isDiagnoseResponse_Result() +} + +type DiagnoseResponse_CheckHealth struct { + CheckHealth *CheckHealthResult `protobuf:"bytes,1,opt,name=check_health,json=checkHealth,proto3,oneof"` +} + +type DiagnoseResponse_FetchInstances struct { + FetchInstances *FetchInstancesResult `protobuf:"bytes,2,opt,name=fetch_instances,json=fetchInstances,proto3,oneof"` +} + +type DiagnoseResponse_AddInstance struct { + AddInstance *AddInstanceResult `protobuf:"bytes,3,opt,name=add_instance,json=addInstance,proto3,oneof"` +} + +type DiagnoseResponse_DeleteInstance struct { + DeleteInstance *DeleteInstanceResult `protobuf:"bytes,4,opt,name=delete_instance,json=deleteInstance,proto3,oneof"` +} + +func (*DiagnoseResponse_CheckHealth) isDiagnoseResponse_Result() {} + +func (*DiagnoseResponse_FetchInstances) isDiagnoseResponse_Result() {} + +func (*DiagnoseResponse_AddInstance) isDiagnoseResponse_Result() {} + +func (*DiagnoseResponse_DeleteInstance) isDiagnoseResponse_Result() {} + +var File_proto_api_proto protoreflect.FileDescriptor + +var file_proto_api_proto_rawDesc = []byte{ + 0x0a, 0x0f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x61, 0x70, 0x69, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x12, 0x03, 0x61, 0x70, 0x69, 0x1a, 0x0f, 0x64, 0x61, 0x74, 0x61, 0x2f, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x6b, 0x0a, 0x0b, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x53, 0x70, 0x65, 0x63, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x6f, 0x72, 0x74, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6f, 0x72, 0x74, + 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xdd, 0x01, 0x0a, 0x0e, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2c, 0x0a, 0x08, 0x73, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x53, 0x70, 0x65, 0x63, 0x52, 0x08, 0x73, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x39, 0x0a, 0x0f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, + 0x2e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x52, + 0x0f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, + 0x12, 0x2c, 0x0a, 0x11, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x63, 0x61, 0x6c, + 0x6c, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x34, + 0x0a, 0x16, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x5f, 0x66, 0x75, 0x6c, 0x6c, 0x5f, 0x65, + 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, + 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x46, 0x75, 0x6c, 0x6c, 0x45, 0x6e, 0x64, 0x70, 0x6f, + 0x69, 0x6e, 0x74, 0x73, 0x22, 0x76, 0x0a, 0x10, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, + 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x22, 0x0a, 0x02, 0x6f, 0x70, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x02, 0x18, 0x01, 0x52, 0x02, 0x6f, 0x70, 0x12, 0x12, 0x0a, 0x04, + 0x68, 0x6f, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x6f, 0x73, 0x74, + 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, + 0x70, 0x6f, 0x72, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0x76, 0x0a, 0x10, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, + 0x12, 0x24, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x53, 0x70, 0x65, 0x63, + 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x12, 0x3c, 0x0a, 0x0e, 0x69, 0x6e, 0x73, 0x74, 0x5f, 0x65, + 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x45, 0x6e, 0x64, + 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x0d, 0x69, 0x6e, 0x73, 0x74, 0x45, 0x6e, 0x64, 0x70, 0x6f, + 0x69, 0x6e, 0x74, 0x73, 0x22, 0x4d, 0x0a, 0x0f, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3a, 0x0a, 0x0d, 0x73, 0x76, 0x63, 0x5f, 0x65, + 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x45, 0x6e, 0x64, 0x70, + 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x52, 0x0c, 0x73, 0x76, 0x63, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, + 0x6e, 0x74, 0x73, 0x22, 0x84, 0x01, 0x0a, 0x11, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x4c, 0x6f, + 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x24, 0x0a, 0x04, 0x73, 0x70, 0x65, + 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x12, + 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x70, + 0x6f, 0x72, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x06, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x66, + 0x69, 0x78, 0x65, 0x64, 0x5f, 0x68, 0x6f, 0x73, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x09, 0x66, 0x69, 0x78, 0x65, 0x64, 0x48, 0x6f, 0x73, 0x74, 0x22, 0x14, 0x0a, 0x12, 0x52, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x4c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x18, 0x0a, 0x16, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x49, + 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x42, 0x0a, 0x0a, 0x48, 0x65, + 0x61, 0x6c, 0x74, 0x68, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x6e, 0x64, 0x70, + 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x65, 0x6e, 0x64, 0x70, + 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x6c, 0x61, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x6c, 0x61, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x22, 0x45, + 0x0a, 0x11, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x12, 0x30, 0x0a, 0x0b, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x5f, 0x69, 0x6e, + 0x66, 0x6f, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x48, + 0x65, 0x61, 0x6c, 0x74, 0x68, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0a, 0x68, 0x65, 0x61, 0x6c, 0x74, + 0x68, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x1b, 0x0a, 0x19, 0x46, 0x65, 0x74, 0x63, 0x68, 0x49, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x49, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x22, 0x52, 0x0a, 0x14, 0x46, 0x65, 0x74, 0x63, 0x68, 0x49, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x3a, 0x0a, 0x0d, 0x73, 0x76, + 0x63, 0x5f, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x15, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x45, + 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x52, 0x0c, 0x73, 0x76, 0x63, 0x45, 0x6e, 0x64, + 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x22, 0x54, 0x0a, 0x16, 0x41, 0x64, 0x64, 0x49, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x3a, 0x0a, 0x0d, 0x73, 0x76, 0x63, 0x5f, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, + 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x52, 0x0c, + 0x73, 0x76, 0x63, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x22, 0x13, 0x0a, 0x11, + 0x41, 0x64, 0x64, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x73, 0x75, 0x6c, + 0x74, 0x22, 0x57, 0x0a, 0x19, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3a, + 0x0a, 0x0d, 0x73, 0x76, 0x63, 0x5f, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x52, 0x0c, 0x73, 0x76, + 0x63, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x22, 0x16, 0x0a, 0x14, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x22, 0xba, 0x02, 0x0a, 0x0f, 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x40, 0x0a, 0x0c, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, + 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x49, 0x6e, + 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x0b, 0x63, 0x68, 0x65, + 0x63, 0x6b, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, 0x49, 0x0a, 0x0f, 0x66, 0x65, 0x74, 0x63, + 0x68, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x46, 0x65, 0x74, 0x63, 0x68, 0x49, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x49, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x48, 0x00, 0x52, 0x0e, 0x66, 0x65, 0x74, 0x63, 0x68, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, + 0x63, 0x65, 0x73, 0x12, 0x40, 0x0a, 0x0c, 0x61, 0x64, 0x64, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x41, 0x64, 0x64, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x72, + 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x0b, 0x61, 0x64, 0x64, 0x49, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x49, 0x0a, 0x0f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x5f, + 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, + 0x52, 0x0e, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, + 0x42, 0x0d, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, + 0xa2, 0x02, 0x0a, 0x10, 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x0c, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x68, 0x65, + 0x61, 0x6c, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x48, 0x00, 0x52, 0x0b, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x6c, 0x74, + 0x68, 0x12, 0x44, 0x0a, 0x0f, 0x66, 0x65, 0x74, 0x63, 0x68, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x46, 0x65, 0x74, 0x63, 0x68, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x52, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x48, 0x00, 0x52, 0x0e, 0x66, 0x65, 0x74, 0x63, 0x68, 0x49, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x3b, 0x0a, 0x0c, 0x61, 0x64, 0x64, 0x5f, 0x69, + 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x41, 0x64, 0x64, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x48, 0x00, 0x52, 0x0b, 0x61, 0x64, 0x64, 0x49, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x63, 0x65, 0x12, 0x44, 0x0a, 0x0f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x5f, 0x69, + 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, + 0x63, 0x65, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x48, 0x00, 0x52, 0x0e, 0x64, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x42, 0x08, 0x0a, 0x06, 0x72, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x2a, 0x20, 0x0a, 0x09, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x07, 0x0a, 0x03, 0x41, 0x64, 0x64, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x10, 0x01, 0x32, 0xc7, 0x01, 0x0a, 0x05, 0x53, 0x6b, 0x79, 0x6c, 0x62, + 0x12, 0x36, 0x0a, 0x07, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x12, 0x13, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x12, 0x3f, 0x0a, 0x0a, 0x52, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x4c, 0x6f, 0x61, 0x64, 0x12, 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x4c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x4c, 0x6f, 0x61, 0x64, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x28, 0x01, 0x12, 0x45, 0x0a, 0x12, 0x41, 0x74, 0x74, + 0x61, 0x63, 0x68, 0x46, 0x6f, 0x72, 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x69, 0x73, 0x12, + 0x15, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x1a, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x69, 0x61, + 0x67, 0x6e, 0x6f, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x28, 0x01, 0x30, 0x01, + 0x42, 0x2e, 0x0a, 0x1c, 0x63, 0x6f, 0x6d, 0x2e, 0x62, 0x69, 0x6e, 0x63, 0x68, 0x65, 0x6e, 0x63, + 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x73, 0x6b, 0x79, 0x6c, 0x62, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x42, 0x0c, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x50, 0x00, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_proto_api_proto_rawDescOnce sync.Once + file_proto_api_proto_rawDescData = file_proto_api_proto_rawDesc +) + +func file_proto_api_proto_rawDescGZIP() []byte { + file_proto_api_proto_rawDescOnce.Do(func() { + file_proto_api_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_api_proto_rawDescData) + }) + return file_proto_api_proto_rawDescData +} + +var file_proto_api_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_proto_api_proto_msgTypes = make([]protoimpl.MessageInfo, 18) +var file_proto_api_proto_goTypes = []interface{}{ + (Operation)(0), // 0: api.Operation + (*ServiceSpec)(nil), // 1: api.ServiceSpec + (*ResolveRequest)(nil), // 2: api.ResolveRequest + (*InstanceEndpoint)(nil), // 3: api.InstanceEndpoint + (*ServiceEndpoints)(nil), // 4: api.ServiceEndpoints + (*ResolveResponse)(nil), // 5: api.ResolveResponse + (*ReportLoadRequest)(nil), // 6: api.ReportLoadRequest + (*ReportLoadResponse)(nil), // 7: api.ReportLoadResponse + (*CheckHealthInstruction)(nil), // 8: api.CheckHealthInstruction + (*HealthInfo)(nil), // 9: api.HealthInfo + (*CheckHealthResult)(nil), // 10: api.CheckHealthResult + (*FetchInstancesInstruction)(nil), // 11: api.FetchInstancesInstruction + (*FetchInstancesResult)(nil), // 12: api.FetchInstancesResult + (*AddInstanceInstruction)(nil), // 13: api.AddInstanceInstruction + (*AddInstanceResult)(nil), // 14: api.AddInstanceResult + (*DeleteInstanceInstruction)(nil), // 15: api.DeleteInstanceInstruction + (*DeleteInstanceResult)(nil), // 16: api.DeleteInstanceResult + (*DiagnoseRequest)(nil), // 17: api.DiagnoseRequest + (*DiagnoseResponse)(nil), // 18: api.DiagnoseResponse + (data.ServiceId)(0), // 19: data.ServiceId +} +var file_proto_api_proto_depIdxs = []int32{ + 1, // 0: api.ResolveRequest.services:type_name -> api.ServiceSpec + 19, // 1: api.ResolveRequest.callerServiceId:type_name -> data.ServiceId + 0, // 2: api.InstanceEndpoint.op:type_name -> api.Operation + 1, // 3: api.ServiceEndpoints.spec:type_name -> api.ServiceSpec + 3, // 4: api.ServiceEndpoints.inst_endpoints:type_name -> api.InstanceEndpoint + 4, // 5: api.ResolveResponse.svc_endpoints:type_name -> api.ServiceEndpoints + 1, // 6: api.ReportLoadRequest.spec:type_name -> api.ServiceSpec + 9, // 7: api.CheckHealthResult.health_info:type_name -> api.HealthInfo + 4, // 8: api.FetchInstancesResult.svc_endpoints:type_name -> api.ServiceEndpoints + 4, // 9: api.AddInstanceInstruction.svc_endpoints:type_name -> api.ServiceEndpoints + 4, // 10: api.DeleteInstanceInstruction.svc_endpoints:type_name -> api.ServiceEndpoints + 8, // 11: api.DiagnoseRequest.check_health:type_name -> api.CheckHealthInstruction + 11, // 12: api.DiagnoseRequest.fetch_instances:type_name -> api.FetchInstancesInstruction + 13, // 13: api.DiagnoseRequest.add_instance:type_name -> api.AddInstanceInstruction + 15, // 14: api.DiagnoseRequest.delete_instance:type_name -> api.DeleteInstanceInstruction + 10, // 15: api.DiagnoseResponse.check_health:type_name -> api.CheckHealthResult + 12, // 16: api.DiagnoseResponse.fetch_instances:type_name -> api.FetchInstancesResult + 14, // 17: api.DiagnoseResponse.add_instance:type_name -> api.AddInstanceResult + 16, // 18: api.DiagnoseResponse.delete_instance:type_name -> api.DeleteInstanceResult + 2, // 19: api.Skylb.Resolve:input_type -> api.ResolveRequest + 6, // 20: api.Skylb.ReportLoad:input_type -> api.ReportLoadRequest + 18, // 21: api.Skylb.AttachForDiagnosis:input_type -> api.DiagnoseResponse + 5, // 22: api.Skylb.Resolve:output_type -> api.ResolveResponse + 7, // 23: api.Skylb.ReportLoad:output_type -> api.ReportLoadResponse + 17, // 24: api.Skylb.AttachForDiagnosis:output_type -> api.DiagnoseRequest + 22, // [22:25] is the sub-list for method output_type + 19, // [19:22] is the sub-list for method input_type + 19, // [19:19] is the sub-list for extension type_name + 19, // [19:19] is the sub-list for extension extendee + 0, // [0:19] is the sub-list for field type_name +} + +func init() { file_proto_api_proto_init() } +func file_proto_api_proto_init() { + if File_proto_api_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_proto_api_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ServiceSpec); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_api_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ResolveRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_api_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*InstanceEndpoint); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_api_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ServiceEndpoints); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_api_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ResolveResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_api_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ReportLoadRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_api_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ReportLoadResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_api_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CheckHealthInstruction); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_api_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*HealthInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_api_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CheckHealthResult); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_api_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FetchInstancesInstruction); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_api_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FetchInstancesResult); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_api_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AddInstanceInstruction); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_api_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AddInstanceResult); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_api_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteInstanceInstruction); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_api_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteInstanceResult); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_api_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DiagnoseRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_api_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DiagnoseResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_proto_api_proto_msgTypes[16].OneofWrappers = []interface{}{ + (*DiagnoseRequest_CheckHealth)(nil), + (*DiagnoseRequest_FetchInstances)(nil), + (*DiagnoseRequest_AddInstance)(nil), + (*DiagnoseRequest_DeleteInstance)(nil), + } + file_proto_api_proto_msgTypes[17].OneofWrappers = []interface{}{ + (*DiagnoseResponse_CheckHealth)(nil), + (*DiagnoseResponse_FetchInstances)(nil), + (*DiagnoseResponse_AddInstance)(nil), + (*DiagnoseResponse_DeleteInstance)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_proto_api_proto_rawDesc, + NumEnums: 1, + NumMessages: 18, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_proto_api_proto_goTypes, + DependencyIndexes: file_proto_api_proto_depIdxs, + EnumInfos: file_proto_api_proto_enumTypes, + MessageInfos: file_proto_api_proto_msgTypes, + }.Build() + File_proto_api_proto = out.File + file_proto_api_proto_rawDesc = nil + file_proto_api_proto_goTypes = nil + file_proto_api_proto_depIdxs = nil +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConnInterface + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion6 + +// SkylbClient is the client API for Skylb service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type SkylbClient interface { + Resolve(ctx context.Context, in *ResolveRequest, opts ...grpc.CallOption) (Skylb_ResolveClient, error) + ReportLoad(ctx context.Context, opts ...grpc.CallOption) (Skylb_ReportLoadClient, error) + AttachForDiagnosis(ctx context.Context, opts ...grpc.CallOption) (Skylb_AttachForDiagnosisClient, error) +} + +type skylbClient struct { + cc grpc.ClientConnInterface +} + +func NewSkylbClient(cc grpc.ClientConnInterface) SkylbClient { + return &skylbClient{cc} +} + +func (c *skylbClient) Resolve(ctx context.Context, in *ResolveRequest, opts ...grpc.CallOption) (Skylb_ResolveClient, error) { + stream, err := c.cc.NewStream(ctx, &_Skylb_serviceDesc.Streams[0], "/api.Skylb/Resolve", opts...) + if err != nil { + return nil, err + } + x := &skylbResolveClient{stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +type Skylb_ResolveClient interface { + Recv() (*ResolveResponse, error) + grpc.ClientStream +} + +type skylbResolveClient struct { + grpc.ClientStream +} + +func (x *skylbResolveClient) Recv() (*ResolveResponse, error) { + m := new(ResolveResponse) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +func (c *skylbClient) ReportLoad(ctx context.Context, opts ...grpc.CallOption) (Skylb_ReportLoadClient, error) { + stream, err := c.cc.NewStream(ctx, &_Skylb_serviceDesc.Streams[1], "/api.Skylb/ReportLoad", opts...) + if err != nil { + return nil, err + } + x := &skylbReportLoadClient{stream} + return x, nil +} + +type Skylb_ReportLoadClient interface { + Send(*ReportLoadRequest) error + CloseAndRecv() (*ReportLoadResponse, error) + grpc.ClientStream +} + +type skylbReportLoadClient struct { + grpc.ClientStream +} + +func (x *skylbReportLoadClient) Send(m *ReportLoadRequest) error { + return x.ClientStream.SendMsg(m) +} + +func (x *skylbReportLoadClient) CloseAndRecv() (*ReportLoadResponse, error) { + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + m := new(ReportLoadResponse) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +func (c *skylbClient) AttachForDiagnosis(ctx context.Context, opts ...grpc.CallOption) (Skylb_AttachForDiagnosisClient, error) { + stream, err := c.cc.NewStream(ctx, &_Skylb_serviceDesc.Streams[2], "/api.Skylb/AttachForDiagnosis", opts...) + if err != nil { + return nil, err + } + x := &skylbAttachForDiagnosisClient{stream} + return x, nil +} + +type Skylb_AttachForDiagnosisClient interface { + Send(*DiagnoseResponse) error + Recv() (*DiagnoseRequest, error) + grpc.ClientStream +} + +type skylbAttachForDiagnosisClient struct { + grpc.ClientStream +} + +func (x *skylbAttachForDiagnosisClient) Send(m *DiagnoseResponse) error { + return x.ClientStream.SendMsg(m) +} + +func (x *skylbAttachForDiagnosisClient) Recv() (*DiagnoseRequest, error) { + m := new(DiagnoseRequest) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// SkylbServer is the server API for Skylb service. +type SkylbServer interface { + Resolve(*ResolveRequest, Skylb_ResolveServer) error + ReportLoad(Skylb_ReportLoadServer) error + AttachForDiagnosis(Skylb_AttachForDiagnosisServer) error +} + +// UnimplementedSkylbServer can be embedded to have forward compatible implementations. +type UnimplementedSkylbServer struct { +} + +func (*UnimplementedSkylbServer) Resolve(*ResolveRequest, Skylb_ResolveServer) error { + return status.Errorf(codes.Unimplemented, "method Resolve not implemented") +} +func (*UnimplementedSkylbServer) ReportLoad(Skylb_ReportLoadServer) error { + return status.Errorf(codes.Unimplemented, "method ReportLoad not implemented") +} +func (*UnimplementedSkylbServer) AttachForDiagnosis(Skylb_AttachForDiagnosisServer) error { + return status.Errorf(codes.Unimplemented, "method AttachForDiagnosis not implemented") +} + +func RegisterSkylbServer(s *grpc.Server, srv SkylbServer) { + s.RegisterService(&_Skylb_serviceDesc, srv) +} + +func _Skylb_Resolve_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(ResolveRequest) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(SkylbServer).Resolve(m, &skylbResolveServer{stream}) +} + +type Skylb_ResolveServer interface { + Send(*ResolveResponse) error + grpc.ServerStream +} + +type skylbResolveServer struct { + grpc.ServerStream +} + +func (x *skylbResolveServer) Send(m *ResolveResponse) error { + return x.ServerStream.SendMsg(m) +} + +func _Skylb_ReportLoad_Handler(srv interface{}, stream grpc.ServerStream) error { + return srv.(SkylbServer).ReportLoad(&skylbReportLoadServer{stream}) +} + +type Skylb_ReportLoadServer interface { + SendAndClose(*ReportLoadResponse) error + Recv() (*ReportLoadRequest, error) + grpc.ServerStream +} + +type skylbReportLoadServer struct { + grpc.ServerStream +} + +func (x *skylbReportLoadServer) SendAndClose(m *ReportLoadResponse) error { + return x.ServerStream.SendMsg(m) +} + +func (x *skylbReportLoadServer) Recv() (*ReportLoadRequest, error) { + m := new(ReportLoadRequest) + if err := x.ServerStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +func _Skylb_AttachForDiagnosis_Handler(srv interface{}, stream grpc.ServerStream) error { + return srv.(SkylbServer).AttachForDiagnosis(&skylbAttachForDiagnosisServer{stream}) +} + +type Skylb_AttachForDiagnosisServer interface { + Send(*DiagnoseRequest) error + Recv() (*DiagnoseResponse, error) + grpc.ServerStream +} + +type skylbAttachForDiagnosisServer struct { + grpc.ServerStream +} + +func (x *skylbAttachForDiagnosisServer) Send(m *DiagnoseRequest) error { + return x.ServerStream.SendMsg(m) +} + +func (x *skylbAttachForDiagnosisServer) Recv() (*DiagnoseResponse, error) { + m := new(DiagnoseResponse) + if err := x.ServerStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +var _Skylb_serviceDesc = grpc.ServiceDesc{ + ServiceName: "api.Skylb", + HandlerType: (*SkylbServer)(nil), + Methods: []grpc.MethodDesc{}, + Streams: []grpc.StreamDesc{ + { + StreamName: "Resolve", + Handler: _Skylb_Resolve_Handler, + ServerStreams: true, + }, + { + StreamName: "ReportLoad", + Handler: _Skylb_ReportLoad_Handler, + ClientStreams: true, + }, + { + StreamName: "AttachForDiagnosis", + Handler: _Skylb_AttachForDiagnosis_Handler, + ServerStreams: true, + ClientStreams: true, + }, + }, + Metadata: "proto/api.proto", +} diff --git a/repositories.bzl b/repositories.bzl index e88c6f7..adbf05b 100644 --- a/repositories.bzl +++ b/repositories.bzl @@ -1,12 +1,12 @@ load("@bazel_gazelle//:deps.bzl", "go_repository") def go_repositories(): - go_repository( - name = "com_github_binchencoder_ease_gateway", - importpath = "github.com/binchencoder/ease-gateway", - sum = "h1:hRpJwksSTfcSQeKWW7CpjH/Gq2BteNwhI8hzI0nn/z4=", - version = "v0.0.4", - ) + # go_repository( + # name = "com_github_binchencoder_ease_gateway", + # importpath = "github.com/binchencoder/ease-gateway", + # sum = "h1:hRpJwksSTfcSQeKWW7CpjH/Gq2BteNwhI8hzI0nn/z4=", + # version = "v0.0.4", + # ) go_repository( name = "com_github_binchencoder_gateway_proto", importpath = "github.com/binchencoder/gateway-proto", @@ -17,7 +17,7 @@ def go_repositories(): name = "com_github_binchencoder_letsgo", importpath = "github.com/binchencoder/letsgo", sum = "h1:hEDDOeGdX9R/JPYMdVo9N/9iQa5BeBLluTssrNYy/ng=", - version = "v0.0.3", + version = "v0.0.5", ) go_repository( @@ -64,6 +64,14 @@ def go_repositories(): sum = "h1:0IKlLyQ3Hs9nDaiK5cSHAGmcQEIC8l2Ts1u6x5Dfrqg=", version = "v1.2.0", ) + + go_repository( + name = "com_github_jtolds_gls", + importpath = "github.com/jtolds/gls", + sum = "h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=", + version = "v4.20.0+incompatible", + ) + go_repository( name = "com_github_matttproud_golang_protobuf_extension", importpath = "github.com/matttproud/golang_protobuf_extensions", @@ -113,12 +121,41 @@ def go_repositories(): version = "v0.1.3", ) + # smartystreets + go_repository( + name = "com_github_smartystreets_assertions", + importpath = "github.com/smartystreets/assertions", + sum = "h1:voD4ITNjPL5jjBfgR/r8fPIIBrliWrWHeiJApdr3r4w=", + version = "v1.0.1", + ) + go_repository( + name = "com_github_smartystreets_goconvey", + importpath = "github.com/smartystreets/goconvey", + sum = "h1:QdmJJYlDQhMDFrFP8IvVnx66D8mCbaQM4TsxKf7BXzo=", + version = "v1.6.3", + ) + go_repository( name = "com_github_soheilhy_cmux", importpath = "github.com/soheilhy/cmux", sum = "h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E=", version = "v0.1.4", ) + + # stretchr + go_repository( + name = "com_github_stretchr_testify", + importpath = "github.com/stretchr/testify", + sum = "h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=", + version = "v1.7.1", + ) + go_repository( + name = "com_github_stretchr_objx", + importpath = "github.com/stretchr/objx", + sum = "h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48=", + version = "v0.2.0", + ) + # Uber go_repository( name = "com_github_uber_jaeger_client_go", @@ -140,6 +177,13 @@ def go_repositories(): version = "v1.0.0", ) + go_repository( + name="in_gopkg_yaml_v3", + importpath="gopkg.in/yaml.v3", + sum="h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=", + version="v3.0.0-20210107192922-496545a6307b" + ) + go_repository( name = "org_uber_go_atomic", importpath = "go.uber.org/atomic", diff --git a/resolver/BUILD.bazel b/resolver/BUILD.bazel new file mode 100644 index 0000000..3cb222a --- /dev/null +++ b/resolver/BUILD.bazel @@ -0,0 +1,33 @@ +package(default_visibility = ["//visibility:public"]) + +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "go_default_library", + srcs = glob( + ["*.go"], + exclude = ["*_test.go"], + ), + importpath = "github.com/binchencoder/skylb-api/resolver", + deps = [ + "//client/option:go_default_library", + "//proto:go_default_library", + "@org_golang_google_grpc//:go_default_library", + "@org_golang_google_grpc//resolver:go_default_library", + ], +) + +go_test( + name = "tests", + size = "small", + srcs = glob( + ["*_test.go"] + ), + embed = [ + ":go_default_library", + ], + deps = [ + "@com_github_stretchr_testify//assert:go_default_library", + "@com_github_stretchr_testify//mock:go_default_library", + ], +) diff --git a/resolver/direct_builder.go b/resolver/direct_builder.go new file mode 100644 index 0000000..55bdfcf --- /dev/null +++ b/resolver/direct_builder.go @@ -0,0 +1,46 @@ +package resolver + +import ( + "strings" + + "google.golang.org/grpc/resolver" +) + +type directBuilder struct{} + +type directResolver struct { + cc resolver.ClientConn +} + +// Build +func (d *directBuilder) Build(target resolver.Target, cc resolver.ClientConn, opts resolver.BuildOptions) ( + resolver.Resolver, error) { + var addrs []resolver.Address + endpoints := strings.FieldsFunc(target.URL.Host, func(r rune) bool { + return r == EndpointSepChar + }) + + for _, val := range subset(endpoints, subsetSize) { + addrs = append(addrs, resolver.Address{ + Addr: val, + }) + } + if err := cc.UpdateState(resolver.State{ + Addresses: addrs, + }); err != nil { + cc.ReportError(err) + return nil, err + } + + return &directResolver{cc: cc}, nil +} + +func (b *directBuilder) Scheme() string { + return DirectScheme +} + +func (r *directResolver) Close() { +} + +func (r *directResolver) ResolveNow(options resolver.ResolveNowOptions) { +} diff --git a/resolver/resolver.go b/resolver/resolver.go new file mode 100644 index 0000000..11af5cb --- /dev/null +++ b/resolver/resolver.go @@ -0,0 +1,54 @@ +package resolver + +import ( + "errors" + "fmt" + + "github.com/binchencoder/skylb-api/client/option" + "google.golang.org/grpc/resolver" +) + +const ( + // DirectScheme stands for direct scheme. + DirectScheme = "direct" + // SkyLBScheme stands for skylb scheme. + SkyLBScheme = "skylb" +) + +const ( + // EndpointSepChar is the separator cha in endpoints. + EndpointSepChar = ',' + + // EqualSpeChar is the separator cha in endpoints. + EqualSpeChar = "=" + // SlashSpeChar is the separator cha in endpoints. + SlashSpeChar = "/" + + subsetSize = 32 +) + +var ( + ErrUnsupportSchema = errors.New("unsupport schema skylb") + ErrMissServiceName = errors.New("target miss service name") + ErrInvalidTarget = errors.New("Invalid target url") + ErrNoInstances = errors.New("no valid instance") +) + +var ( + // EndpointSep is the separator string in endpoints. + EndpointSep = fmt.Sprintf("%c", EndpointSepChar) + + directResolverBuilder directBuilder +) + +func init() { + // Registers the direct scheme to the resolver. + resolver.Register(&directResolverBuilder) +} + +// Registers the skylb scheme to the resolver. +func RegisterSkylbResolverBuilder(keeper option.SkyLbKeeper) { + resolver.Register(&skylbBuilder{ + keeper: keeper, + }) +} diff --git a/resolver/skylb_builder.go b/resolver/skylb_builder.go new file mode 100644 index 0000000..2f1993c --- /dev/null +++ b/resolver/skylb_builder.go @@ -0,0 +1,53 @@ +package resolver + +import ( + "net/url" + + "github.com/binchencoder/skylb-api/client/option" + pb "github.com/binchencoder/skylb-api/proto" + "google.golang.org/grpc/resolver" +) + +type skylbBuilder struct { + keeper option.SkyLbKeeper +} + +type skylbResolver struct { + cliConn resolver.ClientConn +} + +// Build +func (b *skylbBuilder) Build(target resolver.Target, cc resolver.ClientConn, opts resolver.BuildOptions) ( + resolver.Resolver, error) { + if target.URL.Scheme != SkyLBScheme { + return nil, ErrUnsupportSchema + } + + _, err := url.Parse(target.Endpoint) + if err != nil { + panic(ErrInvalidTarget) + } + + url := target.URL + values := url.Query() + servSpec := &pb.ServiceSpec{ + ServiceName: url.Host, + Namespace: values.Get("ns"), + PortName: values.Get("pn"), + } + + b.keeper.RegisterServiceCliConn(servSpec, cc) + + resolver := &skylbResolver{cliConn: cc} + return resolver, nil +} + +func (b *skylbBuilder) Scheme() string { + return SkyLBScheme +} + +func (r *skylbResolver) Close() { +} + +func (r *skylbResolver) ResolveNow(options resolver.ResolveNowOptions) { +} diff --git a/resolver/subset.go b/resolver/subset.go new file mode 100644 index 0000000..32cb9c8 --- /dev/null +++ b/resolver/subset.go @@ -0,0 +1,44 @@ +package resolver + +import ( + "math" + "math/rand" +) + +const ( + epsilon = 1e-6 +) + +func subset(set []string, sub int) []string { + rand.Shuffle(len(set), func(i, j int) { + set[i], set[j] = set[j], set[i] + }) + if len(set) <= sub { + return set + } + + return set[:sub] +} + +// CalcEntropy calculates the entropy of m. +func CalcEntropy(m map[interface{}]int) float64 { + if len(m) == 0 || len(m) == 1 { + return 1 + } + + var entropy float64 + var total int + for _, v := range m { + total += v + } + + for _, v := range m { + proba := float64(v) / float64(total) + if proba < epsilon { + proba = epsilon + } + entropy -= proba * math.Log2(proba) + } + + return entropy / math.Log2(float64(len(m))) +} diff --git a/resolver/subset_test.go b/resolver/subset_test.go new file mode 100644 index 0000000..5a8df9e --- /dev/null +++ b/resolver/subset_test.go @@ -0,0 +1,53 @@ +package resolver + +import ( + "strconv" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestSubset(t *testing.T) { + tests := []struct { + name string + set int + sub int + }{ + { + name: "more vals to subset", + set: 100, + sub: 36, + }, + { + name: "less vals to subset", + set: 100, + sub: 200, + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + var vals []string + for i := 0; i < test.set; i++ { + vals = append(vals, strconv.Itoa(i)) + } + + m := make(map[interface{}]int) + for i := 0; i < 1000; i++ { + set := subset(append([]string(nil), vals...), test.sub) + if test.sub < test.set { + assert.Equal(t, test.sub, len(set)) + } else { + assert.Equal(t, test.set, len(set)) + } + + for _, val := range set { + m[val]++ + } + } + + assert.True(t, CalcEntropy(m) > 0.95) + }) + } +} diff --git a/resolver/target.go b/resolver/target.go new file mode 100644 index 0000000..5bf0f33 --- /dev/null +++ b/resolver/target.go @@ -0,0 +1,23 @@ +package resolver + +import ( + "fmt" + "strings" + + pb "github.com/binchencoder/skylb-api/proto" +) + +// SkyLBTarget returns a string that represents the given endpoints with skylb schema. +func SkyLBTarget(spec *pb.ServiceSpec) string { + return fmt.Sprintf("%s://%s?ns=%s&pn=%s", SkyLBScheme, spec.ServiceName, spec.Namespace, spec.PortName) +} + +// DirectTarget returns a string that represents the given endpoints with direct schema. +func DirectTarget(addrs string) string { + addrs = strings.TrimSpace(addrs) + if addrs == "" { + return addrs + } + + return fmt.Sprintf("%s://%s", DirectScheme, addrs) +} diff --git a/resolver/target_test.go b/resolver/target_test.go new file mode 100644 index 0000000..66bda46 --- /dev/null +++ b/resolver/target_test.go @@ -0,0 +1,58 @@ +package resolver + +import ( + "fmt" + "net/url" + "strings" + "testing" + + pb "github.com/binchencoder/skylb-api/proto" + "github.com/stretchr/testify/assert" + "google.golang.org/grpc/resolver" +) + +func TestDirectTarget(t *testing.T) { + target := DirectTarget("localhost:123,localhost:456") + fmt.Println(target) + assert.Equal(t, "direct://localhost:123,localhost:456", target) +} + +func TestSkyLBTarget(t *testing.T) { + target := SkyLBTarget(&pb.ServiceSpec{ + Namespace: "namespace", + ServiceName: "serviceName", + PortName: "portName", + }) + fmt.Println(target) + assert.Equal(t, "skylb://serviceName?ns=namespace&pn=portName", target) +} + +func TestParseTarget(t *testing.T) { + target := SkyLBTarget(&pb.ServiceSpec{ + Namespace: "namespace", + ServiceName: "serviceName", + PortName: "portName", + }) + + u, _ := url.Parse(target) + // For targets of the form "[scheme]://[authority]/endpoint, the endpoint + // value returned from url.Parse() contains a leading "/". Although this is + // in accordance with RFC 3986, we do not want to break existing resolver + // implementations which expect the endpoint without the leading "/". So, we + // end up stripping the leading "/" here. But this will result in an + // incorrect parsing for something like "unix:///path/to/socket". Since we + // own the "unix" resolver, we can workaround in the unix resolver by using + // the `URL` field instead of the `Endpoint` field. + endpoint := u.Path + if endpoint == "" { + endpoint = u.Opaque + } + endpoint = strings.TrimPrefix(endpoint, "/") + resTarget := resolver.Target{ + Scheme: u.Scheme, + Authority: u.Host, + Endpoint: endpoint, + URL: *u, + } + fmt.Printf("target: %s, parsedTarget: %+v \n", target, resTarget) +} diff --git a/server/BUILD.bazel b/server/BUILD.bazel index 69f38a2..fe1c396 100644 --- a/server/BUILD.bazel +++ b/server/BUILD.bazel @@ -8,17 +8,17 @@ go_library( ["*.go"], exclude = ["*_test.go"], ), - importpath = "github.com/binchencoder/skylb-apiv2/server", + importpath = "github.com/binchencoder/skylb-api/server", deps = [ - "@com_github_binchencoder_gateway_proto//data:go_default_library", - "@com_github_binchencoder_letsgo//grpc:go_default_library", - "@com_github_binchencoder_letsgo//metrics:go_default_library", - "@com_github_binchencoder_letsgo//runtime/pprof:go_default_library", - "@com_github_binchencoder_letsgo//service/naming:go_default_library", "//internal/flags:go_default_library", "//internal/rpccli:go_default_library", "//metrics:go_default_library", + "//naming:go_default_library", "//proto:go_default_library", + "@com_github_binchencoder_gateway_proto//data:go_default_library", + "@com_github_binchencoder_letsgo//grpc:go_default_library", + "@com_github_binchencoder_letsgo//metrics:go_default_library", + "@com_github_binchencoder_letsgo//runtime/pprof:go_default_library", "@com_github_golang_glog//:go_default_library", "@com_github_grpc_ecosystem_go_grpc_middleware//:go_default_library", "@com_github_grpc_ecosystem_go_grpc_middleware//recovery:go_default_library", diff --git a/server/server.go b/server/server.go index 4d41d94..a506317 100644 --- a/server/server.go +++ b/server/server.go @@ -26,11 +26,11 @@ import ( jg "github.com/binchencoder/letsgo/grpc" lmetrics "github.com/binchencoder/letsgo/metrics" "github.com/binchencoder/letsgo/runtime/pprof" - "github.com/binchencoder/letsgo/service/naming" - "github.com/binchencoder/skylb-apiv2/internal/flags" - "github.com/binchencoder/skylb-apiv2/internal/rpccli" - "github.com/binchencoder/skylb-apiv2/metrics" - pb "github.com/binchencoder/skylb-apiv2/proto" + "github.com/binchencoder/skylb-api/internal/flags" + "github.com/binchencoder/skylb-api/internal/rpccli" + "github.com/binchencoder/skylb-api/metrics" + "github.com/binchencoder/skylb-api/naming" + pb "github.com/binchencoder/skylb-api/proto" ) const ( @@ -39,7 +39,7 @@ const ( ) var ( - // TODO(fuyc): change default value to true when most apps are k8s-ready. + // TODO(chenbin): change default value to true when most apps are k8s-ready. withinK8s = flag.Bool("within-k8s", false, "Whether this grpc service runs in kubernetes cluster") reportInterval = flag.Duration("skylb-report-interval", 3*time.Second, "The SkyLB load-report interval.") EnablePromOnSamePort = flag.Bool("enable-prom-on-same-port", false, "Enable serving prometheus metrics on the same port as gRPC.") @@ -213,11 +213,11 @@ func startHTTPServer(lis net.Listener, mux *http.ServeMux) { } func start0(hostAddr string, servicePort int, spec *pb.ServiceSpec, interceptors ...grpc.UnaryServerInterceptor) (net.Listener, *grpc.Server) { - if !*withinK8s { - glog.Infoln("Outside k8s, starting load reporter.") + if *withinK8s { + glog.Infoln("Inside k8s, starting load reporter.") go StartSkylbReportLoad(spec, servicePort) } else { - glog.Warningln("WARNING: Inside k8s, load-reporting disabled.") + glog.Warningln("WARNING: Outside k8s, load-reporting disabled.") } lis, err := net.Listen("tcp", hostAddr) @@ -238,7 +238,7 @@ func start0(hostAddr string, servicePort int, spec *pb.ServiceSpec, interceptors incepts = append(incepts, metricsInterceptor, openTracingInterceptor) incepts = append(incepts, interceptors...) - glog.Infof("Creating grpc server %s at %s", spec.ServiceName, hostAddr) + glog.Infof("Creating grpc server[%s] at [%s]", spec.ServiceName, hostAddr) opts := make([]grpc.ServerOption, 0, 10) opts = append(opts, grpcServerOptions...) diff --git a/testing/BUILD.bazel b/testing/BUILD.bazel new file mode 100644 index 0000000..497a58f --- /dev/null +++ b/testing/BUILD.bazel @@ -0,0 +1,18 @@ +package(default_visibility = ["//visibility:public"]) + +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "go_default_library", + srcs = [ + "keeper.go", + ], + importpath = "github.com/binchencoder/skylb-api/testing", + deps = [ + "//client/option:go_default_library", + "//proto:go_default_library", + "@com_github_binchencoder_gateway_proto//data:go_default_library", + "@com_github_stretchr_testify//mock:go_default_library", + "@org_golang_google_grpc//resolver:go_default_library", + ], +) diff --git a/testing/keeper.go b/testing/keeper.go new file mode 100644 index 0000000..24580fb --- /dev/null +++ b/testing/keeper.go @@ -0,0 +1,30 @@ +package testing + +import ( + "github.com/stretchr/testify/mock" + "google.golang.org/grpc/resolver" + + vexpb "github.com/binchencoder/gateway-proto/data" + pb "github.com/binchencoder/skylb-api/proto" +) + +// SkyLbKeeperMock mocks SkyLB API option.SkyLbKeeper. +type SkyLbKeeperMock struct { + mock.Mock +} + +func (skm *SkyLbKeeperMock) RegisterService(spec *pb.ServiceSpec, cliConn resolver.ClientConn) { + skm.Called(spec, cliConn) +} + +func (skm *SkyLbKeeperMock) Start(csId vexpb.ServiceId, csName string, resolveFullEps bool) { + skm.Called(csId, csName, resolveFullEps) +} + +func (skm *SkyLbKeeperMock) WaitUntilReady() { + skm.Called() +} + +func (skm *SkyLbKeeperMock) Shutdown() { + skm.Called() +} diff --git a/tests/BUILD.bazel b/tests/BUILD.bazel new file mode 100644 index 0000000..ef50080 --- /dev/null +++ b/tests/BUILD.bazel @@ -0,0 +1,16 @@ +package(default_visibility = ["//__subpackages__"]) + +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_test( + name = "tests", + size = "medium", + srcs = glob(["*_test.go"]), + deps = [ + "@com_github_binchencoder_letsgo//strings:go_default_library", + "@com_github_golang_protobuf//jsonpb:go_default_library", + "@com_github_smartystreets_goconvey//convey:go_default_library", + "@com_github_stretchr_testify//assert:go_default_library", + "@org_golang_google_grpc//resolver:go_default_library", + ], +) diff --git a/tests/strings_test.go b/tests/strings_test.go new file mode 100644 index 0000000..00b71ed --- /dev/null +++ b/tests/strings_test.go @@ -0,0 +1,19 @@ +package tests + +import ( + "fmt" + "strings" + "testing" + + lst "github.com/binchencoder/letsgo/strings" +) + +func TestReplaceAll(t *testing.T) { + oldStr := "vexillary-service=vxserver:4100" + fmt.Printf("oldString: %s\n, newString: %s\n", oldStr, strings.ReplaceAll(oldStr, "=", "/")) +} + +func TestCsvString(t *testing.T) { + str := "192.168.38.6:1900,192.168.39.6:1900" + fmt.Printf("str: %s\n, csvString: %s\n", str, lst.CsvToSlice(str)) +} diff --git a/tests/target_test.go b/tests/target_test.go new file mode 100644 index 0000000..e534f0b --- /dev/null +++ b/tests/target_test.go @@ -0,0 +1,48 @@ +package tests + +import ( + "fmt" + "net/url" + "strings" + "testing" + + "google.golang.org/grpc/resolver" +) + +func TestParseTarget(t *testing.T) { + target := "direct://vxserver:4100,vxserver1:4100" + u, err := url.Parse(target) + if err != nil { + fmt.Println("parset err: ", err) + return + } + // For targets of the form "[scheme]://[authority]/endpoint, the endpoint + // value returned from url.Parse() contains a leading "/". Although this is + // in accordance with RFC 3986, we do not want to break existing resolver + // implementations which expect the endpoint without the leading "/". So, we + // end up stripping the leading "/" here. But this will result in an + // incorrect parsing for something like "unix:///path/to/socket". Since we + // own the "unix" resolver, we can workaround in the unix resolver by using + // the `URL` field instead of the `Endpoint` field. + endpoint := u.Path + if endpoint == "" { + endpoint = u.Opaque + } + endpoint = strings.TrimPrefix(endpoint, "/") + fmt.Printf("resolver.Target: %+v \n", resolver.Target{ + Scheme: u.Scheme, + Authority: u.Host, + Endpoint: endpoint, + URL: *u, + }) +} + +func TestParseUrl(t *testing.T) { + target := "skylb://testserver" + u, err := url.Parse(target) + if err != nil { + fmt.Println("parset err: ", err) + return + } + fmt.Printf("target: %s, \nparsedUrl: %+v \n", target, *u) +}