org.kchine.rpf.reg.ServantProviderFactoryReg.java Source code

Java tutorial

Introduction

Here is the source code for org.kchine.rpf.reg.ServantProviderFactoryReg.java

Source

/*
 * Biocep: R-based Platform for Computational e-Science.
 *  
 * Copyright (C) 2007-2009 Karim Chine - karim.chine@m4x.org
 *  
 * Copyright (C) 2007 EMBL-EBI-Microarray Informatics
 *  
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.kchine.rpf.reg;

import java.io.FileInputStream;
import java.io.InputStream;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.NoSuchElementException;
import java.util.Vector;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.apache.commons.logging.Log;
import org.kchine.rpf.ManagedServant;
import org.kchine.rpf.PoolUtils;
import org.kchine.rpf.ServantProvider;
import org.kchine.rpf.ServantProviderFactory;
import org.kchine.rpf.ServerDefaults;
import org.kchine.rpf.TimeoutException;
import org.kchine.rpf.reg.ServantProxyPoolSingletonReg;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import static org.kchine.rpf.PoolUtils.*;

/**
 * @author Karim Chine karim.chine@m4x.org
 */
public class ServantProviderFactoryReg extends ServantProviderFactory {

    private HashMap<String, PoolData> _poolHashMap = new HashMap<String, PoolData>();
    private Hashtable<ManagedServant, PoolNode> _borrowedServants = new Hashtable<ManagedServant, PoolNode>();
    private String _defaultPoolName = null;
    private final Log log = org.apache.commons.logging.LogFactory.getLog(ServantProviderFactoryReg.class);

    private Registry _rmiRegistry = null;

    private ServantProvider _servantProvider = null;

