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 dfcdb7491..383c2769e 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 @@ -21,7 +21,6 @@ import java.net.InetAddress; import java.net.MalformedURLException; import java.net.URL; import java.net.UnknownHostException; -import java.security.GeneralSecurityException; import java.util.Collection; import java.util.Collections; import java.util.HashSet; @@ -31,18 +30,14 @@ import java.util.concurrent.Executors; import java.util.regex.Pattern; import com.netflix.appinfo.ApplicationInfoManager; -import com.netflix.discovery.AbstractDiscoveryClientOptionalArgs; import com.netflix.discovery.EurekaClient; import com.netflix.discovery.EurekaClientConfig; -import com.netflix.discovery.Jersey3DiscoveryClientOptionalArgs; import com.netflix.discovery.converters.EurekaJacksonCodec; import com.netflix.discovery.converters.wrappers.CodecWrapper; import com.netflix.discovery.converters.wrappers.CodecWrappers; -import com.netflix.discovery.shared.transport.jersey.TransportClientFactories; import com.netflix.discovery.shared.transport.jersey3.EurekaIdentityHeaderFilter; import com.netflix.discovery.shared.transport.jersey3.EurekaJersey3Client; import com.netflix.discovery.shared.transport.jersey3.EurekaJersey3ClientImpl; -import com.netflix.discovery.shared.transport.jersey3.Jersey3TransportClientFactories; import com.netflix.eureka.DefaultEurekaServerContext; import com.netflix.eureka.EurekaServerConfig; import com.netflix.eureka.EurekaServerContext; @@ -54,7 +49,6 @@ import com.netflix.eureka.resources.DefaultServerCodecs; import com.netflix.eureka.resources.ServerCodecs; import com.netflix.eureka.transport.EurekaServerHttpClientFactory; import com.netflix.eureka.transport.Jersey3DynamicGZIPContentEncodingFilter; -import com.netflix.eureka.transport.Jersey3EurekaServerHttpClientFactory; import com.netflix.eureka.transport.Jersey3ReplicationClient; import jakarta.servlet.Filter; import jakarta.servlet.FilterChain; @@ -89,8 +83,6 @@ import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.cloud.client.actuator.HasFeatures; -import org.springframework.cloud.configuration.SSLContextFactory; -import org.springframework.cloud.configuration.TlsProperties; import org.springframework.cloud.context.environment.EnvironmentChangeEvent; import org.springframework.cloud.netflix.eureka.EurekaConstants; import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean; @@ -194,31 +186,6 @@ public class EurekaServerAutoConfiguration implements WebMvcConfigurer { return new ReplicationClientAdditionalFilters(Collections.emptySet()); } - @Bean - @ConditionalOnMissingBean(TransportClientFactories.class) - public Jersey3TransportClientFactories jersey3TransportClientFactories() { - return Jersey3TransportClientFactories.getInstance(); - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - @Bean - @ConditionalOnMissingBean(EurekaServerHttpClientFactory.class) - public Jersey3EurekaServerHttpClientFactory jersey3EurekaServerHttpClientFactory() { - return new Jersey3EurekaServerHttpClientFactory(); - } - - @Bean - @ConditionalOnMissingBean(AbstractDiscoveryClientOptionalArgs.class) - public Jersey3DiscoveryClientOptionalArgs jersey3DiscoveryClientOptionalArgs( - @Autowired(required = false) TlsProperties tlsProperties) throws GeneralSecurityException, IOException { - Jersey3DiscoveryClientOptionalArgs optionalArgs = new Jersey3DiscoveryClientOptionalArgs(); - if (tlsProperties != null && tlsProperties.isEnabled()) { - SSLContextFactory factory = new SSLContextFactory(tlsProperties); - optionalArgs.setSSLContext(factory.createSSLContext()); - } - return optionalArgs; - } - @Bean public PeerAwareInstanceRegistry peerAwareInstanceRegistry(ServerCodecs serverCodecs, EurekaServerHttpClientFactory eurekaServerHttpClientFactory, diff --git a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaServerJerseyClientAutoConfiguration.java b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaServerJerseyClientAutoConfiguration.java new file mode 100644 index 000000000..35c93b273 --- /dev/null +++ b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaServerJerseyClientAutoConfiguration.java @@ -0,0 +1,68 @@ +/* + * Copyright 2013-2025 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.io.IOException; +import java.security.GeneralSecurityException; + +import com.netflix.discovery.AbstractDiscoveryClientOptionalArgs; +import com.netflix.discovery.Jersey3DiscoveryClientOptionalArgs; +import com.netflix.discovery.shared.transport.jersey.TransportClientFactories; +import com.netflix.discovery.shared.transport.jersey3.Jersey3TransportClientFactories; +import com.netflix.eureka.transport.EurekaServerHttpClientFactory; +import com.netflix.eureka.transport.Jersey3EurekaServerHttpClientFactory; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.cloud.configuration.SSLContextFactory; +import org.springframework.cloud.configuration.TlsProperties; +import org.springframework.context.annotation.Bean; + +/** + * @author Olga Maciaszek-Sharma + */ +@AutoConfiguration +@ConditionalOnBean(EurekaServerMarkerConfiguration.Marker.class) +public class EurekaServerJerseyClientAutoConfiguration { + + @Bean + @ConditionalOnMissingBean(AbstractDiscoveryClientOptionalArgs.class) + public Jersey3DiscoveryClientOptionalArgs jersey3DiscoveryClientOptionalArgs( + @Autowired(required = false) TlsProperties tlsProperties) throws GeneralSecurityException, IOException { + Jersey3DiscoveryClientOptionalArgs optionalArgs = new Jersey3DiscoveryClientOptionalArgs(); + if (tlsProperties != null && tlsProperties.isEnabled()) { + SSLContextFactory factory = new SSLContextFactory(tlsProperties); + optionalArgs.setSSLContext(factory.createSSLContext()); + } + return optionalArgs; + } + + @Bean + @ConditionalOnMissingBean(TransportClientFactories.class) + public Jersey3TransportClientFactories jersey3TransportClientFactories() { + return Jersey3TransportClientFactories.getInstance(); + } + + @Bean + @ConditionalOnMissingBean(EurekaServerHttpClientFactory.class) + public Jersey3EurekaServerHttpClientFactory jersey3EurekaServerHttpClientFactory() { + return new Jersey3EurekaServerHttpClientFactory(); + } + +} diff --git a/spring-cloud-netflix-eureka-server/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-cloud-netflix-eureka-server/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index ac59ffdca..07f014ce6 100644 --- a/spring-cloud-netflix-eureka-server/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/spring-cloud-netflix-eureka-server/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -1,2 +1,3 @@ org.springframework.cloud.netflix.eureka.server.EurekaServerAutoConfiguration +org.springframework.cloud.netflix.eureka.server.EurekaServerJerseyClientAutoConfiguration org.springframework.cloud.netflix.eureka.server.metrics.EurekaInstanceMetricsAutoConfiguration diff --git a/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/EurekaServerRefreshDisabledTests.java b/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/EurekaServerRefreshDisabledTests.java new file mode 100644 index 000000000..fb170ca49 --- /dev/null +++ b/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/EurekaServerRefreshDisabledTests.java @@ -0,0 +1,63 @@ +/* + * Copyright 2013-2025 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.Map; + +import org.junit.jupiter.api.Test; + +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; + +/** + * Verifies the behaviour of Eureka server with peer registration enabled and refresh + * disabled. + * + * @author Olga Maciaszek-Sharma + */ +@SpringBootTest(classes = EurekaServerRefreshDisabledTests.Application.class, webEnvironment = RANDOM_PORT, + properties = { "management.endpoints.web.exposure.include=*", "spring.cloud.refresh.enabled=false" }) +public class EurekaServerRefreshDisabledTests { + + @LocalServerPort + private int port = 0; + + // verifies GH-4407 + @SuppressWarnings("rawtypes") + @Test + void appCatalogLoads() { + ResponseEntity entity = new TestRestTemplate() + .getForEntity("http://localhost:" + this.port + "/eureka/apps", Map.class); + assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); + } + + @Configuration(proxyBeanMethods = false) + @EnableAutoConfiguration + @EnableEurekaServer + protected static class Application { + + } + +}