1 /* 2 * Copyright 2015 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 java.net.URI; 20 import java.util.List; 21 import javax.annotation.Nullable; 22 import javax.annotation.concurrent.ThreadSafe; 23 24 /** 25 * A pluggable component that resolves a target {@link URI} and return addresses to the caller. 26 * 27 * <p>A {@code NameResolver} uses the URI's scheme to determine whether it can resolve it, and uses 28 * the components after the scheme for actual resolution. 29 * 30 * <p>The addresses and attributes of a target may be changed over time, thus the caller registers a 31 * {@link Listener} to receive continuous updates. 32 * 33 * <p>A {@code NameResolver} does not need to automatically re-resolve on failure. Instead, the 34 * {@link Listener} is responsible for eventually (after an appropriate backoff period) invoking 35 * {@link #refresh()}. 36 * 37 * @since 1.0.0 38 */ 39 @ExperimentalApi("https://github.com/grpc/grpc-java/issues/1770") 40 @ThreadSafe 41 public abstract class NameResolver { 42 /** 43 * Returns the authority used to authenticate connections to servers. It <strong>must</strong> be 44 * from a trusted source, because if the authority is tampered with, RPCs may be sent to the 45 * attackers which may leak sensitive user data. 46 * 47 * <p>An implementation must generate it without blocking, typically in line, and 48 * <strong>must</strong> keep it unchanged. {@code NameResolver}s created from the same factory 49 * with the same argument must return the same authority. 50 * 51 * @since 1.0.0 52 */ getServiceAuthority()53 public abstract String getServiceAuthority(); 54 55 /** 56 * Starts the resolution. 57 * 58 * @param listener used to receive updates on the target 59 * @since 1.0.0 60 */ start(Listener listener)61 public abstract void start(Listener listener); 62 63 /** 64 * Stops the resolution. Updates to the Listener will stop. 65 * 66 * @since 1.0.0 67 */ shutdown()68 public abstract void shutdown(); 69 70 /** 71 * Re-resolve the name. 72 * 73 * <p>Can only be called after {@link #start} has been called. 74 * 75 * <p>This is only a hint. Implementation takes it as a signal but may not start resolution 76 * immediately. It should never throw. 77 * 78 * <p>The default implementation is no-op. 79 * 80 * @since 1.0.0 81 */ refresh()82 public void refresh() {} 83 84 /** 85 * Factory that creates {@link NameResolver} instances. 86 * 87 * @since 1.0.0 88 */ 89 public abstract static class Factory { 90 /** 91 * The port number used in case the target or the underlying naming system doesn't provide a 92 * port number. 93 * 94 * @since 1.0.0 95 */ 96 public static final Attributes.Key<Integer> PARAMS_DEFAULT_PORT = 97 Attributes.Key.create("params-default-port"); 98 99 /** 100 * Creates a {@link NameResolver} for the given target URI, or {@code null} if the given URI 101 * cannot be resolved by this factory. The decision should be solely based on the scheme of the 102 * URI. 103 * 104 * @param targetUri the target URI to be resolved, whose scheme must not be {@code null} 105 * @param params optional parameters. Canonical keys are defined as {@code PARAMS_*} fields in 106 * {@link Factory}. 107 * @since 1.0.0 108 */ 109 @Nullable newNameResolver(URI targetUri, Attributes params)110 public abstract NameResolver newNameResolver(URI targetUri, Attributes params); 111 112 /** 113 * Returns the default scheme, which will be used to construct a URI when {@link 114 * ManagedChannelBuilder#forTarget(String)} is given an authority string instead of a compliant 115 * URI. 116 * 117 * @since 1.0.0 118 */ getDefaultScheme()119 public abstract String getDefaultScheme(); 120 } 121 122 /** 123 * Receives address updates. 124 * 125 * <p>All methods are expected to return quickly. 126 * 127 * @since 1.0.0 128 */ 129 @ThreadSafe 130 public interface Listener { 131 /** 132 * Handles updates on resolved addresses and attributes. 133 * 134 * <p>Implementations will not modify the given {@code servers}. 135 * 136 * @param servers the resolved server addresses. An empty list will trigger {@link #onError} 137 * @param attributes extra metadata from naming system 138 * @since 1.3.0 139 */ onAddresses(List<EquivalentAddressGroup> servers, Attributes attributes)140 void onAddresses(List<EquivalentAddressGroup> servers, Attributes attributes); 141 142 /** 143 * Handles an error from the resolver. The listener is responsible for eventually invoking 144 * {@link #refresh()} to re-attempt resolution. 145 * 146 * @param error a non-OK status 147 * @since 1.0.0 148 */ onError(Status error)149 void onError(Status error); 150 } 151 } 152