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