From ec28a40f9065cedd7a30804b798760b8a79b01b6 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Mon, 29 Jul 2019 14:33:48 +0200 Subject: [PATCH 1/2] Added symbolic link of index.adoc --- docs/src/main/asciidoc/index.adoc | 1 + 1 file changed, 1 insertion(+) create mode 120000 docs/src/main/asciidoc/index.adoc diff --git a/docs/src/main/asciidoc/index.adoc b/docs/src/main/asciidoc/index.adoc new file mode 120000 index 000000000..5d677a319 --- /dev/null +++ b/docs/src/main/asciidoc/index.adoc @@ -0,0 +1 @@ +spring-cloud-netflix.adoc \ No newline at end of file From df37357316a19c3c344b68f0c29b3008907c7e5d Mon Sep 17 00:00:00 2001 From: Yuxin Bai Date: Thu, 1 Aug 2019 17:00:48 -0400 Subject: [PATCH 2/2] set replication client filters in RefreshablePeerEurekaNodes (#3610) fixes gh-3554 --- spring-cloud-netflix-eureka-server/pom.xml | 4 + .../server/EurekaServerAutoConfiguration.java | 37 ++++++- .../ReplicationClientAdditionalFilters.java | 39 +++++++ .../RefreshablePeerEurekaNodesTests.java | 3 +- ...PeerEurekaNodesWithCustomFiltersTests.java | 104 ++++++++++++++++++ 5 files changed, 183 insertions(+), 4 deletions(-) create mode 100644 spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/ReplicationClientAdditionalFilters.java create mode 100644 spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/RefreshablePeerEurekaNodesWithCustomFiltersTests.java diff --git a/spring-cloud-netflix-eureka-server/pom.xml b/spring-cloud-netflix-eureka-server/pom.xml index f07080a04..444f03545 100644 --- a/spring-cloud-netflix-eureka-server/pom.xml +++ b/spring-cloud-netflix-eureka-server/pom.xml @@ -61,6 +61,10 @@ com.sun.jersey jersey-server + + com.sun.jersey + jersey-client + com.netflix.eureka eureka-core diff --git a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaServerAutoConfiguration.java b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaServerAutoConfiguration.java index f97d8e580..5d5a3dbfb 100644 --- a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaServerAutoConfiguration.java +++ b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaServerAutoConfiguration.java @@ -36,10 +36,12 @@ import com.netflix.discovery.converters.wrappers.CodecWrappers; import com.netflix.eureka.DefaultEurekaServerContext; import com.netflix.eureka.EurekaServerConfig; import com.netflix.eureka.EurekaServerContext; +import com.netflix.eureka.cluster.PeerEurekaNode; import com.netflix.eureka.cluster.PeerEurekaNodes; import com.netflix.eureka.registry.PeerAwareInstanceRegistry; import com.netflix.eureka.resources.DefaultServerCodecs; import com.netflix.eureka.resources.ServerCodecs; +import com.netflix.eureka.transport.JerseyReplicationClient; import com.sun.jersey.api.core.DefaultResourceConfig; import com.sun.jersey.spi.container.servlet.ServletContainer; @@ -139,6 +141,12 @@ public class EurekaServerAutoConfiguration extends WebMvcConfigurerAdapter { : codec; } + @Bean + @ConditionalOnMissingBean + public ReplicationClientAdditionalFilters replicationClientAdditionalFilters() { + return new ReplicationClientAdditionalFilters(Collections.emptySet()); + } + @Bean public PeerAwareInstanceRegistry peerAwareInstanceRegistry( ServerCodecs serverCodecs) { @@ -152,9 +160,11 @@ public class EurekaServerAutoConfiguration extends WebMvcConfigurerAdapter { @Bean @ConditionalOnMissingBean public PeerEurekaNodes peerEurekaNodes(PeerAwareInstanceRegistry registry, - ServerCodecs serverCodecs) { + ServerCodecs serverCodecs, + ReplicationClientAdditionalFilters replicationClientAdditionalFilters) { return new RefreshablePeerEurekaNodes(registry, this.eurekaServerConfig, - this.eurekaClientConfig, serverCodecs, this.applicationInfoManager); + this.eurekaClientConfig, serverCodecs, this.applicationInfoManager, + replicationClientAdditionalFilters); } @Bean @@ -273,12 +283,33 @@ public class EurekaServerAutoConfiguration extends WebMvcConfigurerAdapter { static class RefreshablePeerEurekaNodes extends PeerEurekaNodes implements ApplicationListener { + private ReplicationClientAdditionalFilters replicationClientAdditionalFilters; + RefreshablePeerEurekaNodes(final PeerAwareInstanceRegistry registry, final EurekaServerConfig serverConfig, final EurekaClientConfig clientConfig, final ServerCodecs serverCodecs, - final ApplicationInfoManager applicationInfoManager) { + final ApplicationInfoManager applicationInfoManager, + final ReplicationClientAdditionalFilters replicationClientAdditionalFilters) { super(registry, serverConfig, clientConfig, serverCodecs, applicationInfoManager); + this.replicationClientAdditionalFilters = replicationClientAdditionalFilters; + } + + @Override + protected PeerEurekaNode createPeerEurekaNode(String peerEurekaNodeUrl) { + JerseyReplicationClient replicationClient = JerseyReplicationClient + .createReplicationClient(serverConfig, serverCodecs, + peerEurekaNodeUrl); + + this.replicationClientAdditionalFilters.getFilters() + .forEach(replicationClient::addReplicationClientFilter); + + String targetHost = hostFromUrl(peerEurekaNodeUrl); + if (targetHost == null) { + targetHost = "host"; + } + return new PeerEurekaNode(registry, targetHost, peerEurekaNodeUrl, + replicationClient, serverConfig); } @Override diff --git a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/ReplicationClientAdditionalFilters.java b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/ReplicationClientAdditionalFilters.java new file mode 100644 index 000000000..e954b27c0 --- /dev/null +++ b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/ReplicationClientAdditionalFilters.java @@ -0,0 +1,39 @@ +/* + * Copyright 2013-2019 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.server; + +import java.util.Collection; +import java.util.LinkedHashSet; + +import com.sun.jersey.api.client.filter.ClientFilter; + +/** + * @author Yuxin Bai + */ +public class ReplicationClientAdditionalFilters { + + private Collection filters; + + public ReplicationClientAdditionalFilters(Collection filters) { + this.filters = new LinkedHashSet<>(filters); + } + + public Collection getFilters() { + return this.filters; + } + +} diff --git a/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/RefreshablePeerEurekaNodesTests.java b/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/RefreshablePeerEurekaNodesTests.java index 058b4aa25..f9c1630b8 100644 --- a/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/RefreshablePeerEurekaNodesTests.java +++ b/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/RefreshablePeerEurekaNodesTests.java @@ -159,7 +159,8 @@ public class RefreshablePeerEurekaNodesTests { ServerCodecs serverCodecs, ApplicationInfoManager applicationInfoManager) { super(registry, serverConfig, clientConfig, serverCodecs, - applicationInfoManager); + applicationInfoManager, + new ReplicationClientAdditionalFilters(Collections.emptySet())); } protected void updatePeerEurekaNodes(List newPeerUrls) { diff --git a/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/RefreshablePeerEurekaNodesWithCustomFiltersTests.java b/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/RefreshablePeerEurekaNodesWithCustomFiltersTests.java new file mode 100644 index 000000000..5ffaea112 --- /dev/null +++ b/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/RefreshablePeerEurekaNodesWithCustomFiltersTests.java @@ -0,0 +1,104 @@ +/* + * Copyright 2013-2019 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.server; + +import java.lang.reflect.Field; +import java.util.Collections; + +import com.netflix.eureka.cluster.PeerEurekaNodes; +import com.sun.jersey.api.client.ClientHandlerException; +import com.sun.jersey.api.client.ClientRequest; +import com.sun.jersey.api.client.ClientResponse; +import com.sun.jersey.api.client.filter.ClientFilter; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.cloud.netflix.eureka.server.EurekaServerAutoConfiguration.RefreshablePeerEurekaNodes; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.util.ReflectionUtils; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Yuxin Bai + */ +@RunWith(SpringRunner.class) +@SpringBootTest( + classes = RefreshablePeerEurekaNodesWithCustomFiltersTests.Application.class, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + value = { "spring.application.name=eureka", "server.contextPath=/context", + "management.security.enabled=false" }) +public class RefreshablePeerEurekaNodesWithCustomFiltersTests { + + @Autowired + private PeerEurekaNodes peerEurekaNodes; + + @Test + public void testCustomPeerNodesShouldTakePrecedenceOverDefault() { + assertThat(peerEurekaNodes instanceof RefreshablePeerEurekaNodes) + .as("PeerEurekaNodes should be an instance of RefreshablePeerEurekaNodes") + .isTrue(); + + ReplicationClientAdditionalFilters filters = getField( + RefreshablePeerEurekaNodes.class, + (RefreshablePeerEurekaNodes) peerEurekaNodes, + "replicationClientAdditionalFilters"); + assertThat(filters.getFilters()).as( + "PeerEurekaNodes'should have only one filter set on replicationClientAdditionalFilters") + .hasSize(1); + assertThat(filters.getFilters().iterator() + .next() instanceof Application.CustomClientFilter).as( + "The type of the filter should be CustomClientFilter as user declared so") + .isTrue(); + } + + private static R getField(Class clazz, T target, String fieldName) { + Field field = ReflectionUtils.findField(clazz, fieldName); + ReflectionUtils.makeAccessible(field); + @SuppressWarnings("unchecked") + R value = (R) ReflectionUtils.getField(field, target); + return value; + } + + @Configuration + @EnableAutoConfiguration + @EnableEurekaServer + protected static class Application { + + @Bean + public ReplicationClientAdditionalFilters customFilters() { + return new ReplicationClientAdditionalFilters( + Collections.singletonList(new CustomClientFilter())); + } + + protected class CustomClientFilter extends ClientFilter { + + @Override + public ClientResponse handle(ClientRequest cr) throws ClientHandlerException { + return getNext().handle(cr); + } + + } + + } + +}