Skip to content

Commit 1858813

Browse files
Provide a mechanism to set a routing hint for the d2 request to get request symbol table (#787)
Co-authored-by: Karthik Ramgopal <[email protected]>
1 parent 67931f9 commit 1858813

File tree

4 files changed

+149
-62
lines changed

4 files changed

+149
-62
lines changed

CHANGELOG.md

+5-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ and what APIs have changed, if applicable.
1414

1515
## [Unreleased]
1616

17+
## [29.33.6] - 2022-05-03
18+
- Provide a mechanism to set a routing hint for the d2 request to get request symbol table.
19+
1720
## [29.33.5] - 2022-05-02
1821
- Expose RestLiConfig from RestLiServer.
1922

@@ -5227,7 +5230,8 @@ patch operations can re-use these classes for generating patch messages.
52275230

52285231
## [0.14.1]
52295232

5230-
[Unreleased]: https://github.com/linkedin/rest.li/compare/v29.33.5...master
5233+
[Unreleased]: https://github.com/linkedin/rest.li/compare/v29.33.6...master
5234+
[29.33.6]: https://github.com/linkedin/rest.li/compare/v29.33.5...v29.33.6
52315235
[29.33.5]: https://github.com/linkedin/rest.li/compare/v29.33.4...v29.33.5
52325236
[29.33.4]: https://github.com/linkedin/rest.li/compare/v29.33.3...v29.33.4
52335237
[29.33.3]: https://github.com/linkedin/rest.li/compare/v29.33.2...v29.33.3

gradle.properties

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
version=29.33.5
1+
version=29.33.6
22
group=com.linkedin.pegasus
33
org.gradle.configureondemand=true
44
org.gradle.parallel=true

restli-tools/src/main/java/com/linkedin/restli/tools/symbol/RestLiSymbolTableProvider.java

+66-4
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import com.github.benmanes.caffeine.cache.Cache;
2020
import com.github.benmanes.caffeine.cache.Caffeine;
21+
import com.linkedin.d2.balancer.KeyMapper;
2122
import com.linkedin.d2.balancer.util.LoadBalancerUtil;
2223
import com.linkedin.data.ByteString;
2324
import com.linkedin.data.codec.symbol.EmptySymbolTable;
@@ -27,6 +28,7 @@
2728
import com.linkedin.data.codec.symbol.SymbolTableProvider;
2829
import com.linkedin.data.codec.symbol.SymbolTableSerializer;
2930
import com.linkedin.data.schema.DataSchema;
31+
import com.linkedin.r2.message.RequestContext;
3032
import com.linkedin.r2.message.rest.RestRequestBuilder;
3133
import com.linkedin.r2.message.rest.RestResponse;
3234
import com.linkedin.r2.transport.common.Client;
@@ -48,6 +50,7 @@
4850
import java.util.concurrent.ExecutionException;
4951
import java.util.concurrent.Future;
5052
import java.util.concurrent.TimeUnit;
53+
import javax.annotation.Nullable;
5154
import org.slf4j.Logger;
5255
import org.slf4j.LoggerFactory;
5356

@@ -93,6 +96,7 @@ public class RestLiSymbolTableProvider implements SymbolTableProvider, ResourceD
9396
private final SymbolTableNameHandler _symbolTableNameHandler;
9497
private final Cache<String, SymbolTable> _serviceNameToSymbolTableCache;
9598
private final Cache<String, SymbolTable> _symbolTableNameToSymbolTableCache;
99+
private final Map<String, URI> _d2ServiceNameToTargetHostMap;
96100
private volatile SymbolTable _defaultResponseSymbolTable = null;
97101
private volatile String _defaultResponseSymbolTableName = null;
98102

@@ -174,6 +178,33 @@ public RestLiSymbolTableProvider(Client client,
174178
String symbolTablePrefix,
175179
String serverNodeUri,
176180
List<String> overriddenSymbols)
181+
{
182+
this(client, uriPrefix, cacheSize, timeout, symbolTablePrefix, serverNodeUri, overriddenSymbols,
183+
Collections.emptyMap());
184+
}
185+
186+
/**
187+
* Constructor
188+
*
189+
* @param client The {@link Client} to use to make requests to remote services to fetch their symbol tables.
190+
* @param uriPrefix The URI prefix to use when invoking remote services by name (and not by hostname:port)
191+
* @param cacheSize The size of the caches used to store symbol tables.
192+
* @param timeout The client request timeout to fetch remote symbol table.
193+
* @param symbolTablePrefix The prefix to use for symbol tables vended by this instance.
194+
* @param serverNodeUri The URI on which the current service is running. This should also include the context
195+
* and servlet path (if applicable).
196+
* @param overriddenSymbols The list of overridden symbols to use for the symbol table.
197+
* @param d2ServiceNameToTargetHostMap A map from d2 service name to target hosts for configuring target host routing
198+
* when making request symbol table calls.
199+
*/
200+
public RestLiSymbolTableProvider(Client client,
201+
String uriPrefix,
202+
int cacheSize,
203+
long timeout,
204+
String symbolTablePrefix,
205+
String serverNodeUri,
206+
List<String> overriddenSymbols,
207+
Map<String, URI> d2ServiceNameToTargetHostMap)
177208
{
178209
_client = client;
179210
_uriPrefix = uriPrefix;
@@ -188,6 +219,7 @@ public RestLiSymbolTableProvider(Client client,
188219
_defaultResponseSymbolTable = new InMemorySymbolTable(symbolTableName, overriddenSymbols);
189220
_defaultResponseSymbolTableName = _symbolTableNameHandler.extractMetadata(symbolTableName).getSymbolTableName();
190221
}
222+
_d2ServiceNameToTargetHostMap = d2ServiceNameToTargetHostMap;
191223
}
192224

193225
/**
@@ -207,6 +239,30 @@ public RestLiSymbolTableProvider(Client client,
207239
long timeout,
208240
String serverNodeUri,
209241
SymbolTable responseSymbolTable)
242+
{
243+
this(client, uriPrefix, cacheSize, timeout, serverNodeUri, responseSymbolTable, Collections.emptyMap());
244+
}
245+
246+
/**
247+
* Constructor
248+
*
249+
* @param client The {@link Client} to use to make requests to remote services to fetch their symbol tables.
250+
* @param uriPrefix The URI prefix to use when invoking remote services by name (and not by hostname:port)
251+
* @param cacheSize The size of the caches used to store symbol tables.
252+
* @param timeout The client request timeout to fetch remote symbol table.
253+
* @param serverNodeUri The URI on which the current service is running. This should also include the context
254+
* and servlet path (if applicable).
255+
* @param responseSymbolTable The pre-generated response symbol table.
256+
* @param d2ServiceNameToTargetHostMap A map from d2 service name to target hosts for configuring target host routing
257+
* when making request symbol table calls.
258+
*/
259+
public RestLiSymbolTableProvider(Client client,
260+
String uriPrefix,
261+
int cacheSize,
262+
long timeout,
263+
String serverNodeUri,
264+
SymbolTable responseSymbolTable,
265+
Map<String, URI> d2ServiceNameToTargetHostMap)
210266
{
211267
_client = client;
212268
_uriPrefix = uriPrefix;
@@ -220,6 +276,7 @@ public RestLiSymbolTableProvider(Client client,
220276
_defaultResponseSymbolTable = responseSymbolTable;
221277
_defaultResponseSymbolTableName = responseSymbolTable.getName();
222278
}
279+
_d2ServiceNameToTargetHostMap = d2ServiceNameToTargetHostMap;
223280
}
224281

225282
@Override
@@ -253,7 +310,7 @@ public SymbolTable getSymbolTable(String symbolTableName)
253310

254311
// Ok, we didn't find it in the cache, let's go query the service the table was served from.
255312
URI symbolTableUri = new URI(serverNodeUri + "/" + RestLiSymbolTableRequestHandler.SYMBOL_TABLE_URI_PATH + "/" + tableName);
256-
symbolTable = fetchRemoteSymbolTable(symbolTableUri, Collections.emptyMap(), false);
313+
symbolTable = fetchRemoteSymbolTable(new RequestContext(), symbolTableUri, Collections.emptyMap(), false);
257314

258315
if (symbolTable != null)
259316
{
@@ -297,7 +354,12 @@ public SymbolTable getRequestSymbolTable(URI requestUri)
297354
// Fetch remote symbol table, configuring the fetch to return an empty table on 404. This will ensure that
298355
// for services that don't have symbol tables enabled yet, we will not use any symbol tables when encoding.
299356
//
300-
symbolTable = fetchRemoteSymbolTable(symbolTableUri, Collections.emptyMap(), true);
357+
RequestContext requestContext = new RequestContext();
358+
URI routingHint = _d2ServiceNameToTargetHostMap.get(serviceName);
359+
if (routingHint != null) {
360+
KeyMapper.TargetHostHints.setRequestContextTargetHost(requestContext, routingHint);
361+
}
362+
symbolTable = fetchRemoteSymbolTable(requestContext, symbolTableUri, Collections.emptyMap(), true);
301363

302364
if (symbolTable != null)
303365
{
@@ -350,13 +412,13 @@ public void onInitialized(Map<String, ResourceDefinition> resourceDefinitions)
350412
_symbolTableNameHandler.extractMetadata(_defaultResponseSymbolTable.getName()).getSymbolTableName();
351413
}
352414

353-
SymbolTable fetchRemoteSymbolTable(URI symbolTableUri, Map<String, String> requestHeaders, boolean returnEmptyOn404)
415+
private SymbolTable fetchRemoteSymbolTable(RequestContext requestContext, URI symbolTableUri, Map<String, String> requestHeaders, boolean returnEmptyOn404)
354416
{
355417
try
356418
{
357419
Map<String, String> headers = new HashMap<>(requestHeaders);
358420
headers.put(RestConstants.HEADER_FETCH_SYMBOL_TABLE, Boolean.TRUE.toString());
359-
Future<RestResponse> future = _client.restRequest(new RestRequestBuilder(symbolTableUri).setHeaders(headers).build());
421+
Future<RestResponse> future = _client.restRequest(new RestRequestBuilder(symbolTableUri).setHeaders(headers).build(), requestContext);
360422
RestResponse restResponse = future.get(_timeout, TimeUnit.MILLISECONDS);
361423
int status = restResponse.getStatus();
362424

0 commit comments

Comments
 (0)