    public ServantProviderFactoryReg() {

        if (System.getProperty("pools.regmode.configuration.file") != null
                && !System.getProperty("pools.regmode.configuration.file").equals("")) {
            try {
                initPoolsHashMap(new FileInputStream(System.getProperty("pools.regmode.configuration.file")));
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else if (System.getProperty("pools.regmode.configuration.resource") != null
                && !System.getProperty("pools.regmode.configuration.resource").equals("")) {
            try {
                initPoolsHashMap(this.getClass()
                        .getResourceAsStream(System.getProperty("pools.regmode.configuration.resource")));
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {

            String poolPrefix = ServerDefaults._servantPoolPrefix;
            String registryHost = ServerDefaults._registryHost;
            int registryPort = ServerDefaults._registryPort;

            int timeOutMillisec = System.getProperty("timeout") != null && !System.getProperty("timeout").equals("")
                    ? Integer.decode(System.getProperty("timeout"))
                    : DEFAULT_TIMEOUT;

            _defaultPoolName = "DEFAULT";
            PoolData poolData = new PoolData(_defaultPoolName, timeOutMillisec, new Vector<PoolNode>());
            poolData.getNodes().add(new PoolNode(poolPrefix, registryHost, registryPort));
            _poolHashMap.put(poolData.getPoolName(), poolData);

            try {
                _rmiRegistry = LocateRegistry.getRegistry(registryHost, registryPort);
            } catch (Exception e) {
                e.printStackTrace();
            }

        }

        System.out.println(_poolHashMap);

        _servantProvider = new ServantProvider() {

            public ManagedServant borrowServantProxy(String poolName) throws TimeoutException {
                ManagedServant proxy = null;
                int nodesSize = _poolHashMap.get(poolName).getNodes().size();
                Vector<Integer> order = PoolUtils.getRandomOrder(nodesSize);
                int nodeIndex = 0;
                PoolNode node = null;
                long tstart = System.currentTimeMillis();
                do {
                    try {
                        node = _poolHashMap.get(poolName).getNodes().elementAt(order.elementAt(nodeIndex));
                        proxy = (ManagedServant) ServantProxyPoolSingletonReg.getInstance(node.getRegistryHost(),
                                node.getRegistryPort(), node.getServantPoolPrefix()).borrowObject();
                    } catch (NoSuchElementException e) {
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }

                    if (proxy != null) {
                        try {
                            log.info("<" + Thread.currentThread().getName() + "> obtained resource : "
                                    + proxy.getServantName());
                        } catch (Exception e) {
                        }
                        break;
                    } else {
                        nodeIndex = (nodeIndex + 1) % nodesSize;
                    }

                    if (System.currentTimeMillis() - tstart > _poolHashMap.get(poolName).getBorrowTimeout())
                        throw new TimeoutException();
                    try {
                        Thread.sleep(20);
                    } catch (Exception e) {
                    }

                    log.info("<" + Thread.currentThread().getName() + "> thread waiting for resource for  : "
                            + ((System.currentTimeMillis() - tstart) / 1000) + " seconds");

                } while (true);

                _borrowedServants.put(proxy, node);
                return proxy;
            }

            public ManagedServant borrowServantProxyNoWait(String poolName) {
                ManagedServant proxy = null;
                int nodesSize = _poolHashMap.get(poolName).getNodes().size();
                Vector<Integer> order = PoolUtils.getRandomOrder(nodesSize);
                int nodeIndex = 0;
                PoolNode node = null;
                do {
                    try {
                        node = _poolHashMap.get(poolName).getNodes().elementAt(order.elementAt(nodeIndex));
                        proxy = (ManagedServant) ServantProxyPoolSingletonReg.getInstance(node.getRegistryHost(),
                                node.getRegistryPort(), node.getServantPoolPrefix()).borrowObject();
                    } catch (NoSuchElementException e) {
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }

                    if (proxy != null) {
                        try {
                            log.info("<" + Thread.currentThread().getName() + "> obtained resource : "
                                    + proxy.getServantName());
                        } catch (Exception e) {
                        }
                        break;
                    } else {
                        nodeIndex = (nodeIndex + 1);
                        if (nodeIndex >= nodesSize)
                            break;
                    }

                } while (true);

                if (proxy != null)
                    _borrowedServants.put(proxy, node);
                return proxy;
            }

            public void returnServantProxy(ManagedServant proxy) {
                if (proxy == null)
                    return;
                try {
                    PoolNode node = _borrowedServants.get(proxy);
                    _borrowedServants.remove(proxy);
                    ServantProxyPoolSingletonReg.getInstance(node.getRegistryHost(), node.getRegistryPort(),
                            node.getServantPoolPrefix()).returnObject(proxy);
                } catch (Exception e) {
                    e.printStackTrace();
                    System.exit(0);
                }
            }

            public void returnServantProxy(String poolName, ManagedServant proxy) {
                if (proxy == null)
                    return;
                try {
                    PoolNode node = _borrowedServants.get(proxy);
                    _borrowedServants.remove(proxy);
                    ServantProxyPoolSingletonReg.getInstance(node.getRegistryHost(), node.getRegistryPort(),
                            node.getServantPoolPrefix()).returnObject(proxy);
                } catch (Exception e) {
                    e.printStackTrace();
                    System.exit(0);
                }
            }

            public ManagedServant borrowServantProxy() throws TimeoutException {
                return borrowServantProxy(_defaultPoolName);
            }

            public ManagedServant borrowServantProxyNoWait() {
                return borrowServantProxyNoWait(_defaultPoolName);
            }

            public String getDefaultPoolName() {
                return _defaultPoolName;
            }

            public Registry getRegistry() {
                return _rmiRegistry;
            }

        };

    }

    @Override
    public ServantProvider getServantProvider() {
        return _servantProvider;
    }

    void initPoolsHashMap(InputStream poolsXmlStream) throws Exception {
        DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
        domFactory.setNamespaceAware(true);
        domFactory.setValidating(false);
        DocumentBuilder documentBuilder = domFactory.newDocumentBuilder();

        Document document = documentBuilder.parse(poolsXmlStream);
        NodeList pools = document.getDocumentElement().getChildNodes();
        for (int i = 0; i < pools.getLength(); ++i) {
            Node p = pools.item(i);
            if (p.getNodeName().equals("pool")) {
                String name = p.getAttributes().getNamedItem("name").getNodeValue();
                int timeout = p.getAttributes().getNamedItem("borrowTimeout") == null ? DEFAULT_TIMEOUT
                        : Integer.decode(p.getAttributes().getNamedItem("borrowTimeout").getNodeValue());
                PoolData poolData = new PoolData(name, timeout, new Vector<PoolNode>());
                _poolHashMap.put(poolData.getPoolName(), poolData);

                NodeList pnodes = p.getChildNodes();
                for (int j = 0; j < pnodes.getLength(); ++j) {
                    Node pn = pnodes.item(j);
                    if (pn.getNodeName().equals("node")) {
                        String prefix = pn.getAttributes().getNamedItem("prefix") == null ? DEFAULT_PREFIX
                                : pn.getAttributes().getNamedItem("prefix").getNodeValue();
                        String host = pn.getAttributes().getNamedItem("registryHost") == null
                                ? DEFAULT_REGISTRY_HOST
                                : pn.getAttributes().getNamedItem("registryHost").getNodeValue();
                        int port = pn.getAttributes().getNamedItem("registryPort") == null ? DEFAULT_REGISTRY_PORT
                                : Integer.decode(pn.getAttributes().getNamedItem("registryPort").getNodeValue());
                        poolData.getNodes().add(new PoolNode(prefix, host, port));
                    }
                }
            }
        }

        _defaultPoolName = document.getDocumentElement().getAttribute("default");
        if (_poolHashMap.get(_defaultPoolName) == null)
            throw new Exception("bad default pool name");
    }

    private static class PoolNode {
        private String _servantPoolPrefix;
        private String _registryHost;
        private int _registryPort;

        public PoolNode(String poolPrefix, String host, int port) {
            _servantPoolPrefix = poolPrefix;
            _registryHost = host;
            _registryPort = port;
        }

        public String toString() {
            return "PoolNode[prefic=" + _servantPoolPrefix + " host=" + _registryHost + " port=" + _registryPort
                    + "]";
        }

        public String getRegistryHost() {
            return _registryHost;
        }

        public int getRegistryPort() {
            return _registryPort;
        }

        public String getServantPoolPrefix() {
            return _servantPoolPrefix;
        }
    }

    private static class PoolData {
        private String _poolName;
        private Vector<PoolNode> _nodes;
        private int _borrowTimeout;

        public PoolData(String name, int timeout, Vector<PoolNode> nodes) {
            super();
            _poolName = name;
            this._nodes = nodes;
            _borrowTimeout = timeout;
        }

        public int getBorrowTimeout() {
            return _borrowTimeout;
        }

        public Vector<PoolNode> getNodes() {
            return _nodes;
        }

        public String getPoolName() {
            return _poolName;
        }

        public String toString() {
            return "PoolData[name=" + _poolName + " bto=" + _borrowTimeout + " nodes=" + _nodes + "]";
        }
    }

}