package com.theorem.radserver3.examples.server; import com.theorem.radserver3.*; import com.theorem.radserver3.radutil.*; import com.theorem.misc.*; import java.util.*; /** * Sends packets to a series of servers in an attempt to load balance * server usage or handle dead or busy servers. */ public class ProxyFailover extends ProxyImpl { LogImpl dbg, svr; Configure conf; // Timer for creating a list of servers to try. Timer timer; // Circular list of servers to try. CircularList serverList = new CircularList(); // List of timer object. They will remove themselves as they expire. // This is required so a Timer won't disappear because of a lack of a reference. ArrayList timerList = new ArrayList(); /** * Constructor. * @param conf Configuration object. */ public ProxyFailover(Configure conf) { super(); this.conf = conf; timer = new Timer(); // For the sake of testing add the same server twice. addServer("andromeda"); addServer("andromeda"); } /** * Intialize the logs for this class. * * @param svrLog Server log object. * @param dbgLog Debug log object. */ public void logs(LogImpl svrLog, LogImpl dbgLog) { dbg = dbgLog; svr = svrLog; } /** * Method to add a server to the circular list. * @param server Server realm. * The realm must be in our list of proxy target servers. */ public void addServer(String server) { serverList.add(server); } /** * Send a proxy request to a number of servers in the hopes one will respond. * * @param prx ProxyInfo object from server. */ public void changeRequest(ProxyInfo prx) throws AccessDropException, AccessRejectException { timer = new Timer(); timerList.add(timer); try { // Try sending a packet from within this method. // Set up the proxyClient with no particular associated object. ProxyClient pc = prx.getProxyClient(false, PacketType.Access_Request, prx.getRequestAttributeList(), null); // Create the packet timeout object that will handle all the attempts // to send the packet. ProxyPacketTimeout t = new ProxyPacketTimeout(timer, pc, timerList); // Add realms from the circular list - start with a random entry. Random r = new Random(); int count = serverList.size(); int skip = r.nextInt() % count; for (int i = 0; i < count; i++) serverList.next(); for (int i = 0; i < count; i++) t.addRealm((String) serverList.next()); // Set the time between attempts to some number of seconds. t.setInterval(2); // Set the timer. t.go(); } catch (RADIUSServerException rse) { System.out.println(rse.getMessage()); } catch (AccessDropException ade) { System.out.println(ade.getMessage()); } // Unless we make this more sophisticated drop the original packet so we don't // send it to one of the proxy servers twice. throw new AccessDropException("Dropping original packet"); } /** * Change proxy response routing. * Don't actually change a proxies response attributes in this case. * * @param prx ProxyInfo object from server. */ public void changeResponse(ProxyInfo prx) throws AccessDropException, AccessRejectException { // Once a packet is successfully recovered cancel the timer. ProxyPacketTimeout ppt = (ProxyPacketTimeout) prx.getProxyStateObject(); if (ppt != null) { System.out.println("Time left on the timer is " + (new Date().getTime() - ppt.scheduledExecutionTime())); ppt.cancel(); } } }