Currently we use haproxy to direct users to certain versions of our software based on a cookie. This is so that the user can select which version of the software they want to use (e.g. Legacy, Stable, Beta) ... Having that kind of application functionality in the load balancer is something I'd rather not do. I'd rather have Tomcat read the cookie and switch contexts based on the cookie. I'd like to be able to simply pass the connection on to a different context and not have to 3XX redirect the client, but I don't see where that functionality exists.
I might be looking at the problem the wrong way though. I would love some suggestions on safe and simple ways to get this done. Here's what I have so far as a skeleton. For fun, it will flop based on the time you access the service from one service to the next: public class ProxyValve extends ValveBase { private enum BaseType {LEGACY, STABLE, BETA}; private String legacyBase; private String stableBase; private String betaBase; private String base; /** * The descriptive information related to this implementation. */ private static final String info = "org.apache.catalina.valves.ProxyValve/0.0"; /** * Return descriptive information about this Valve implementation. */ @Override public String getInfo() { return (info); } public void invoke(Request request, Response response) throws IOException, ServletException { if (request.getContextPath().equals(base)) { BaseType bt = convertBase(); switchContexts(bt, request, response); } getNext().invoke(request, response); } private void switchContexts(BaseType bt, Request request, Response response) throws IOException { Context c = request.getContext(); String path = request.getContextPath(); switch(bt) { case BETA: path = betaBase; break; case LEGACY: path = legacyBase; break; case STABLE: path = stableBase; break; } if (!path.equals(base)) { //do the switch here. But how? :) } } private BaseType convertBase() { Date d = new Date(); switch (d.getSeconds() % 3) { case 0: return BaseType.LEGACY; case 1: return BaseType.STABLE; case 2: return BaseType.BETA; } return BaseType.STABLE; } public String getLegacyBase() { return legacyBase; } public void setLegacyBase(String legacyBase) { this.legacyBase = legacyBase; } public String getStableBase() { return stableBase; } public void setStableBase(String stableBase) { this.stableBase = stableBase; } public String getBetaBase() { return betaBase; } public void setBetaBase(String betaBase) { this.betaBase = betaBase; } public String getBase() { return base; } public void setBase(String base) { this.base = base; } }