• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2014 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.util;
18 
19 import io.grpc.BindableService;
20 import io.grpc.ExperimentalApi;
21 import io.grpc.HandlerRegistry;
22 import io.grpc.MethodDescriptor;
23 import io.grpc.ServerMethodDefinition;
24 import io.grpc.ServerServiceDefinition;
25 import java.util.ArrayList;
26 import java.util.Collections;
27 import java.util.List;
28 import java.util.concurrent.ConcurrentHashMap;
29 import java.util.concurrent.ConcurrentMap;
30 import javax.annotation.Nullable;
31 import javax.annotation.concurrent.ThreadSafe;
32 
33 /**
34  * Default implementation of {@link MutableHandlerRegistry}.
35  *
36  * <p>Uses {@link ConcurrentHashMap} to avoid service registration excessively
37  * blocking method lookup.
38  */
39 @ThreadSafe
40 @ExperimentalApi("https://github.com/grpc/grpc-java/issues/933")
41 public final class MutableHandlerRegistry extends HandlerRegistry {
42   private final ConcurrentMap<String, ServerServiceDefinition> services
43       = new ConcurrentHashMap<>();
44 
45   /**
46    * Registers a service.
47    *
48    * @return the previously registered service with the same service descriptor name if exists,
49    *         otherwise {@code null}.
50    */
51   @Nullable
addService(ServerServiceDefinition service)52   public ServerServiceDefinition addService(ServerServiceDefinition service) {
53     return services.put(service.getServiceDescriptor().getName(), service);
54   }
55 
56   /**
57    * Registers a service.
58    *
59    * @return the previously registered service with the same service descriptor name if exists,
60    *         otherwise {@code null}.
61    */
62   @Nullable
addService(BindableService bindableService)63   public ServerServiceDefinition addService(BindableService bindableService) {
64     return addService(bindableService.bindService());
65   }
66 
67   /**
68    * Removes a registered service.
69    *
70    * @return true if the service was found to be removed.
71    */
removeService(ServerServiceDefinition service)72   public boolean removeService(ServerServiceDefinition service) {
73     return services.remove(service.getServiceDescriptor().getName(), service);
74   }
75 
76   /**
77    *  Note: This does not necessarily return a consistent view of the map.
78    */
79   @Override
80   @ExperimentalApi("https://github.com/grpc/grpc-java/issues/2222")
getServices()81   public List<ServerServiceDefinition> getServices() {
82     return Collections.unmodifiableList(new ArrayList<>(services.values()));
83   }
84 
85   /**
86    * Note: This does not actually honor the authority provided.  It will, eventually in the future.
87    */
88   @Override
89   @Nullable
lookupMethod(String methodName, @Nullable String authority)90   public ServerMethodDefinition<?, ?> lookupMethod(String methodName, @Nullable String authority) {
91     String serviceName = MethodDescriptor.extractFullServiceName(methodName);
92     if (serviceName == null) {
93       return null;
94     }
95     ServerServiceDefinition service = services.get(serviceName);
96     if (service == null) {
97       return null;
98     }
99     return service.getMethod(methodName);
100   }
101 }
102