/* * Copyright 2015 Netflix, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.netflix.eureka.transport; import javax.inject.Inject; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.Collections; import com.netflix.discovery.EurekaIdentityHeaderFilter; import com.netflix.discovery.shared.resolver.EurekaEndpoint; import com.netflix.discovery.shared.transport.EurekaHttpClient; import com.netflix.discovery.shared.transport.TransportClientFactory; import com.netflix.discovery.shared.transport.jersey.EurekaJerseyClient; import com.netflix.discovery.shared.transport.jersey.EurekaJerseyClientImpl.EurekaJerseyClientBuilder; import com.netflix.discovery.shared.transport.jersey.JerseyApplicationClient; import com.netflix.eureka.EurekaServerConfig; import com.netflix.eureka.EurekaServerIdentity; import com.netflix.eureka.resources.ServerCodecs; import com.sun.jersey.api.client.filter.GZIPContentEncodingFilter; import com.sun.jersey.client.apache4.ApacheHttpClient4; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Tomasz Bak */ public class JerseyRemoteRegionClientFactory implements TransportClientFactory { private static final Logger logger = LoggerFactory.getLogger(JerseyRemoteRegionClientFactory.class); private final EurekaServerConfig serverConfig; private final ServerCodecs serverCodecs; private final String region; private volatile EurekaJerseyClient jerseyClient; private final Object lock = new Object(); @Inject public JerseyRemoteRegionClientFactory(EurekaServerConfig serverConfig, ServerCodecs serverCodecs, String region) { this.serverConfig = serverConfig; this.serverCodecs = serverCodecs; this.region = region; } @Override public EurekaHttpClient newClient(EurekaEndpoint endpoint) { return new JerseyApplicationClient(getOrCreateJerseyClient(region, endpoint).getClient(), endpoint.getServiceUrl(), Collections.<String, String>emptyMap()); } @Override public void shutdown() { if (jerseyClient != null) { jerseyClient.destroyResources(); } } private EurekaJerseyClient getOrCreateJerseyClient(String region, EurekaEndpoint endpoint) { if (jerseyClient != null) { return jerseyClient; } synchronized (lock) { if (jerseyClient == null) { EurekaJerseyClientBuilder clientBuilder = new EurekaJerseyClientBuilder() .withUserAgent("Java-EurekaClient-RemoteRegion") .withEncoderWrapper(serverCodecs.getFullJsonCodec()) .withDecoderWrapper(serverCodecs.getFullJsonCodec()) .withConnectionTimeout(serverConfig.getRemoteRegionConnectTimeoutMs()) .withReadTimeout(serverConfig.getRemoteRegionReadTimeoutMs()) .withMaxConnectionsPerHost(serverConfig.getRemoteRegionTotalConnectionsPerHost()) .withMaxTotalConnections(serverConfig.getRemoteRegionTotalConnections()) .withConnectionIdleTimeout(serverConfig.getRemoteRegionConnectionIdleTimeoutSeconds()); if (endpoint.isSecure()) { clientBuilder.withClientName("Discovery-RemoteRegionClient-" + region); } else if ("true".equals(System.getProperty("com.netflix.eureka.shouldSSLConnectionsUseSystemSocketFactory"))) { clientBuilder.withClientName("Discovery-RemoteRegionSystemSecureClient-" + region) .withSystemSSLConfiguration(); } else { clientBuilder.withClientName("Discovery-RemoteRegionSecureClient-" + region) .withTrustStoreFile( serverConfig.getRemoteRegionTrustStore(), serverConfig.getRemoteRegionTrustStorePassword() ); } jerseyClient = clientBuilder.build(); ApacheHttpClient4 discoveryApacheClient = jerseyClient.getClient(); // Add gzip content encoding support boolean enableGZIPContentEncodingFilter = serverConfig.shouldGZipContentFromRemoteRegion(); if (enableGZIPContentEncodingFilter) { discoveryApacheClient.addFilter(new GZIPContentEncodingFilter(false)); } // always enable client identity headers String ip = null; try { ip = InetAddress.getLocalHost().getHostAddress(); } catch (UnknownHostException e) { logger.warn("Cannot find localhost ip", e); } EurekaServerIdentity identity = new EurekaServerIdentity(ip); discoveryApacheClient.addFilter(new EurekaIdentityHeaderFilter(identity)); } } return jerseyClient; } }