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