mirror of
https://github.com/spring-cloud/spring-cloud-netflix.git
synced 2026-09-17 15:49:00 +00:00
Merge branch '2.2.x'
This commit is contained in:
@@ -14,7 +14,7 @@
|
||||
<name>spring-cloud-netflix-dependencies</name>
|
||||
<description>Spring Cloud Netflix Dependencies</description>
|
||||
<properties>
|
||||
<eureka.version>1.9.19</eureka.version>
|
||||
<eureka.version>1.9.21</eureka.version>
|
||||
</properties>
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
|
||||
+1
-1
@@ -1086,7 +1086,7 @@ public class EurekaClientConfigBean implements EurekaClientConfig, Ordered {
|
||||
.append(decoderName).append("', ").append("clientDataAccept='")
|
||||
.append(clientDataAccept).append("', ")
|
||||
.append("shouldUnregisterOnShutdown='").append(shouldUnregisterOnShutdown)
|
||||
.append("', ").append("shouldEnforceRegistrationAtInit='")
|
||||
.append("shouldEnforceRegistrationAtInit='")
|
||||
.append(shouldEnforceRegistrationAtInit).append("', ").append("order='")
|
||||
.append(order).append("'}").toString();
|
||||
}
|
||||
|
||||
+23
-1
@@ -17,13 +17,17 @@
|
||||
package org.springframework.cloud.netflix.eureka.config;
|
||||
|
||||
import com.netflix.discovery.AbstractDiscoveryClientOptionalArgs;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.autoconfigure.condition.SearchStrategy;
|
||||
import org.springframework.cloud.netflix.eureka.MutableDiscoveryClientOptionalArgs;
|
||||
import org.springframework.cloud.netflix.eureka.http.RestTemplateDiscoveryClientOptionalArgs;
|
||||
import org.springframework.cloud.netflix.eureka.http.WebClientDiscoveryClientOptionalArgs;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@@ -33,14 +37,32 @@ import org.springframework.context.annotation.Configuration;
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
public class DiscoveryClientOptionalArgsConfiguration {
|
||||
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingClass("com.sun.jersey.api.client.filter.ClientFilter")
|
||||
@ConditionalOnMissingBean(value = AbstractDiscoveryClientOptionalArgs.class,
|
||||
@ConditionalOnMissingBean(value = { AbstractDiscoveryClientOptionalArgs.class },
|
||||
search = SearchStrategy.CURRENT)
|
||||
@ConditionalOnProperty(prefix = "eureka.client", name = { "webclient.enabled" },
|
||||
matchIfMissing = true, havingValue = "false")
|
||||
public RestTemplateDiscoveryClientOptionalArgs restTemplateDiscoveryClientOptionalArgs() {
|
||||
logger.info("Eureka HTTP Client uses RestTemplate.");
|
||||
return new RestTemplateDiscoveryClientOptionalArgs();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingClass("com.sun.jersey.api.client.filter.ClientFilter")
|
||||
@ConditionalOnMissingBean(
|
||||
value = { AbstractDiscoveryClientOptionalArgs.class,
|
||||
RestTemplateDiscoveryClientOptionalArgs.class },
|
||||
search = SearchStrategy.CURRENT)
|
||||
@ConditionalOnProperty(prefix = "eureka.client", name = { "webclient.enabled" },
|
||||
havingValue = "true")
|
||||
public WebClientDiscoveryClientOptionalArgs webClientDiscoveryClientOptionalArgs() {
|
||||
logger.info("Eureka HTTP Client uses WebClient.");
|
||||
return new WebClientDiscoveryClientOptionalArgs();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnClass(name = "com.sun.jersey.api.client.filter.ClientFilter")
|
||||
@ConditionalOnMissingBean(value = AbstractDiscoveryClientOptionalArgs.class,
|
||||
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2017-2020 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
|
||||
*
|
||||
* https://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.netflix.eureka.http;
|
||||
|
||||
import com.netflix.discovery.AbstractDiscoveryClientOptionalArgs;
|
||||
|
||||
/**
|
||||
* @author Daniel Lavoie
|
||||
* @author Haytham Mohamed
|
||||
*/
|
||||
public class WebClientDiscoveryClientOptionalArgs
|
||||
extends AbstractDiscoveryClientOptionalArgs<Void> {
|
||||
|
||||
public WebClientDiscoveryClientOptionalArgs() {
|
||||
setTransportClientFactories(new WebClientTransportClientFactories());
|
||||
}
|
||||
|
||||
}
|
||||
+236
@@ -0,0 +1,236 @@
|
||||
/*
|
||||
* Copyright 2017-2020 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
|
||||
*
|
||||
* https://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.netflix.eureka.http;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.netflix.appinfo.InstanceInfo;
|
||||
import com.netflix.appinfo.InstanceInfo.InstanceStatus;
|
||||
import com.netflix.discovery.shared.Application;
|
||||
import com.netflix.discovery.shared.Applications;
|
||||
import com.netflix.discovery.shared.transport.EurekaHttpClient;
|
||||
import com.netflix.discovery.shared.transport.EurekaHttpResponse;
|
||||
import com.netflix.discovery.shared.transport.EurekaHttpResponse.EurekaHttpResponseBuilder;
|
||||
import com.netflix.discovery.util.StringUtil;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.reactive.function.BodyInserters;
|
||||
import org.springframework.web.reactive.function.client.ClientResponse;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
|
||||
import static com.netflix.discovery.shared.transport.EurekaHttpResponse.anEurekaHttpResponse;
|
||||
|
||||
/**
|
||||
* @author Daniel Lavoie
|
||||
* @author Haytham Mohamed
|
||||
*/
|
||||
public class WebClientEurekaHttpClient implements EurekaHttpClient {
|
||||
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
private WebClient webClient;
|
||||
|
||||
public WebClientEurekaHttpClient(WebClient webClient) {
|
||||
this.webClient = webClient;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EurekaHttpResponse<Void> register(InstanceInfo info) {
|
||||
return webClient.post().uri("apps/" + info.getAppName(), Void.class)
|
||||
.body(BodyInserters.fromValue(info))
|
||||
.header(HttpHeaders.ACCEPT_ENCODING, "gzip")
|
||||
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
|
||||
.exchange().map(response -> eurekaHttpResponse(response)).block();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EurekaHttpResponse<Void> cancel(String appName, String id) {
|
||||
return webClient.delete().uri("apps/" + appName + '/' + id, Void.class).exchange()
|
||||
.map(response -> eurekaHttpResponse(response)).block();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EurekaHttpResponse<InstanceInfo> sendHeartBeat(String appName, String id,
|
||||
InstanceInfo info, InstanceStatus overriddenStatus) {
|
||||
String urlPath = "apps/" + appName + '/' + id + "?status="
|
||||
+ info.getStatus().toString() + "&lastDirtyTimestamp="
|
||||
+ info.getLastDirtyTimestamp().toString() + (overriddenStatus != null
|
||||
? "&overriddenstatus=" + overriddenStatus.name() : "");
|
||||
|
||||
ClientResponse response = webClient.put().uri(urlPath, InstanceInfo.class)
|
||||
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
|
||||
.header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE).exchange()
|
||||
.block();
|
||||
|
||||
EurekaHttpResponseBuilder<InstanceInfo> builder = anEurekaHttpResponse(
|
||||
statusCodeValueOf(response), InstanceInfo.class)
|
||||
.headers(headersOf(response));
|
||||
|
||||
InstanceInfo entity = response.toEntity(InstanceInfo.class).block().getBody();
|
||||
|
||||
if (entity != null) {
|
||||
builder.entity(entity);
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public EurekaHttpResponse<Void> statusUpdate(String appName, String id,
|
||||
InstanceStatus newStatus, InstanceInfo info) {
|
||||
String urlPath = "apps/" + appName + '/' + id + "/status?value="
|
||||
+ newStatus.name() + "&lastDirtyTimestamp="
|
||||
+ info.getLastDirtyTimestamp().toString();
|
||||
|
||||
return webClient.put().uri(urlPath, Void.class)
|
||||
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
|
||||
.exchange().map(response -> eurekaHttpResponse(response)).block();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EurekaHttpResponse<Void> deleteStatusOverride(String appName, String id,
|
||||
InstanceInfo info) {
|
||||
String urlPath = "apps/" + appName + '/' + id + "/status?lastDirtyTimestamp="
|
||||
+ info.getLastDirtyTimestamp().toString();
|
||||
|
||||
return webClient.delete().uri(urlPath, Void.class)
|
||||
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
|
||||
.exchange().map(response -> eurekaHttpResponse(response)).block();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EurekaHttpResponse<Applications> getApplications(String... regions) {
|
||||
return getApplicationsInternal("apps/", regions);
|
||||
}
|
||||
|
||||
private EurekaHttpResponse<Applications> getApplicationsInternal(String urlPath,
|
||||
String[] regions) {
|
||||
String url = urlPath;
|
||||
|
||||
if (regions != null && regions.length > 0) {
|
||||
url = url + (urlPath.contains("?") ? "&" : "?") + "regions="
|
||||
+ StringUtil.join(regions);
|
||||
}
|
||||
|
||||
ClientResponse response = webClient.get().uri(url, Applications.class)
|
||||
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
|
||||
.header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE).exchange()
|
||||
.block();
|
||||
|
||||
int statusCode = statusCodeValueOf(response);
|
||||
|
||||
Applications body = response.toEntity(Applications.class).block().getBody();
|
||||
|
||||
return anEurekaHttpResponse(statusCode,
|
||||
statusCode == HttpStatus.OK.value() && body != null ? body : null)
|
||||
.headers(headersOf(response)).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EurekaHttpResponse<Applications> getDelta(String... regions) {
|
||||
return getApplicationsInternal("apps/delta", regions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EurekaHttpResponse<Applications> getVip(String vipAddress, String... regions) {
|
||||
return getApplicationsInternal("vips/" + vipAddress, regions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EurekaHttpResponse<Applications> getSecureVip(String secureVipAddress,
|
||||
String... regions) {
|
||||
return getApplicationsInternal("svips/" + secureVipAddress, regions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EurekaHttpResponse<Application> getApplication(String appName) {
|
||||
|
||||
ClientResponse response = webClient.get()
|
||||
.uri("apps/" + appName, Application.class)
|
||||
.header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE).exchange()
|
||||
.block();
|
||||
|
||||
int statusCode = statusCodeValueOf(response);
|
||||
Application body = response.toEntity(Application.class).block().getBody();
|
||||
|
||||
Application application = statusCode == HttpStatus.OK.value() && body != null
|
||||
? body : null;
|
||||
|
||||
return anEurekaHttpResponse(statusCode, application).headers(headersOf(response))
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EurekaHttpResponse<InstanceInfo> getInstance(String appName, String id) {
|
||||
return getInstanceInternal("apps/" + appName + '/' + id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EurekaHttpResponse<InstanceInfo> getInstance(String id) {
|
||||
return getInstanceInternal("instances/" + id);
|
||||
}
|
||||
|
||||
private EurekaHttpResponse<InstanceInfo> getInstanceInternal(String urlPath) {
|
||||
ClientResponse response = webClient.get().uri(urlPath, InstanceInfo.class)
|
||||
.header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE).exchange()
|
||||
.block();
|
||||
|
||||
int statusCode = statusCodeValueOf(response);
|
||||
InstanceInfo body = response.toEntity(InstanceInfo.class).block().getBody();
|
||||
|
||||
return anEurekaHttpResponse(statusCode,
|
||||
statusCode == HttpStatus.OK.value() && body != null ? body : null)
|
||||
.headers(headersOf(response)).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() {
|
||||
// Nothing to do
|
||||
}
|
||||
|
||||
private static Map<String, String> headersOf(ClientResponse response) {
|
||||
ClientResponse.Headers httpHeaders = response.headers();
|
||||
if (httpHeaders == null) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
HttpHeaders asHeaders = httpHeaders.asHttpHeaders();
|
||||
if (asHeaders == null) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
Map<String, String> headers = new HashMap<>();
|
||||
asHeaders.entrySet().stream().forEach(entry -> entry.getValue().stream()
|
||||
.forEach(v -> headers.put(entry.getKey(), v)));
|
||||
return headers;
|
||||
}
|
||||
|
||||
private int statusCodeValueOf(ClientResponse response) {
|
||||
return response.statusCode().value();
|
||||
}
|
||||
|
||||
private EurekaHttpResponse<Void> eurekaHttpResponse(ClientResponse response) {
|
||||
return anEurekaHttpResponse(statusCodeValueOf(response))
|
||||
.headers(headersOf(response)).build();
|
||||
}
|
||||
|
||||
}
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2017-2020 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
|
||||
*
|
||||
* https://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.netflix.eureka.http;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Optional;
|
||||
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
import javax.net.ssl.SSLContext;
|
||||
|
||||
import com.netflix.appinfo.InstanceInfo;
|
||||
import com.netflix.discovery.EurekaClientConfig;
|
||||
import com.netflix.discovery.shared.transport.TransportClientFactory;
|
||||
import com.netflix.discovery.shared.transport.jersey.EurekaJerseyClient;
|
||||
import com.netflix.discovery.shared.transport.jersey.TransportClientFactories;
|
||||
|
||||
/**
|
||||
* @author Daniel Lavoie
|
||||
* @author Haytham Mohamed
|
||||
*/
|
||||
public class WebClientTransportClientFactories implements TransportClientFactories<Void> {
|
||||
|
||||
@Override
|
||||
public TransportClientFactory newTransportClientFactory(
|
||||
Collection<Void> additionalFilters, EurekaJerseyClient providedJerseyClient) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransportClientFactory newTransportClientFactory(
|
||||
EurekaClientConfig clientConfig, Collection<Void> additionalFilters,
|
||||
InstanceInfo myInstanceInfo) {
|
||||
return new WebClientTransportClientFactory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransportClientFactory newTransportClientFactory(
|
||||
final EurekaClientConfig clientConfig,
|
||||
final Collection<Void> additionalFilters, final InstanceInfo myInstanceInfo,
|
||||
final Optional<SSLContext> sslContext,
|
||||
final Optional<HostnameVerifier> hostnameVerifier) {
|
||||
return new WebClientTransportClientFactory();
|
||||
}
|
||||
|
||||
}
|
||||
+196
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* Copyright 2017-2020 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
|
||||
*
|
||||
* https://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.netflix.eureka.http;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
import com.fasterxml.jackson.databind.BeanDescription;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.JsonSerializer;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
|
||||
import com.fasterxml.jackson.databind.SerializationConfig;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||
import com.fasterxml.jackson.databind.ser.BeanSerializerModifier;
|
||||
import com.fasterxml.jackson.databind.ser.std.BeanSerializerBase;
|
||||
import com.netflix.appinfo.InstanceInfo;
|
||||
import com.netflix.discovery.converters.jackson.mixin.ApplicationsJsonMixIn;
|
||||
import com.netflix.discovery.converters.jackson.mixin.InstanceInfoJsonMixIn;
|
||||
import com.netflix.discovery.converters.jackson.serializer.InstanceInfoJsonBeanSerializer;
|
||||
import com.netflix.discovery.shared.Applications;
|
||||
import com.netflix.discovery.shared.resolver.EurekaEndpoint;
|
||||
import com.netflix.discovery.shared.transport.EurekaHttpClient;
|
||||
import com.netflix.discovery.shared.transport.TransportClientFactory;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.codec.json.Jackson2JsonDecoder;
|
||||
import org.springframework.http.codec.json.Jackson2JsonEncoder;
|
||||
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
|
||||
import org.springframework.web.reactive.function.client.ClientResponse;
|
||||
import org.springframework.web.reactive.function.client.ExchangeFilterFunction;
|
||||
import org.springframework.web.reactive.function.client.ExchangeFilterFunctions;
|
||||
import org.springframework.web.reactive.function.client.ExchangeStrategies;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
|
||||
/**
|
||||
* Provides the custom {@link WebClient.Builder} required by the
|
||||
* {@link WebClientEurekaHttpClient}. Relies on Jackson for serialization and
|
||||
* deserialization.
|
||||
*
|
||||
* @author Daniel Lavoie
|
||||
* @author Haytham Mohamed
|
||||
*/
|
||||
public class WebClientTransportClientFactory implements TransportClientFactory {
|
||||
|
||||
@Override
|
||||
public EurekaHttpClient newClient(EurekaEndpoint serviceUrl) {
|
||||
WebClient.Builder builder = of(serviceUrl.getServiceUrl());
|
||||
this.setExchangeStrategies(builder);
|
||||
this.skipHttp400Error(builder);
|
||||
return new WebClientEurekaHttpClient(builder.build());
|
||||
}
|
||||
|
||||
private WebClient.Builder of(String serviceUrl) {
|
||||
String url = serviceUrl;
|
||||
WebClient.Builder builder = WebClient.builder();
|
||||
try {
|
||||
URI serviceURI = new URI(serviceUrl);
|
||||
if (serviceURI.getUserInfo() != null) {
|
||||
String[] credentials = serviceURI.getUserInfo().split(":");
|
||||
if (credentials.length == 2) {
|
||||
builder.filter(ExchangeFilterFunctions
|
||||
.basicAuthentication(credentials[0], credentials[1]));
|
||||
url = serviceUrl.replace(credentials[0] + ":" + credentials[1] + "@",
|
||||
"");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (URISyntaxException ignore) {
|
||||
}
|
||||
return builder.baseUrl(url);
|
||||
}
|
||||
|
||||
private void setExchangeStrategies(WebClient.Builder builder) {
|
||||
ObjectMapper objectMapper = mappingJacksonHttpMessageConverter()
|
||||
.getObjectMapper();
|
||||
ExchangeStrategies strategies = ExchangeStrategies.builder()
|
||||
.codecs(clientDefaultCodecsConfigurer -> {
|
||||
clientDefaultCodecsConfigurer.defaultCodecs()
|
||||
.jackson2JsonEncoder(new Jackson2JsonEncoder(objectMapper,
|
||||
MediaType.APPLICATION_JSON));
|
||||
clientDefaultCodecsConfigurer.defaultCodecs()
|
||||
.jackson2JsonDecoder(new Jackson2JsonDecoder(objectMapper,
|
||||
MediaType.APPLICATION_JSON));
|
||||
|
||||
}).build();
|
||||
builder.exchangeStrategies(strategies);
|
||||
}
|
||||
|
||||
private void skipHttp400Error(WebClient.Builder builder) {
|
||||
builder.filter(Http4xxErrorExchangeFilterFunction());
|
||||
}
|
||||
|
||||
// Skip over 4xx http errors
|
||||
private ExchangeFilterFunction Http4xxErrorExchangeFilterFunction() {
|
||||
return ExchangeFilterFunction.ofResponseProcessor(clientResponse -> {
|
||||
// literally 400 pass the tests, not 4xxClientError
|
||||
if (clientResponse.statusCode().value() == 400) {
|
||||
ClientResponse newResponse = ClientResponse.from(clientResponse)
|
||||
.statusCode(HttpStatus.OK).build();
|
||||
newResponse.body((clientHttpResponse, context) -> {
|
||||
return clientHttpResponse.getBody();
|
||||
});
|
||||
return Mono.just(newResponse);
|
||||
}
|
||||
return Mono.just(clientResponse);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the serialization configurations required by the Eureka Server. JSON
|
||||
* content exchanged with eureka requires a root node matching the entity being
|
||||
* serialized or deserialized. Achieved with
|
||||
* {@link SerializationFeature#WRAP_ROOT_VALUE} and
|
||||
* {@link DeserializationFeature#UNWRAP_ROOT_VALUE}.
|
||||
* {@link PropertyNamingStrategy.SnakeCaseStrategy} is applied to the underlying
|
||||
* {@link ObjectMapper}.
|
||||
* @return a {@link MappingJackson2HttpMessageConverter} object
|
||||
*/
|
||||
public MappingJackson2HttpMessageConverter mappingJacksonHttpMessageConverter() {
|
||||
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
|
||||
converter.setObjectMapper(new ObjectMapper()
|
||||
.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE));
|
||||
|
||||
SimpleModule jsonModule = new SimpleModule();
|
||||
jsonModule.setSerializerModifier(createJsonSerializerModifier()); // keyFormatter,
|
||||
// compact));
|
||||
converter.getObjectMapper().registerModule(jsonModule);
|
||||
|
||||
converter.getObjectMapper().configure(SerializationFeature.WRAP_ROOT_VALUE, true);
|
||||
converter.getObjectMapper().configure(DeserializationFeature.UNWRAP_ROOT_VALUE,
|
||||
true);
|
||||
converter.getObjectMapper().addMixIn(Applications.class,
|
||||
ApplicationsJsonMixIn.class);
|
||||
converter.getObjectMapper().addMixIn(InstanceInfo.class,
|
||||
InstanceInfoJsonMixIn.class);
|
||||
|
||||
// converter.getObjectMapper().addMixIn(DataCenterInfo.class,
|
||||
// DataCenterInfoXmlMixIn.class);
|
||||
// converter.getObjectMapper().addMixIn(InstanceInfo.PortWrapper.class,
|
||||
// PortWrapperXmlMixIn.class);
|
||||
// converter.getObjectMapper().addMixIn(Application.class,
|
||||
// ApplicationXmlMixIn.class);
|
||||
// converter.getObjectMapper().addMixIn(Applications.class,
|
||||
// ApplicationsXmlMixIn.class);
|
||||
|
||||
return converter;
|
||||
}
|
||||
|
||||
public static BeanSerializerModifier createJsonSerializerModifier() { // final
|
||||
// KeyFormatter
|
||||
// keyFormatter,
|
||||
// final
|
||||
// boolean
|
||||
// compactMode)
|
||||
// {
|
||||
return new BeanSerializerModifier() {
|
||||
@Override
|
||||
public JsonSerializer<?> modifySerializer(SerializationConfig config,
|
||||
BeanDescription beanDesc, JsonSerializer<?> serializer) {
|
||||
/*
|
||||
* if (beanDesc.getBeanClass().isAssignableFrom(Applications.class)) {
|
||||
* return new ApplicationsJsonBeanSerializer((BeanSerializerBase)
|
||||
* serializer, keyFormatter); }
|
||||
*/
|
||||
if (beanDesc.getBeanClass().isAssignableFrom(InstanceInfo.class)) {
|
||||
return new InstanceInfoJsonBeanSerializer(
|
||||
(BeanSerializerBase) serializer, false);
|
||||
}
|
||||
return serializer;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() {
|
||||
}
|
||||
|
||||
}
|
||||
+6
@@ -17,6 +17,12 @@
|
||||
"name": "ribbon.eureka.enabled",
|
||||
"description": "Enables the use of Eureka with Ribbon.",
|
||||
"type": "java.lang.Boolean"
|
||||
},
|
||||
{
|
||||
"defaultValue": false,
|
||||
"name": "eureka.client.webclient.enabled",
|
||||
"description": "Enables the use of WebClient for Eureka HTTP Client.",
|
||||
"type": "java.lang.Boolean"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
+45
-3
@@ -24,12 +24,13 @@ import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.cloud.netflix.eureka.http.RestTemplateDiscoveryClientOptionalArgs;
|
||||
import org.springframework.cloud.netflix.eureka.http.WebClientDiscoveryClientOptionalArgs;
|
||||
import org.springframework.cloud.netflix.eureka.sample.EurekaSampleApplication;
|
||||
import org.springframework.cloud.test.ClassPathExclusions;
|
||||
import org.springframework.cloud.test.ModifiedClassPathRunner;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
|
||||
|
||||
/**
|
||||
* @author Daniel Lavoie
|
||||
@@ -38,15 +39,56 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
@ClassPathExclusions({ "jersey-client-*", "jersey-core-*", "jersey-apache-client4-*" })
|
||||
@SpringBootTest(classes = EurekaSampleApplication.class,
|
||||
webEnvironment = WebEnvironment.RANDOM_PORT)
|
||||
public class RestTemplateOptionalArgsConfigurationTest {
|
||||
public class EurekaHttpClientsOptionalArgsConfigurationTest {
|
||||
|
||||
@Test
|
||||
public void contextLoads() {
|
||||
public void contextLoadsWithRestTemplate() {
|
||||
try (ConfigurableApplicationContext context = new SpringApplicationBuilder()
|
||||
.web(WebApplicationType.NONE).sources(EurekaSampleApplication.class)
|
||||
.properties(new String[] { "eureka.client.webclient.enabled=false" })
|
||||
.run()) {
|
||||
assertThat(context.getBean(RestTemplateDiscoveryClientOptionalArgs.class))
|
||||
.isNotNull();
|
||||
try {
|
||||
Object bean = context.getBean(WebClientDiscoveryClientOptionalArgs.class);
|
||||
assertThat(bean).isNull();
|
||||
}
|
||||
catch (Exception ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contextLoadsWithWebClient() {
|
||||
try (ConfigurableApplicationContext context = new SpringApplicationBuilder()
|
||||
.web(WebApplicationType.NONE).sources(EurekaSampleApplication.class)
|
||||
.properties(new String[] { "eureka.client.webclient.enabled=true" })
|
||||
.run()) {
|
||||
assertThat(context.getBean(WebClientDiscoveryClientOptionalArgs.class))
|
||||
.isNotNull();
|
||||
try {
|
||||
Object bean = context
|
||||
.getBean(RestTemplateDiscoveryClientOptionalArgs.class);
|
||||
assertThat(bean).isNull();
|
||||
}
|
||||
catch (Exception ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contextLoadsWithRestTemplateAsDefault() {
|
||||
try (ConfigurableApplicationContext context = new SpringApplicationBuilder()
|
||||
.web(WebApplicationType.NONE).sources(EurekaSampleApplication.class)
|
||||
.run()) {
|
||||
assertThat(context.getBean(RestTemplateDiscoveryClientOptionalArgs.class))
|
||||
.isNotNull();
|
||||
try {
|
||||
Object bean = context.getBean(WebClientDiscoveryClientOptionalArgs.class);
|
||||
assertThat(bean).isNull();
|
||||
}
|
||||
catch (Exception ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright 2012-2020 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
|
||||
*
|
||||
* https://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.netflix.eureka.http;
|
||||
|
||||
import com.netflix.appinfo.InstanceInfo;
|
||||
import com.netflix.discovery.shared.Applications;
|
||||
import com.netflix.discovery.shared.transport.EurekaHttpClient;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Haytham Mohamed
|
||||
**/
|
||||
public abstract class AbstractEurekaHttpClientTest {
|
||||
|
||||
protected EurekaHttpClient eurekaHttpClient;
|
||||
|
||||
protected InstanceInfo info;
|
||||
|
||||
abstract public void setup();
|
||||
|
||||
@Test
|
||||
public void testRegister() {
|
||||
assertThat(eurekaHttpClient.register(info).getStatusCode())
|
||||
.isEqualTo(HttpStatus.OK.value());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCancel() {
|
||||
assertThat(eurekaHttpClient.cancel("test", "test").getStatusCode())
|
||||
.isEqualTo(HttpStatus.OK.value());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendHeartBeat() {
|
||||
assertThat(eurekaHttpClient.sendHeartBeat("test", "test", info, null)
|
||||
.getStatusCode()).isEqualTo(HttpStatus.OK.value());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendHeartBeatFourOFour() {
|
||||
assertThat(eurekaHttpClient.sendHeartBeat("fourOFour", "test", info, null)
|
||||
.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND.value());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStatusUpdate() {
|
||||
assertThat(eurekaHttpClient
|
||||
.statusUpdate("test", "test", InstanceInfo.InstanceStatus.UP, info)
|
||||
.getStatusCode()).isEqualTo(HttpStatus.OK.value());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteStatusOverride() {
|
||||
assertThat(eurekaHttpClient.deleteStatusOverride("test", "test", info)
|
||||
.getStatusCode()).isEqualTo(HttpStatus.OK.value());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetApplications() {
|
||||
Applications entity = eurekaHttpClient.getApplications().getEntity();
|
||||
assertThat(entity).isNotNull();
|
||||
assertThat(eurekaHttpClient.getApplications("us", "eu").getEntity()).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDelta() {
|
||||
eurekaHttpClient.getDelta().getEntity();
|
||||
eurekaHttpClient.getDelta("us", "eu").getEntity();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetVips() {
|
||||
eurekaHttpClient.getVip("test");
|
||||
eurekaHttpClient.getVip("test", "us", "eu");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSecureVip() {
|
||||
eurekaHttpClient.getSecureVip("test");
|
||||
eurekaHttpClient.getSecureVip("test", "us", "eu");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetApplication() {
|
||||
eurekaHttpClient.getApplication("test");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetInstance() {
|
||||
eurekaHttpClient.getInstance("test");
|
||||
eurekaHttpClient.getInstance("test", "test");
|
||||
}
|
||||
|
||||
}
|
||||
+1
-85
@@ -16,14 +16,9 @@
|
||||
|
||||
package org.springframework.cloud.netflix.eureka.http;
|
||||
|
||||
import com.netflix.appinfo.InstanceInfo;
|
||||
import com.netflix.appinfo.InstanceInfo.InstanceStatus;
|
||||
import com.netflix.appinfo.providers.EurekaConfigBasedInstanceInfoProvider;
|
||||
import com.netflix.discovery.shared.Applications;
|
||||
import com.netflix.discovery.shared.resolver.DefaultEndpoint;
|
||||
import com.netflix.discovery.shared.transport.EurekaHttpClient;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -32,12 +27,9 @@ import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.cloud.commons.util.InetUtils;
|
||||
import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Daniel Lavoie
|
||||
*/
|
||||
@@ -46,7 +38,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
properties = { "debug=true", "security.basic.enabled=true" },
|
||||
webEnvironment = WebEnvironment.RANDOM_PORT)
|
||||
@DirtiesContext
|
||||
public class RestTemplateEurekaHttpClientTest {
|
||||
public class RestTemplateEurekaHttpClientTest extends AbstractEurekaHttpClientTest {
|
||||
|
||||
@Autowired
|
||||
private InetUtils inetUtils;
|
||||
@@ -54,10 +46,6 @@ public class RestTemplateEurekaHttpClientTest {
|
||||
@Value("http://${security.user.name}:${security.user.password}@localhost:${local.server.port}")
|
||||
private String serviceUrl;
|
||||
|
||||
private EurekaHttpClient eurekaHttpClient;
|
||||
|
||||
private InstanceInfo info;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
eurekaHttpClient = new RestTemplateTransportClientFactory()
|
||||
@@ -78,76 +66,4 @@ public class RestTemplateEurekaHttpClientTest {
|
||||
info = new EurekaConfigBasedInstanceInfoProvider(config).get();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRegister() {
|
||||
assertThat(eurekaHttpClient.register(info).getStatusCode())
|
||||
.isEqualTo(HttpStatus.OK.value());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCancel() {
|
||||
assertThat(eurekaHttpClient.cancel("test", "test").getStatusCode())
|
||||
.isEqualTo(HttpStatus.OK.value());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendHeartBeat() {
|
||||
assertThat(eurekaHttpClient.sendHeartBeat("test", "test", info, null)
|
||||
.getStatusCode()).isEqualTo(HttpStatus.OK.value());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendHeartBeatFourOFour() {
|
||||
assertThat(eurekaHttpClient.sendHeartBeat("fourOFour", "test", info, null)
|
||||
.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND.value());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStatusUpdate() {
|
||||
assertThat(eurekaHttpClient.statusUpdate("test", "test", InstanceStatus.UP, info)
|
||||
.getStatusCode()).isEqualTo(HttpStatus.OK.value());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteStatusOverride() {
|
||||
assertThat(eurekaHttpClient.deleteStatusOverride("test", "test", info)
|
||||
.getStatusCode()).isEqualTo(HttpStatus.OK.value());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetApplications() {
|
||||
Applications entity = eurekaHttpClient.getApplications().getEntity();
|
||||
assertThat(entity).isNotNull();
|
||||
assertThat(eurekaHttpClient.getApplications("us", "eu").getEntity()).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDelta() {
|
||||
eurekaHttpClient.getDelta().getEntity();
|
||||
eurekaHttpClient.getDelta("us", "eu").getEntity();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetVips() {
|
||||
eurekaHttpClient.getVip("test");
|
||||
eurekaHttpClient.getVip("test", "us", "eu");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSecureVip() {
|
||||
eurekaHttpClient.getSecureVip("test");
|
||||
eurekaHttpClient.getSecureVip("test", "us", "eu");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetApplication() {
|
||||
eurekaHttpClient.getApplication("test");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetInstance() {
|
||||
eurekaHttpClient.getInstance("test");
|
||||
eurekaHttpClient.getInstance("test", "test");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2017-2020 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
|
||||
*
|
||||
* https://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.netflix.eureka.http;
|
||||
|
||||
import com.netflix.appinfo.providers.EurekaConfigBasedInstanceInfoProvider;
|
||||
import com.netflix.discovery.shared.resolver.DefaultEndpoint;
|
||||
import org.junit.Before;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.cloud.commons.util.InetUtils;
|
||||
import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* @author Daniel Lavoie
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringBootTest(classes = EurekaServerMockApplication.class,
|
||||
properties = { "debug=true", "security.basic.enabled=true",
|
||||
"eureka.client.webclient.enabled=true" },
|
||||
webEnvironment = WebEnvironment.RANDOM_PORT)
|
||||
@DirtiesContext
|
||||
public class WebClientEurekaHttpClientTest extends AbstractEurekaHttpClientTest {
|
||||
|
||||
@Autowired
|
||||
private InetUtils inetUtils;
|
||||
|
||||
@Value("http://${security.user.name}:${security.user.password}@localhost:${local.server.port}")
|
||||
private String serviceUrl;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
eurekaHttpClient = new WebClientTransportClientFactory()
|
||||
.newClient(new DefaultEndpoint(serviceUrl));
|
||||
|
||||
EurekaInstanceConfigBean config = new EurekaInstanceConfigBean(inetUtils);
|
||||
|
||||
String appname = "customapp";
|
||||
config.setIpAddress("127.0.0.1");
|
||||
config.setHostname("localhost");
|
||||
config.setAppname(appname);
|
||||
config.setVirtualHostName(appname);
|
||||
config.setSecureVirtualHostName(appname);
|
||||
config.setNonSecurePort(4444);
|
||||
config.setSecurePort(8443);
|
||||
config.setInstanceId("127.0.0.1:customapp:4444");
|
||||
|
||||
info = new EurekaConfigBasedInstanceInfoProvider(config).get();
|
||||
}
|
||||
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2017-2020 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
|
||||
*
|
||||
* https://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.netflix.eureka.http;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @author Daniel Lavoie
|
||||
*/
|
||||
public class WebClientTransportClientFactoriesTest {
|
||||
|
||||
@Test(expected = UnsupportedOperationException.class)
|
||||
public void testJerseyIsUnsuported() {
|
||||
new WebClientTransportClientFactories().newTransportClientFactory(null, null);
|
||||
}
|
||||
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2017-2020 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
|
||||
*
|
||||
* https://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.netflix.eureka.http;
|
||||
|
||||
import com.netflix.discovery.shared.resolver.DefaultEndpoint;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @author Daniel Lavoie
|
||||
*/
|
||||
public class WebClientTransportClientFactoryTest {
|
||||
|
||||
private WebClientTransportClientFactory transportClientFatory;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
transportClientFatory = new WebClientTransportClientFactory();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithoutUserInfo() {
|
||||
transportClientFatory.newClient(new DefaultEndpoint("http://localhost:8761"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvalidUserInfo() {
|
||||
transportClientFatory
|
||||
.newClient(new DefaultEndpoint("http://test@localhost:8761"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUserInfo() {
|
||||
transportClientFatory
|
||||
.newClient(new DefaultEndpoint("http://test:test@localhost:8761"));
|
||||
}
|
||||
|
||||
@After
|
||||
public void shutdown() {
|
||||
transportClientFatory.shutdown();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user