public static <T> List<T> createProxies( MetricRegistry metricRegistry, Optional<TrustContext> trustContext, Collection<String> endpointUris, boolean refreshingHttpClient, Class<T> type, String userAgent) { List<T> ret = Lists.newArrayListWithCapacity(endpointUris.size()); for (String uri : endpointUris) { ret.add(createProxy(metricRegistry, trustContext, uri, refreshingHttpClient, type, userAgent)); } return ret; }
/** * Constructs an HTTP-invoking dynamic proxy for the specified type that will cycle through the list of supplied * endpoints after encountering an exception or connection failure, using the supplied SSL factory if it is * present. Also use the supplied the proxy selector to set the proxy on the clients if present. * <p> * Failover will continue to cycle through the supplied endpoint list indefinitely. */ public static <T> T createProxyWithFailover( MetricRegistry metricRegistry, Optional<TrustContext> trustContext, Optional<ProxySelector> proxySelector, Collection<String> endpointUris, Class<T> type) { return createProxyWithFailover( metricRegistry, trustContext, proxySelector, endpointUris, type, UserAgents.DEFAULT_USER_AGENT); }
private static <T> T createService( MetricsManager metricsManager, Supplier<ServerListConfig> serverListConfigSupplier, Function<SslConfiguration, TrustContext> trustContextCreator, Function<ProxyConfiguration, ProxySelector> proxySelectorCreator, Class<T> type, String userAgent) { return AtlasDbHttpClients.createLiveReloadingProxyWithFailover( metricsManager.getRegistry(), serverListConfigSupplier, trustContextCreator, proxySelectorCreator, type, userAgent); }
public static <T> List<T> createProxies( MetricRegistry metricRegistry, Optional<TrustContext> trustContext, Collection<String> endpointUris, Class<T> type, String userAgent) { List<T> ret = Lists.newArrayListWithCapacity(endpointUris.size()); for (String uri : endpointUris) { ret.add(createProxy(metricRegistry, trustContext, uri, type, userAgent)); } return ret; }
public static <T> List<T> createProxyAndLocalList( MetricRegistry metrics, T localObject, Set<String> remoteUris, Optional<TrustContext> trustContext, Class<T> clazz, String userAgent) { return ImmutableList.copyOf(Iterables.concat( AtlasDbHttpClients.createProxies(metrics, trustContext, remoteUris, true, clazz, userAgent), ImmutableList.of(localObject))); }
@Test public void httpProxyThrowsServiceNotAvailableExceptionIfConfiguredWithZeroNodes() { TestResource testResource = AtlasDbHttpClients.createLiveReloadingProxyWithQuickFailoverForTesting( new MetricRegistry(), () -> ImmutableServerListConfig.builder().build(), SslSocketFactories::createTrustContext, proxyConfiguration -> ProxySelector.getDefault(), TestResource.class, UserAgents.DEFAULT_VALUE); assertThatThrownBy(testResource::getTestNumber).isInstanceOf(ServiceNotAvailableException.class); }
private static <T> T createFromUris(MetricRegistry metricRegistry, List<String> endpointUris, Class<T> type) { return AtlasDbHttpClients.createProxyWithQuickFailoverForTesting( metricRegistry, Optional.empty(), Optional.empty(), endpointUris, type); } }
public static <T> List<T> createProxies( MetricRegistry metricRegistry, Optional<TrustContext> trustContext, Collection<String> endpointUris, Class<T> type, String userAgent) { List<T> ret = Lists.newArrayListWithCapacity(endpointUris.size()); for (String uri : endpointUris) { ret.add(createProxy(metricRegistry, trustContext, uri, type, userAgent)); } return ret; }
public static <T> List<T> createProxyAndLocalList( MetricRegistry metrics, T localObject, Set<String> remoteUris, Optional<TrustContext> trustContext, Class<T> clazz, String userAgent) { return ImmutableList.copyOf(Iterables.concat( AtlasDbHttpClients.createProxies(metrics, trustContext, remoteUris, true, clazz, userAgent), ImmutableList.of(localObject))); }
@Test public void httpProxyCanBeCommissionedAndDecommissionedIfNodeAvailabilityChanges() { AtomicReference<ServerListConfig> config = new AtomicReference<>(ImmutableServerListConfig.builder().build()); TestResource testResource = AtlasDbHttpClients.createLiveReloadingProxyWithQuickFailoverForTesting( new MetricRegistry(), config::get, SslSocketFactories::createTrustContext, proxyConfiguration -> ProxySelector.getDefault(), TestResource.class, UserAgents.DEFAULT_VALUE); // At this point, there are zero nodes in the config, so we should get ServiceNotAvailable. assertThatThrownBy(testResource::getTestNumber).isInstanceOf(ServiceNotAvailableException.class); config.set(ImmutableServerListConfig.builder().addServers(getUriForPort(availablePort)).build()); Uninterruptibles.sleepUninterruptibly( PollingRefreshable.DEFAULT_REFRESH_INTERVAL.getSeconds() + 1, TimeUnit.SECONDS); assertThat(testResource.getTestNumber(), equalTo(TEST_NUMBER)); config.set(ImmutableServerListConfig.builder().build()); Uninterruptibles.sleepUninterruptibly( PollingRefreshable.DEFAULT_REFRESH_INTERVAL.getSeconds() + 1, TimeUnit.SECONDS); assertThatThrownBy(testResource::getTestNumber).isInstanceOf(ServiceNotAvailableException.class); }
public static <T> T createProxy( MetricRegistry metricRegistry, Optional<TrustContext> trustContext, String uri, Class<T> type, String userAgent) { return AtlasDbMetrics.instrument( metricRegistry, type, AtlasDbFeignTargetFactory.createProxy(trustContext, uri, type, userAgent), MetricRegistry.name(type)); }
/** * @deprecated please use {@link #createProxyWithFailover(Optional, Optional, Collection, Class)}, which requires * you to specify the ProxySelector parameter. */ @Deprecated public static <T> T createProxyWithFailover( MetricRegistry metricRegistry, Optional<TrustContext> trustContext, Collection<String> endpointUris, Class<T> type) { return createProxyWithFailover( metricRegistry, trustContext, Optional.empty(), endpointUris, type, UserAgents.DEFAULT_USER_AGENT); }
private static <T> T createService( MetricsManager metricsManager, Supplier<ServerListConfig> serverListConfigSupplier, Function<SslConfiguration, TrustContext> trustContextCreator, Function<ProxyConfiguration, ProxySelector> proxySelectorCreator, Class<T> type, String userAgent) { return AtlasDbHttpClients.createLiveReloadingProxyWithFailover( metricsManager.getRegistry(), serverListConfigSupplier, trustContextCreator, proxySelectorCreator, type, userAgent); }
@Test public void canLiveReloadServersList() { unavailableServer.stubFor(ENDPOINT_MAPPING.willReturn(aResponse().withStatus(503))); List<String> servers = Lists.newArrayList(getUriForPort(unavailablePort)); TestResource client = AtlasDbHttpClients.createLiveReloadingProxyWithQuickFailoverForTesting( new MetricRegistry(), () -> ImmutableServerListConfig.builder() .servers(servers) .build(), SslSocketFactories::createTrustContext, unused -> ProxySelector.getDefault(), TestResource.class, "user (123)"); // actually a Feign RetryableException but that's not on our classpath assertThatThrownBy(client::getTestNumber).isInstanceOf(RuntimeException.class); servers.add(getUriForPort(availablePort)); Uninterruptibles.sleepUninterruptibly( PollingRefreshable.DEFAULT_REFRESH_INTERVAL.getSeconds() + 1, TimeUnit.SECONDS); int response = client.getTestNumber(); assertThat(response, equalTo(TEST_NUMBER)); unavailableServer.verify(getRequestedFor(urlMatching(TEST_ENDPOINT))); }
private static <T> T createClientFor(Class<T> clazz, String host, short port) { String uri = String.format("http://%s:%s", host, port); return AtlasDbHttpClients.createProxy(new MetricRegistry(), NO_SSL, uri, clazz); } }
/** * @deprecated please use {@link #createProxyWithFailover(Optional, Optional, Collection, Class, String)}, which * requires you to specify the ProxySelector parameter. */ @Deprecated public static <T> T createProxyWithFailover( MetricRegistry metricRegistry, Optional<TrustContext> trustContext, Collection<String> endpointUris, Class<T> type, String userAgent) { return createProxyWithFailover( metricRegistry, trustContext, Optional.empty(), endpointUris, type, userAgent); }
public static Map<PingableLeader, HostAndPort> generatePingables( MetricsManager metricsManager, Collection<String> remoteEndpoints, Optional<TrustContext> trustContext, String userAgent) { /* The interface used as a key here may be a proxy, which may have strange .equals() behavior. * This is circumvented by using an IdentityHashMap which will just use native == for equality. */ Map<PingableLeader, HostAndPort> pingables = new IdentityHashMap<>(); for (String endpoint : remoteEndpoints) { PingableLeader remoteInterface = AtlasDbHttpClients .createProxy(metricsManager.getRegistry(), trustContext, endpoint, true, PingableLeader.class, userAgent); HostAndPort hostAndPort = HostAndPort.fromString(endpoint); pingables.put(remoteInterface, hostAndPort); } return pingables; }
private static <T> T createClientToMultipleNodes(Class<T> clazz, List<String> nodeNames, short port) { Collection<String> uris = nodeNames.stream() .map(nodeName -> String.format("http://%s:%s", nodeName, port)) .collect(Collectors.toList()); return AtlasDbHttpClients.createProxyWithFailover(new MetricRegistry(), NO_SSL, Optional.empty(), uris, clazz); }
private static TimestampService createTimeLockTimestampClient() { String uri = String.format("http://%s:%s/%s", TIMELOCK_CONTAINER, TIMELOCK_PORT, TEST_CLIENT); return AtlasDbHttpClients.createProxy(new MetricRegistry(), Optional.empty(), uri, TimestampService.class); } }
@Test public void ifOneServerResponds503WithNoRetryHeaderTheRequestIsRerouted() { unavailableServer.stubFor(ENDPOINT_MAPPING.willReturn(aResponse().withStatus(503))); TestResource client = AtlasDbHttpClients.createProxyWithFailover(new MetricRegistry(), NO_SSL, Optional.empty(), bothUris, TestResource.class); int response = client.getTestNumber(); assertThat(response, equalTo(TEST_NUMBER)); unavailableServer.verify(getRequestedFor(urlMatching(TEST_ENDPOINT))); }