diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/RouteLocator.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/RouteLocator.java index 72aebcdb..be4103fc 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/RouteLocator.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/RouteLocator.java @@ -4,127 +4,95 @@ import java.lang.reflect.Field; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import java.util.Set; import java.util.concurrent.atomic.AtomicReference; import lombok.extern.slf4j.Slf4j; -import org.springframework.boot.bind.PropertySourceUtils; import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.cloud.context.environment.EnvironmentChangeEvent; import org.springframework.context.ApplicationListener; -import org.springframework.context.EnvironmentAware; import org.springframework.core.env.CompositePropertySource; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.core.env.Environment; -import org.springframework.core.env.MutablePropertySources; -import org.springframework.core.env.PropertySource; -import org.springframework.core.env.StandardEnvironment; import org.springframework.util.ReflectionUtils; /** * @author Spencer Gibb */ @Slf4j -public class RouteLocator implements ApplicationListener, EnvironmentAware { +public class RouteLocator implements ApplicationListener { - public static final String DEFAULT_ROUTE = "/"; + public static final String DEFAULT_ROUTE = "/"; - private ConfigurableEnvironment env = new StandardEnvironment(); + private DiscoveryClient discovery; - private DiscoveryClient discovery; + private ZuulProperties properties; - private ZuulProperties properties; + private Field propertySourcesField; + private AtomicReference> routes = new AtomicReference<>(); - private Field propertySourcesField; - private AtomicReference> routes = new AtomicReference<>(); - - @Override - public void setEnvironment(Environment environment) { - env = (ConfigurableEnvironment) environment; - } - - public RouteLocator(DiscoveryClient discovery, ZuulProperties properties) { - this.discovery = discovery; + public RouteLocator(DiscoveryClient discovery, ZuulProperties properties) { + this.discovery = discovery; this.properties = properties; initField(); - } + } - private void initField() { - propertySourcesField = ReflectionUtils.findField(CompositePropertySource.class, "propertySources"); - propertySourcesField.setAccessible(true); - } + private void initField() { + propertySourcesField = ReflectionUtils.findField(CompositePropertySource.class, + "propertySources"); + propertySourcesField.setAccessible(true); + } - @Override - public void onApplicationEvent(EnvironmentChangeEvent event) { - for (String key : event.getKeys()) { - if (key.startsWith(properties.getRoutePrefix())) { - routes.set(locateRoutes()); - return; - } - } - } + @Override + public void onApplicationEvent(EnvironmentChangeEvent event) { + for (String key : event.getKeys()) { + if (key.startsWith(properties.getMapping())) { + routes.set(locateRoutes()); + return; + } + } + } - //TODO: respond to changes in eureka - public Map getRoutes() { - if (routes.get() == null) { - routes.set(locateRoutes()); - } + public Map getRoutes() { + if (routes.get() == null) { + routes.set(locateRoutes()); + } - return routes.get(); - } + return routes.get(); + } - protected LinkedHashMap locateRoutes() { - LinkedHashMap routesMap = new LinkedHashMap<>(); + protected LinkedHashMap locateRoutes() { + LinkedHashMap routesMap = new LinkedHashMap<>(); - //Add routes for discovery services by default - List services = discovery.getServices(); - for (String serviceId : services) { - //Ignore specified services - if (!properties.getIgnoredServices().contains(serviceId)) - routesMap.put("/" + serviceId + "/**", serviceId); - } + // Add routes for discovery services by default + List services = discovery.getServices(); + for (String serviceId : services) { + // Ignore specified services + if (!properties.getIgnoredServices().contains(serviceId)) + routesMap.put("/" + serviceId + "/**", serviceId); + } - MutablePropertySources propertySources = env.getPropertySources(); - for (PropertySource propertySource : propertySources) { - getRoutes(propertySource, routesMap); - } + addConfiguredRoutes(routesMap); - String defaultServiceId = routesMap.get(DEFAULT_ROUTE); + String defaultServiceId = routesMap.get(DEFAULT_ROUTE); - if (defaultServiceId != null) { - //move the defaultServiceId to the end - routesMap.remove(DEFAULT_ROUTE); - routesMap.put(DEFAULT_ROUTE, defaultServiceId); - } - return routesMap; - } + if (defaultServiceId != null) { + // move the defaultServiceId to the end + routesMap.remove(DEFAULT_ROUTE); + routesMap.put(DEFAULT_ROUTE, defaultServiceId); + } + return routesMap; + } - protected void getRoutes(PropertySource propertySource, Map routes) { - if (propertySource instanceof CompositePropertySource) { - try { - @SuppressWarnings("unchecked") - Set> sources = (Set>) propertySourcesField.get(propertySource); - for (PropertySource source : sources) { - getRoutes(source, routes); - } - } catch (IllegalAccessException e) { - return; - } - } else { - //EnumerablePropertySource enumerable = (EnumerablePropertySource) propertySource; - MutablePropertySources propertySources = new MutablePropertySources(); - propertySources.addLast(propertySource); - Map routeEntries = PropertySourceUtils.getSubProperties(propertySources, properties.getRoutePrefix()); - for (Map.Entry entry : routeEntries.entrySet()) { - String serviceId = entry.getKey(); - String route = entry.getValue().toString(); + protected void addConfiguredRoutes(Map routes) { + Map routeEntries = properties.getRoute(); + for (Map.Entry entry : routeEntries.entrySet()) { + String serviceId = entry.getKey(); + String route = entry.getValue() ; - if (routes.containsKey(route)) { - log.warn("Overwriting route {}: already defined by {}", route, routes.get(route)); - } - routes.put(route, serviceId); - } - } - } + if (routes.containsKey(route)) { + log.warn("Overwriting route {}: already defined by {}", route, + routes.get(route)); + } + routes.put(route, serviceId); + } + } } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/ZuulHandlerMapping.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/ZuulHandlerMapping.java index d176aae9..c73ecac7 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/ZuulHandlerMapping.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/ZuulHandlerMapping.java @@ -58,7 +58,7 @@ public class ZuulHandlerMapping extends AbstractUrlHandlerMapping implements url = "/" + url; } - if (StringUtils.hasText(properties.getRoutePrefix())) { + if (StringUtils.hasText(properties.getMapping())) { url = properties.getMapping() + url; if (!url.startsWith("/")) { url = "/" + url; diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/ZuulProperties.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/ZuulProperties.java index def65ab8..86e2acde 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/ZuulProperties.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/ZuulProperties.java @@ -1,10 +1,13 @@ package org.springframework.cloud.netflix.zuul; -import lombok.Data; -import org.springframework.boot.context.properties.ConfigurationProperties; - import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; + +import lombok.Data; + +import org.springframework.boot.context.properties.ConfigurationProperties; /** * @author Spencer Gibb @@ -14,7 +17,7 @@ import java.util.List; public class ZuulProperties { private String mapping = ""; private boolean stripMapping = false; - private String routePrefix = "zuul.route."; + private Map route = new HashMap(); private boolean addProxyHeaders = true; private List ignoredServices = Collections.emptyList(); } diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/RouteLocatorTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/RouteLocatorTests.java index 7d658d2e..ef94e3a9 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/RouteLocatorTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/RouteLocatorTests.java @@ -1,19 +1,21 @@ package org.springframework.cloud.netflix.zuul; -import com.google.common.collect.Lists; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +import java.util.Map; + import org.junit.Before; import org.junit.Test; import org.mockito.Mock; import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.core.env.MutablePropertySources; -import org.springframework.mock.env.MockPropertySource; -import java.util.Map; - -import static org.junit.Assert.*; -import static org.mockito.Mockito.*; -import static org.mockito.MockitoAnnotations.initMocks; +import com.google.common.collect.Lists; /** * @author Spencer Gibb @@ -23,6 +25,7 @@ public class RouteLocatorTests { public static final String IGNOREDSERVICE = "ignoredservice"; public static final String ASERVICE = "aservice"; public static final String MYSERVICE = "myservice"; + @Mock ConfigurableEnvironment env; @@ -39,12 +42,8 @@ public class RouteLocatorTests { ZuulProperties properties = new ZuulProperties(); RouteLocator routeLocator = new RouteLocator(this.discovery, properties); properties.setIgnoredServices(Lists.newArrayList(IGNOREDSERVICE)); - routeLocator.setEnvironment(this.env); + properties.getRoute().put(ASERVICE, "/"+ASERVICE + "/**"); - MutablePropertySources propertySources = new MutablePropertySources(); - propertySources.addFirst(new MockPropertySource().withProperty("zuul.route." - + ASERVICE, getMapping(ASERVICE))); - when(env.getPropertySources()).thenReturn(propertySources); when(discovery.getServices()).thenReturn( Lists.newArrayList(MYSERVICE, IGNOREDSERVICE));