Merge remote-tracking branch 'origin/master' into 2.0.x
This commit is contained in:
@@ -487,3 +487,16 @@ spring:
|
||||
inetutils:
|
||||
useOnlySiteLocalInterfaces: true
|
||||
----
|
||||
|
||||
[[http-clients]]
|
||||
=== HTTP Client Factories
|
||||
|
||||
Spring Cloud Commons provides beans for creating both Apache HTTP clients (`ApacheHttpClientFactory`)
|
||||
as well as OK HTTP clients (`OkHttpClientFactory`). The `OkHttpClientFactory` bean will only be created
|
||||
if the OK HTTP jar is on the classpath. In addition, Spring Cloud Commons provides beans for creating
|
||||
the connection managers used by both clients, `ApacheHttpClientConnectionManagerFactory` for the Apache
|
||||
HTTP client and `OkHttpClientConnectionPoolFactory` for the OK HTTP client. You can provide
|
||||
your own implementation of these beans if you would like to customize how the HTTP clients are created
|
||||
in downstream projects. You can also disable the creation of these beans by setting
|
||||
`spring.cloud.httpclientfactories.apache.enabled` or `spring.cloud.httpclientfactories.ok.enabled` to
|
||||
`false`.
|
||||
@@ -13,6 +13,10 @@
|
||||
<packaging>jar</packaging>
|
||||
<name>Spring Cloud Commons</name>
|
||||
<description>Spring Cloud Commons</description>
|
||||
<properties>
|
||||
<okhttp3.version>3.6.0</okhttp3.version>
|
||||
<apachehttpclient.version>4.5.1</apachehttpclient.version>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
@@ -75,11 +79,22 @@
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<scope>compile</scope>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>okhttp</artifactId>
|
||||
<version>${okhttp3.version}</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>logging-interceptor</artifactId>
|
||||
<version>${okhttp3.version}</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>${apachehttpclient.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
* Copyright 2013-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,20 +16,17 @@
|
||||
|
||||
package org.springframework.cloud.client;
|
||||
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Default implementation of {@link ServiceInstance}.
|
||||
*
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@Data
|
||||
@RequiredArgsConstructor
|
||||
public class DefaultServiceInstance implements ServiceInstance {
|
||||
|
||||
private final String serviceId;
|
||||
@@ -42,6 +39,15 @@ public class DefaultServiceInstance implements ServiceInstance {
|
||||
|
||||
private final Map<String, String> metadata;
|
||||
|
||||
public DefaultServiceInstance(String serviceId, String host, int port, boolean secure,
|
||||
Map<String, String> metadata) {
|
||||
this.serviceId = serviceId;
|
||||
this.host = host;
|
||||
this.port = port;
|
||||
this.secure = secure;
|
||||
this.metadata = metadata;
|
||||
}
|
||||
|
||||
public DefaultServiceInstance(String serviceId, String host, int port,
|
||||
boolean secure) {
|
||||
this(serviceId, host, port, secure, new LinkedHashMap<String, String>());
|
||||
@@ -68,4 +74,52 @@ public class DefaultServiceInstance implements ServiceInstance {
|
||||
instance.getPort());
|
||||
return URI.create(uri);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServiceId() {
|
||||
return serviceId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHost() {
|
||||
return host;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSecure() {
|
||||
return secure;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "DefaultServiceInstance{" +
|
||||
"serviceId='" + serviceId + '\'' +
|
||||
", host='" + host + '\'' +
|
||||
", port=" + port +
|
||||
", secure=" + secure +
|
||||
", metadata=" + metadata +
|
||||
'}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
DefaultServiceInstance that = (DefaultServiceInstance) o;
|
||||
return port == that.port &&
|
||||
secure == that.secure &&
|
||||
Objects.equals(serviceId, that.serviceId) &&
|
||||
Objects.equals(host, that.host) &&
|
||||
Objects.equals(metadata, that.metadata);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(serviceId, host, port, secure, metadata);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright 2017 the original author or authors.
|
||||
*
|
||||
* 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 org.springframework.cloud.client.actuator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -10,7 +26,6 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
|
||||
import lombok.Value;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
@@ -75,17 +90,47 @@ public class FeaturesEndpoint extends AbstractEndpoint<FeaturesEndpoint.Features
|
||||
type.getPackage().getImplementationVendor()));
|
||||
}
|
||||
|
||||
@Value
|
||||
class Features {
|
||||
List<Feature> enabled = new ArrayList<>();
|
||||
List<String> disabled = new ArrayList<>();
|
||||
final List<Feature> enabled = new ArrayList<>();
|
||||
final List<String> disabled = new ArrayList<>();
|
||||
|
||||
public List<Feature> getEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public List<String> getDisabled() {
|
||||
return disabled;
|
||||
}
|
||||
}
|
||||
|
||||
@Value
|
||||
|
||||
class Feature {
|
||||
final String type;
|
||||
final String name;
|
||||
final String version;
|
||||
final String vendor;
|
||||
|
||||
public Feature(String type, String name, String version, String vendor) {
|
||||
this.type = type;
|
||||
this.name = name;
|
||||
this.version = version;
|
||||
this.vendor = vendor;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public String getVendor() {
|
||||
return vendor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,38 @@
|
||||
/*
|
||||
* Copyright 2017 the original author or authors.
|
||||
*
|
||||
* 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 org.springframework.cloud.client.actuator;
|
||||
|
||||
import lombok.Value;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@Value
|
||||
public class NamedFeature {
|
||||
private final String name;
|
||||
private final Class<?> type;
|
||||
|
||||
public NamedFeature(String name, Class<?> type) {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public Class<?> getType() {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
* Copyright 2013-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,6 +19,8 @@ package org.springframework.cloud.client.discovery.health;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.boot.actuate.health.Health;
|
||||
import org.springframework.boot.actuate.health.Status;
|
||||
import org.springframework.cloud.client.discovery.DiscoveryClient;
|
||||
@@ -26,12 +28,10 @@ import org.springframework.cloud.client.discovery.event.InstanceRegisteredEvent;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.core.Ordered;
|
||||
|
||||
import lombok.extern.apachecommons.CommonsLog;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@CommonsLog
|
||||
public class DiscoveryClientHealthIndicator implements DiscoveryHealthIndicator, Ordered,
|
||||
ApplicationListener<InstanceRegisteredEvent<?>> {
|
||||
|
||||
@@ -42,6 +42,8 @@ public class DiscoveryClientHealthIndicator implements DiscoveryHealthIndicator,
|
||||
private final DiscoveryClient discoveryClient;
|
||||
private final DiscoveryClientHealthIndicatorProperties properties;
|
||||
|
||||
private final Log log = LogFactory.getLog(DiscoveryClientHealthIndicator.class);
|
||||
|
||||
@Deprecated
|
||||
public DiscoveryClientHealthIndicator(DiscoveryClient discoveryClient) {
|
||||
this(discoveryClient, new DiscoveryClientHealthIndicatorProperties());
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
* Copyright 2013-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -21,6 +21,8 @@ import java.net.UnknownHostException;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
@@ -36,8 +38,6 @@ import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.event.ContextRefreshedEvent;
|
||||
import org.springframework.core.env.Environment;
|
||||
|
||||
import lombok.extern.apachecommons.CommonsLog;
|
||||
|
||||
/**
|
||||
*
|
||||
* @deprecated Use
|
||||
@@ -48,7 +48,6 @@ import lombok.extern.apachecommons.CommonsLog;
|
||||
@Configuration
|
||||
@EnableConfigurationProperties
|
||||
@ConditionalOnMissingBean(DiscoveryClient.class)
|
||||
@CommonsLog
|
||||
@Deprecated
|
||||
public class NoopDiscoveryClientAutoConfiguration
|
||||
implements ApplicationListener<ContextRefreshedEvent> {
|
||||
@@ -67,6 +66,8 @@ public class NoopDiscoveryClientAutoConfiguration
|
||||
|
||||
private DefaultServiceInstance serviceInstance;
|
||||
|
||||
private final Log log = LogFactory.getLog(NoopDiscoveryClientAutoConfiguration.class);
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
String host = "localhost";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2015 the original author or authors.
|
||||
* Copyright 2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package org.springframework.cloud.client.hypermedia;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -50,17 +49,39 @@ public class CloudHypermediaAutoConfiguration {
|
||||
properties.getRefresh().getInitialDelay());
|
||||
}
|
||||
|
||||
@Data
|
||||
@ConfigurationProperties(prefix = "spring.cloud.hypermedia")
|
||||
public static class CloudHypermediaProperties {
|
||||
|
||||
private Refresh refresh = new Refresh();
|
||||
|
||||
@Data
|
||||
public Refresh getRefresh() {
|
||||
return refresh;
|
||||
}
|
||||
|
||||
public void setRefresh(Refresh refresh) {
|
||||
this.refresh = refresh;
|
||||
}
|
||||
|
||||
public static class Refresh {
|
||||
|
||||
private int fixedDelay = 5000;
|
||||
private int initialDelay = 10000;
|
||||
|
||||
public int getFixedDelay() {
|
||||
return fixedDelay;
|
||||
}
|
||||
|
||||
public void setFixedDelay(int fixedDelay) {
|
||||
this.fixedDelay = fixedDelay;
|
||||
}
|
||||
|
||||
public int getInitialDelay() {
|
||||
return initialDelay;
|
||||
}
|
||||
|
||||
public void setInitialDelay(int initialDelay) {
|
||||
this.initialDelay = initialDelay;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2015 the original author or authors.
|
||||
* Copyright 2015-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -15,12 +15,10 @@
|
||||
*/
|
||||
package org.springframework.cloud.client.hypermedia;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.hateoas.Link;
|
||||
import org.springframework.hateoas.MediaTypes;
|
||||
@@ -35,15 +33,22 @@ import org.springframework.web.client.RestTemplate;
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class DiscoveredResource implements RemoteResource {
|
||||
|
||||
private final ServiceInstanceProvider provider;
|
||||
private final TraversalDefinition traversal;
|
||||
|
||||
|
||||
private RestOperations restOperations = new RestTemplate();
|
||||
private @Getter Link link = null;
|
||||
private Link link = null;
|
||||
|
||||
private final Logger log = LoggerFactory.getLogger(DiscoveredResource.class);
|
||||
|
||||
|
||||
public DiscoveredResource(ServiceInstanceProvider provider, TraversalDefinition traversal) {
|
||||
this.provider = provider;
|
||||
this.traversal = traversal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the {@link RestOperations} to use to execute the traversal and verifying HEAD calls.
|
||||
@@ -54,6 +59,27 @@ public class DiscoveredResource implements RemoteResource {
|
||||
this.restOperations = restOperations == null ? new RestTemplate() : restOperations;
|
||||
}
|
||||
|
||||
public ServiceInstanceProvider getProvider() {
|
||||
return provider;
|
||||
}
|
||||
|
||||
public TraversalDefinition getTraversal() {
|
||||
return traversal;
|
||||
}
|
||||
|
||||
public RestOperations getRestOperations() {
|
||||
return restOperations;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Link getLink() {
|
||||
return link;
|
||||
}
|
||||
|
||||
public void setLink(Link link) {
|
||||
this.link = link;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies the link to the current
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2015 the original author or authors.
|
||||
* Copyright 2015-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -15,8 +15,6 @@
|
||||
*/
|
||||
package org.springframework.cloud.client.hypermedia;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
@@ -28,16 +26,20 @@ import org.springframework.cloud.client.discovery.DiscoveryClient;
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
public class DynamicServiceInstanceProvider implements ServiceInstanceProvider {
|
||||
|
||||
private final DiscoveryClient client;
|
||||
private final String serviceName;
|
||||
|
||||
public DynamicServiceInstanceProvider(DiscoveryClient client, String serviceName) {
|
||||
this.client = client;
|
||||
this.serviceName = serviceName;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see example.customers.integration.ServiceInstanceProvider#getServiceInstance()
|
||||
*/
|
||||
* (non-Javadoc)
|
||||
* @see example.customers.integration.ServiceInstanceProvider#getServiceInstance()
|
||||
*/
|
||||
@Override
|
||||
public ServiceInstance getServiceInstance() {
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2015 the original author or authors.
|
||||
* Copyright 2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -15,8 +15,6 @@
|
||||
*/
|
||||
package org.springframework.cloud.client.hypermedia;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.scheduling.config.ContextLifecycleScheduledTaskRegistrar;
|
||||
@@ -29,16 +27,21 @@ import org.springframework.scheduling.config.ScheduledTaskRegistrar;
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
public class RemoteResourceRefresher extends ContextLifecycleScheduledTaskRegistrar {
|
||||
|
||||
private final List<RemoteResource> discoveredResources;
|
||||
private final int fixedDelay, initialDelay;
|
||||
|
||||
public RemoteResourceRefresher(List<RemoteResource> discoveredResources, int fixedDelay, int initialDelay) {
|
||||
this.discoveredResources = discoveredResources;
|
||||
this.fixedDelay = fixedDelay;
|
||||
this.initialDelay = initialDelay;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.scheduling.config.ContextLifecycleScheduledTaskRegistrar#afterPropertiesSet()
|
||||
*/
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.scheduling.config.ContextLifecycleScheduledTaskRegistrar#afterPropertiesSet()
|
||||
*/
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2015 the original author or authors.
|
||||
* Copyright 2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -15,8 +15,6 @@
|
||||
*/
|
||||
package org.springframework.cloud.client.hypermedia;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
|
||||
/**
|
||||
@@ -24,15 +22,18 @@ import org.springframework.cloud.client.ServiceInstance;
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
public class StaticServiceInstanceProvider implements ServiceInstanceProvider {
|
||||
|
||||
private final ServiceInstance instance;
|
||||
|
||||
public StaticServiceInstanceProvider(ServiceInstance instance) {
|
||||
this.instance = instance;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see example.customers.integration.ServiceInstanceProvider#getServiceInstance()
|
||||
*/
|
||||
* (non-Javadoc)
|
||||
* @see example.customers.integration.ServiceInstanceProvider#getServiceInstance()
|
||||
*/
|
||||
@Override
|
||||
public ServiceInstance getServiceInstance() {
|
||||
return instance;
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright 2013-2016 the original author or authors.
|
||||
* *
|
||||
* * 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 org.springframework.cloud.commons.httpclient;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.apache.http.config.RegistryBuilder;
|
||||
import org.apache.http.conn.HttpClientConnectionManager;
|
||||
|
||||
/**
|
||||
* Interface for creating an {@link HttpClientConnectionManager}.
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
public interface ApacheHttpClientConnectionManagerFactory {
|
||||
public static final String HTTP_SCHEME = "http";
|
||||
public static final String HTTPS_SCHEME = "https";
|
||||
|
||||
/**
|
||||
* Creates a new {@link HttpClientConnectionManager}.
|
||||
* @param disableSslValidation True to disable SSL validation, false otherwise
|
||||
* @param maxTotalConnections The total number of connections
|
||||
* @param maxConnectionsPerRoute The total number of connections per route
|
||||
* @param timeToLive The time a connection is allowed to exist
|
||||
* @param timeUnit The time unit for the time to live value
|
||||
* @param registryBuilder The {@link RegistryBuilder} to use in the connection manager
|
||||
* @return A new {@link HttpClientConnectionManager}
|
||||
*/
|
||||
public HttpClientConnectionManager newConnectionManager(boolean disableSslValidation,
|
||||
int maxTotalConnections, int maxConnectionsPerRoute, long timeToLive,
|
||||
TimeUnit timeUnit, RegistryBuilder registryBuilder);
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright 2013-2016 the original author or authors.
|
||||
* *
|
||||
* * 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 org.springframework.cloud.commons.httpclient;
|
||||
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.conn.HttpClientConnectionManager;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
|
||||
/**
|
||||
* Factory for creating a new {@link CloseableHttpClient}.
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
public interface ApacheHttpClientFactory {
|
||||
|
||||
/**
|
||||
* Creates an {@link HttpClientBuilder} that can be used to create a new {@link CloseableHttpClient}.
|
||||
* @return A {@link HttpClientBuilder}
|
||||
*/
|
||||
public HttpClientBuilder createBuilder();
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
package org.springframework.cloud.commons.httpclient;
|
||||
|
||||
import java.security.KeyManagementException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.TrustManager;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.http.config.Registry;
|
||||
import org.apache.http.config.RegistryBuilder;
|
||||
import org.apache.http.conn.HttpClientConnectionManager;
|
||||
import org.apache.http.conn.socket.ConnectionSocketFactory;
|
||||
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
|
||||
import org.apache.http.conn.ssl.NoopHostnameVerifier;
|
||||
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
|
||||
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
/**
|
||||
* Default implementation of {@link ApacheHttpClientConnectionManagerFactory}.
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
public class DefaultApacheHttpClientConnectionManagerFactory
|
||||
implements ApacheHttpClientConnectionManagerFactory {
|
||||
|
||||
private static final Log LOG = LogFactory
|
||||
.getLog(DefaultApacheHttpClientConnectionManagerFactory.class);
|
||||
|
||||
public HttpClientConnectionManager newConnectionManager(boolean disableSslValidation,
|
||||
int maxTotalConnections, int maxConnectionsPerRoute) {
|
||||
return newConnectionManager(disableSslValidation, maxTotalConnections,
|
||||
maxConnectionsPerRoute, -1, TimeUnit.MILLISECONDS, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpClientConnectionManager newConnectionManager(boolean disableSslValidation,
|
||||
int maxTotalConnections, int maxConnectionsPerRoute, long timeToLive,
|
||||
TimeUnit timeUnit, RegistryBuilder registryBuilder) {
|
||||
if (registryBuilder == null) {
|
||||
registryBuilder = RegistryBuilder.<ConnectionSocketFactory> create()
|
||||
.register(HTTP_SCHEME, PlainConnectionSocketFactory.INSTANCE);
|
||||
}
|
||||
if (disableSslValidation) {
|
||||
try {
|
||||
final SSLContext sslContext = SSLContext.getInstance("SSL");
|
||||
sslContext.init(null, new TrustManager[] { new X509TrustManager() {
|
||||
@Override
|
||||
public void checkClientTrusted(X509Certificate[] x509Certificates,
|
||||
String s) throws CertificateException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkServerTrusted(X509Certificate[] x509Certificates,
|
||||
String s) throws CertificateException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public X509Certificate[] getAcceptedIssuers() {
|
||||
return null;
|
||||
}
|
||||
} }, new SecureRandom());
|
||||
registryBuilder.register(HTTPS_SCHEME, new SSLConnectionSocketFactory(
|
||||
sslContext, NoopHostnameVerifier.INSTANCE));
|
||||
}
|
||||
catch (NoSuchAlgorithmException e) {
|
||||
LOG.warn("Error creating SSLContext", e);
|
||||
}
|
||||
catch (KeyManagementException e) {
|
||||
LOG.warn("Error creating SSLContext", e);
|
||||
}
|
||||
}
|
||||
final Registry<ConnectionSocketFactory> registry = registryBuilder.build();
|
||||
|
||||
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(
|
||||
registry, null, null, null, timeToLive, timeUnit);
|
||||
connectionManager.setMaxTotal(maxTotalConnections);
|
||||
connectionManager.setDefaultMaxPerRoute(maxConnectionsPerRoute);
|
||||
|
||||
return connectionManager;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package org.springframework.cloud.commons.httpclient;
|
||||
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.conn.HttpClientConnectionManager;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
|
||||
/**
|
||||
* Default implementation of {@link ApacheHttpClientFactory}.
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
public class DefaultApacheHttpClientFactory implements ApacheHttpClientFactory {
|
||||
|
||||
/**
|
||||
* A default {@link HttpClientBuilder}. The {@link HttpClientBuilder} returned will
|
||||
* have content compression disabled, cookie management disabled, and use system properties.
|
||||
*/
|
||||
@Override
|
||||
public HttpClientBuilder createBuilder() {
|
||||
return HttpClientBuilder.create().disableContentCompression()
|
||||
.disableCookieManagement().useSystemProperties();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package org.springframework.cloud.commons.httpclient;
|
||||
|
||||
import okhttp3.ConnectionPool;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Default implementation of {@link OkHttpClientConnectionPoolFactory}.
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
public class DefaultOkHttpClientConnectionPoolFactory implements OkHttpClientConnectionPoolFactory {
|
||||
|
||||
@Override
|
||||
public ConnectionPool create(int maxIdleConnections, long keepAliveDuration, TimeUnit timeUnit) {
|
||||
return new ConnectionPool(maxIdleConnections, keepAliveDuration, timeUnit);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package org.springframework.cloud.commons.httpclient;
|
||||
|
||||
import okhttp3.ConnectionPool;
|
||||
import okhttp3.OkHttpClient;
|
||||
|
||||
import java.security.KeyManagementException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLSocketFactory;
|
||||
import javax.net.ssl.TrustManager;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Default implementation of {@link OkHttpClientFactory}.
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
public class DefaultOkHttpClientFactory implements OkHttpClientFactory {
|
||||
|
||||
private static final Log LOG = LogFactory.getLog(DefaultOkHttpClientFactory.class);
|
||||
|
||||
@Override
|
||||
public OkHttpClient.Builder createBuilder(boolean disableSslValidation) {
|
||||
OkHttpClient.Builder builder = new OkHttpClient.Builder();
|
||||
if (disableSslValidation) {
|
||||
try {
|
||||
X509TrustManager disabledTrustManager = new DisableValidationTrustManager();
|
||||
TrustManager[] trustManagers = new TrustManager[1];
|
||||
trustManagers[0] = disabledTrustManager;
|
||||
SSLContext sslContext = SSLContext.getInstance("SSL");
|
||||
sslContext.init(null, trustManagers, new java.security.SecureRandom());
|
||||
SSLSocketFactory disabledSSLSocketFactory = sslContext.getSocketFactory();
|
||||
builder.sslSocketFactory(disabledSSLSocketFactory, disabledTrustManager);
|
||||
builder.hostnameVerifier(new TrustAllHostnames());
|
||||
}
|
||||
catch (NoSuchAlgorithmException e) {
|
||||
LOG.warn("Error setting SSLSocketFactory in OKHttpClient", e);
|
||||
}
|
||||
catch (KeyManagementException e) {
|
||||
LOG.warn("Error setting SSLSocketFactory in OKHttpClient", e);
|
||||
}
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package org.springframework.cloud.commons.httpclient;
|
||||
|
||||
import okhttp3.OkHttpClient;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
@Configuration
|
||||
public class HttpClientConfiguration {
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnProperty(name = "spring.cloud.httpclientfactories.apache.enabled", matchIfMissing = true)
|
||||
static class ApacheHttpClientConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public ApacheHttpClientConnectionManagerFactory connManFactory() {
|
||||
return new DefaultApacheHttpClientConnectionManagerFactory();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public ApacheHttpClientFactory apacheHttpClientFactory() {
|
||||
return new DefaultApacheHttpClientFactory();
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnProperty(name = "spring.cloud.httpclientfactories.ok.enabled", matchIfMissing = true)
|
||||
@ConditionalOnClass(OkHttpClient.class)
|
||||
static class OkHttpClientConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public OkHttpClientConnectionPoolFactory connPoolFactory() {
|
||||
return new DefaultOkHttpClientConnectionPoolFactory();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public OkHttpClientFactory okHttpClientFactory() {
|
||||
return new DefaultOkHttpClientFactory();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package org.springframework.cloud.commons.httpclient;
|
||||
|
||||
import okhttp3.ConnectionPool;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Creates {@link ConnectionPool}s for {@link okhttp3.OkHttpClient}s
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
public interface OkHttpClientConnectionPoolFactory {
|
||||
|
||||
/**
|
||||
* Creates a new {@link ConnectionPool}.
|
||||
* @param maxIdleConnections number of max idle connections to allow
|
||||
* @param keepAliveDuration amount of time to keep connections alive
|
||||
* @param timeUnit the time unit for the keep alive duration
|
||||
* @return A new {@link ConnectionPool}
|
||||
*/
|
||||
public ConnectionPool create(int maxIdleConnections, long keepAliveDuration, TimeUnit timeUnit);
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package org.springframework.cloud.commons.httpclient;
|
||||
|
||||
import okhttp3.ConnectionPool;
|
||||
import okhttp3.OkHttpClient;
|
||||
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
import javax.net.ssl.SSLSession;
|
||||
import javax.net.ssl.SSLSocketFactory;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
|
||||
/**
|
||||
* Creates new {@link OkHttpClient}s.
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
public interface OkHttpClientFactory {
|
||||
|
||||
/**
|
||||
* Creates a {@link OkHttpClient.Builder} used to build an {@link OkHttpClient}.
|
||||
* @param disableSslValidation Disables SSL validation
|
||||
* @return A new {@link OkHttpClient.Builder}
|
||||
*/
|
||||
public OkHttpClient.Builder createBuilder(boolean disableSslValidation);
|
||||
|
||||
/**
|
||||
* A {@link X509TrustManager} that does not validate SSL certificates.
|
||||
*/
|
||||
public static class DisableValidationTrustManager implements X509TrustManager {
|
||||
|
||||
@Override
|
||||
public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {}
|
||||
|
||||
@Override
|
||||
public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {}
|
||||
|
||||
@Override
|
||||
public X509Certificate[] getAcceptedIssuers() {
|
||||
return new X509Certificate[0];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A {@link HostnameVerifier} that does not validate any hostnames.
|
||||
*/
|
||||
public static class TrustAllHostnames implements HostnameVerifier {
|
||||
|
||||
@Override
|
||||
public boolean verify(String s, SSLSession sslSession) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -31,20 +31,21 @@ import java.util.concurrent.Future;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.extern.apachecommons.CommonsLog;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@CommonsLog
|
||||
public class InetUtils implements Closeable {
|
||||
|
||||
// TODO: maybe shutdown the thread pool if it isn't being used?
|
||||
private final ExecutorService executorService;
|
||||
private final InetUtilsProperties properties;
|
||||
private static final InetUtils instance = new InetUtils(new InetUtilsProperties());
|
||||
|
||||
|
||||
private final Log log = LogFactory.getLog(InetUtils.class);
|
||||
|
||||
public InetUtils(final InetUtilsProperties properties) {
|
||||
this.properties = properties;
|
||||
this.executorService = Executors
|
||||
@@ -200,7 +201,6 @@ public class InetUtils implements Closeable {
|
||||
return new HostInfo(host).getIpAddressAsInt();
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class HostInfo {
|
||||
public boolean override;
|
||||
private String ipAddress;
|
||||
@@ -227,6 +227,30 @@ public class InetUtils implements Closeable {
|
||||
}
|
||||
return ByteBuffer.wrap(inetAddress.getAddress()).getInt();
|
||||
}
|
||||
|
||||
public boolean isOverride() {
|
||||
return override;
|
||||
}
|
||||
|
||||
public void setOverride(boolean override) {
|
||||
this.override = override;
|
||||
}
|
||||
|
||||
public String getIpAddress() {
|
||||
return ipAddress;
|
||||
}
|
||||
|
||||
public void setIpAddress(String ipAddress) {
|
||||
this.ipAddress = ipAddress;
|
||||
}
|
||||
|
||||
public String getHostname() {
|
||||
return hostname;
|
||||
}
|
||||
|
||||
public void setHostname(String hostname) {
|
||||
this.hostname = hostname;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright 2017 the original author or authors.
|
||||
*
|
||||
* 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 org.springframework.cloud.commons.util;
|
||||
|
||||
import java.net.InetAddress;
|
||||
@@ -7,12 +23,9 @@ import java.util.List;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@Data
|
||||
@ConfigurationProperties(InetUtilsProperties.PREFIX)
|
||||
public class InetUtilsProperties {
|
||||
public static final String PREFIX = "spring.cloud.inetutils";
|
||||
@@ -47,4 +60,56 @@ public class InetUtilsProperties {
|
||||
* List of Java regex expressions for network addresses that will be preferred.
|
||||
*/
|
||||
private List<String> preferredNetworks = new ArrayList<>();
|
||||
|
||||
public static String getPREFIX() {
|
||||
return PREFIX;
|
||||
}
|
||||
|
||||
public String getDefaultHostname() {
|
||||
return defaultHostname;
|
||||
}
|
||||
|
||||
public void setDefaultHostname(String defaultHostname) {
|
||||
this.defaultHostname = defaultHostname;
|
||||
}
|
||||
|
||||
public String getDefaultIpAddress() {
|
||||
return defaultIpAddress;
|
||||
}
|
||||
|
||||
public void setDefaultIpAddress(String defaultIpAddress) {
|
||||
this.defaultIpAddress = defaultIpAddress;
|
||||
}
|
||||
|
||||
public int getTimeoutSeconds() {
|
||||
return timeoutSeconds;
|
||||
}
|
||||
|
||||
public void setTimeoutSeconds(int timeoutSeconds) {
|
||||
this.timeoutSeconds = timeoutSeconds;
|
||||
}
|
||||
|
||||
public List<String> getIgnoredInterfaces() {
|
||||
return ignoredInterfaces;
|
||||
}
|
||||
|
||||
public void setIgnoredInterfaces(List<String> ignoredInterfaces) {
|
||||
this.ignoredInterfaces = ignoredInterfaces;
|
||||
}
|
||||
|
||||
public boolean isUseOnlySiteLocalInterfaces() {
|
||||
return useOnlySiteLocalInterfaces;
|
||||
}
|
||||
|
||||
public void setUseOnlySiteLocalInterfaces(boolean useOnlySiteLocalInterfaces) {
|
||||
this.useOnlySiteLocalInterfaces = useOnlySiteLocalInterfaces;
|
||||
}
|
||||
|
||||
public List<String> getPreferredNetworks() {
|
||||
return preferredNetworks;
|
||||
}
|
||||
|
||||
public void setPreferredNetworks(List<String> preferredNetworks) {
|
||||
this.preferredNetworks = preferredNetworks;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
* Copyright 2013-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -20,6 +20,8 @@ import java.util.ArrayList;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.factory.BeanClassLoaderAware;
|
||||
import org.springframework.context.EnvironmentAware;
|
||||
import org.springframework.context.annotation.DeferredImportSelector;
|
||||
@@ -30,7 +32,6 @@ import org.springframework.core.io.support.SpringFactoriesLoader;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import lombok.extern.apachecommons.CommonsLog;
|
||||
|
||||
/**
|
||||
* Selects configurations to load defined by the generic type T. Loads implementations
|
||||
@@ -39,7 +40,6 @@ import lombok.extern.apachecommons.CommonsLog;
|
||||
* @author Spencer Gibb
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@CommonsLog
|
||||
public abstract class SpringFactoryImportSelector<T>
|
||||
implements DeferredImportSelector, BeanClassLoaderAware, EnvironmentAware {
|
||||
|
||||
@@ -49,6 +49,8 @@ public abstract class SpringFactoryImportSelector<T>
|
||||
|
||||
private Environment environment;
|
||||
|
||||
private final Log log = LogFactory.getLog(SpringFactoryImportSelector.class);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected SpringFactoryImportSelector() {
|
||||
this.annotationClass = (Class<T>) GenericTypeResolver
|
||||
|
||||
@@ -8,7 +8,8 @@ org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration,\
|
||||
org.springframework.cloud.client.serviceregistry.ServiceRegistryAutoConfiguration,\
|
||||
org.springframework.cloud.commons.util.UtilAutoConfiguration,\
|
||||
org.springframework.cloud.client.discovery.composite.CompositeDiscoveryClientAutoConfiguration,\
|
||||
org.springframework.cloud.client.discovery.simple.SimpleDiscoveryClientAutoConfiguration
|
||||
org.springframework.cloud.client.discovery.simple.SimpleDiscoveryClientAutoConfiguration,\
|
||||
org.springframework.cloud.commons.httpclient.HttpClientConfiguration
|
||||
|
||||
|
||||
# Environment Post Processors
|
||||
|
||||
@@ -1,20 +1,33 @@
|
||||
/*
|
||||
* Copyright 2017 the original author or authors.
|
||||
*
|
||||
* 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 org.springframework.cloud.client.loadbalancer;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.empty;
|
||||
import static org.hamcrest.Matchers.hasSize;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -25,7 +38,6 @@ import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.http.client.ClientHttpRequestInterceptor;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
/**
|
||||
@@ -138,15 +150,21 @@ public abstract class AbstractLoadBalancerAutoConfigurationTests {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public <T> T execute(String serviceId, LoadBalancerRequest<T> request) {
|
||||
return request.apply(choose(serviceId));
|
||||
try {
|
||||
return request.apply(choose(serviceId));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public <T> T execute(String serviceId, ServiceInstance serviceInstance, LoadBalancerRequest<T> request) throws IOException {
|
||||
return request.apply(choose(serviceId));
|
||||
try {
|
||||
return request.apply(choose(serviceId));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,6 +1,21 @@
|
||||
/*
|
||||
* Copyright 2017 the original author or authors.
|
||||
*
|
||||
* 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 org.springframework.cloud.client.loadbalancer;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
import org.hamcrest.MatcherAssert;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -140,15 +155,21 @@ public class AsyncLoadBalancerAutoConfigurationTests {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public <T> T execute(String serviceId, LoadBalancerRequest<T> request) {
|
||||
return request.apply(choose(serviceId));
|
||||
try {
|
||||
return request.apply(choose(serviceId));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public <T> T execute(String serviceId, ServiceInstance serviceInstance, LoadBalancerRequest<T> request) throws IOException {
|
||||
return request.apply(choose(serviceId));
|
||||
try {
|
||||
return request.apply(choose(serviceId));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
package org.springframework.cloud.commons.httpclient;
|
||||
|
||||
import okhttp3.ConnectionPool;
|
||||
import okhttp3.OkHttpClient;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import javax.net.ssl.SSLSocketFactory;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.config.RegistryBuilder;
|
||||
import org.apache.http.conn.HttpClientConnectionManager;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = CustomApplication.class, properties = {"spring.cloud.httpclient.ok.enabled: true"})
|
||||
public class CustomHttpClientConfigurationTests {
|
||||
|
||||
@Autowired
|
||||
ApacheHttpClientFactory httpClientFactory;
|
||||
|
||||
@Autowired
|
||||
ApacheHttpClientConnectionManagerFactory connectionManagerFactory;
|
||||
|
||||
@Autowired
|
||||
OkHttpClientFactory okHttpClientFactory;
|
||||
|
||||
@Autowired
|
||||
OkHttpClientConnectionPoolFactory okHttpClientConnectionPoolFactory;
|
||||
|
||||
@Test
|
||||
public void connManFactory() throws Exception {
|
||||
assertTrue(ApacheHttpClientConnectionManagerFactory.class
|
||||
.isInstance(connectionManagerFactory));
|
||||
assertTrue(CustomApplication.MyApacheHttpClientConnectionManagerFactory.class
|
||||
.isInstance(connectionManagerFactory));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void apacheHttpClientFactory() throws Exception {
|
||||
assertTrue(ApacheHttpClientFactory.class.isInstance(httpClientFactory));
|
||||
assertTrue(CustomApplication.MyApacheHttpClientFactory.class
|
||||
.isInstance(httpClientFactory));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void connectionPoolFactory() throws Exception {
|
||||
assertTrue(OkHttpClientConnectionPoolFactory.class.isInstance(okHttpClientConnectionPoolFactory));
|
||||
assertTrue(CustomApplication.MyOkHttpConnectionPoolFactory.class.isInstance(okHttpClientConnectionPoolFactory));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void okHttpClientFactory() throws Exception {
|
||||
assertTrue(OkHttpClientFactory.class.isInstance(okHttpClientFactory));
|
||||
assertTrue(CustomApplication.MyOkHttpClientFactory.class.isInstance(okHttpClientFactory));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
class CustomApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(MyApplication.class, args);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class MyConfig {
|
||||
|
||||
@Bean
|
||||
public ApacheHttpClientFactory clientFactory() {
|
||||
return new MyApacheHttpClientFactory();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ApacheHttpClientConnectionManagerFactory connectionManagerFactory() {
|
||||
return new MyApacheHttpClientConnectionManagerFactory();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public OkHttpClientConnectionPoolFactory connectionPoolFactory() {
|
||||
return new MyOkHttpConnectionPoolFactory();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public OkHttpClientFactory okHttpClientFactory() {
|
||||
return new MyOkHttpClientFactory();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class MyApacheHttpClientFactory implements ApacheHttpClientFactory {
|
||||
|
||||
@Override
|
||||
public HttpClientBuilder createBuilder() {
|
||||
return HttpClientBuilder.create();
|
||||
}
|
||||
}
|
||||
|
||||
static class MyApacheHttpClientConnectionManagerFactory
|
||||
implements ApacheHttpClientConnectionManagerFactory {
|
||||
|
||||
@Override
|
||||
public HttpClientConnectionManager newConnectionManager(
|
||||
boolean disableSslValidation, int maxTotalConnections,
|
||||
int maxConnectionsPerRoute, long timeToLive, TimeUnit timeUnit,
|
||||
RegistryBuilder registryBuilder) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
static class MyOkHttpClientFactory implements OkHttpClientFactory {
|
||||
@Override
|
||||
public OkHttpClient.Builder createBuilder(boolean disableSslValidation) {
|
||||
return new OkHttpClient.Builder();
|
||||
}
|
||||
}
|
||||
|
||||
static class MyOkHttpConnectionPoolFactory implements OkHttpClientConnectionPoolFactory {
|
||||
|
||||
@Override
|
||||
public ConnectionPool create(int maxIdleConnections, long keepAliveDuration, TimeUnit timeUnit) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package org.springframework.cloud.commons.httpclient;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import org.apache.http.conn.HttpClientConnectionManager;
|
||||
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
|
||||
import org.junit.Test;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
|
||||
/**
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
public class DefaultApacheHttpClientConnectionManagerFactoryTests {
|
||||
@Test
|
||||
public void newConnectionManager() throws Exception {
|
||||
HttpClientConnectionManager connectionManager = new DefaultApacheHttpClientConnectionManagerFactory()
|
||||
.newConnectionManager(false, 2, 6);
|
||||
assertEquals(6, ((PoolingHttpClientConnectionManager) connectionManager)
|
||||
.getDefaultMaxPerRoute());
|
||||
assertEquals(2,
|
||||
((PoolingHttpClientConnectionManager) connectionManager).getMaxTotal());
|
||||
Object pool = getField(((PoolingHttpClientConnectionManager) connectionManager),
|
||||
"pool");
|
||||
assertEquals(-1l, ((Long)getField(pool, "timeToLive")).longValue());
|
||||
TimeUnit timeUnit = getField(pool, "tunit");
|
||||
assertEquals(TimeUnit.MILLISECONDS, timeUnit);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void newConnectionManagerWithTTL() throws Exception {
|
||||
HttpClientConnectionManager connectionManager = new DefaultApacheHttpClientConnectionManagerFactory()
|
||||
.newConnectionManager(false, 2, 6, 56l, TimeUnit.DAYS, null);
|
||||
assertEquals(6, ((PoolingHttpClientConnectionManager) connectionManager)
|
||||
.getDefaultMaxPerRoute());
|
||||
assertEquals(2,
|
||||
((PoolingHttpClientConnectionManager) connectionManager).getMaxTotal());
|
||||
Object pool = getField(((PoolingHttpClientConnectionManager) connectionManager),
|
||||
"pool");
|
||||
assertEquals(56l, ((Long)getField(pool, "timeToLive")).longValue());
|
||||
TimeUnit timeUnit = getField(pool, "tunit");
|
||||
assertEquals(TimeUnit.DAYS, timeUnit);
|
||||
}
|
||||
|
||||
protected <T> T getField(Object target, String name) {
|
||||
Field field = ReflectionUtils.findField(target.getClass(), name);
|
||||
ReflectionUtils.makeAccessible(field);
|
||||
Object value = ReflectionUtils.getField(field, target);
|
||||
return (T) value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package org.springframework.cloud.commons.httpclient;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import org.apache.http.client.config.CookieSpecs;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.client.methods.Configurable;
|
||||
import org.apache.http.conn.HttpClientConnectionManager;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.junit.Test;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
public class DefaultApacheHttpClientFactoryTests {
|
||||
@Test
|
||||
public void createClient() throws Exception {
|
||||
final RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(100)
|
||||
.setConnectTimeout(200).setCookieSpec(CookieSpecs.IGNORE_COOKIES).build();
|
||||
CloseableHttpClient httpClient = new DefaultApacheHttpClientFactory().createBuilder().
|
||||
setConnectionManager(mock(HttpClientConnectionManager.class)).
|
||||
setDefaultRequestConfig(requestConfig).build();
|
||||
Assertions.assertThat(httpClient).isInstanceOf(Configurable.class);
|
||||
RequestConfig config = ((Configurable) httpClient).getConfig();
|
||||
assertEquals(100, config.getSocketTimeout());
|
||||
assertEquals(200, config.getConnectTimeout());
|
||||
assertEquals(CookieSpecs.IGNORE_COOKIES, config.getCookieSpec());
|
||||
}
|
||||
|
||||
protected <T> T getField(Object target, String name) {
|
||||
Field field = ReflectionUtils.findField(target.getClass(), name);
|
||||
ReflectionUtils.makeAccessible(field);
|
||||
Object value = ReflectionUtils.getField(field, target);
|
||||
return (T) value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package org.springframework.cloud.commons.httpclient;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = MyApplication.class, properties = {"spring.cloud.httpclient.ok.enabled: true"})
|
||||
public class DefaultHttpClientConfigurationTests {
|
||||
@Autowired
|
||||
ApacheHttpClientFactory httpClientFactory;
|
||||
|
||||
@Autowired
|
||||
ApacheHttpClientConnectionManagerFactory connectionManagerFactory;
|
||||
|
||||
@Autowired
|
||||
OkHttpClientFactory okHttpClientFactory;
|
||||
|
||||
@Autowired
|
||||
OkHttpClientConnectionPoolFactory okHttpClientConnectionPoolFactory;
|
||||
|
||||
@Test
|
||||
public void connManFactory() throws Exception {
|
||||
assertTrue(ApacheHttpClientConnectionManagerFactory.class
|
||||
.isInstance(connectionManagerFactory));
|
||||
assertTrue(DefaultApacheHttpClientConnectionManagerFactory.class
|
||||
.isInstance(connectionManagerFactory));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void apacheHttpClientFactory() throws Exception {
|
||||
assertTrue(ApacheHttpClientFactory.class.isInstance(httpClientFactory));
|
||||
assertTrue(DefaultApacheHttpClientFactory.class.isInstance(httpClientFactory));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void connPoolFactory() throws Exception {
|
||||
assertTrue(OkHttpClientConnectionPoolFactory.class.isInstance(okHttpClientConnectionPoolFactory));
|
||||
assertTrue(DefaultOkHttpClientConnectionPoolFactory.class.isInstance(okHttpClientConnectionPoolFactory));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setOkHttpClientFactory() throws Exception {
|
||||
assertTrue(OkHttpClientFactory.class.isInstance(okHttpClientFactory));
|
||||
assertTrue(DefaultOkHttpClientFactory.class.isInstance(okHttpClientFactory));
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
class MyApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(MyApplication.class, args);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package org.springframework.cloud.commons.httpclient;
|
||||
|
||||
import okhttp3.ConnectionPool;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import org.junit.Test;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
public class DefaultOkHttpClientConnectionPoolFactoryTest {
|
||||
@Test
|
||||
public void create() throws Exception {
|
||||
DefaultOkHttpClientConnectionPoolFactory connectionPoolFactory = new DefaultOkHttpClientConnectionPoolFactory();
|
||||
ConnectionPool connectionPool = connectionPoolFactory.create(2,
|
||||
3, TimeUnit.MILLISECONDS);
|
||||
int idleConnections = getField(connectionPool, "maxIdleConnections");
|
||||
long keepAliveDuration = getField(connectionPool, "keepAliveDurationNs");
|
||||
assertEquals(2, idleConnections);
|
||||
assertEquals(TimeUnit.MILLISECONDS.toNanos(3), keepAliveDuration);
|
||||
}
|
||||
|
||||
protected <T> T getField(Object target, String name) {
|
||||
Field field = ReflectionUtils.findField(target.getClass(), name);
|
||||
ReflectionUtils.makeAccessible(field);
|
||||
Object value = ReflectionUtils.getField(field, target);
|
||||
return (T) value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package org.springframework.cloud.commons.httpclient;
|
||||
|
||||
import okhttp3.ConnectionPool;
|
||||
import okhttp3.OkHttpClient;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
import org.junit.Test;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
public class DefaultOkHttpClientFactoryTest {
|
||||
@Test
|
||||
public void create() throws Exception {
|
||||
DefaultOkHttpClientFactory okHttpClientFactory = new DefaultOkHttpClientFactory();
|
||||
DefaultOkHttpClientConnectionPoolFactory poolFactory = new DefaultOkHttpClientConnectionPoolFactory();
|
||||
ConnectionPool pool = poolFactory.create(4, 5, TimeUnit.DAYS);
|
||||
OkHttpClient httpClient = okHttpClientFactory.createBuilder(true).
|
||||
connectTimeout(2, TimeUnit.MILLISECONDS).
|
||||
readTimeout(3, TimeUnit.HOURS).
|
||||
followRedirects(true).
|
||||
connectionPool(pool).build();
|
||||
int connectTimeout = getField(httpClient, "connectTimeout");
|
||||
assertEquals(2, connectTimeout);
|
||||
int readTimeout = getField(httpClient, "readTimeout");
|
||||
assertEquals(TimeUnit.HOURS.toMillis(3), readTimeout);
|
||||
boolean followRedirects = getField(httpClient, "followRedirects");
|
||||
assertTrue(followRedirects);
|
||||
ConnectionPool poolFromClient = getField(httpClient, "connectionPool");
|
||||
assertEquals(pool, poolFromClient);
|
||||
HostnameVerifier hostnameVerifier = getField(httpClient, "hostnameVerifier");
|
||||
assertTrue(OkHttpClientFactory.TrustAllHostnames.class.isInstance(hostnameVerifier));
|
||||
}
|
||||
|
||||
protected <T> T getField(Object target, String name) {
|
||||
Field field = ReflectionUtils.findField(target.getClass(), name);
|
||||
ReflectionUtils.makeAccessible(field);
|
||||
Object value = ReflectionUtils.getField(field, target);
|
||||
return (T) value;
|
||||
}
|
||||
}
|
||||
@@ -68,9 +68,8 @@ public class EnvironmentManager implements ApplicationEventPublisherAware {
|
||||
public Map<String, Object> reset() {
|
||||
Map<String, Object> result = new LinkedHashMap<String, Object>(map);
|
||||
if (!map.isEmpty()) {
|
||||
Set<String> keys = map.keySet();
|
||||
map.clear();
|
||||
publish(new EnvironmentChangeEvent(keys));
|
||||
publish(new EnvironmentChangeEvent(result.keySet()));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
package org.springframework.cloud.context.environment;
|
||||
|
||||
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mockito;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.mock.env.MockEnvironment;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
public class EnvironmentManagerTest {
|
||||
|
||||
@Test
|
||||
public void testCorrectEvents() {
|
||||
MockEnvironment environment = new MockEnvironment();
|
||||
ApplicationEventPublisher publisher = mock(ApplicationEventPublisher.class);
|
||||
EnvironmentManager environmentManager = new EnvironmentManager(environment);
|
||||
environmentManager.setApplicationEventPublisher(publisher);
|
||||
|
||||
environmentManager.setProperty("foo", "bar");
|
||||
|
||||
assertThat(environment.getProperty("foo")).isEqualTo("bar");
|
||||
ArgumentCaptor<ApplicationEvent> eventCaptor = ArgumentCaptor.forClass(ApplicationEvent.class);
|
||||
verify(publisher, times(1)).publishEvent(eventCaptor.capture());
|
||||
assertThat(eventCaptor.getValue()).isInstanceOf(EnvironmentChangeEvent.class);
|
||||
EnvironmentChangeEvent event = (EnvironmentChangeEvent) eventCaptor.getValue();
|
||||
assertThat(event.getKeys()).containsExactly("foo");
|
||||
|
||||
reset(publisher);
|
||||
|
||||
environmentManager.reset();
|
||||
assertThat(environment.getProperty("foo")).isNull();
|
||||
verify(publisher, times(1)).publishEvent(eventCaptor.capture());
|
||||
assertThat(eventCaptor.getValue()).isInstanceOf(EnvironmentChangeEvent.class);
|
||||
event = (EnvironmentChangeEvent) eventCaptor.getValue();
|
||||
assertThat(event.getKeys()).containsExactly("foo");
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user