/******************************************************************************* * Copyright (c) 2010 - 2013 SpringSource, a divison of VMware, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * SpringSource, a division of VMware, Inc. - initial API and implementation *******************************************************************************/ package org.eclipse.virgo.ide.runtime.internal.core.runtimes; import java.io.File; import java.io.FileFilter; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Properties; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Status; import org.eclipse.jdt.launching.IRuntimeClasspathEntry; import org.eclipse.jdt.launching.JavaRuntime; import org.eclipse.libra.framework.editor.core.model.IBundle; import org.eclipse.virgo.ide.runtime.core.IServerBehaviour; import org.eclipse.virgo.ide.runtime.core.IServerRuntimeProvider; import org.eclipse.virgo.ide.runtime.core.ServerCorePlugin; import org.eclipse.virgo.ide.runtime.core.ServerUtils; import org.eclipse.virgo.ide.runtime.internal.core.DeploymentIdentity; import org.eclipse.virgo.ide.runtime.internal.core.command.GenericJmxServerDeployCommand; import org.eclipse.virgo.ide.runtime.internal.core.command.IServerCommand; import org.eclipse.virgo.ide.runtime.internal.core.command.JmxBundleAdminExecuteCommand; import org.eclipse.virgo.ide.runtime.internal.core.command.JmxBundleAdminServerCommand; import org.eclipse.virgo.ide.runtime.internal.core.command.JmxServerDeployCommand; import org.eclipse.virgo.ide.runtime.internal.core.command.JmxServerPingCommand; import org.eclipse.virgo.ide.runtime.internal.core.command.JmxServerRefreshCommand; import org.eclipse.virgo.ide.runtime.internal.core.command.JmxServerShutdownCommand; import org.eclipse.virgo.ide.runtime.internal.core.command.JmxServerUndeployCommand; import org.eclipse.virgo.ide.runtime.internal.core.command.JmxServerUpdateCommand; import org.eclipse.virgo.util.common.StringUtils; import org.eclipse.wst.server.core.IModule; import org.eclipse.wst.server.core.IRuntime; import org.eclipse.wst.server.core.IServer; import org.eclipse.wst.server.core.model.IModuleFile; import org.eclipse.wst.server.core.util.PublishHelper; /** * {@link IServerRuntimeProvider} for Generic Virgo Server. * * @author Terry Hon * @author Christian Dupuis * @author Miles Parker * @author Leo Dos Santos * @since 2.0.0 */ public abstract class VirgoRuntimeProvider implements IServerRuntimeProvider { private static final String EXT_DIR = "ext"; private static final String USR_DIR = "usr"; private static final String REPOSITORY_DIR = "repository"; public static final String SERVER_VIRGO_BASE = "org.eclipse.virgo.server.runtime.virgo"; private static final String BUNDLE_OBJECT_NAME = "org.eclipse.virgo.kernel:type=Model,artifact-type=bundle,name=$NAME,version=$VERSION"; private static final String DEPLOYER_MBEAN_NAME = "org.eclipse.virgo.kernel:category=Control,type=Deployer"; private static final String PAR_OBJECT_NAME = "org.eclipse.virgo.kernel:type=Model,artifact-type=par,name=$NAME,version=$VERSION"; private static final String PLAN_OBJECT_NAME = "org.eclipse.virgo.kernel:type=Model,artifact-type=plan,name=$NAME,version=$VERSION"; private static final String RECOVERY_MONITOR_MBEAN_NAME = "org.eclipse.virgo.kernel:category=Control,type=RecoveryMonitor"; private static final String SHUTDOWN_MBEAN_NAME = "org.eclipse.virgo.kernel:type=Shutdown"; /** * {@inheritDoc} */ public String getDeployerMBeanName() { return DEPLOYER_MBEAN_NAME; } /** * {@inheritDoc} */ public String getRecoveryMonitorMBeanName() { return RECOVERY_MONITOR_MBEAN_NAME; } /** * {@inheritDoc} Provides generic runtime arguments shared by all versions. */ public String[] getRuntimeVMArguments(IServerBehaviour behaviour, IPath installPath, IPath configPath, IPath deployPath) { String serverHome = ServerUtils.getServer(behaviour).getRuntimeBaseDirectory().toOSString(); String absConfigDir = serverHome + "/" + getConfigurationDir(); List<String> list = new ArrayList<String>(); list.add("-XX:+HeapDumpOnOutOfMemoryError"); list.add("-XX:ErrorFile=\"" + serverHome + "/serviceability/error.log\""); list.add("-XX:HeapDumpPath=\"" + serverHome + "/serviceability/heap_dump.hprof\""); list.add("-XX:MaxPermSize=" + ServerUtils.getServer(behaviour).getMaxPermSize()); list.add("-Djava.rmi.server.hostname=127.0.0.1"); list.add("-Dorg.eclipse.virgo.kernel.home=\"" + serverHome + "\""); list.add("-Djava.io.tmpdir=\"" + serverHome + "/work/tmp/\""); list.add("-Dcom.sun.management.jmxremote"); list.add("-Dssh.server.keystore=\"" + absConfigDir + "/hostkey.ser\""); list.add("-Dcom.sun.management.jmxremote.port=" + ServerUtils.getServer(behaviour).getMBeanServerPort()); list.add("-Dcom.sun.management.jmxremote.authenticate=false"); list.add("-Dcom.sun.management.jmxremote.ssl=false"); list.add("-Dorg.eclipse.virgo.kernel.authentication.file=\"" + absConfigDir + "/org.eclipse.virgo.kernel.users.properties\""); list.add("-Djava.security.auth.login.config=\"" + absConfigDir + "/org.eclipse.virgo.kernel.authentication.config\""); if (getInstallationType(ServerUtils.getServer(behaviour).getRuntime().getRuntime()) == InstallationType.JETTY) { list.add("-Djetty.home=\"" + serverHome + "/jetty\""); } return list.toArray(new String[list.size()]); } /** * {@inheritDoc} */ public IServerCommand<Void> getServerUndeployCommand(IServerBehaviour serverBehaviour, IModule module) { return new JmxServerUndeployCommand(serverBehaviour, module); } /** * {@inheritDoc} */ public IServerCommand<Void> getServerUpdateCommand(IServerBehaviour serverBehaviour, IModule module, IModuleFile moduleFile, DeploymentIdentity identity, String bundleSymbolicName, String targetPath) { return new JmxServerUpdateCommand(serverBehaviour, module, moduleFile, identity, bundleSymbolicName, targetPath, BUNDLE_OBJECT_NAME, PAR_OBJECT_NAME, PLAN_OBJECT_NAME); } /** * {@inheritDoc} */ public String getShutdownMBeanName() { return SHUTDOWN_MBEAN_NAME; } /** * {@inheritDoc} * * @throws IOException */ public Properties getProperties(IPath installPath, String type) throws IOException { String version = installPath.append("lib").append("." + type).toOSString(); File versionFile = new File(version); if (versionFile.exists()) { InputStream is = null; is = new FileInputStream(versionFile); Properties versionProperties = new Properties(); versionProperties.load(is); try { is.close(); } catch (IOException e) { } return versionProperties; } else { throw new IOException("Installation does not contain a properties file. Path: " + installPath); } } protected String getRepositoryConfigurationFileName() { return "org.eclipse.virgo.repository.properties"; } /** * {@inheritDoc} */ public IStatus canAddModule(IModule module) { return Status.OK_STATUS; } public IServerCommand<Boolean> getServerPingCommand(IServerBehaviour IServerBehaviour) { return new JmxServerPingCommand(IServerBehaviour); } /** * {@inheritDoc} */ public IServerCommand<Void> getServerShutdownCommand(IServerBehaviour IServerBehaviour) { return new JmxServerShutdownCommand(IServerBehaviour); } /** * {@inheritDoc} */ public IServerCommand<Void> getServerRefreshCommand(IServerBehaviour IServerBehaviour, IModule module, String bundleSymbolicName) { return new JmxServerRefreshCommand(IServerBehaviour, module, bundleSymbolicName); } /** * {@inheritDoc} */ public String[] getExcludedRuntimeProgramArguments(boolean starting) { List<String> list = new ArrayList<String>(); return list.toArray(new String[list.size()]); } /** * {@inheritDoc} */ public String getConfigPath(IRuntime runtime) { return runtime.getLocation().append(getConfigurationDir()).append("server.config").toString(); } /** * {@inheritDoc} */ public String getProfilePath(IRuntime runtime) { return runtime.getLocation().append(getProfileDir()).append(getServerProfileName()).toString(); } protected String getServerProfileName() { return "java6-server.profile"; } /** * {@inheritDoc} */ public IPath getRuntimeBaseDirectory(IServer server) { return server.getRuntime().getLocation(); } /** * Provides runtime class path common to server versions. * * @see org.eclipse.virgo.ide.runtime.core.IServerRuntimeProvider#getRuntimeClasspath(org.eclipse.core.runtime.IPath) */ public List<IRuntimeClasspathEntry> getRuntimeClasspath(IPath installPath) { List<IRuntimeClasspathEntry> cp = new ArrayList<IRuntimeClasspathEntry>(); IPath binPath = installPath.append("lib"); if (binPath.toFile().exists()) { File libFolder = binPath.toFile(); for (File library : libFolder.listFiles(new FileFilter() { public boolean accept(File pathname) { return pathname.isFile() && pathname.toString().endsWith(".jar"); } })) { IPath path = binPath.append(library.getName()); cp.add(JavaRuntime.newArchiveRuntimeClasspathEntry(path)); } } return cp; } /** * {@inheritDoc} */ public String getUserLevelBundleRepositoryPath(IRuntime runtime) { return runtime.getLocation().append(REPOSITORY_DIR).append(USR_DIR).toString(); } /** * {@inheritDoc} */ public String getUserLevelLibraryRepositoryPath(IRuntime runtime) { return runtime.getLocation().append(REPOSITORY_DIR).append(USR_DIR).toString(); } /** * @see org.eclipse.virgo.ide.runtime.core.IServerRuntimeProvider#getExtLevelBundleRepositoryPath(org.eclipse.wst.server.core.IRuntime) */ public String getExtLevelBundleRepositoryPath(IRuntime runtime) { return runtime.getLocation().append(REPOSITORY_DIR).append(EXT_DIR).toString(); } /** * {@inheritDoc} */ public IServerCommand<DeploymentIdentity> getServerDeployCommand(IServerBehaviour IServerBehaviour, IModule module) { return new JmxServerDeployCommand(IServerBehaviour, module); } /** * {@inheritDoc} */ public IServerCommand<DeploymentIdentity> getServerRedeployCommand(IServerBehaviour IServerBehaviour, IModule module) { return getServerDeployCommand(IServerBehaviour, module); } /** * {@inheritDoc} */ public IServerCommand<Map<Long, IBundle>> getServerBundleAdminCommand(IServerBehaviour serverBehaviour) { return new JmxBundleAdminServerCommand(serverBehaviour); } /** * @see org.eclipse.virgo.ide.runtime.core.IServerRuntimeProvider#getServerDeployCommand(org.eclipse.virgo.ide.runtime.core.IServerBehaviour) */ public IServerCommand<DeploymentIdentity> getServerDeployCommand(IServerBehaviour serverBehaviour) { return new GenericJmxServerDeployCommand(serverBehaviour, getConnectorBundleUri()); } /** * {@inheritDoc} */ public IServerCommand<String> getServerBundleAdminExecuteCommand(IServerBehaviour serverBehaviour, String command) { return new JmxBundleAdminExecuteCommand(serverBehaviour, command); } private void createRepositoryConfiguration(IServerBehaviour serverBehaviour, String fileName) { // copy repository.properties into the stage and add the stage // repository File serverHome = ServerUtils.getServer(serverBehaviour).getRuntimeBaseDirectory().toFile(); Properties properties = new Properties(); try { properties.load(new FileInputStream(new File(serverHome, getConfigurationDir() + File.separatorChar + fileName))); } catch (FileNotFoundException e) { // TODO CD add logging } catch (IOException e) { // TODO CD add logging } properties.put("stage.type", "watched"); properties.put("stage.watchDirectory", "stage"); String chain = properties.getProperty("chain"); chain = "stage" + (StringUtils.hasLength(chain) ? "," + chain : ""); properties.put("chain", chain); try { File stageDirectory = new File(serverHome, "stage"); if (!stageDirectory.exists()) { stageDirectory.mkdirs(); } properties.store(new FileOutputStream(new File(serverHome, "stage" + File.separator + fileName)), "Generated by Virgo IDE " + ServerCorePlugin.getDefault().getBundle().getVersion()); } catch (FileNotFoundException e) { // TODO CD add logging } catch (IOException e) { // TODO CD add logging } } public void preStartup(IServerBehaviour serverBehaviour) { File serverHome = ServerUtils.getServer(serverBehaviour).getRuntimeBaseDirectory().toFile(); File workFolder = new File(serverHome, "work"); if (ServerUtils.getServer(serverBehaviour).shouldCleanStartup()) { PublishHelper.deleteDirectory(workFolder, new NullProgressMonitor()); PublishHelper.deleteDirectory(new File(serverHome, "serviceability"), new NullProgressMonitor()); } new File(workFolder, "tmp").mkdirs(); // Fix 464814 createRepositoryConfiguration(serverBehaviour, getRepositoryConfigurationFileName()); } public abstract boolean isHandlerFor(IRuntime runtime); /** * {@inheritDoc} */ public IStatus verifyInstallation(IRuntime runtime) { InstallationType installation = getInstallationType(runtime); if (installation == null) { return new Status(IStatus.ERROR, ServerCorePlugin.PLUGIN_ID, "Invalid Virgo Server: Could not determine version."); } return new Status(IStatus.OK, ServerCorePlugin.PLUGIN_ID, "Valid installation: " + getName(runtime) + "."); } public InstallationType getInstallationType(IRuntime runtime) { Properties versionProperties; IPath location = runtime.getLocation(); try { versionProperties = getProperties(location, "version"); } catch (IOException e) { return null; } String versionString = versionProperties.getProperty("virgo.server.version"); if (versionString != null) { if (location.append("jetty").toFile().exists()) { return InstallationType.JETTY; } else { return InstallationType.TOMCAT; } } versionString = versionProperties.getProperty("virgo.kernel.version"); if (versionString != null) { return InstallationType.KERNEL; } versionString = versionProperties.getProperty("virgo.nano.version"); if (versionString != null) { return InstallationType.NANO; } return null; } public String getVersionName(IRuntime runtime) { Properties versionProperties; try { versionProperties = getProperties(runtime.getLocation(), "version"); } catch (IOException e) { return null; } String versionString = versionProperties.getProperty("virgo.server.version"); if (versionString == null) { versionString = versionProperties.getProperty("virgo.kernel.version"); } if (versionString == null) { versionString = versionProperties.getProperty("virgo.nano.version"); } if (versionString == null) { versionString = "Unknown"; } return versionString; } public String getName(IRuntime runtime) { return getInstallationType(runtime).getName() + " v" + getVersionName(runtime); } public abstract String getSupportedVersions(); public abstract String getConfigurationDir(); public String[] getServerPropertiesDirectories() { return new String[] { getConfigurationDir(), "repository/ext" }; } public String[] getServerLogDirectories() { return new String[] { getLogDir() + "/logs", getLogDir() + "/eventlogs" }; } /** * @see org.eclipse.virgo.ide.runtime.internal.core.runtimes.VirgoRuntimeProvider#getLogDir() */ public String getLogDir() { return "serviceability"; } /** * Non-API */ abstract String getProfileDir(); }