use of com.linkedin.r2.transport.common.Client in project rest.li by linkedin.
the class SimpleLoadBalancer method getClient.
/**
* Given a Request, returns a TransportClient that can handle requests for the Request.
*
*
* @param request
* A request whose URI is a URL of the format "d2://>servicename</optional/path".
* @param requestContext context for this request
* @return A client that can be called to retrieve data for the URN.
* @throws ServiceUnavailableException
* If the load balancer can't figure out how to reach a service for the given
* URN, an ServiceUnavailableException will be thrown.
*/
@Override
public TransportClient getClient(Request request, RequestContext requestContext) throws ServiceUnavailableException {
TransportClient client;
URI uri = request.getURI();
debug(_log, "get client for uri: ", uri);
ServiceProperties service = listenToServiceAndCluster(uri);
String serviceName = service.getServiceName();
String clusterName = service.getClusterName();
ClusterProperties cluster = getClusterProperties(serviceName, clusterName);
// Check if we want to override the service URL and bypass choosing among the existing
// tracker clients. This is useful when the service we want is not announcing itself to
// the cluster, ie a private service for a set of clients.
URI targetService = LoadBalancerUtil.TargetHints.getRequestContextTargetService(requestContext);
if (targetService == null) {
LoadBalancerStateItem<UriProperties> uriItem = getUriItem(serviceName, clusterName, cluster);
UriProperties uris = uriItem.getProperty();
List<LoadBalancerState.SchemeStrategyPair> orderedStrategies = _state.getStrategiesForService(serviceName, service.getPrioritizedSchemes());
TrackerClient trackerClient = chooseTrackerClient(request, requestContext, serviceName, clusterName, cluster, uriItem, uris, orderedStrategies, service);
String clusterAndServiceUriString = trackerClient.getUri() + service.getPath();
client = new RewriteClient(serviceName, URI.create(clusterAndServiceUriString), trackerClient);
_serviceAvailableStats.inc();
} else {
_log.debug("service hint found, using generic client for target: {}", targetService);
TransportClient transportClient = _state.getClient(serviceName, targetService.getScheme());
client = new RewriteClient(serviceName, targetService, transportClient);
}
return client;
}
use of com.linkedin.r2.transport.common.Client in project rest.li by linkedin.
the class SimpleLoadBalancerState method getClient.
@Override
public TransportClient getClient(String serviceName, String scheme) {
Map<String, TransportClient> transportClients = _serviceClients.get(serviceName);
TransportClient transportClient = null;
if (transportClients != null) {
transportClient = transportClients.get(scheme.toLowerCase());
if (transportClient == null) {
warn(_log, "no generic transport client for service " + serviceName + " and scheme: " + scheme);
}
} else {
warn(_log, "get client called on unknown service ", serviceName);
}
return transportClient;
}
use of com.linkedin.r2.transport.common.Client in project rest.li by linkedin.
the class SimpleLoadBalancerState method createAndInsertTransportClientTo.
private Map<String, TransportClient> createAndInsertTransportClientTo(ServiceProperties serviceProperties) {
Map<String, Object> transportClientProperties = new HashMap<String, Object>(serviceProperties.getTransportClientProperties());
Object allowedClientOverrideKeysObj = transportClientProperties.remove(PropertyKeys.ALLOWED_CLIENT_OVERRIDE_KEYS);
Set<String> allowedClientOverrideKeys = new HashSet<String>(ConfigValueExtractor.buildList(allowedClientOverrideKeysObj, LIST_SEPARATOR));
Map<String, Object> clientSuppliedServiceProperties = _clientServicesConfig.get(serviceProperties.getServiceName());
if (clientSuppliedServiceProperties != null) {
debug(_log, "Client supplied configs for service {}", new Object[] { serviceProperties.getServiceName() });
// check for overrides
for (String clientSuppliedKey : clientSuppliedServiceProperties.keySet()) {
// clients can only override config properties which have been allowed by the service
if (allowedClientOverrideKeys.contains(clientSuppliedKey)) {
if (ClientServiceConfigValidator.isValidValue(transportClientProperties, clientSuppliedServiceProperties, clientSuppliedKey)) {
transportClientProperties.put(clientSuppliedKey, clientSuppliedServiceProperties.get(clientSuppliedKey));
info(_log, "Client overrode config property {} for service {}. This is being used to instantiate the Transport Client", new Object[] { clientSuppliedKey, serviceProperties.getServiceName() });
} else {
warn(_log, "Client supplied config property {} with an invalid value {} for service {}", new Object[] { clientSuppliedKey, clientSuppliedServiceProperties.get(clientSuppliedKey), serviceProperties.getServiceName() });
}
}
}
}
List<String> schemes = serviceProperties.getPrioritizedSchemes();
Map<String, TransportClient> newTransportClients = new HashMap<String, TransportClient>();
if (schemes != null && !schemes.isEmpty()) {
for (String scheme : schemes) {
TransportClientFactory factory = _clientFactories.get(scheme);
if ("https".equals(scheme)) {
if (_isSSLEnabled) {
// should have been passed in during creation.
if (_sslContext != null && _sslParameters != null) {
transportClientProperties.put(HttpClientFactory.HTTP_SSL_CONTEXT, _sslContext);
transportClientProperties.put(HttpClientFactory.HTTP_SSL_PARAMS, _sslParameters);
} else {
_log.error("https specified as a prioritized scheme for service: " + serviceProperties.getServiceName() + " but no SSLContext or SSLParameters have been configured.");
if (schemes.size() == 1) {
// throw exception when https is the only scheme specified
throw new IllegalStateException("SSL enabled but required SSLContext and SSLParameters" + "were not both present.");
}
// Do not create the transport client for https.
continue;
}
} else {
// is requested later on, getTrackerClient will catch this situation and log an error.
continue;
}
}
if (factory != null) {
transportClientProperties.put(HttpClientFactory.HTTP_SERVICE_NAME, serviceProperties.getServiceName());
TransportClient client = factory.getClient(transportClientProperties);
newTransportClients.put(scheme.toLowerCase(), client);
} else {
_log.warn("Failed to find client factory for scheme {}", scheme);
}
}
} else {
_log.warn("Prioritized schemes is null for service properties = " + serviceProperties.getServiceName());
}
return newTransportClients;
}
use of com.linkedin.r2.transport.common.Client in project rest.li by linkedin.
the class SimpleLoadBalancerState method shutdown.
@Override
public void shutdown(final PropertyEventShutdownCallback shutdown) {
trace(_log, "shutdown");
// shutdown all three registries, all tracker clients, and the event thread
_executor.execute(new PropertyEvent("shutdown load balancer state") {
@Override
public void innerRun() {
// Need to shutdown loadBalancerStrategies before the transportClients are shutdown
for (Map<String, LoadBalancerStrategy> strategyEntry : _serviceStrategies.values()) {
strategyEntry.values().forEach(LoadBalancerStrategy::shutdown);
}
// put all tracker clients into a single set for convenience
Set<TransportClient> transportClients = new HashSet<TransportClient>();
for (Map<String, TransportClient> clientsByScheme : _serviceClients.values()) {
transportClients.addAll(clientsByScheme.values());
}
Callback<None> trackerCallback = Callbacks.countDown(Callbacks.<None>adaptSimple(new SimpleCallback() {
@Override
public void onDone() {
shutdown.done();
}
}), transportClients.size());
info(_log, "shutting down cluster clients");
for (TransportClient transportClient : transportClients) {
transportClient.shutdown(trackerCallback);
}
// so it is needed to notify all the listeners
for (SimpleLoadBalancerStateListener listener : _listeners) {
// Notify the strategy removal
for (Map.Entry<String, Map<String, LoadBalancerStrategy>> serviceStrategy : _serviceStrategies.entrySet()) {
for (Map.Entry<String, LoadBalancerStrategy> strategyEntry : serviceStrategy.getValue().entrySet()) {
listener.onStrategyRemoved(serviceStrategy.getKey(), strategyEntry.getKey(), strategyEntry.getValue());
}
// Also notify the client removal
Map<URI, TrackerClient> trackerClients = _trackerClients.get(serviceStrategy.getKey());
if (trackerClients != null) {
for (TrackerClient client : trackerClients.values()) {
listener.onClientRemoved(serviceStrategy.getKey(), client);
}
}
}
}
}
});
}
use of com.linkedin.r2.transport.common.Client in project rest.li by linkedin.
the class RewriteClientTestStreamRequest method testWithEverything.
@Test
public void testWithEverything() {
URI uri = URI.create("http://username:password@test.linkedin.com:9876/test");
String serviceName = "HistoryService";
TestClient wrappedClient = new TestClient();
RewriteClient client = new RewriteClient(serviceName, uri, wrappedClient);
assertEquals(client.getUri(), uri);
assertEquals(client.getServiceName(), serviceName);
assertEquals(client.getWrappedClient(), wrappedClient);
StreamRequest streamRequest = getRequest("d2://HistoryService/getCube?bar=baz#fragId");
Map<String, String> restWireAttrs = new HashMap<String, String>();
TestTransportCallback<StreamResponse> restCallback = new TestTransportCallback<StreamResponse>();
client.streamRequest(streamRequest, new RequestContext(), restWireAttrs, restCallback);
assertFalse(restCallback.response.hasError());
assertEquals(wrappedClient.streamRequest.getHeaders(), streamRequest.getHeaders());
assertEquals(wrappedClient.streamRequest.getMethod(), streamRequest.getMethod());
assertEquals(wrappedClient.streamRequest.getURI(), URI.create("http://username:password@test.linkedin.com:9876/test/getCube?bar=baz#fragId"));
}
Aggregations