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