Don't refresh routes on management context events.

Previously, the RouteRefreshListener reset the routes cache on all ContextRefreshedEvents. If actuator is run on a seperate port, to ContextRefreshedEvents are published. This adds a check to only reset the cache if the event does not come from the management context.

Fixes gh-1928
This commit is contained in:
spencergibb
2020-09-14 16:52:28 -04:00
parent 676866cfcf
commit 52930d2458
2 changed files with 38 additions and 2 deletions

View File

@@ -16,6 +16,7 @@
package org.springframework.cloud.gateway.route;
import org.springframework.boot.web.context.WebServerApplicationContext;
import org.springframework.cloud.client.discovery.event.HeartbeatEvent;
import org.springframework.cloud.client.discovery.event.HeartbeatMonitor;
import org.springframework.cloud.client.discovery.event.InstanceRegisteredEvent;
@@ -43,8 +44,14 @@ public class RouteRefreshListener implements ApplicationListener<ApplicationEven
@Override
public void onApplicationEvent(ApplicationEvent event) {
if (event instanceof ContextRefreshedEvent
|| event instanceof RefreshScopeRefreshedEvent
if (event instanceof ContextRefreshedEvent) {
ContextRefreshedEvent refreshedEvent = (ContextRefreshedEvent) event;
if (!WebServerApplicationContext.hasServerNamespace(
refreshedEvent.getApplicationContext(), "management")) {
reset();
}
}
else if (event instanceof RefreshScopeRefreshedEvent
|| event instanceof InstanceRegisteredEvent) {
reset();
}

View File

@@ -18,19 +18,48 @@ package org.springframework.cloud.gateway.route;
import org.junit.Test;
import org.springframework.boot.web.context.WebServerApplicationContext;
import org.springframework.cloud.client.discovery.event.HeartbeatEvent;
import org.springframework.cloud.client.discovery.event.InstanceRegisteredEvent;
import org.springframework.cloud.client.discovery.event.ParentHeartbeatEvent;
import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.event.ContextRefreshedEvent;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.Mockito.when;
public class RouteRefreshListenerTests {
@Test
public void onContextRefreshedEventManagement() {
ApplicationEventPublisher publisher = mock(ApplicationEventPublisher.class);
RouteRefreshListener listener = new RouteRefreshListener(publisher);
WebServerApplicationContext applicationContext = mock(
WebServerApplicationContext.class);
when(applicationContext.getServerNamespace()).thenReturn("management");
listener.onApplicationEvent(new ContextRefreshedEvent(applicationContext));
verifyNoInteractions(publisher);
}
@Test
public void onContextRefreshedEvent() {
ApplicationEventPublisher publisher = mock(ApplicationEventPublisher.class);
RouteRefreshListener listener = new RouteRefreshListener(publisher);
listener.onApplicationEvent(
new ContextRefreshedEvent(mock(ApplicationContext.class)));
verify(publisher).publishEvent(any(RefreshRoutesEvent.class));
}
@Test
public void onInstanceRegisteredEvent() {
ApplicationEventPublisher publisher = mock(ApplicationEventPublisher.class);