Browse Source
Change /routes endpoint to use EndpointMvcAdapter and AbstractEndpoint. Fixes #1797pull/6/head
13 changed files with 347 additions and 52 deletions
@ -0,0 +1,58 @@
@@ -0,0 +1,58 @@
|
||||
/* |
||||
* |
||||
* * Copyright 2013-2016 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 |
||||
* * |
||||
* * http://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.zuul; |
||||
|
||||
import org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter; |
||||
import org.springframework.cloud.netflix.zuul.filters.RouteLocator; |
||||
import org.springframework.context.ApplicationEventPublisher; |
||||
import org.springframework.context.ApplicationEventPublisherAware; |
||||
import org.springframework.jmx.export.annotation.ManagedOperation; |
||||
import org.springframework.jmx.export.annotation.ManagedResource; |
||||
import org.springframework.web.bind.annotation.RequestMapping; |
||||
import org.springframework.web.bind.annotation.RequestMethod; |
||||
import org.springframework.web.bind.annotation.ResponseBody; |
||||
|
||||
/** |
||||
* Endpoint used to reset the reverse proxy routes |
||||
* @author Ryan Baxter |
||||
*/ |
||||
@ManagedResource(description = "Can be used to reset the reverse proxy routes") |
||||
public class RoutesMvcEndpoint extends EndpointMvcAdapter implements ApplicationEventPublisherAware { |
||||
|
||||
private RouteLocator routes; |
||||
private ApplicationEventPublisher publisher; |
||||
|
||||
public RoutesMvcEndpoint(RoutesEndpoint endpoint, RouteLocator routes) { |
||||
super(endpoint); |
||||
this.routes = routes; |
||||
} |
||||
|
||||
@Override |
||||
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { |
||||
this.publisher = applicationEventPublisher; |
||||
} |
||||
|
||||
@RequestMapping(method = RequestMethod.POST) |
||||
@ResponseBody |
||||
@ManagedOperation |
||||
public Object reset() { |
||||
this.publisher.publishEvent(new RoutesRefreshedEvent(this.routes)); |
||||
return super.invoke(); |
||||
} |
||||
} |
@ -0,0 +1,85 @@
@@ -0,0 +1,85 @@
|
||||
/* |
||||
* |
||||
* * Copyright 2013-2016 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 |
||||
* * |
||||
* * http://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.zuul; |
||||
|
||||
import java.util.Map; |
||||
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.test.context.SpringBootTest; |
||||
import org.springframework.boot.test.web.client.TestRestTemplate; |
||||
import org.springframework.context.ApplicationListener; |
||||
import org.springframework.context.annotation.Configuration; |
||||
import org.springframework.stereotype.Component; |
||||
import org.springframework.test.annotation.DirtiesContext; |
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; |
||||
import org.springframework.web.bind.annotation.RestController; |
||||
|
||||
import static org.junit.Assert.assertEquals; |
||||
import static org.junit.Assert.assertTrue; |
||||
|
||||
/** |
||||
* @author Ryan Baxter |
||||
*/ |
||||
@RunWith(SpringJUnit4ClassRunner.class) |
||||
@SpringBootTest( |
||||
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, |
||||
value = {"zuul.routes.sslservice.url=https://localhost:8443", "management.security.enabled=false"}) |
||||
@DirtiesContext |
||||
public class RoutesEndpointIntegrationTests { |
||||
|
||||
@Autowired |
||||
private TestRestTemplate restTemplate; |
||||
|
||||
@Autowired |
||||
private SimpleZuulProxyApplication.RoutesRefreshListener refreshListener; |
||||
|
||||
@Test |
||||
public void getRoutesTest() { |
||||
Map<String, String> routes = restTemplate.getForObject("/admin/routes", Map.class); |
||||
assertEquals("https://localhost:8443", routes.get("/sslservice/**")); |
||||
} |
||||
|
||||
@Test |
||||
public void postRoutesTest() { |
||||
Map<String, String> routes = restTemplate.postForObject("/admin/routes", null, Map.class); |
||||
assertEquals("https://localhost:8443", routes.get("/sslservice/**")); |
||||
assertTrue(refreshListener.wasCalled()); |
||||
} |
||||
|
||||
@Configuration |
||||
@EnableAutoConfiguration |
||||
@RestController |
||||
@EnableZuulProxy |
||||
static class SimpleZuulProxyApplication { |
||||
@Component |
||||
static class RoutesRefreshListener implements ApplicationListener<RoutesRefreshedEvent> { |
||||
private boolean called = false; |
||||
@Override |
||||
public void onApplicationEvent(RoutesRefreshedEvent routesRefreshedEvent) { |
||||
called = true; |
||||
} |
||||
|
||||
public boolean wasCalled() { |
||||
return called; |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,86 @@
@@ -0,0 +1,86 @@
|
||||
/* |
||||
* |
||||
* * Copyright 2013-2016 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 |
||||
* * |
||||
* * http://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.zuul; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.Collection; |
||||
import java.util.Collections; |
||||
import java.util.HashMap; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
import org.junit.Before; |
||||
import org.junit.Test; |
||||
import org.springframework.cloud.netflix.zuul.filters.Route; |
||||
import org.springframework.cloud.netflix.zuul.filters.RouteLocator; |
||||
|
||||
import static org.junit.Assert.assertEquals; |
||||
import static org.junit.Assert.assertTrue; |
||||
|
||||
/** |
||||
* @author Ryan Baxter |
||||
*/ |
||||
public class RoutesEndpointTests { |
||||
|
||||
private RouteLocator locator; |
||||
|
||||
@Before |
||||
public void setUp() { |
||||
this.locator = new RouteLocator() { |
||||
@Override |
||||
public Collection<String> getIgnoredPaths() { |
||||
return null; |
||||
} |
||||
|
||||
@Override |
||||
public List<Route> getRoutes() { |
||||
List<Route> routes = new ArrayList<>(); |
||||
routes.add(new Route("foo", "foopath", "foolocation", null, true, Collections.EMPTY_SET)); |
||||
routes.add(new Route("bar", "barpath", "barlocation", null, true, Collections.EMPTY_SET)); |
||||
return routes; |
||||
} |
||||
|
||||
@Override |
||||
public Route getMatchingRoute(String path) { |
||||
return null; |
||||
} |
||||
}; |
||||
} |
||||
|
||||
@Test |
||||
public void testInvoke() { |
||||
RoutesEndpoint endpoint = new RoutesEndpoint(locator); |
||||
Map<String, String> result = new HashMap<String, String>(); |
||||
for(Route r : locator.getRoutes()) { |
||||
result.put(r.getFullPath(), r.getLocation()); |
||||
} |
||||
assertEquals(result , endpoint.invoke()); |
||||
} |
||||
|
||||
@Test |
||||
public void testId() { |
||||
RoutesEndpoint endpoint = new RoutesEndpoint(locator); |
||||
assertEquals("routes", endpoint.getId()); |
||||
} |
||||
|
||||
@Test |
||||
public void testIsSensitive() { |
||||
RoutesEndpoint endpoint = new RoutesEndpoint(locator); |
||||
assertTrue(endpoint.isSensitive()); |
||||
} |
||||
} |
@ -0,0 +1,91 @@
@@ -0,0 +1,91 @@
|
||||
/* |
||||
* |
||||
* * Copyright 2013-2016 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 |
||||
* * |
||||
* * http://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.zuul; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.Collection; |
||||
import java.util.Collections; |
||||
import java.util.HashMap; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
import org.junit.Before; |
||||
import org.junit.Test; |
||||
import org.junit.runner.RunWith; |
||||
import org.mockito.Mock; |
||||
import org.mockito.runners.MockitoJUnitRunner; |
||||
import org.springframework.boot.test.context.SpringBootTest; |
||||
import org.springframework.cloud.netflix.zuul.filters.Route; |
||||
import org.springframework.cloud.netflix.zuul.filters.RouteLocator; |
||||
import org.springframework.context.ApplicationEventPublisher; |
||||
|
||||
import static org.junit.Assert.assertEquals; |
||||
import static org.mockito.Matchers.isA; |
||||
import static org.mockito.Mockito.spy; |
||||
import static org.mockito.Mockito.times; |
||||
import static org.mockito.Mockito.verify; |
||||
|
||||
/** |
||||
* @author Ryan Baxter |
||||
*/ |
||||
@SpringBootTest |
||||
@RunWith(MockitoJUnitRunner.class) |
||||
public class RoutesMvcEndpointTests { |
||||
private RouteLocator locator; |
||||
private RoutesEndpoint endpoint; |
||||
@Mock |
||||
private ApplicationEventPublisher publisher; |
||||
|
||||
@Before |
||||
public void setUp() { |
||||
this.locator = new RouteLocator() { |
||||
@Override |
||||
public Collection<String> getIgnoredPaths() { |
||||
return null; |
||||
} |
||||
|
||||
@Override |
||||
public List<Route> getRoutes() { |
||||
List<Route> routes = new ArrayList<>(); |
||||
routes.add(new Route("foo", "foopath", "foolocation", null, true, Collections.EMPTY_SET)); |
||||
routes.add(new Route("bar", "barpath", "barlocation", null, true, Collections.EMPTY_SET)); |
||||
return routes; |
||||
} |
||||
|
||||
@Override |
||||
public Route getMatchingRoute(String path) { |
||||
return null; |
||||
} |
||||
}; |
||||
endpoint = spy(new RoutesEndpoint(locator)); |
||||
} |
||||
|
||||
@Test |
||||
public void reset() throws Exception { |
||||
RoutesMvcEndpoint mvcEndpoint = new RoutesMvcEndpoint(endpoint, locator); |
||||
mvcEndpoint.setApplicationEventPublisher(publisher); |
||||
Map<String, String> result = new HashMap<String, String>(); |
||||
for(Route r : locator.getRoutes()) { |
||||
result.put(r.getFullPath(), r.getLocation()); |
||||
} |
||||
assertEquals(result , mvcEndpoint.reset()); |
||||
verify(endpoint, times(1)).invoke(); |
||||
verify(publisher, times(1)).publishEvent(isA(RoutesRefreshedEvent.class)); |
||||
} |
||||
|
||||
} |
Loading…
Reference in new issue