/* * Copyright 2010-2012 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"). * You may not use this file except in compliance with the License. * A copy of the License is located at * * http://aws.amazon.com/apache2.0 * * or in the "license" file accompanying this file. This file is distributed * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the License for the specific language governing * permissions and limitations under the License. */ package com.amazonaws.eclipse.elasticbeanstalk; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.List; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.resource.ImageRegistry; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.FontData; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.IStartup; import org.eclipse.ui.plugin.AbstractUIPlugin; import org.eclipse.wst.server.core.IRuntimeWorkingCopy; import org.eclipse.wst.server.core.IServer; import org.eclipse.wst.server.core.IServerLifecycleListener; import org.eclipse.wst.server.core.IServerType; import org.eclipse.wst.server.core.IServerWorkingCopy; import org.eclipse.wst.server.core.ServerCore; import org.osgi.framework.BundleContext; import com.amazonaws.eclipse.core.AwsToolkitCore; import com.amazonaws.eclipse.core.regions.Region; import com.amazonaws.eclipse.core.regions.ServiceAbbreviations; import com.amazonaws.eclipse.elasticbeanstalk.jobs.SyncEnvironmentsJob; import com.amazonaws.eclipse.elasticbeanstalk.server.ui.ServerDefaultsUtils; import com.amazonaws.eclipse.elasticbeanstalk.solutionstacks.SolutionStacks; import com.amazonaws.eclipse.elasticbeanstalk.util.ElasticBeanstalkClientExtensions; import com.amazonaws.services.elasticbeanstalk.AWSElasticBeanstalk; import com.amazonaws.services.elasticbeanstalk.model.ApplicationDescription; import com.amazonaws.services.elasticbeanstalk.model.ConfigurationOptionSetting; import com.amazonaws.services.elasticbeanstalk.model.ConfigurationSettingsDescription; import com.amazonaws.services.elasticbeanstalk.model.DescribeApplicationsRequest; import com.amazonaws.services.elasticbeanstalk.model.DescribeApplicationsResult; import com.amazonaws.services.elasticbeanstalk.model.EnvironmentDescription; /** * The activator class controls the plug-in life cycle */ public class ElasticBeanstalkPlugin extends AbstractUIPlugin implements IStartup { public static final String IMG_AWS_BOX = "aws-box"; public static final String IMG_SERVER = "server"; public static final String IMG_IMPORT = "import"; public static final String IMG_EXPORT = "export"; public static final String IMG_CLIPBOARD = "clipboard"; public static final String IMG_ENVIRONMENT = "environment"; public static final String IMG_SERVICE = "beanstalk-service"; public static final String IMG_APPLICATION = "application"; private static final String SUBTLE_DIALOG_FONT = "subtle-dialog"; public static final String PLUGIN_ID = "com.amazonaws.eclipse.elasticbeanstalk"; //$NON-NLS-1$ public static final String DEFAULT_REGION = "us-east-1"; // The shared instance private static ElasticBeanstalkPlugin plugin; private SyncEnvironmentsJob syncEnvironmentsJob; private NewServerListener newServerListener; public static final String TOMCAT_6_SERVER_TYPE_ID = "com.amazonaws.eclipse.elasticbeanstalk.servers.environment"; //$NON-NLS-1$ public static final String TOMCAT_7_SERVER_TYPE_ID = "com.amazonaws.eclipse.elasticbeanstalk.servers.tomcat7"; //$NON-NLS-1$ public static final String TOMCAT_8_SERVER_TYPE_ID = "com.amazonaws.eclipse.elasticbeanstalk.servers.tomcat8"; //$NON-NLS-1$ public static final Collection<String> SERVER_TYPE_IDS = new HashSet<String>(); private Font subtleDialogFont; static { SERVER_TYPE_IDS.add(TOMCAT_6_SERVER_TYPE_ID); SERVER_TYPE_IDS.add(TOMCAT_7_SERVER_TYPE_ID); SERVER_TYPE_IDS.add(TOMCAT_8_SERVER_TYPE_ID); } /** * Returns the shared plugin instance. * * @return the shared plugin instance. */ public static ElasticBeanstalkPlugin getDefault() { return plugin; } public static void trace(String message) { if ( Platform.inDebugMode() ) System.out.println(message); } public void start(BundleContext context) throws Exception { super.start(context); plugin = this; syncEnvironmentsJob = new SyncEnvironmentsJob(); syncEnvironmentsJob.schedule(); newServerListener = new NewServerListener(); ServerCore.addServerLifecycleListener(newServerListener); } /* * (non-Javadoc) * * @see * org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext * ) */ public void stop(BundleContext context) throws Exception { plugin = null; syncEnvironmentsJob.cancel(); ServerCore.removeServerLifecycleListener(newServerListener); super.stop(context); if (subtleDialogFont != null) subtleDialogFont.dispose(); subtleDialogFont = null; } /* (non-Javadoc) * @see org.eclipse.ui.IStartup#earlyStartup() */ public void earlyStartup() { } public void syncEnvironments() { if ( syncEnvironmentsJob != null ) syncEnvironmentsJob.wakeUp(); } @Override protected ImageRegistry createImageRegistry() { ImageRegistry imageRegistry = new ImageRegistry(Display.getCurrent()); imageRegistry.put(IMG_EXPORT, ImageDescriptor.createFromFile(getClass(), "/icons/export.gif")); imageRegistry.put(IMG_IMPORT, ImageDescriptor.createFromFile(getClass(), "/icons/import.gif")); imageRegistry.put(IMG_SERVER, ImageDescriptor.createFromFile(getClass(), "/icons/server.png")); imageRegistry.put(IMG_AWS_BOX, ImageDescriptor.createFromFile(getClass(), "/icons/aws-box.gif")); imageRegistry.put(IMG_CLIPBOARD, ImageDescriptor.createFromFile(getClass(), "/icons/clipboard.gif")); imageRegistry.put(IMG_ENVIRONMENT, ImageDescriptor.createFromFile(getClass(), "/icons/environment.png")); imageRegistry.put(IMG_SERVICE, ImageDescriptor.createFromFile(getClass(), "/icons/beanstalk-service.png")); imageRegistry.put(IMG_APPLICATION, ImageDescriptor.createFromFile(getClass(), "/icons/application.png")); return imageRegistry; } public Font getSubtleDialogFont() { return subtleDialogFont; } public void initializeSubtleDialogFont(Font baseFont) { if (getSubtleDialogFont() != null) return; FontData[] fontData = baseFont.getFontData(); for (FontData fd : fontData) fd.setStyle(SWT.ITALIC); subtleDialogFont = new Font(Display.getDefault(), fontData); } /** * Returns all AWS Elastic Beanstalk servers known to ServerCore. */ public static Collection<IServer> getExistingElasticBeanstalkServers() { List<IServer> elasticBeanstalkServers = new ArrayList<IServer>(); IServer[] servers = ServerCore.getServers(); for ( IServer server : servers ) { if ( server.getServerType() == null) continue; if ( SERVER_TYPE_IDS.contains(server.getServerType().getId()) ) { elasticBeanstalkServers.add(server); } } return elasticBeanstalkServers; } /** * Returns the server matching the description given in the region given, if * it can be found, or null otherwise. */ public static IServer getServer(EnvironmentDescription environmentDescription, Region region) { for ( IServer server : getExistingElasticBeanstalkServers() ) { if ( environmentsSame(environmentDescription, region, server) ) { return server; } } return null; } /** * Returns whether the environment given represents the server given. */ public static boolean environmentsSame(EnvironmentDescription env, Region region, IServer server) { String beanstalkEndpoint = region.getServiceEndpoints().get(ServiceAbbreviations.BEANSTALK); Environment environment = (Environment) server.getAdapter(Environment.class); if (environment == null) return false; return environment.getApplicationName().equals(env.getApplicationName()) && environment.getEnvironmentName().equals(env.getEnvironmentName()) && environment.getRegionEndpoint().equals(beanstalkEndpoint); } /** * Imports an environment as a Server and returns it. * * @param monitor * An optional progress monitor that will perform 3 units of work * during the import process. * @throws CoreException * If the environment cannot be imported */ public static IServer importEnvironment(EnvironmentDescription environmentDescription, Region region, IProgressMonitor monitor) throws CoreException { String solutionStackName = environmentDescription.getSolutionStackName(); String serverTypeId = null; try { serverTypeId = SolutionStacks.lookupServerTypeIdBySolutionStack(solutionStackName); } catch ( Exception e ) { throw new CoreException(new Status(IStatus.ERROR, ElasticBeanstalkPlugin.PLUGIN_ID, e.getMessage())); } final IServerType serverType = ServerCore.findServerType(serverTypeId); IRuntimeWorkingCopy runtime = serverType.getRuntimeType().createRuntime(null, monitor); IServerWorkingCopy serverWorkingCopy = serverType.createServer(null, null, runtime, monitor); ServerDefaultsUtils.setDefaultHostName(serverWorkingCopy, region.getServiceEndpoints().get(ServiceAbbreviations.BEANSTALK)); ServerDefaultsUtils.setDefaultServerName(serverWorkingCopy, environmentDescription.getEnvironmentName()); /* * These values must be bootstrapped before we can ask the environment * about its configuration. */ Environment env = (Environment) serverWorkingCopy.loadAdapter(Environment.class, monitor); env.setAccountId(AwsToolkitCore.getDefault().getCurrentAccountId()); env.setRegionId(region.getId()); env.setApplicationName(environmentDescription.getApplicationName()); env.setEnvironmentName(environmentDescription.getEnvironmentName()); env.setIncrementalDeployment(true); fillInEnvironmentValues(environmentDescription, env, monitor); monitor.subTask("Creating server"); IServer server = serverWorkingCopy.save(true, monitor); runtime.save(true, monitor); monitor.worked(1); return server; } /** * Fills in the environment given with the values in the environment * description. * * @see ElasticBeanstalkPlugin#importEnvironment(EnvironmentDescription, IProgressMonitor) */ private static void fillInEnvironmentValues(EnvironmentDescription elasticBeanstalkEnv, Environment env, IProgressMonitor monitor) { ElasticBeanstalkClientExtensions clientExt = new ElasticBeanstalkClientExtensions(env); monitor.subTask("Getting application info"); ApplicationDescription applicationDesc = clientExt.getApplicationDescription(elasticBeanstalkEnv .getApplicationName()); if (applicationDesc != null) { env.setApplicationDescription(applicationDesc.getDescription()); } monitor.worked(1); monitor.subTask("Getting environment configuration"); List<ConfigurationSettingsDescription> currentSettings = env.getCurrentSettings(); for ( ConfigurationSettingsDescription settingDescription : currentSettings ) { for ( ConfigurationOptionSetting setting : settingDescription.getOptionSettings() ) { if ( setting.getNamespace().equals("aws:autoscaling:launchconfiguration") && setting.getOptionName().equals("EC2KeyName") ) { env.setKeyPairName(setting.getValue()); } } } monitor.worked(1); env.setCname(elasticBeanstalkEnv.getCNAME()); env.setEnvironmentDescription(elasticBeanstalkEnv.getDescription()); } /** * Listens for the creation of new elastic beanstalk servers and syncs all * environments' status. */ private class NewServerListener implements IServerLifecycleListener { public void serverAdded(IServer server) { if ( SERVER_TYPE_IDS.contains(server.getServerType().getId()) ) { ElasticBeanstalkPlugin.getDefault().syncEnvironments(); } } public void serverChanged(IServer server) { } public void serverRemoved(IServer server) { } } /** * Convenience method for exception logging. */ public void logException(String errorMessage, Throwable e) { getLog().log(new Status(Status.ERROR, PLUGIN_ID, errorMessage, e)); } }