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