/* * Controller.java * Copyright (C) 2011,2012 Wannes De Smet * * 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.xenmaster.controller; import java.net.URL; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import org.apache.log4j.Logger; import org.xenmaster.api.Session; import org.xenmaster.entities.Host; /** * Provides easily accessible context per thread * @created Oct 1, 2011 * @author double-u */ public class Controller { private static ThreadLocal<Controller> instance = new ThreadLocal<Controller>() { @Override protected Controller initialValue() { return new Controller(); } }; protected final static ConcurrentHashMap<UUID, Controller> instances = new ConcurrentHashMap<>(); protected Dispatcher dispatcher; private Controller(URL xenHost) { this.dispatcher = buildDispatcher(xenHost); } private Controller() { } protected final Dispatcher buildDispatcher(URL xenHost) { Dispatcher d = new Dispatcher(xenHost); d.getConnections().getSession().addListener(new SAL()); return d; } public static void build(Host host) { ThreadLocal<Controller> tl = new ThreadLocal<>(); tl.set(new Controller(host.connect().getUrl())); instance = tl; } public static void build(URL url) { ThreadLocal<Controller> tl = new ThreadLocal<>(); tl.set(new Controller(url)); instance = tl; } public static Controller getLocal() { if (instance.get() == null) { Logger.getLogger(Controller.class).warn("Controller is not initialized, switching to next available"); switchToNextAvailableContext(); } return instance.get(); } public static void switchContext(UUID hostUUID) { if (!instances.containsKey(hostUUID)) { // new Controller(getConfigForHost(uuid)) //Controller c = new Controller(); //c.getDispatcher().getConnection().getSession().loginWithPassword("root", "r00tme"); Logger.getLogger(Controller.class).info("Creating new context for host " + hostUUID.toString()); } instance.set(instances.get(hostUUID)); } public static void switchToNextAvailableContext() { if (instances.size() < 1) { Logger.getLogger(Controller.class).error("No host context available"); } else { if (instances.values().iterator().hasNext()) { instance.set(instances.values().iterator().next()); } else { Logger.getLogger(Controller.class).info("No more available contexts"); } } } public Dispatcher getDispatcher() { return dispatcher; } public static Session getSession() { return Controller.getLocal().getDispatcher().getConnections().getSession(); } public static Object dispatch(String methodName, Object... params) throws BadAPICallException { if (Controller.getLocal() == null) { Logger.getLogger(Controller.class).warn("Local Host context not set, switching to next available one"); switchToNextAvailableContext(); } return Controller.getLocal().getDispatcher().dispatchWithSession(methodName, params); } public static Object dispatchOn(String methodName, int connection, Object... params) throws BadAPICallException { if (Controller.getLocal() == null) { Logger.getLogger(Controller.class).warn("Local Host context not set, switching to next available one"); switchToNextAvailableContext(); } Logger.getLogger(Controller.class).debug("Dispatching call " + methodName + " to connection #" + connection); return Controller.getLocal().getDispatcher().dispatchWithSession(methodName, params, connection); } protected class SAL implements Session.SessionActivityListener { @Override public void sessionEstablished(Session session) { instances.put(session.getThisHost().getUUID(), Controller.this); } } }