From 2b1e045a55daf8b0a37dd5592b2831873ea5eb27 Mon Sep 17 00:00:00 2001 From: Olga MaciaszekSharma Date: Tue, 23 Jan 2024 18:38:28 +0100 Subject: [PATCH] Publish InstancePreRegisteredEvent. Fixes gh-4237. --- .../EurekaAutoServiceRegistration.java | 40 ++++--- ...toServiceRegistrationIntegrationTests.java | 106 ++++++++++++++++++ 2 files changed, 129 insertions(+), 17 deletions(-) create mode 100644 spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/eureka/serviceregistry/EurekaAutoServiceRegistrationIntegrationTests.java diff --git a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/serviceregistry/EurekaAutoServiceRegistration.java b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/serviceregistry/EurekaAutoServiceRegistration.java index f90c32bae..37a105b2d 100644 --- a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/serviceregistry/EurekaAutoServiceRegistration.java +++ b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/serviceregistry/EurekaAutoServiceRegistration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2022 the original author or authors. + * Copyright 2013-2023 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. @@ -23,6 +23,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.boot.web.context.WebServerInitializedEvent; +import org.springframework.cloud.client.discovery.event.InstancePreRegisteredEvent; import org.springframework.cloud.client.discovery.event.InstanceRegisteredEvent; import org.springframework.cloud.client.serviceregistry.AutoServiceRegistration; import org.springframework.context.ApplicationContext; @@ -33,11 +34,15 @@ import org.springframework.context.event.SmartApplicationListener; import org.springframework.core.Ordered; /** + * Provides an implementation of {@link AutoServiceRegistration} for registering service + * instances in Eureka. + * * @author Dave Syer * @author Spencer Gibb * @author Jon Schneider * @author Jakub Narloch * @author Raiyan Raiyan + * @author Olga Maciaszek-Sharma */ public class EurekaAutoServiceRegistration implements AutoServiceRegistration, SmartLifecycle, Ordered, SmartApplicationListener { @@ -65,37 +70,38 @@ public class EurekaAutoServiceRegistration @Override public void start() { - // only set the port if the nonSecurePort or securePort is 0 and this.port != 0 - if (this.port.get() != 0) { - if (this.registration.getNonSecurePort() == 0) { - this.registration.setNonSecurePort(this.port.get()); + // only set the port if the nonSecurePort or securePort is 0 and port != 0 + if (port.get() != 0) { + if (registration.getNonSecurePort() == 0) { + registration.setNonSecurePort(port.get()); } - if (this.registration.getSecurePort() == 0 && this.registration.isSecure()) { - this.registration.setSecurePort(this.port.get()); + if (registration.getSecurePort() == 0 && registration.isSecure()) { + registration.setSecurePort(port.get()); } } // only initialize if nonSecurePort is greater than 0 and it isn't already running // because of containerPortInitializer below - if (!this.running.get() && this.registration.getNonSecurePort() > 0) { + if (!running.get() && registration.getNonSecurePort() > 0) { + context.publishEvent(new InstancePreRegisteredEvent(this, registration)); - this.serviceRegistry.register(this.registration); + serviceRegistry.register(registration); - this.context.publishEvent(new InstanceRegisteredEvent<>(this, this.registration.getInstanceConfig())); - this.running.set(true); + context.publishEvent(new InstanceRegisteredEvent<>(this, registration.getInstanceConfig())); + running.set(true); } } @Override public void stop() { - this.serviceRegistry.deregister(this.registration); - this.running.set(false); + serviceRegistry.deregister(registration); + running.set(false); } @Override public boolean isRunning() { - return this.running.get(); + return running.get(); } @Override @@ -116,7 +122,7 @@ public class EurekaAutoServiceRegistration @Override public int getOrder() { - return this.order; + return order; } @Override @@ -140,9 +146,9 @@ public class EurekaAutoServiceRegistration String contextName = event.getApplicationContext().getServerNamespace(); if (contextName == null || !contextName.equals("management")) { int localPort = event.getWebServer().getPort(); - if (this.port.get() == 0) { + if (port.get() == 0) { log.info("Updating port to " + localPort); - this.port.compareAndSet(0, localPort); + port.compareAndSet(0, localPort); start(); } } diff --git a/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/eureka/serviceregistry/EurekaAutoServiceRegistrationIntegrationTests.java b/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/eureka/serviceregistry/EurekaAutoServiceRegistrationIntegrationTests.java new file mode 100644 index 000000000..a8d96ce71 --- /dev/null +++ b/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/eureka/serviceregistry/EurekaAutoServiceRegistrationIntegrationTests.java @@ -0,0 +1,106 @@ +/* + * Copyright 2013-2023 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.serviceregistry; + +import org.junit.jupiter.api.Test; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.cloud.client.discovery.event.InstancePreRegisteredEvent; +import org.springframework.cloud.client.discovery.event.InstanceRegisteredEvent; +import org.springframework.cloud.client.serviceregistry.Registration; +import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean; +import org.springframework.context.ApplicationListener; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration tests for {@link EurekaAutoServiceRegistration}. + * + * @author Olga Maciaszek-Sharma + */ +@SpringBootTest(classes = EurekaAutoServiceRegistrationIntegrationTests.Config.class, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +class EurekaAutoServiceRegistrationIntegrationTests { + + @LocalServerPort + private int serverPort; + + @Autowired + private PreEventListener preEventListener; + + @Autowired + private PostEventListener postEventListener; + + @Test + void shouldPublishRegistrationEvents() { + assertThat(preEventListener.wasFired).isTrue(); + assertThat(preEventListener.registration).isInstanceOf(EurekaRegistration.class); + assertThat(preEventListener.registration.getPort()).isEqualTo(serverPort); + assertThat(postEventListener.wasFired).isTrue(); + assertThat(postEventListener.config.getNonSecurePort()).isEqualTo(serverPort); + } + + @EnableAutoConfiguration + @Configuration(proxyBeanMethods = false) + public static class Config { + + @Bean + public PreEventListener preRegisterListener() { + return new PreEventListener(); + } + + @Bean + public PostEventListener postEventListener() { + return new PostEventListener(); + } + + } + + public static class PreEventListener implements ApplicationListener { + + public boolean wasFired = false; + + public Registration registration; + + @Override + public void onApplicationEvent(InstancePreRegisteredEvent event) { + this.registration = event.getRegistration(); + this.wasFired = true; + } + + } + + public static class PostEventListener implements ApplicationListener { + + public boolean wasFired = false; + + public EurekaInstanceConfigBean config; + + @Override + public void onApplicationEvent(InstanceRegisteredEvent event) { + this.config = (EurekaInstanceConfigBean) event.getConfig(); + this.wasFired = true; + } + + } + +}