/*
* Copyright 2010-2012 Amazon Technologies, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://aws.amazon.com/apache2.0
*
* 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.server.ui;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.LinkedList;
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.Status;
import org.eclipse.jface.layout.TreeColumnLayout;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.CheckboxTreeViewer;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.wst.server.core.IServer;
import com.amazonaws.AmazonClientException;
import com.amazonaws.AmazonServiceException;
import com.amazonaws.eclipse.core.AwsToolkitCore;
import com.amazonaws.eclipse.core.regions.Region;
import com.amazonaws.eclipse.core.regions.RegionUtils;
import com.amazonaws.eclipse.core.regions.ServiceAbbreviations;
import com.amazonaws.eclipse.elasticbeanstalk.ElasticBeanstalkPlugin;
import com.amazonaws.eclipse.elasticbeanstalk.NoCredentialsDialog;
import com.amazonaws.services.elasticbeanstalk.AWSElasticBeanstalk;
import com.amazonaws.services.elasticbeanstalk.model.EnvironmentDescription;
import com.amazonaws.services.elasticbeanstalk.model.EnvironmentStatus;
/**
* Wizard that allows the user to select running AWS Elastic Beanstalk environments to import into
* the servers view.
*/
public class ImportEnvironmentsWizard extends Wizard {
private CheckboxTreeViewer viewer;
private static final int COL_ENV_NAME = 0;
private static final int COL_APPLICATION_NAME = 1;
private static final int COL_DATE = 2;
private static final int COL_STATUS = 3;
private static final int COL_REGION = 4;
private static final int NUM_COLS = 5;
/*
* Environments to import, cast as Objects to interface easily with jface.
*/
private Object[] toImport = null;
public ImportEnvironmentsWizard() {
super();
setWindowTitle("Import environments into the Servers view");
setHelpAvailable(false);
}
private static final class RegionEnvironmentDescription {
private final Region region;
private final EnvironmentDescription environmentDescription;
public RegionEnvironmentDescription(Region region, EnvironmentDescription environmentDescription) {
this.region = region;
this.environmentDescription = environmentDescription;
}
}
/**
* Our single page is responsible for creating the controls.
*/
private class ImportPage extends WizardPage {
private static final String MESSAGE = "Choose the environments to import.";
protected ImportPage() {
super("Import environments", MESSAGE, AwsToolkitCore
.getDefault().getImageRegistry().getDescriptor(AwsToolkitCore.IMAGE_AWS_LOGO));
}
public void createControl(Composite container) {
if ( !AwsToolkitCore.getDefault().getAccountInfo().isValid() ) {
setControl(NoCredentialsDialog.createComposite(container));
return;
}
IStatus status = testConnection();
if ( !status.isOK() ) {
setControl(new ErrorComposite(container, SWT.None, status));
return;
}
Composite parent = new Composite(container, SWT.None);
FillLayout layout = new FillLayout(SWT.VERTICAL);
parent.setLayout(layout);
/*
* Determine which elastic beanstalk environments aren't already imported as servers
*/
List<RegionEnvironmentDescription> environmentsToImport = new LinkedList<ImportEnvironmentsWizard.RegionEnvironmentDescription>();
for ( Region region : RegionUtils.getRegionsForService(ServiceAbbreviations.BEANSTALK) ) {
List<EnvironmentDescription> elasticBeanstalkEnvs = getExistingEnvironments(region);
Collection<IServer> elasticBeanstalkServers = ElasticBeanstalkPlugin
.getExistingElasticBeanstalkServers();
for ( EnvironmentDescription env : elasticBeanstalkEnvs ) {
boolean alreadyExists = false;
for ( IServer server : elasticBeanstalkServers ) {
if ( ElasticBeanstalkPlugin.environmentsSame(env, region, server) ) {
alreadyExists = true;
break;
}
}
if ( !alreadyExists ) {
environmentsToImport.add(new RegionEnvironmentDescription(region, env));
}
}
}
if ( environmentsToImport.isEmpty() ) {
new Label(parent, SWT.None).setText("There are no running environments to import.");
} else {
Composite treeContainer = new Composite(parent, SWT.None);
treeContainer.setLayout(new TreeColumnLayout());
int style = SWT.V_SCROLL | SWT.BORDER | SWT.SINGLE;
viewer = new CheckboxTreeViewer(treeContainer, style);
viewer.getTree().setLinesVisible(true);
viewer.getTree().setHeaderVisible(true);
EnvironmentSelectionTreeProvider labelProvider = new EnvironmentSelectionTreeProvider();
viewer.setContentProvider(labelProvider);
viewer.setLabelProvider(labelProvider);
for ( int i = 0; i < NUM_COLS; i++ ) {
switch (i) {
case COL_ENV_NAME:
newColumn("Environment name", 10);
break;
case COL_APPLICATION_NAME:
newColumn("Application name", 10);
break;
case COL_DATE:
newColumn("Last updated", 10);
break;
case COL_STATUS:
newColumn("Status", 10);
break;
case COL_REGION:
newColumn("Region", 10);
break;
}
}
viewer.setInput(environmentsToImport.toArray(new RegionEnvironmentDescription[environmentsToImport.size()]));
viewer.getTree().addSelectionListener(new SelectionListener() {
public void widgetSelected(SelectionEvent e) {
if ( viewer.getCheckedElements().length > 0 ) {
setErrorMessage(null);
setMessage(MESSAGE);
toImport = viewer.getCheckedElements();
} else {
setErrorMessage("Select at least one environment to import");
toImport = null;
}
ImportEnvironmentsWizard.this.getContainer().updateButtons();
}
public void widgetDefaultSelected(SelectionEvent e) {
widgetSelected(e);
}
});
}
setControl(container);
}
private IStatus testConnection() {
try {
this.getWizard()
.getContainer()
.run(true,
false,
new CheckAccountRunnable(AwsToolkitCore.getClientFactory()
.getElasticBeanstalkClientByEndpoint(
RegionUtils.getRegion(ElasticBeanstalkPlugin.DEFAULT_REGION)
.getServiceEndpoints().get(ServiceAbbreviations.BEANSTALK))));
return Status.OK_STATUS;
} catch ( InvocationTargetException ite ) {
String errorMessage = "Unable to connect to AWS Elastic Beanstalk. ";
try {
throw ite.getCause();
} catch ( AmazonServiceException ase ) {
errorMessage += "Make sure you've registered your AWS account for the AWS Elastic Beanstalk service.";
} catch ( AmazonClientException ace ) {
errorMessage += "Make sure your computer is connected to the internet, and any network firewalls or proxys are configured appropriately.";
} catch ( Throwable t ) {
}
return new Status(IStatus.ERROR, ElasticBeanstalkPlugin.PLUGIN_ID, errorMessage, ite.getCause());
} catch ( InterruptedException e ) {
return Status.CANCEL_STATUS;
}
}
}
@Override
public void addPages() {
addPage(new ImportPage());
}
/**
* Returns all AWS Elastic Beanstalk environments in the region given.
*/
private List<EnvironmentDescription> getExistingEnvironments(Region region) {
List<EnvironmentDescription> filtered = new ArrayList<EnvironmentDescription>();
AWSElasticBeanstalk client = AwsToolkitCore.getClientFactory().getElasticBeanstalkClientByEndpoint(
region.getServiceEndpoints().get(ServiceAbbreviations.BEANSTALK));
List<EnvironmentDescription> environments = client.describeEnvironments().getEnvironments();
// Only list the active environments
for ( EnvironmentDescription env : environments ) {
if ( !(env.getStatus().equals(EnvironmentStatus.Terminated.toString()) || env.getStatus().equals(
EnvironmentStatus.Terminating.toString())) )
filtered.add(env);
}
return filtered;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.wizard.Wizard#performFinish()
*/
@Override
public boolean performFinish() {
try {
getContainer().run(true, false, new IRunnableWithProgress() {
public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
monitor.beginTask("Importing servers", toImport.length * 3);
try {
for ( Object elasticBeanstalkEnv : toImport ) {
try {
RegionEnvironmentDescription regionEnvironmentDescription = (RegionEnvironmentDescription) elasticBeanstalkEnv;
ElasticBeanstalkPlugin.importEnvironment(
regionEnvironmentDescription.environmentDescription,
regionEnvironmentDescription.region, monitor);
} catch ( CoreException e ) {
throw new RuntimeException(e);
}
}
} finally {
monitor.done();
}
}
});
} catch ( Exception e ) {
throw new RuntimeException(e);
}
return true;
}
@Override
public boolean needsProgressMonitor() {
return true;
}
@Override
public boolean canFinish() {
return toImport != null;
}
protected TreeColumn newColumn(String columnText, int weight) {
Tree table = viewer.getTree();
TreeColumn column = new TreeColumn(table, SWT.NONE);
column.setText(columnText);
TreeColumnLayout tableColumnLayout = (TreeColumnLayout) viewer.getTree().getParent().getLayout();
if ( tableColumnLayout == null )
tableColumnLayout = new TreeColumnLayout();
tableColumnLayout.setColumnData(column, new ColumnWeightData(weight));
viewer.getTree().getParent().setLayout(tableColumnLayout);
return column;
}
private class EnvironmentSelectionTreeProvider implements ITableLabelProvider, ITreeContentProvider {
public void removeListener(ILabelProviderListener listener) {
}
public boolean isLabelProperty(Object element, String property) {
return false;
}
public void dispose() {
}
public void addListener(ILabelProviderListener listener) {
}
public String getColumnText(Object element, int columnIndex) {
RegionEnvironmentDescription env = (RegionEnvironmentDescription) element;
switch (columnIndex) {
case COL_ENV_NAME:
return env.environmentDescription.getEnvironmentName();
case COL_APPLICATION_NAME:
return env.environmentDescription.getApplicationName();
case COL_DATE:
return env.environmentDescription.getDateUpdated().toString();
case COL_STATUS:
return env.environmentDescription.getStatus();
case COL_REGION:
return env.region.getName();
}
return "";
}
public Image getColumnImage(Object element, int columnIndex) {
if ( columnIndex == 0 )
return ElasticBeanstalkPlugin.getDefault().getImageRegistry().get(ElasticBeanstalkPlugin.IMG_SERVER);
return null;
}
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
}
public boolean hasChildren(Object element) {
return false;
}
public Object getParent(Object element) {
return null;
}
public Object[] getElements(Object inputElement) {
return (Object[]) inputElement;
}
public Object[] getChildren(Object parentElement) {
return new Object[0];
}
}
}