serverreflection.go raw

   1  /*
   2   *
   3   * Copyright 2016 gRPC authors.
   4   *
   5   * Licensed under the Apache License, Version 2.0 (the "License");
   6   * you may not use this file except in compliance with the License.
   7   * You may obtain a copy of the License at
   8   *
   9   *     http://www.apache.org/licenses/LICENSE-2.0
  10   *
  11   * Unless required by applicable law or agreed to in writing, software
  12   * distributed under the License is distributed on an "AS IS" BASIS,
  13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14   * See the License for the specific language governing permissions and
  15   * limitations under the License.
  16   *
  17   */
  18  
  19  /*
  20  Package reflection implements server reflection service.
  21  
  22  The service implemented is defined in:
  23  https://github.com/grpc/grpc/blob/master/src/proto/grpc/reflection/v1alpha/reflection.proto.
  24  
  25  To register server reflection on a gRPC server:
  26  
  27  	import "google.golang.org/grpc/reflection"
  28  
  29  	s := grpc.NewServer()
  30  	pb.RegisterYourOwnServer(s, &server{})
  31  
  32  	// Register reflection service on gRPC server.
  33  	reflection.Register(s)
  34  
  35  	s.Serve(lis)
  36  */
  37  package reflection // import "google.golang.org/grpc/reflection"
  38  
  39  import (
  40  	"google.golang.org/grpc"
  41  	"google.golang.org/grpc/reflection/internal"
  42  	"google.golang.org/protobuf/reflect/protodesc"
  43  	"google.golang.org/protobuf/reflect/protoreflect"
  44  	"google.golang.org/protobuf/reflect/protoregistry"
  45  
  46  	v1reflectiongrpc "google.golang.org/grpc/reflection/grpc_reflection_v1"
  47  	v1alphareflectiongrpc "google.golang.org/grpc/reflection/grpc_reflection_v1alpha"
  48  )
  49  
  50  // GRPCServer is the interface provided by a gRPC server. It is implemented by
  51  // *grpc.Server, but could also be implemented by other concrete types. It acts
  52  // as a registry, for accumulating the services exposed by the server.
  53  type GRPCServer interface {
  54  	grpc.ServiceRegistrar
  55  	ServiceInfoProvider
  56  }
  57  
  58  var _ GRPCServer = (*grpc.Server)(nil)
  59  
  60  // Register registers the server reflection service on the given gRPC server.
  61  // Both the v1 and v1alpha versions are registered.
  62  func Register(s GRPCServer) {
  63  	svr := NewServerV1(ServerOptions{Services: s})
  64  	v1alphareflectiongrpc.RegisterServerReflectionServer(s, asV1Alpha(svr))
  65  	v1reflectiongrpc.RegisterServerReflectionServer(s, svr)
  66  }
  67  
  68  // RegisterV1 registers only the v1 version of the server reflection service
  69  // on the given gRPC server. Many clients may only support v1alpha so most
  70  // users should use Register instead, at least until clients have upgraded.
  71  func RegisterV1(s GRPCServer) {
  72  	svr := NewServerV1(ServerOptions{Services: s})
  73  	v1reflectiongrpc.RegisterServerReflectionServer(s, svr)
  74  }
  75  
  76  // ServiceInfoProvider is an interface used to retrieve metadata about the
  77  // services to expose.
  78  //
  79  // The reflection service is only interested in the service names, but the
  80  // signature is this way so that *grpc.Server implements it. So it is okay
  81  // for a custom implementation to return zero values for the
  82  // grpc.ServiceInfo values in the map.
  83  //
  84  // # Experimental
  85  //
  86  // Notice: This type is EXPERIMENTAL and may be changed or removed in a
  87  // later release.
  88  type ServiceInfoProvider interface {
  89  	GetServiceInfo() map[string]grpc.ServiceInfo
  90  }
  91  
  92  // ExtensionResolver is the interface used to query details about extensions.
  93  // This interface is satisfied by protoregistry.GlobalTypes.
  94  //
  95  // # Experimental
  96  //
  97  // Notice: This type is EXPERIMENTAL and may be changed or removed in a
  98  // later release.
  99  type ExtensionResolver interface {
 100  	protoregistry.ExtensionTypeResolver
 101  	RangeExtensionsByMessage(message protoreflect.FullName, f func(protoreflect.ExtensionType) bool)
 102  }
 103  
 104  // ServerOptions represents the options used to construct a reflection server.
 105  //
 106  // # Experimental
 107  //
 108  // Notice: This type is EXPERIMENTAL and may be changed or removed in a
 109  // later release.
 110  type ServerOptions struct {
 111  	// The source of advertised RPC services. If not specified, the reflection
 112  	// server will report an empty list when asked to list services.
 113  	//
 114  	// This value will typically be a *grpc.Server. But the set of advertised
 115  	// services can be customized by wrapping a *grpc.Server or using an
 116  	// alternate implementation that returns a custom set of service names.
 117  	Services ServiceInfoProvider
 118  	// Optional resolver used to load descriptors. If not specified,
 119  	// protoregistry.GlobalFiles will be used.
 120  	DescriptorResolver protodesc.Resolver
 121  	// Optional resolver used to query for known extensions. If not specified,
 122  	// protoregistry.GlobalTypes will be used.
 123  	ExtensionResolver ExtensionResolver
 124  }
 125  
 126  // NewServer returns a reflection server implementation using the given options.
 127  // This can be used to customize behavior of the reflection service. Most usages
 128  // should prefer to use Register instead. For backwards compatibility reasons,
 129  // this returns the v1alpha version of the reflection server. For a v1 version
 130  // of the reflection server, see NewServerV1.
 131  //
 132  // # Experimental
 133  //
 134  // Notice: This function is EXPERIMENTAL and may be changed or removed in a
 135  // later release.
 136  func NewServer(opts ServerOptions) v1alphareflectiongrpc.ServerReflectionServer {
 137  	return asV1Alpha(NewServerV1(opts))
 138  }
 139  
 140  // NewServerV1 returns a reflection server implementation using the given options.
 141  // This can be used to customize behavior of the reflection service. Most usages
 142  // should prefer to use Register instead.
 143  //
 144  // # Experimental
 145  //
 146  // Notice: This function is EXPERIMENTAL and may be changed or removed in a
 147  // later release.
 148  func NewServerV1(opts ServerOptions) v1reflectiongrpc.ServerReflectionServer {
 149  	if opts.DescriptorResolver == nil {
 150  		opts.DescriptorResolver = protoregistry.GlobalFiles
 151  	}
 152  	if opts.ExtensionResolver == nil {
 153  		opts.ExtensionResolver = protoregistry.GlobalTypes
 154  	}
 155  	return &internal.ServerReflectionServer{
 156  		S:            opts.Services,
 157  		DescResolver: opts.DescriptorResolver,
 158  		ExtResolver:  opts.ExtensionResolver,
 159  	}
 160  }
 161