Skip to content

Instantly share code, notes, and snippets.

@kakawait
Created December 16, 2016 20:47
Show Gist options
  • Save kakawait/546955e79f902913ae61b63325cb0545 to your computer and use it in GitHub Desktop.
Save kakawait/546955e79f902913ae61b63325cb0545 to your computer and use it in GitHub Desktop.
DiscoveryHostUrlFilter
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import org.springframework.stereotype.Component;
import java.net.URL;
/**
* <i>Spring Cloud Netflix - Zuul</i> does not support <i>load-balanced</i> routing if target service has
* context path different than {@code /}.
*
* Only "solution" is to use {@code zuul.<route-name>.url = http://hostname:port/context-path}, but by choosing this way
* you will loose <b>load-balancing</b> and <b>circuit-breaking</b> capacities. That is not really acceptable.
*
* Following {@link ZuulFilter} is simple by-pass to enhance {@code zuul.<route-name>.url} properties to accept
* {@code service-id} in addition to plain old {@code hostname:port}.
* Like {@link org.springframework.web.client.RestTemplate} with
* {@link org.springframework.cloud.client.loadbalancer.LoadBalanced} you can use following syntax:
* {@code http://<service-id>/} or even {@code http://<service-id>/path}.
*
* As you can see you have now the capacity to add {@code path} after {@code <service-id>} that can be used to manage
* target context path.
*
* Please track following issue https://github.com/spring-cloud/spring-cloud-netflix/issues/1235 that talk about
* refactoring whole <i>Spring Cloud Netflix - Zuul</i> routing configuration.
*
* @author Thibaud Leprêtre
*/
@Component
public class DiscoveryHostUrlFilter extends ZuulFilter {
private static final String DISCOVERY_FRAGMENT = "discovery";
@Override
public String filterType() {
return "pre";
}
@Override
public int filterOrder() {
return 10;
}
@Override
public boolean shouldFilter() {
RequestContext ctx = RequestContext.getCurrentContext();
URL url = ctx.getRouteHost();
return !ctx.containsKey("serviceId") && url != null && DISCOVERY_FRAGMENT.equals(url.getRef());
}
@Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
URL url = ctx.getRouteHost();
String serviceId = url.getHost();
ctx.set("serviceId", serviceId);
ctx.setRouteHost(null);
ctx.addOriginResponseHeader("X-Zuul-ServiceId", serviceId);
String path = !ctx.containsKey("requestURI") ? "" : (String) ctx.get("requestURI");
ctx.set("requestURI", (url.getPath() + path).replace("//", "/"));
return null;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment