From dd97b6a4b71fc2612feeb07fabd7872b6d91d50b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20S=C5=82ota?= Date: Fri, 7 Oct 2016 00:11:24 +0200 Subject: [PATCH 1/4] #1376 Register and cancel event sending fix --- .../eureka/server/InstanceRegistry.java | 66 ++++++++++++++----- 1 file changed, 50 insertions(+), 16 deletions(-) diff --git a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistry.java b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistry.java index 05c5676f..fe2090f6 100644 --- a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistry.java +++ b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistry.java @@ -18,6 +18,7 @@ package org.springframework.cloud.netflix.eureka.server; import java.util.List; +import com.netflix.eureka.lease.Lease; import org.springframework.beans.BeansException; import org.springframework.cloud.netflix.eureka.server.event.EurekaInstanceCanceledEvent; import org.springframework.cloud.netflix.eureka.server.event.EurekaInstanceRegisteredEvent; @@ -78,27 +79,23 @@ public class InstanceRegistry extends PeerAwareInstanceRegistryImpl @Override public void register(InstanceInfo info, int leaseDuration, boolean isReplication) { - if (log.isDebugEnabled()) { - log.debug("register " + info.getAppName() + ", vip " + info.getVIPAddress() - + ", leaseDuration " + leaseDuration + ", isReplication " - + isReplication); - } - // TODO: what to publish from info (whole object?) - this.ctxt.publishEvent(new EurekaInstanceRegisteredEvent(this, info, - leaseDuration, isReplication)); - + logRegistration(info, isReplication, leaseDuration); + publishEurekaInstanceRegisteredEvent(info, leaseDuration, isReplication); super.register(info, leaseDuration, isReplication); } @Override - public boolean cancel(String appName, String serverId, boolean isReplication) { - if (log.isDebugEnabled()) { - log.debug("cancel " + appName + " serverId " + serverId + ", isReplication {}" - + isReplication); - } - this.ctxt.publishEvent( - new EurekaInstanceCanceledEvent(this, appName, serverId, isReplication)); + public void register(final InstanceInfo info, final boolean isReplication) { + final int instanceLeaseDuration = resolveInstanceLeaseDuration(info); + logRegistration(info, isReplication, instanceLeaseDuration); + publishEurekaInstanceRegisteredEvent(info, instanceLeaseDuration, isReplication); + super.register(info, isReplication); + } + @Override + public boolean cancel(String appName, String serverId, boolean isReplication) { + logCancelation(appName, serverId, isReplication); + publishEurekaInstanceCanceledEvent(appName, serverId, isReplication); return super.cancel(appName, serverId, isReplication); } @@ -126,4 +123,41 @@ public class InstanceRegistry extends PeerAwareInstanceRegistryImpl } return super.renew(appName, serverId, isReplication); } + + @Override + protected boolean internalCancel(String appName, String id, boolean isReplication) { + logCancelation(appName, id, isReplication); + publishEurekaInstanceCanceledEvent(appName, id, isReplication); + return super.internalCancel(appName, id, isReplication); + } + + private void logRegistration(InstanceInfo info, boolean isReplication, int instanceLeaseDuration) { + if (log.isDebugEnabled()) { + log.debug("register " + info.getAppName() + ", vip " + info.getVIPAddress() + + ", leaseDuration " + instanceLeaseDuration + ", isReplication " + isReplication); + } + } + + private void logCancelation(String appName, String serverId, boolean isReplication) { + if (log.isDebugEnabled()) { + log.debug("cancel " + appName + " serverId " + serverId + ", isReplication " + isReplication); + } + } + + private void publishEurekaInstanceRegisteredEvent(InstanceInfo info, int leaseDuration, boolean isReplication) { + // TODO: what to publish from info (whole object?) + this.ctxt.publishEvent(new EurekaInstanceRegisteredEvent(this, info, leaseDuration, isReplication)); + } + + private void publishEurekaInstanceCanceledEvent(String appName, String serverId, boolean isReplication) { + this.ctxt.publishEvent(new EurekaInstanceCanceledEvent(this, appName, serverId, isReplication)); + } + + private int resolveInstanceLeaseDuration(final InstanceInfo info) { + int leaseDuration = Lease.DEFAULT_DURATION_IN_SECS; + if (info.getLeaseInfo() != null && info.getLeaseInfo().getDurationInSecs() > 0) { + leaseDuration = info.getLeaseInfo().getDurationInSecs(); + } + return leaseDuration; + } } From 151e021ef970c5c01c0efe056736a9e5e593558d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20S=C5=82ota?= Date: Sat, 8 Oct 2016 00:15:47 +0200 Subject: [PATCH 2/4] formatting fixed + tests, fixes #1376 --- .../eureka/server/InstanceRegistry.java | 34 +++- .../eureka/server/InstanceRegistryTest.java | 179 ++++++++++++++++++ 2 files changed, 204 insertions(+), 9 deletions(-) create mode 100644 spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistryTest.java diff --git a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistry.java b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistry.java index fe2090f6..7ff9de68 100644 --- a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistry.java +++ b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistry.java @@ -89,7 +89,7 @@ public class InstanceRegistry extends PeerAwareInstanceRegistryImpl final int instanceLeaseDuration = resolveInstanceLeaseDuration(info); logRegistration(info, isReplication, instanceLeaseDuration); publishEurekaInstanceRegisteredEvent(info, instanceLeaseDuration, isReplication); - super.register(info, isReplication); + superRegister(info, isReplication); } @Override @@ -128,29 +128,45 @@ public class InstanceRegistry extends PeerAwareInstanceRegistryImpl protected boolean internalCancel(String appName, String id, boolean isReplication) { logCancelation(appName, id, isReplication); publishEurekaInstanceCanceledEvent(appName, id, isReplication); + return superInternalCancel(appName, id, isReplication); + } + + protected boolean superInternalCancel(String appName, String id, + boolean isReplication) { return super.internalCancel(appName, id, isReplication); } - private void logRegistration(InstanceInfo info, boolean isReplication, int instanceLeaseDuration) { + protected void superRegister(InstanceInfo info, boolean isReplication) { + super.register(info, isReplication); + } + + private void logRegistration(InstanceInfo info, boolean isReplication, + int instanceLeaseDuration) { if (log.isDebugEnabled()) { - log.debug("register " + info.getAppName() + ", vip " + info.getVIPAddress() - + ", leaseDuration " + instanceLeaseDuration + ", isReplication " + isReplication); + log.debug("register " + info.getAppName() + ", vip " + info.getVIPAddress() + + ", leaseDuration " + instanceLeaseDuration + ", isReplication " + + isReplication); } } private void logCancelation(String appName, String serverId, boolean isReplication) { if (log.isDebugEnabled()) { - log.debug("cancel " + appName + " serverId " + serverId + ", isReplication " + isReplication); + log.debug("cancel " + appName + " serverId " + serverId + ", isReplication " + + isReplication); } } - private void publishEurekaInstanceRegisteredEvent(InstanceInfo info, int leaseDuration, boolean isReplication) { + private void publishEurekaInstanceRegisteredEvent(InstanceInfo info, + int leaseDuration, boolean isReplication) { // TODO: what to publish from info (whole object?) - this.ctxt.publishEvent(new EurekaInstanceRegisteredEvent(this, info, leaseDuration, isReplication)); + this.ctxt.publishEvent(new EurekaInstanceRegisteredEvent(this, info, + leaseDuration, isReplication)); } - private void publishEurekaInstanceCanceledEvent(String appName, String serverId, boolean isReplication) { - this.ctxt.publishEvent(new EurekaInstanceCanceledEvent(this, appName, serverId, isReplication)); + private void publishEurekaInstanceCanceledEvent(String appName, String serverId, + boolean isReplication) { + this.ctxt.publishEvent( + new EurekaInstanceCanceledEvent(this, appName, serverId, isReplication)); } private int resolveInstanceLeaseDuration(final InstanceInfo info) { diff --git a/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistryTest.java b/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistryTest.java new file mode 100644 index 00000000..4c32ce34 --- /dev/null +++ b/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistryTest.java @@ -0,0 +1,179 @@ +package org.springframework.cloud.netflix.eureka.server; + +import static org.junit.Assert.*; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyBoolean; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.*; + +import java.util.LinkedList; +import java.util.List; + +import org.junit.Before; +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.builder.SpringApplicationBuilder; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.cloud.netflix.eureka.server.InstanceRegistryTest.Application; +import org.springframework.cloud.netflix.eureka.server.event.EurekaInstanceCanceledEvent; +import org.springframework.cloud.netflix.eureka.server.event.EurekaInstanceRegisteredEvent; +import org.springframework.context.ApplicationEvent; +import org.springframework.context.ApplicationListener; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.netflix.appinfo.InstanceInfo; +import com.netflix.appinfo.LeaseInfo; +import com.netflix.eureka.registry.PeerAwareInstanceRegistry; + +/** + * @author Bartlomiej Slota + */ +@RunWith(SpringJUnit4ClassRunner.class) +@SpringBootTest(classes = Application.class, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + value = {"spring.application.name=eureka", "logging.level.org.springframework." + + "cloud.netflix.eureka.server.InstanceRegistry=DEBUG"}) +public class InstanceRegistryTest { + + @SpyBean(PeerAwareInstanceRegistry.class) + private InstanceRegistry instanceRegistry; + + @Autowired + private Listener eurekaEventListener; + + @Before + public void setup() { + eurekaEventListener.getApplicationEvents().clear(); + } + + @Test + public void testRegister() throws Exception { + // stubbing superclass method invocation + doNothing().when(instanceRegistry) + .superRegister(any(InstanceInfo.class), anyBoolean()); + + // creating instance info + LeaseInfo leaseInfo = getLeaseInfo(); + InstanceInfo instanceInfo = getInstanceInfo(leaseInfo); + + // calling tested method + instanceRegistry.register(instanceInfo, false); + + // event of proper type is registered + assertEquals(1, eurekaEventListener.getApplicationEvents().size()); + assertTrue(eurekaEventListener.getApplicationEvents().get(0) + instanceof EurekaInstanceRegisteredEvent); + + // event details are correct + EurekaInstanceRegisteredEvent registeredEvent = (EurekaInstanceRegisteredEvent) + (eurekaEventListener.getApplicationEvents().get(0)); + assertEquals(instanceInfo, registeredEvent.getInstanceInfo()); + assertEquals(leaseInfo.getDurationInSecs(), registeredEvent.getLeaseDuration()); + assertEquals(instanceRegistry, registeredEvent.getSource()); + assertFalse(registeredEvent.isReplication()); + + // superclass method wrapper was successfully invoked + verify(instanceRegistry).superRegister(instanceInfo, false); + } + + @Test + public void testDefaultLeaseDurationRegisterEvent() throws Exception { + // stubbing superclass method invocation + doNothing().when(instanceRegistry) + .superRegister(any(InstanceInfo.class), anyBoolean()); + + // creating instance info + InstanceInfo instanceInfo = getInstanceInfo(null); + + // calling tested method + instanceRegistry.register(instanceInfo, false); + + // instance info duration is set to default + EurekaInstanceRegisteredEvent registeredEvent = (EurekaInstanceRegisteredEvent) + (eurekaEventListener.getApplicationEvents().get(0)); + assertEquals(LeaseInfo.DEFAULT_LEASE_DURATION, registeredEvent.getLeaseDuration()); + } + + @Test + public void testInternalCancel() throws Exception { + // stubbing superclass method invocation + doReturn(Boolean.TRUE).when(instanceRegistry) + .superInternalCancel(anyString(), anyString(), anyBoolean()); + + // calling tested method + boolean cancellationResult = instanceRegistry + .internalCancel("my-app", "appId", false); + + // event of proper type is registered + assertEquals(1, eurekaEventListener.getApplicationEvents().size()); + assertTrue(eurekaEventListener.getApplicationEvents().get(0) + instanceof EurekaInstanceCanceledEvent); + + // event details are correct + EurekaInstanceCanceledEvent registeredEvent = (EurekaInstanceCanceledEvent) + (eurekaEventListener.getApplicationEvents().get(0)); + assertEquals("my-app", registeredEvent.getAppName()); + assertEquals("appId", registeredEvent.getServerId()); + assertEquals(instanceRegistry, registeredEvent.getSource()); + assertFalse(registeredEvent.isReplication()); + + // superclass method wrapper was successfully invoked + verify(instanceRegistry).superInternalCancel("my-app", "appId", false); + assertTrue(cancellationResult); + } + + @Configuration + @EnableAutoConfiguration + @EnableEurekaServer + protected static class Application { + + public static void main(String[] args) { + new SpringApplicationBuilder(Application.class) + .properties("spring.application.name=eureka").run(args); + } + + @Bean + public Listener eurekaEventsListener() { + return new Listener(); + } + } + + private LeaseInfo getLeaseInfo() { + LeaseInfo.Builder leaseBuilder = LeaseInfo.Builder.newBuilder(); + leaseBuilder.setRenewalIntervalInSecs(10); + leaseBuilder.setDurationInSecs(15); + return leaseBuilder.build(); + } + + + private InstanceInfo getInstanceInfo(LeaseInfo leaseInfo) { + InstanceInfo.Builder builder = InstanceInfo.Builder.newBuilder(); + builder.setAppName("my-app-name"); + builder.setHostName("my-host-name"); + builder.setPort(8008); + builder.setLeaseInfo(leaseInfo); + return builder.build(); + } + + private static class Listener implements ApplicationListener { + + private final List applicationEvents = new LinkedList<>(); + + @Override + public void onApplicationEvent(ApplicationEvent event) { + if (event instanceof EurekaInstanceCanceledEvent || + event instanceof EurekaInstanceRegisteredEvent) { + applicationEvents.add(event); + } + } + + public List getApplicationEvents() { + return applicationEvents; + } + } +} \ No newline at end of file From 279edf0665e4646e8ea633b5468f27f5fb7d097d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20S=C5=82ota?= Date: Mon, 10 Oct 2016 22:54:39 +0200 Subject: [PATCH 3/4] super class method wrappers removal and test update #1376 --- .../eureka/server/InstanceRegistry.java | 11 +- .../eureka/server/InstanceRegistryTest.java | 231 ++++++++---------- 2 files changed, 101 insertions(+), 141 deletions(-) diff --git a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistry.java b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistry.java index 7ff9de68..69fe52ba 100644 --- a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistry.java +++ b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistry.java @@ -89,7 +89,7 @@ public class InstanceRegistry extends PeerAwareInstanceRegistryImpl final int instanceLeaseDuration = resolveInstanceLeaseDuration(info); logRegistration(info, isReplication, instanceLeaseDuration); publishEurekaInstanceRegisteredEvent(info, instanceLeaseDuration, isReplication); - superRegister(info, isReplication); + super.register(info, isReplication); } @Override @@ -128,18 +128,9 @@ public class InstanceRegistry extends PeerAwareInstanceRegistryImpl protected boolean internalCancel(String appName, String id, boolean isReplication) { logCancelation(appName, id, isReplication); publishEurekaInstanceCanceledEvent(appName, id, isReplication); - return superInternalCancel(appName, id, isReplication); - } - - protected boolean superInternalCancel(String appName, String id, - boolean isReplication) { return super.internalCancel(appName, id, isReplication); } - protected void superRegister(InstanceInfo info, boolean isReplication) { - super.register(info, isReplication); - } - private void logRegistration(InstanceInfo info, boolean isReplication, int instanceLeaseDuration) { if (log.isDebugEnabled()) { diff --git a/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistryTest.java b/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistryTest.java index 4c32ce34..fa740240 100644 --- a/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistryTest.java +++ b/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistryTest.java @@ -1,10 +1,8 @@ package org.springframework.cloud.netflix.eureka.server; import static org.junit.Assert.*; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyBoolean; -import static org.mockito.Matchers.anyString; -import static org.mockito.Mockito.*; +import static org.mockito.Matchers.isA; +import static org.mockito.Mockito.doAnswer; import java.util.LinkedList; import java.util.List; @@ -12,17 +10,18 @@ import java.util.List; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.boot.test.mock.mockito.SpyBean; import org.springframework.cloud.netflix.eureka.server.InstanceRegistryTest.Application; import org.springframework.cloud.netflix.eureka.server.event.EurekaInstanceCanceledEvent; import org.springframework.cloud.netflix.eureka.server.event.EurekaInstanceRegisteredEvent; import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationListener; -import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @@ -40,140 +39,110 @@ import com.netflix.eureka.registry.PeerAwareInstanceRegistry; + "cloud.netflix.eureka.server.InstanceRegistry=DEBUG"}) public class InstanceRegistryTest { - @SpyBean(PeerAwareInstanceRegistry.class) - private InstanceRegistry instanceRegistry; + private final List applicationEvents = new LinkedList<>(); - @Autowired - private Listener eurekaEventListener; + @SpyBean(PeerAwareInstanceRegistry.class) + private InstanceRegistry instanceRegistry; - @Before - public void setup() { - eurekaEventListener.getApplicationEvents().clear(); - } + @MockBean + private ApplicationListener + instanceRegisteredEventListenerMock; - @Test - public void testRegister() throws Exception { - // stubbing superclass method invocation - doNothing().when(instanceRegistry) - .superRegister(any(InstanceInfo.class), anyBoolean()); + @MockBean + private ApplicationListener + instanceCanceledEventListenerMock; - // creating instance info - LeaseInfo leaseInfo = getLeaseInfo(); - InstanceInfo instanceInfo = getInstanceInfo(leaseInfo); + @Before + public void setup() { + applicationEvents.clear(); + Answer applicationListenerAnswer = prepareListenerMockAnswer(); + doAnswer(applicationListenerAnswer).when(instanceRegisteredEventListenerMock) + .onApplicationEvent(isA(EurekaInstanceRegisteredEvent.class)); + doAnswer(applicationListenerAnswer).when(instanceCanceledEventListenerMock) + .onApplicationEvent(isA(EurekaInstanceCanceledEvent.class)); + } + - // calling tested method - instanceRegistry.register(instanceInfo, false); + @Test + public void testRegister() throws Exception { + // creating instance info + LeaseInfo leaseInfo = getLeaseInfo(); + InstanceInfo instanceInfo = getInstanceInfo(leaseInfo); + // calling tested method + instanceRegistry.register(instanceInfo, false); + // event of proper type is registered + assertEquals(1, applicationEvents.size()); + assertTrue(applicationEvents.get(0) instanceof EurekaInstanceRegisteredEvent); + // event details are correct + EurekaInstanceRegisteredEvent registeredEvent = + (EurekaInstanceRegisteredEvent) (applicationEvents.get(0)); + assertEquals(instanceInfo, registeredEvent.getInstanceInfo()); + assertEquals(leaseInfo.getDurationInSecs(), registeredEvent.getLeaseDuration()); + assertEquals(instanceRegistry, registeredEvent.getSource()); + assertFalse(registeredEvent.isReplication()); + } - // event of proper type is registered - assertEquals(1, eurekaEventListener.getApplicationEvents().size()); - assertTrue(eurekaEventListener.getApplicationEvents().get(0) - instanceof EurekaInstanceRegisteredEvent); + @Test + public void testDefaultLeaseDurationRegisterEvent() throws Exception { + // creating instance info + InstanceInfo instanceInfo = getInstanceInfo(null); + // calling tested method + instanceRegistry.register(instanceInfo, false); + // instance info duration is set to default + EurekaInstanceRegisteredEvent registeredEvent = + (EurekaInstanceRegisteredEvent) (applicationEvents.get(0)); + assertEquals(LeaseInfo.DEFAULT_LEASE_DURATION, + registeredEvent.getLeaseDuration()); + } - // event details are correct - EurekaInstanceRegisteredEvent registeredEvent = (EurekaInstanceRegisteredEvent) - (eurekaEventListener.getApplicationEvents().get(0)); - assertEquals(instanceInfo, registeredEvent.getInstanceInfo()); - assertEquals(leaseInfo.getDurationInSecs(), registeredEvent.getLeaseDuration()); - assertEquals(instanceRegistry, registeredEvent.getSource()); - assertFalse(registeredEvent.isReplication()); + @Test + public void testInternalCancel() throws Exception { + // calling tested method + instanceRegistry.internalCancel("my-app", "appId", false); + // event of proper type is registered + assertEquals(1, applicationEvents.size()); + assertTrue(applicationEvents.get(0) instanceof EurekaInstanceCanceledEvent); + // event details are correct + EurekaInstanceCanceledEvent registeredEvent = + (EurekaInstanceCanceledEvent) (applicationEvents.get(0)); + assertEquals("my-app", registeredEvent.getAppName()); + assertEquals("appId", registeredEvent.getServerId()); + assertEquals(instanceRegistry, registeredEvent.getSource()); + assertFalse(registeredEvent.isReplication()); + } - // superclass method wrapper was successfully invoked - verify(instanceRegistry).superRegister(instanceInfo, false); - } + @Configuration + @EnableAutoConfiguration + @EnableEurekaServer + protected static class Application { + public static void main(String[] args) { + new SpringApplicationBuilder(Application.class).run(args); + } + } - @Test - public void testDefaultLeaseDurationRegisterEvent() throws Exception { - // stubbing superclass method invocation - doNothing().when(instanceRegistry) - .superRegister(any(InstanceInfo.class), anyBoolean()); + private LeaseInfo getLeaseInfo() { + LeaseInfo.Builder leaseBuilder = LeaseInfo.Builder.newBuilder(); + leaseBuilder.setRenewalIntervalInSecs(10); + leaseBuilder.setDurationInSecs(15); + return leaseBuilder.build(); + } - // creating instance info - InstanceInfo instanceInfo = getInstanceInfo(null); + private InstanceInfo getInstanceInfo(LeaseInfo leaseInfo) { + InstanceInfo.Builder builder = InstanceInfo.Builder.newBuilder(); + builder.setAppName("my-app-name"); + builder.setHostName("my-host-name"); + builder.setPort(8008); + builder.setLeaseInfo(leaseInfo); + return builder.build(); + } - // calling tested method - instanceRegistry.register(instanceInfo, false); - - // instance info duration is set to default - EurekaInstanceRegisteredEvent registeredEvent = (EurekaInstanceRegisteredEvent) - (eurekaEventListener.getApplicationEvents().get(0)); - assertEquals(LeaseInfo.DEFAULT_LEASE_DURATION, registeredEvent.getLeaseDuration()); - } - - @Test - public void testInternalCancel() throws Exception { - // stubbing superclass method invocation - doReturn(Boolean.TRUE).when(instanceRegistry) - .superInternalCancel(anyString(), anyString(), anyBoolean()); - - // calling tested method - boolean cancellationResult = instanceRegistry - .internalCancel("my-app", "appId", false); - - // event of proper type is registered - assertEquals(1, eurekaEventListener.getApplicationEvents().size()); - assertTrue(eurekaEventListener.getApplicationEvents().get(0) - instanceof EurekaInstanceCanceledEvent); - - // event details are correct - EurekaInstanceCanceledEvent registeredEvent = (EurekaInstanceCanceledEvent) - (eurekaEventListener.getApplicationEvents().get(0)); - assertEquals("my-app", registeredEvent.getAppName()); - assertEquals("appId", registeredEvent.getServerId()); - assertEquals(instanceRegistry, registeredEvent.getSource()); - assertFalse(registeredEvent.isReplication()); - - // superclass method wrapper was successfully invoked - verify(instanceRegistry).superInternalCancel("my-app", "appId", false); - assertTrue(cancellationResult); - } - - @Configuration - @EnableAutoConfiguration - @EnableEurekaServer - protected static class Application { - - public static void main(String[] args) { - new SpringApplicationBuilder(Application.class) - .properties("spring.application.name=eureka").run(args); - } - - @Bean - public Listener eurekaEventsListener() { - return new Listener(); - } - } - - private LeaseInfo getLeaseInfo() { - LeaseInfo.Builder leaseBuilder = LeaseInfo.Builder.newBuilder(); - leaseBuilder.setRenewalIntervalInSecs(10); - leaseBuilder.setDurationInSecs(15); - return leaseBuilder.build(); - } - - - private InstanceInfo getInstanceInfo(LeaseInfo leaseInfo) { - InstanceInfo.Builder builder = InstanceInfo.Builder.newBuilder(); - builder.setAppName("my-app-name"); - builder.setHostName("my-host-name"); - builder.setPort(8008); - builder.setLeaseInfo(leaseInfo); - return builder.build(); - } - - private static class Listener implements ApplicationListener { - - private final List applicationEvents = new LinkedList<>(); - - @Override - public void onApplicationEvent(ApplicationEvent event) { - if (event instanceof EurekaInstanceCanceledEvent || - event instanceof EurekaInstanceRegisteredEvent) { - applicationEvents.add(event); - } - } - - public List getApplicationEvents() { - return applicationEvents; - } - } + private Answer prepareListenerMockAnswer() { + return new Answer() { + @Override + public Object answer(InvocationOnMock invocation) throws Throwable { + return applicationEvents + .add((ApplicationEvent) invocation.getArguments()[0]); + } + }; + } } \ No newline at end of file From 4aaa7d0555baa0e8ebc5f19238eb0cfd735b4f65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20S=C5=82ota?= Date: Tue, 11 Oct 2016 21:46:25 +0200 Subject: [PATCH 4/4] InstanceRegistry class refactor + renew method test #1376 --- .../eureka/server/InstanceRegistry.java | 67 ++++++++---------- .../eureka/server/InstanceRegistryTest.java | 68 +++++++++++++++---- 2 files changed, 81 insertions(+), 54 deletions(-) diff --git a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistry.java b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistry.java index 69fe52ba..c1ba8b25 100644 --- a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistry.java +++ b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistry.java @@ -36,6 +36,7 @@ import com.netflix.eureka.registry.PeerAwareInstanceRegistryImpl; import com.netflix.eureka.resources.ServerCodecs; import lombok.extern.apachecommons.CommonsLog; +import org.springframework.context.ApplicationEvent; /** * @author Spencer Gibb @@ -79,33 +80,27 @@ public class InstanceRegistry extends PeerAwareInstanceRegistryImpl @Override public void register(InstanceInfo info, int leaseDuration, boolean isReplication) { - logRegistration(info, isReplication, leaseDuration); - publishEurekaInstanceRegisteredEvent(info, leaseDuration, isReplication); + handleRegistration(info, leaseDuration, isReplication); super.register(info, leaseDuration, isReplication); } @Override public void register(final InstanceInfo info, final boolean isReplication) { - final int instanceLeaseDuration = resolveInstanceLeaseDuration(info); - logRegistration(info, isReplication, instanceLeaseDuration); - publishEurekaInstanceRegisteredEvent(info, instanceLeaseDuration, isReplication); + handleRegistration(info, resolveInstanceLeaseDuration(info), isReplication); super.register(info, isReplication); } @Override public boolean cancel(String appName, String serverId, boolean isReplication) { - logCancelation(appName, serverId, isReplication); - publishEurekaInstanceCanceledEvent(appName, serverId, isReplication); + handleCancelation(appName, serverId, isReplication); return super.cancel(appName, serverId, isReplication); } @Override public boolean renew(final String appName, final String serverId, boolean isReplication) { - if (log.isDebugEnabled()) { - log.debug("renew " + appName + " serverId " + serverId + ", isReplication {}" - + isReplication); - } + log("renew " + appName + " serverId " + serverId + ", isReplication {}" + + isReplication); List applications = getSortedApplications(); for (Application input : applications) { if (input.getName().equals(appName)) { @@ -116,8 +111,8 @@ public class InstanceRegistry extends PeerAwareInstanceRegistryImpl break; } } - this.ctxt.publishEvent(new EurekaInstanceRenewedEvent(this, appName, - serverId, instance, isReplication)); + publishEvent(new EurekaInstanceRenewedEvent(this, appName, serverId, + instance, isReplication)); break; } } @@ -126,38 +121,32 @@ public class InstanceRegistry extends PeerAwareInstanceRegistryImpl @Override protected boolean internalCancel(String appName, String id, boolean isReplication) { - logCancelation(appName, id, isReplication); - publishEurekaInstanceCanceledEvent(appName, id, isReplication); + handleCancelation(appName, id, isReplication); return super.internalCancel(appName, id, isReplication); } - private void logRegistration(InstanceInfo info, boolean isReplication, - int instanceLeaseDuration) { - if (log.isDebugEnabled()) { - log.debug("register " + info.getAppName() + ", vip " + info.getVIPAddress() - + ", leaseDuration " + instanceLeaseDuration + ", isReplication " - + isReplication); - } + private void handleCancelation(String appName, String id, boolean isReplication) { + log("cancel " + appName + ", serverId " + id + ", isReplication " + isReplication); + publishEvent(new EurekaInstanceCanceledEvent(this, appName, id, isReplication)); } - private void logCancelation(String appName, String serverId, boolean isReplication) { - if (log.isDebugEnabled()) { - log.debug("cancel " + appName + " serverId " + serverId + ", isReplication " - + isReplication); - } - } - - private void publishEurekaInstanceRegisteredEvent(InstanceInfo info, - int leaseDuration, boolean isReplication) { - // TODO: what to publish from info (whole object?) - this.ctxt.publishEvent(new EurekaInstanceRegisteredEvent(this, info, - leaseDuration, isReplication)); - } - - private void publishEurekaInstanceCanceledEvent(String appName, String serverId, + private void handleRegistration(InstanceInfo info, int leaseDuration, boolean isReplication) { - this.ctxt.publishEvent( - new EurekaInstanceCanceledEvent(this, appName, serverId, isReplication)); + log("register " + info.getAppName() + ", vip " + info.getVIPAddress() + + ", leaseDuration " + leaseDuration + ", isReplication " + + isReplication); + publishEvent(new EurekaInstanceRegisteredEvent(this, info, leaseDuration, + isReplication)); + } + + private void log(String message) { + if (log.isDebugEnabled()) { + log.debug(message); + } + } + + private void publishEvent(ApplicationEvent applicationEvent) { + this.ctxt.publishEvent(applicationEvent); } private int resolveInstanceLeaseDuration(final InstanceInfo info) { diff --git a/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistryTest.java b/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistryTest.java index fa740240..9689e779 100644 --- a/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistryTest.java +++ b/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistryTest.java @@ -3,10 +3,13 @@ package org.springframework.cloud.netflix.eureka.server; import static org.junit.Assert.*; import static org.mockito.Matchers.isA; import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doReturn; +import java.util.ArrayList; import java.util.LinkedList; import java.util.List; +import com.netflix.discovery.shared.Application; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -17,9 +20,10 @@ import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.boot.test.mock.mockito.SpyBean; -import org.springframework.cloud.netflix.eureka.server.InstanceRegistryTest.Application; +import org.springframework.cloud.netflix.eureka.server.InstanceRegistryTest.TestApplication; import org.springframework.cloud.netflix.eureka.server.event.EurekaInstanceCanceledEvent; import org.springframework.cloud.netflix.eureka.server.event.EurekaInstanceRegisteredEvent; +import org.springframework.cloud.netflix.eureka.server.event.EurekaInstanceRenewedEvent; import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationListener; import org.springframework.context.annotation.Configuration; @@ -33,13 +37,15 @@ import com.netflix.eureka.registry.PeerAwareInstanceRegistry; * @author Bartlomiej Slota */ @RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = Application.class, +@SpringBootTest(classes = TestApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, value = {"spring.application.name=eureka", "logging.level.org.springframework." + "cloud.netflix.eureka.server.InstanceRegistry=DEBUG"}) public class InstanceRegistryTest { private final List applicationEvents = new LinkedList<>(); + private static final String APP_NAME = "MY-APP-NAME"; + private static final String HOST_NAME = "my-host-name"; @SpyBean(PeerAwareInstanceRegistry.class) private InstanceRegistry instanceRegistry; @@ -52,6 +58,9 @@ public class InstanceRegistryTest { private ApplicationListener instanceCanceledEventListenerMock; + @MockBean + private ApplicationListener instanceRenewedEventListener; + @Before public void setup() { applicationEvents.clear(); @@ -60,21 +69,23 @@ public class InstanceRegistryTest { .onApplicationEvent(isA(EurekaInstanceRegisteredEvent.class)); doAnswer(applicationListenerAnswer).when(instanceCanceledEventListenerMock) .onApplicationEvent(isA(EurekaInstanceCanceledEvent.class)); + doAnswer(applicationListenerAnswer).when(instanceRenewedEventListener) + .onApplicationEvent(isA(EurekaInstanceRenewedEvent.class)); } @Test public void testRegister() throws Exception { // creating instance info - LeaseInfo leaseInfo = getLeaseInfo(); - InstanceInfo instanceInfo = getInstanceInfo(leaseInfo); + final LeaseInfo leaseInfo = getLeaseInfo(); + final InstanceInfo instanceInfo = getInstanceInfo(leaseInfo); // calling tested method instanceRegistry.register(instanceInfo, false); // event of proper type is registered assertEquals(1, applicationEvents.size()); assertTrue(applicationEvents.get(0) instanceof EurekaInstanceRegisteredEvent); // event details are correct - EurekaInstanceRegisteredEvent registeredEvent = + final EurekaInstanceRegisteredEvent registeredEvent = (EurekaInstanceRegisteredEvent) (applicationEvents.get(0)); assertEquals(instanceInfo, registeredEvent.getInstanceInfo()); assertEquals(leaseInfo.getDurationInSecs(), registeredEvent.getLeaseDuration()); @@ -85,11 +96,11 @@ public class InstanceRegistryTest { @Test public void testDefaultLeaseDurationRegisterEvent() throws Exception { // creating instance info - InstanceInfo instanceInfo = getInstanceInfo(null); + final InstanceInfo instanceInfo = getInstanceInfo(null); // calling tested method instanceRegistry.register(instanceInfo, false); // instance info duration is set to default - EurekaInstanceRegisteredEvent registeredEvent = + final EurekaInstanceRegisteredEvent registeredEvent = (EurekaInstanceRegisteredEvent) (applicationEvents.get(0)); assertEquals(LeaseInfo.DEFAULT_LEASE_DURATION, registeredEvent.getLeaseDuration()); @@ -98,25 +109,52 @@ public class InstanceRegistryTest { @Test public void testInternalCancel() throws Exception { // calling tested method - instanceRegistry.internalCancel("my-app", "appId", false); + instanceRegistry.internalCancel(APP_NAME, HOST_NAME, false); // event of proper type is registered assertEquals(1, applicationEvents.size()); assertTrue(applicationEvents.get(0) instanceof EurekaInstanceCanceledEvent); // event details are correct - EurekaInstanceCanceledEvent registeredEvent = + final EurekaInstanceCanceledEvent registeredEvent = (EurekaInstanceCanceledEvent) (applicationEvents.get(0)); - assertEquals("my-app", registeredEvent.getAppName()); - assertEquals("appId", registeredEvent.getServerId()); + assertEquals(APP_NAME, registeredEvent.getAppName()); + assertEquals(HOST_NAME, registeredEvent.getServerId()); assertEquals(instanceRegistry, registeredEvent.getSource()); assertFalse(registeredEvent.isReplication()); } + @Test + public void testRenew() throws Exception { + // creating application list + final LeaseInfo leaseInfo = getLeaseInfo(); + final InstanceInfo instanceInfo = getInstanceInfo(leaseInfo); + final List instances = new ArrayList<>(); + instances.add(instanceInfo); + final Application application = new Application(APP_NAME, instances); + final List applications = new ArrayList<>(); + applications.add(application); + // stubbing applications list + doReturn(applications).when(instanceRegistry).getSortedApplications(); + // calling tested method + instanceRegistry.renew(APP_NAME, HOST_NAME, false); + // event of proper type is registered + assertEquals(1, applicationEvents.size()); + assertTrue(applicationEvents.get(0) instanceof EurekaInstanceRenewedEvent); + // event details are correct + final EurekaInstanceRenewedEvent registeredEvent = (EurekaInstanceRenewedEvent) + (applicationEvents.get(0)); + assertEquals(APP_NAME, registeredEvent.getAppName()); + assertEquals(HOST_NAME, registeredEvent.getServerId()); + assertEquals(instanceRegistry, registeredEvent.getSource()); + assertEquals(instanceInfo, registeredEvent.getInstanceInfo()); + assertFalse(registeredEvent.isReplication()); + } + @Configuration @EnableAutoConfiguration @EnableEurekaServer - protected static class Application { + protected static class TestApplication { public static void main(String[] args) { - new SpringApplicationBuilder(Application.class).run(args); + new SpringApplicationBuilder(TestApplication.class).run(args); } } @@ -129,8 +167,8 @@ public class InstanceRegistryTest { private InstanceInfo getInstanceInfo(LeaseInfo leaseInfo) { InstanceInfo.Builder builder = InstanceInfo.Builder.newBuilder(); - builder.setAppName("my-app-name"); - builder.setHostName("my-host-name"); + builder.setAppName(APP_NAME); + builder.setHostName(HOST_NAME); builder.setPort(8008); builder.setLeaseInfo(leaseInfo); return builder.build();