/* * JBoss, Home of Professional Open Source * Copyright 2006, Red Hat Middleware LLC, and individual contributors * by the @authors tag. See the copyright.txt in the distribution for a * full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.jboss.deployment.remoting; import java.io.InputStream; import java.net.InetAddress; import java.net.URI; import java.net.URL; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import javax.enterprise.deploy.shared.ModuleType; import javax.enterprise.deploy.spi.TargetModuleID; import javax.enterprise.deploy.spi.exceptions.TargetException; import org.jboss.deployment.spi.DeploymentManagerImpl; import org.jboss.deployment.spi.JBossTarget; import org.jboss.deployment.spi.SerializableTargetModuleID; import org.jboss.deployment.spi.TargetModuleIDImpl; import org.jboss.logging.Logger; import org.jboss.remoting.Client; import org.jboss.remoting.InvokerLocator; /** * A JBossTarget implementation that uses remoting streaming to upload * deployments. This target is selected by including a targetType=remote * param in the DeploymentManager deployURI. * * @author Scott.Stark@jboss.org * @version $Revision: 85945 $ */ public class StreamingTarget implements JBossTarget { private static final Logger log = Logger.getLogger(StreamingTarget.class); public static final String DESCRIPTION = "JBoss remoting streaming deployment target"; /** * The default remoting subsystem */ private static final String REMOTING_SUBSYSTEM = "JSR88"; /** The deployment target uri */ private URI deployURI; /** * Create a target given a remoting locator URI * @param deployURI */ public StreamingTarget(URI deployURI) { log.debug("new StreamingTarget: " + deployURI); try { String localHostName = InetAddress.getLocalHost().getHostName(); String scheme = deployURI.getScheme(); String host = deployURI.getHost(); int port = deployURI.getPort(); String query = deployURI.getRawQuery(); String uri = deployURI.toASCIIString(); if (uri.startsWith(DeploymentManagerImpl.DEPLOYER_URI)) { // Using unified invoker remoting defaults scheme = "socket"; host = localHostName; port = 4446; query = null; } StringBuffer tmp = new StringBuffer(scheme + "://"); tmp.append(host != null ? host : localHostName); tmp.append(port > 0 ? ":" + port : ""); tmp.append(query != null ? "/?" + query : ""); deployURI = new URI(tmp.toString()); log.debug("URI changed to: " + deployURI); this.deployURI = deployURI; } catch (Exception e) { log.error(e); } } /** * Get the target's description * @return the description */ public String getDescription() { return DESCRIPTION; } /** * Get the target's name * @return the name */ public String getName() { return deployURI.toString(); } /** * Get the target's host name */ public String getHostName() { return deployURI.getHost(); } /** * Deploy a given module */ public void deploy(TargetModuleID targetModuleID) throws Exception { TargetModuleIDImpl moduleID = (TargetModuleIDImpl)targetModuleID; SerializableTargetModuleID smoduleID = new SerializableTargetModuleID(moduleID); Client client = getClient(); log.info("Begin deploy: " + moduleID); transferDeployment(client, smoduleID); log.info("End deploy"); client.disconnect(); } /** * Start a given module */ public void start(TargetModuleID targetModuleID) throws Exception { Client client = getClient(); URL url = new URL(targetModuleID.getModuleID()); log.debug("Start: " + url); HashMap<String, String> args = new HashMap<String, String>(1); args.put("moduleID", url.toExternalForm()); log.info("Begin start: " + url); invoke(client, "start", args); log.info("End start"); } /** * Stop a given module */ public void stop(TargetModuleID targetModuleID) throws Exception { Client client = getClient(); URL url = new URL(targetModuleID.getModuleID()); log.debug("Start: " + url); HashMap<String, String> args = new HashMap<String, String>(1); args.put("moduleID", url.toExternalForm()); log.info("Begin stop: " + url); invoke(client, "stop", args); log.info("End stop"); } /** * Undeploy a given module */ public void undeploy(TargetModuleID targetModuleID) throws Exception { Client client = getClient(); URL url = new URL(targetModuleID.getModuleID()); log.debug("Start: " + url); HashMap<String, String> args = new HashMap<String, String>(1); args.put("moduleID", url.toExternalForm()); log.info("Begin undeploy: " + url); invoke(client, "undeploy", args); log.info("End undeploy"); } /** * Retrieve the list of all J2EE application modules running or not running * on the identified targets. */ public TargetModuleID[] getAvailableModules(ModuleType moduleType) throws TargetException { try { Client client = getClient(); HashMap<String, Integer> args = new HashMap<String, Integer>(1); args.put("moduleType", moduleType.getValue()); SerializableTargetModuleID[] modules = (SerializableTargetModuleID[]) invoke(client, "getAvailableModules", args); List<TargetModuleID> list = new ArrayList<TargetModuleID>(); for (int n = 0; n < modules.length; n++) { SerializableTargetModuleID id = modules[n]; String moduleID = id.getModuleID(); boolean isRunning = id.isRunning(); ModuleType type = ModuleType.getModuleType(id.getModuleType()); TargetModuleIDImpl tmid = new TargetModuleIDImpl(this, moduleID, null, isRunning, type); convertChildren(tmid, id); list.add(tmid); } TargetModuleID[] targetModuleIDs = new TargetModuleID[list.size()]; list.toArray(targetModuleIDs); return targetModuleIDs; } catch (Exception e) { TargetException tex = new TargetException("Failed to get available modules"); tex.initCause(e); throw tex; } } private void convertChildren(TargetModuleIDImpl parent, SerializableTargetModuleID parentID) { SerializableTargetModuleID[] children = parentID.getChildModuleIDs(); int length = children != null ? children.length : 0; for (int n = 0; n < length; n++) { SerializableTargetModuleID id = children[n]; String moduleID = id.getModuleID(); boolean isRunning = id.isRunning(); ModuleType type = ModuleType.getModuleType(id.getModuleType()); TargetModuleIDImpl child = new TargetModuleIDImpl(this, moduleID, parent, isRunning, type); parent.addChildTargetModuleID(child); convertChildren(child, id); } } /** * Get the remoting client connection * @return * @throws Exception */ private Client getClient() throws Exception { String locatorURI = deployURI.toString(); InvokerLocator locator = new InvokerLocator(locatorURI); log.debug("Calling remoting server with locator uri of: " + locatorURI); Client remotingClient = new Client(locator, REMOTING_SUBSYSTEM); remotingClient.connect(); return remotingClient; } private void transferDeployment(Client client, SerializableTargetModuleID smoduleID) throws Exception { URL deployURL = new URL(smoduleID.getModuleID()); InputStream is = deployURL.openStream(); try { client.invoke(is, smoduleID); } catch(Exception e) { throw e; } catch(Error e) { throw new RuntimeException(e); } catch(Throwable e) { throw new RuntimeException(e); } finally { is.close(); } } private Object invoke(Client client, String name, HashMap args) throws Exception { try { Object returnValue = client.invoke(name, args); return returnValue; } catch(Exception e) { throw e; } catch(Error e) { throw new RuntimeException(e); } catch(Throwable e) { throw new RuntimeException(e); } } }