2022-07-07 20:11:50 +00:00
|
|
|
/*
|
|
|
|
*
|
|
|
|
* Copyright 2016 gRPC authors.
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
Package reflection implements server reflection service.
|
|
|
|
|
|
|
|
The service implemented is defined in:
|
|
|
|
https://github.com/grpc/grpc/blob/master/src/proto/grpc/reflection/v1alpha/reflection.proto.
|
|
|
|
|
|
|
|
To register server reflection on a gRPC server:
|
2024-02-24 00:34:55 +00:00
|
|
|
|
2022-07-07 20:11:50 +00:00
|
|
|
import "google.golang.org/grpc/reflection"
|
|
|
|
|
|
|
|
s := grpc.NewServer()
|
|
|
|
pb.RegisterYourOwnServer(s, &server{})
|
|
|
|
|
|
|
|
// Register reflection service on gRPC server.
|
|
|
|
reflection.Register(s)
|
|
|
|
|
|
|
|
s.Serve(lis)
|
|
|
|
*/
|
|
|
|
package reflection // import "google.golang.org/grpc/reflection"
|
|
|
|
|
|
|
|
import (
|
|
|
|
"google.golang.org/grpc"
|
2024-10-16 10:54:40 +00:00
|
|
|
"google.golang.org/grpc/reflection/internal"
|
2024-02-24 00:34:55 +00:00
|
|
|
"google.golang.org/protobuf/reflect/protodesc"
|
|
|
|
"google.golang.org/protobuf/reflect/protoreflect"
|
|
|
|
"google.golang.org/protobuf/reflect/protoregistry"
|
|
|
|
|
|
|
|
v1reflectiongrpc "google.golang.org/grpc/reflection/grpc_reflection_v1"
|
|
|
|
v1alphareflectiongrpc "google.golang.org/grpc/reflection/grpc_reflection_v1alpha"
|
2022-07-07 20:11:50 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// GRPCServer is the interface provided by a gRPC server. It is implemented by
|
|
|
|
// *grpc.Server, but could also be implemented by other concrete types. It acts
|
|
|
|
// as a registry, for accumulating the services exposed by the server.
|
|
|
|
type GRPCServer interface {
|
|
|
|
grpc.ServiceRegistrar
|
2024-02-24 00:34:55 +00:00
|
|
|
ServiceInfoProvider
|
2022-07-07 20:11:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
var _ GRPCServer = (*grpc.Server)(nil)
|
|
|
|
|
|
|
|
// Register registers the server reflection service on the given gRPC server.
|
2024-02-24 00:34:55 +00:00
|
|
|
// Both the v1 and v1alpha versions are registered.
|
2022-07-07 20:11:50 +00:00
|
|
|
func Register(s GRPCServer) {
|
2024-02-24 00:34:55 +00:00
|
|
|
svr := NewServerV1(ServerOptions{Services: s})
|
|
|
|
v1alphareflectiongrpc.RegisterServerReflectionServer(s, asV1Alpha(svr))
|
|
|
|
v1reflectiongrpc.RegisterServerReflectionServer(s, svr)
|
2022-07-07 20:11:50 +00:00
|
|
|
}
|
|
|
|
|
2024-02-24 00:34:55 +00:00
|
|
|
// RegisterV1 registers only the v1 version of the server reflection service
|
|
|
|
// on the given gRPC server. Many clients may only support v1alpha so most
|
|
|
|
// users should use Register instead, at least until clients have upgraded.
|
|
|
|
func RegisterV1(s GRPCServer) {
|
|
|
|
svr := NewServerV1(ServerOptions{Services: s})
|
|
|
|
v1reflectiongrpc.RegisterServerReflectionServer(s, svr)
|
2022-07-07 20:11:50 +00:00
|
|
|
}
|
|
|
|
|
2024-02-24 00:34:55 +00:00
|
|
|
// ServiceInfoProvider is an interface used to retrieve metadata about the
|
|
|
|
// services to expose.
|
|
|
|
//
|
|
|
|
// The reflection service is only interested in the service names, but the
|
|
|
|
// signature is this way so that *grpc.Server implements it. So it is okay
|
|
|
|
// for a custom implementation to return zero values for the
|
|
|
|
// grpc.ServiceInfo values in the map.
|
|
|
|
//
|
|
|
|
// # Experimental
|
|
|
|
//
|
|
|
|
// Notice: This type is EXPERIMENTAL and may be changed or removed in a
|
|
|
|
// later release.
|
|
|
|
type ServiceInfoProvider interface {
|
|
|
|
GetServiceInfo() map[string]grpc.ServiceInfo
|
2022-07-07 20:11:50 +00:00
|
|
|
}
|
|
|
|
|
2024-02-24 00:34:55 +00:00
|
|
|
// ExtensionResolver is the interface used to query details about extensions.
|
|
|
|
// This interface is satisfied by protoregistry.GlobalTypes.
|
|
|
|
//
|
|
|
|
// # Experimental
|
|
|
|
//
|
|
|
|
// Notice: This type is EXPERIMENTAL and may be changed or removed in a
|
|
|
|
// later release.
|
|
|
|
type ExtensionResolver interface {
|
|
|
|
protoregistry.ExtensionTypeResolver
|
|
|
|
RangeExtensionsByMessage(message protoreflect.FullName, f func(protoreflect.ExtensionType) bool)
|
2022-07-07 20:11:50 +00:00
|
|
|
}
|
|
|
|
|
2024-02-24 00:34:55 +00:00
|
|
|
// ServerOptions represents the options used to construct a reflection server.
|
|
|
|
//
|
|
|
|
// # Experimental
|
|
|
|
//
|
|
|
|
// Notice: This type is EXPERIMENTAL and may be changed or removed in a
|
|
|
|
// later release.
|
|
|
|
type ServerOptions struct {
|
|
|
|
// The source of advertised RPC services. If not specified, the reflection
|
|
|
|
// server will report an empty list when asked to list services.
|
|
|
|
//
|
|
|
|
// This value will typically be a *grpc.Server. But the set of advertised
|
|
|
|
// services can be customized by wrapping a *grpc.Server or using an
|
|
|
|
// alternate implementation that returns a custom set of service names.
|
|
|
|
Services ServiceInfoProvider
|
|
|
|
// Optional resolver used to load descriptors. If not specified,
|
|
|
|
// protoregistry.GlobalFiles will be used.
|
|
|
|
DescriptorResolver protodesc.Resolver
|
|
|
|
// Optional resolver used to query for known extensions. If not specified,
|
|
|
|
// protoregistry.GlobalTypes will be used.
|
|
|
|
ExtensionResolver ExtensionResolver
|
2022-07-07 20:11:50 +00:00
|
|
|
}
|
|
|
|
|
2024-02-24 00:34:55 +00:00
|
|
|
// NewServer returns a reflection server implementation using the given options.
|
|
|
|
// This can be used to customize behavior of the reflection service. Most usages
|
|
|
|
// should prefer to use Register instead. For backwards compatibility reasons,
|
|
|
|
// this returns the v1alpha version of the reflection server. For a v1 version
|
|
|
|
// of the reflection server, see NewServerV1.
|
|
|
|
//
|
|
|
|
// # Experimental
|
|
|
|
//
|
|
|
|
// Notice: This function is EXPERIMENTAL and may be changed or removed in a
|
|
|
|
// later release.
|
|
|
|
func NewServer(opts ServerOptions) v1alphareflectiongrpc.ServerReflectionServer {
|
|
|
|
return asV1Alpha(NewServerV1(opts))
|
2022-07-07 20:11:50 +00:00
|
|
|
}
|
|
|
|
|
2024-02-24 00:34:55 +00:00
|
|
|
// NewServerV1 returns a reflection server implementation using the given options.
|
|
|
|
// This can be used to customize behavior of the reflection service. Most usages
|
|
|
|
// should prefer to use Register instead.
|
|
|
|
//
|
|
|
|
// # Experimental
|
|
|
|
//
|
|
|
|
// Notice: This function is EXPERIMENTAL and may be changed or removed in a
|
|
|
|
// later release.
|
|
|
|
func NewServerV1(opts ServerOptions) v1reflectiongrpc.ServerReflectionServer {
|
|
|
|
if opts.DescriptorResolver == nil {
|
|
|
|
opts.DescriptorResolver = protoregistry.GlobalFiles
|
|
|
|
}
|
|
|
|
if opts.ExtensionResolver == nil {
|
|
|
|
opts.ExtensionResolver = protoregistry.GlobalTypes
|
|
|
|
}
|
2024-10-16 10:54:40 +00:00
|
|
|
return &internal.ServerReflectionServer{
|
|
|
|
S: opts.Services,
|
|
|
|
DescResolver: opts.DescriptorResolver,
|
|
|
|
ExtResolver: opts.ExtensionResolver,
|
2022-07-07 20:11:50 +00:00
|
|
|
}
|
|
|
|
}
|