Package com.caringo.client.locate

Source Code of com.caringo.client.locate.ProxyLocator$ProxyReader

package com.caringo.client.locate;

/**
* @author bguetzlaff
*
*/

import java.net.InetSocketAddress;
import java.io.ByteArrayOutputStream;
import java.lang.Integer;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Date;
import java.lang.IllegalArgumentException;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HeaderElement;
import org.apache.commons.httpclient.NameValuePair;

import com.caringo.client.locate.Locator;
import com.caringo.client.locate.StaticLocator;
import com.caringo.client.locate.NoCastorNodesLocatedException;
import com.caringo.client.request.ScspRequestHandler;
import com.caringo.client.request.LocatorRedirectHandler;
import com.caringo.client.BasicScspResponseOutputStream;
import com.caringo.client.ScspHeaders;

public class ProxyLocator implements Locator {

    protected class ProxyReader extends Object {
        protected String clusterName;
        protected String proxyAddr;
        protected int proxyPort;
       
        public ProxyReader(String clusterName, String proxyAddr, int proxyPort) {
            this.clusterName = clusterName;
            this.proxyAddr = proxyAddr;
            this.proxyPort = proxyPort;
        }
       
        public InetSocketAddress[] discoverNodes() {
            StaticLocator subLocator = new StaticLocator();
            HttpClient httpCli = new HttpClient();
            ScspHeaders metaData = new ScspHeaders();
           
            subLocator.addAddress(proxyAddr, proxyPort);
           
            if (0 < clusterName.length()) {
                metaData.addValue("Scsp-Proxy-Cluster", clusterName);
            }

            ScspRequestHandler client = new ScspRequestHandler(httpCli, new LocatorRedirectHandler(subLocator), 3, 300, null);
            BasicScspResponseOutputStream output = new BasicScspResponseOutputStream(null);

            try {
                client.read("", metaData, "", output);
            }
            catch (Exception ex) {
                throw new NoCastorNodesLocatedException(String.format("Exception when communicating with SCSP Proxy (%s)", ex.toString()));
            }
           
            HashMap<String, String> proxyNodesInfo = new HashMap<String, String>();
            String nodesInfo = output.getHeader("Scsp-Proxy-Nodes");
           
            for (HeaderElement elem : HeaderElement.parseElements(nodesInfo)) {
                proxyNodesInfo.put(elem.getName(), elem.getValue());
            }

            Integer nodeCount = Integer.parseInt(proxyNodesInfo.get("count"));
            String outputBody = output.getBodyString();
           
            if ((0 == nodeCount) || (0 == outputBody.length())) {
                String reason = proxyNodesInfo.get("reason");
                throw new NoCastorNodesLocatedException(reason);
            }
           
            ArrayList<InetSocketAddress> nodeIPs = new ArrayList<InetSocketAddress>();
           
            for (String line : outputBody.split("\\r?\\n")) {
                nodeIPs.add(new InetSocketAddress(line.trim(), 0));
            }
           
            return nodeIPs.toArray(new InetSocketAddress[nodeIPs.size()]);
        }
    }

    private class DeadpoolEntry {
        public long restoreTime;
        public InetSocketAddress address;
        public DeadpoolEntry(long restoreTime, InetSocketAddress address) {
            this.restoreTime = restoreTime;
            this.address = address;
        }
    }

    private List<InetSocketAddress> poolList;
    private List<DeadpoolEntry> deadPool = new ArrayList<DeadpoolEntry>();
    private String clusterName;
    private String proxyAddr;
    private int proxyPort;
    private int retryTime;
    private ProxyReader proxyReader;
   
    /**
     * Constructor.
     * @param clusterName -
     *            The name of the cluster to query.
     * @param proxyAddr -
     *            The SCSP proxy address.
     * @param retryTime -
     *            The numer of seconds that an address will live in the dead pool.
     */
    public ProxyLocator(String clusterName, String proxyAddr, int retryTime) {
        this.proxyAddr = proxyAddr;
        this.clusterName = clusterName;
        this.proxyPort = 80;
        this.retryTime = retryTime;
        setUpPools();
    }
    
