• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2016 The gRPC Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package io.grpc;
18 
19 import static com.google.common.base.Preconditions.checkArgument;
20 import static com.google.common.base.Preconditions.checkNotNull;
21 
22 import com.google.common.base.MoreObjects;
23 import java.util.ArrayList;
24 import java.util.Arrays;
25 import java.util.Collection;
26 import java.util.Collections;
27 import java.util.HashSet;
28 import java.util.List;
29 import java.util.Set;
30 import javax.annotation.Nullable;
31 
32 /**
33  * Descriptor for a service.
34  *
35  * @since 1.0.0
36  */
37 public final class ServiceDescriptor {
38 
39   private final String name;
40   private final Collection<MethodDescriptor<?, ?>> methods;
41   private final Object schemaDescriptor;
42 
43   /**
44    * Constructs a new Service Descriptor.  Users are encouraged to use {@link #newBuilder}
45    * instead.
46    *
47    * @param name The name of the service
48    * @param methods The methods that are part of the service
49    * @since 1.0.0
50    */
ServiceDescriptor(String name, MethodDescriptor<?, ?>... methods)51   public ServiceDescriptor(String name, MethodDescriptor<?, ?>... methods) {
52     this(name, Arrays.asList(methods));
53   }
54 
55   /**
56    * Constructs a new Service Descriptor.  Users are encouraged to use {@link #newBuilder}
57    * instead.
58    *
59    * @param name The name of the service
60    * @param methods The methods that are part of the service
61    * @since 1.0.0
62    */
ServiceDescriptor(String name, Collection<MethodDescriptor<?, ?>> methods)63   public ServiceDescriptor(String name, Collection<MethodDescriptor<?, ?>> methods) {
64     this(newBuilder(name).addAllMethods(checkNotNull(methods, "methods")));
65   }
66 
ServiceDescriptor(Builder b)67   private ServiceDescriptor(Builder b) {
68     this.name = b.name;
69     validateMethodNames(name, b.methods);
70     this.methods = Collections.unmodifiableList(new ArrayList<>(b.methods));
71     this.schemaDescriptor = b.schemaDescriptor;
72   }
73 
74   /**
75    * Simple name of the service. It is not an absolute path.
76    *
77    * @since 1.0.0
78    */
getName()79   public String getName() {
80     return name;
81   }
82 
83   /**
84    * A collection of {@link MethodDescriptor} instances describing the methods exposed by the
85    * service.
86    *
87    * @since 1.0.0
88    */
getMethods()89   public Collection<MethodDescriptor<?, ?>> getMethods() {
90     return methods;
91   }
92 
93   /**
94    * Returns the schema descriptor for this service.  A schema descriptor is an object that is not
95    * used by gRPC core but includes information related to the service.  The type of the object
96    * is specific to the consumer, so both the code setting the schema descriptor and the code
97    * calling {@link #getSchemaDescriptor()} must coordinate.  For example, protobuf generated code
98    * sets this value, in order to be consumed by the server reflection service.  See also:
99    * {@code io.grpc.protobuf.ProtoFileDescriptorSupplier}.
100    *
101    * @since 1.1.0
102    */
103   @Nullable
104   @ExperimentalApi("https://github.com/grpc/grpc-java/issues/2222")
getSchemaDescriptor()105   public Object getSchemaDescriptor() {
106     return schemaDescriptor;
107   }
108 
validateMethodNames(String serviceName, Collection<MethodDescriptor<?, ?>> methods)109   static void validateMethodNames(String serviceName, Collection<MethodDescriptor<?, ?>> methods) {
110     Set<String> allNames = new HashSet<>(methods.size());
111     for (MethodDescriptor<?, ?> method : methods) {
112       checkNotNull(method, "method");
113       String methodServiceName = method.getServiceName();
114       checkArgument(serviceName.equals(methodServiceName),
115           "service names %s != %s", methodServiceName, serviceName);
116       checkArgument(allNames.add(method.getFullMethodName()),
117           "duplicate name %s", method.getFullMethodName());
118     }
119   }
120 
121   /**
122    * Creates a new builder for a {@link ServiceDescriptor}.
123    *
124    * @since 1.1.0
125    */
newBuilder(String name)126   public static Builder newBuilder(String name) {
127     return new Builder(name);
128   }
129 
130   /**
131    * A builder for a {@link ServiceDescriptor}.
132    *
133    * @since 1.1.0
134    */
135   public static final class Builder {
Builder(String name)136     private Builder(String name) {
137       setName(name);
138     }
139 
140     private String name;
141     private List<MethodDescriptor<?, ?>> methods = new ArrayList<>();
142     private Object schemaDescriptor;
143 
144     /**
145      * Sets the name.  This should be non-{@code null}.
146      *
147      * @param name The name of the service.
148      * @return this builder.
149      * @since 1.1.0
150      */
151     @ExperimentalApi("https://github.com/grpc/grpc-java/issues/2666")
setName(String name)152     public Builder setName(String name) {
153       this.name = checkNotNull(name, "name");
154       return this;
155     }
156 
157     /**
158      * Adds a method to this service.  This should be non-{@code null}.
159      *
160      * @param method the method to add to the descriptor.
161      * @return this builder.
162      * @since 1.1.0
163      */
addMethod(MethodDescriptor<?, ?> method)164     public Builder addMethod(MethodDescriptor<?, ?> method) {
165       methods.add(checkNotNull(method, "method"));
166       return this;
167     }
168 
169     /**
170      * Currently not exposed.  Bulk adds methods to this builder.
171      *
172      * @param methods the methods to add.
173      * @return this builder.
174      */
addAllMethods(Collection<MethodDescriptor<?, ?>> methods)175     private Builder addAllMethods(Collection<MethodDescriptor<?, ?>> methods) {
176       this.methods.addAll(methods);
177       return this;
178     }
179 
180     /**
181      * Sets the schema descriptor for this builder.  A schema descriptor is an object that is not
182      * used by gRPC core but includes information related to the service.  The type of the object
183      * is specific to the consumer, so both the code calling this and the code calling
184      * {@link ServiceDescriptor#getSchemaDescriptor()} must coordinate.  For example, protobuf
185      * generated code sets this value, in order to be consumed by the server reflection service.
186      *
187      * @param schemaDescriptor an object that describes the service structure.  Should be immutable.
188      * @return this builder.
189      * @since 1.1.0
190      */
setSchemaDescriptor(@ullable Object schemaDescriptor)191     public Builder setSchemaDescriptor(@Nullable Object schemaDescriptor) {
192       this.schemaDescriptor = schemaDescriptor;
193       return this;
194     }
195 
196     /**
197      * Constructs a new {@link ServiceDescriptor}.  {@link #setName} should have been called with a
198      * non-{@code null} value before calling this.
199      *
200      * @return a new ServiceDescriptor
201      * @since 1.1.0
202      */
build()203     public ServiceDescriptor build() {
204       return new ServiceDescriptor(this);
205     }
206   }
207 
208   @Override
toString()209   public String toString() {
210     return MoreObjects.toStringHelper(this)
211         .add("name", name)
212         .add("schemaDescriptor", schemaDescriptor)
213         .add("methods", methods)
214         .omitNullValues()
215         .toString();
216   }
217 }