Java tutorial
/** * Copyright (c) 2015 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 io.jmnarloch.spring.cloud.zuul.route; import io.jmnarloch.spring.cloud.zuul.matcher.RouteMatcher; import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.cloud.netflix.zuul.filters.ProxyRouteLocator; import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; import org.springframework.util.StringUtils; /** * A simple implementation of {@link ProxyRouteLocator} that delegates to the {@link RouteMatcher} for retrieving the * best matching route for specified request path. * * @author Jakub Narloch */ public class MatcherProxyRouteLocator extends ProxyRouteLocator { /** * The route matcher instance. */ private final RouteMatcher routeMatcher; /** * The servlet path. */ private final String servletPath; /** * The Zuul properties. */ private final ZuulProperties properties; /** * Creates new instance of {@link MatcherProxyRouteLocator}. * * @param servletPath the servlet path * @param discovery the service discovery * @param properties the properties * @param routeMatcher the route matcher */ public MatcherProxyRouteLocator(String servletPath, DiscoveryClient discovery, ZuulProperties properties, RouteMatcher routeMatcher) { super(servletPath, discovery, properties); this.servletPath = servletPath; this.properties = properties; this.routeMatcher = routeMatcher; } /** * {@inheritDoc} */ @Override public ProxyRouteSpec getMatchingRoute(String path) { if (StringUtils.hasText(this.servletPath) && !this.servletPath.equals("/") && path.startsWith(this.servletPath)) { path = path.substring(this.servletPath.length()); } return toProxyRouteSpec(path, routeMatcher.getMatchingRoute(path)); } /** * {@inheritDoc} */ @Override public void resetRoutes() { routeMatcher.setRoutes(locateRoutes()); } /** * Creates a {@link org.springframework.cloud.netflix.zuul.filters.ProxyRouteLocator.ProxyRouteSpec} out of * {@link org.springframework.cloud.netflix.zuul.filters.ZuulProperties.ZuulRoute}. * * @param route the zuul route * @return the route spec */ private ProxyRouteSpec toProxyRouteSpec(final String path, final ZuulProperties.ZuulRoute route) { if (route == null) { return null; } String targetPath = getRequestPath(path); String prefix = properties.getPrefix(); final Boolean retryable = isRetryable(route); if (properties.isStripPrefix() && targetPath.startsWith(prefix)) { targetPath = path.substring(prefix.length()); } if (route.isStripPrefix()) { int index = route.getPath().indexOf("*") - 1; if (index > 0) { String routePrefix = route.getPath().substring(0, index); targetPath = targetPath.replaceFirst(routePrefix, ""); prefix = prefix + routePrefix; } } return new ProxyRouteSpec(route.getId(), targetPath, route.getLocation(), prefix, retryable); } /** * Returns whether connection to specific route is retryable. * * @param route the route * @return true if is retryable, false otherwise */ private Boolean isRetryable(ZuulProperties.ZuulRoute route) { if (route.getRetryable() != null) { return route.getRetryable(); } return properties.getRetryable(); } /** * Retrieves the route path, stripped from the servlet path. * * @param path the route path * @return the route request path */ private String getRequestPath(String path) { if (StringUtils.hasText(this.servletPath) && !this.servletPath.equals("/") && path.startsWith(this.servletPath)) { return path.substring(this.servletPath.length()); } return path; } }