    /**
     * Constructor.
     * @param clusterName -
     *            The name of the cluster to query.
     * @param proxyAddr -
     *            The SCSP proxy address.
     * @param retryTime -
     *            The numer of seconds that an address will live in the dead pool.
     */
    public ProxyLocator(String clusterName, String proxyAddr, int proxyPort, int retryTime) throws IllegalArgumentException {
        this.proxyAddr = proxyAddr;
        this.clusterName = clusterName;
       
        if ((0 >= proxyPort) || (65534 < proxyPort)) {
            throw new IllegalArgumentException("Invalid port specified");
        }
       
        this.proxyPort = proxyPort;
        this.retryTime = retryTime;
        setUpPools();
    }
  
    private void setUpPools() {
        proxyReader = new ProxyReader(clusterName, proxyAddr, proxyPort);
        poolList = new ArrayList<InetSocketAddress>(Arrays.asList(proxyReader.discoverNodes()));
        deadPool.clear();
    }

    /**
     * @see com.caringo.client.locate.Locator#start
     */
    public void start() {
        // nothing to do here.
    }

    /**
     * @see com.caringo.client.locate.Locator#stop()
     */
    public void stop() {
        // nothing to do here.
    }

    /**
     * @see com.caringo.client.locate.Locator#locate()
     */
    public synchronized InetSocketAddress locate()
    {
        InetSocketAddress result = null;

        int memberCount = poolList.size();
        if (memberCount > 0) {
            result = poolList.get(0);
            if (memberCount > 1) {
                // rotate to spread the load
                poolList.remove(0);
                poolList.add(result);
                checkDeadPool();
            }
        }
        else
        {
            poolList = new ArrayList<InetSocketAddress>(Arrays.asList(proxyReader.discoverNodes()));
            memberCount = poolList.size();
            if (memberCount > 0) {
                result = poolList.get(0);
                if (memberCount > 1) {
                    // rotate to spread the load
                    poolList.remove(0);
                    poolList.add(result);
                    checkDeadPool();
                }
            }
        }

        return result;
    }

    /**
     * @see com.caringo.client.locate.Locator#locateAll()
     */
    public synchronized InetSocketAddress[] locateAll() {
        poolList = new ArrayList<InetSocketAddress>(Arrays.asList(proxyReader.discoverNodes()));
       
        if (0 < poolList.size()) {
            checkDeadPool();
        }
       
        return poolList.toArray(new InetSocketAddress[poolList.size()]);
    }

    /**
     * @see com.caringo.client.locate.Locator#foundDead(java.net.InetSocketAddress)
     */
    public synchronized void foundDead(InetSocketAddress addr) {
        if (poolList.size() > 1) {
            if (poolList.contains(addr)) {
                poolList.remove(addr);
                if (retryTime > 0) {
                    deadPool.add(new DeadpoolEntry(new Date().getTime() * 1000 + retryTime, addr));
                }
            }
        } else {
            // don't remove the last entry
        }
    }

    /**
     * @see com.caringo.client.locate.Locator#foundAlive(java.net.InetSocketAddress)
     */
    public synchronized void foundAlive(InetSocketAddress addr) {
        if (!poolList.contains(addr)) {
            poolList.add(addr);
            List<DeadpoolEntry> removeList = new ArrayList<DeadpoolEntry>();
            for (DeadpoolEntry e : deadPool) {
                if (e.address == addr) {
                    removeList.add(e);
                }
            }
            deadPool.removeAll(removeList);
        }
    }

    private void checkDeadPool() {
        ArrayList<DeadpoolEntry> removeList = new ArrayList<DeadpoolEntry>();
        long now = new Date().getTime() * 1000;
        for (DeadpoolEntry e : deadPool) {
            if (e.restoreTime < now) {
                removeList.add(e);
                if (! poolList.contains(e.address)) {
                    poolList.add(e.address);
                }
            }
        }
        deadPool.removeAll(removeList);       
    }
}
TOP

Related Classes of com.caringo.client.locate.ProxyLocator$ProxyReader

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.