org.elasticdroid.model.ControlInstancesModel.java Source code

Java tutorial

Introduction

Here is the source code for org.elasticdroid.model.ControlInstancesModel.java

Source

/**
 *  This file is part of ElasticDroid.
 *
 * ElasticDroid 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.
    
 * ElasticDroid 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 ElasticDroid.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * Authored by siddhu on 7 Jan 2011
 */
package org.elasticdroid.model;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;

import org.elasticdroid.model.tpl.GenericModel;
import org.elasticdroid.tpl.GenericActivity;
import org.elasticdroid.tpl.GenericListActivity;

import android.util.Log;

import com.amazonaws.AmazonClientException;
import com.amazonaws.AmazonServiceException;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.ec2.AmazonEC2Client;
import com.amazonaws.services.ec2.model.CreateTagsRequest;
import com.amazonaws.services.ec2.model.DeleteTagsRequest;
import com.amazonaws.services.ec2.model.StartInstancesRequest;
import com.amazonaws.services.ec2.model.StartInstancesResult;
import com.amazonaws.services.ec2.model.StopInstancesRequest;
import com.amazonaws.services.ec2.model.StopInstancesResult;
import com.amazonaws.services.ec2.model.Tag;

/**
 * Model to allow user to control instance attributes:
 * <ul>
 *    <li>Start instance</li>
 *    <li>Stop instance </li>
 *    <li>Set/change instance tag (tag key = name) </li>
 * </ul>
 * @author siddhu
 *
 * 7 Jan 2011
 */
public class ControlInstancesModel extends GenericModel<String, Void, Object> {

    /** 
     * Enumeration to indicate type of control to perform 
     * */
    public static enum ControlType {
        START_INSTANCE, STOP_INSTANCE, TAG_INSTANCE
    }

    /** The connection Data for AWS */
    private HashMap<String, String> connectionData;

    /** The operation to perform with this particular object */
    private ControlType operationType;

    /** Logging tag */
    private static final String TAG = "org.elasticdroid.model.ControlInstancesModel";

    /** The EC2 tags to create, if any. Used only with @link{ControlType#TAG_INSTANCE} */
    private ArrayList<Tag> ec2Tags;

    /**
     * Initialise the model by supplying connection data to start/stop instances
     * 
     * DO NOT USE THIS CONSTRUCTOR IF YOU ARE GOING TO TAG AN INSTANCE! YOU WILL GET AN ILLEGAL
     * ARGUMENT EXCEPTION WHEN YOU EXECUTE IN BACKGROUND.
     * 
     * @param activity
     * @param connectionData The AWS connection data
     * @param operation Type: Start instance, stop instance, or tag instance. 
     */
    public ControlInstancesModel(GenericActivity activity, HashMap<String, String> connectionData,
            ControlType operationType) {
        super(activity);

        this.connectionData = connectionData;
        this.operationType = operationType;
        //set the tag to null
        this.ec2Tags = null;
    }

    /**
     * Initialise the model by supplying connection data to start/stop instances
     * 
     * DO NOT USE THIS CONSTRUCTOR IF YOU ARE GOING TO TAG AN INSTANCE! YOU WILL GET AN ILLEGAL
     * ARGUMENT EXCEPTION WHEN YOU EXECUTE IN BACKGROUND.
     * 
     * @param listActivity
     * @param connectionData The AWS connection data
     * @param operation Type: Start instance, stop instance, or tag instance.
     */
    public ControlInstancesModel(GenericListActivity listActivity, HashMap<String, String> connectionData,
            ControlType operationType) {
        super(listActivity);

        this.connectionData = connectionData;
        this.operationType = operationType;
        //set the tag to null
        this.ec2Tags = null;
    }

    /**
     * Initialise the model by supplying connection data to tag instances. Requires additional
     * argument specifying the tag to use.
     * 
     * @param activity
     * @param connectionData The AWS connection data
     * @param operation Type: Start instance, stop instance, or tag instance.
     * @param ec2Tagnames: The list of tagnames to assign the instances.
     */
    public ControlInstancesModel(GenericActivity activity, HashMap<String, String> connectionData,
            ControlType operationType, List<String> ec2Tagnames) {
        super(activity);

        this.connectionData = connectionData;
        this.operationType = operationType;

        ec2Tags = new ArrayList<Tag>();
        //create a list of Tags.
        for (String ec2Tagname : ec2Tagnames) {
            ec2Tags.add(new Tag("Name", ec2Tagname));
        }
    }

    /**
     * Initialise the model by supplying connection data to start/stop instances. Requires 
     * additional argument specifying the tag to use
     * 
     * @param listActivity
     * @param connectionData The AWS connection data
     * @param operation Type: Start instance, stop instance, or tag instance.
     * @param ec2Tagnames: The list of tagnames to assign the instances.
     */
    public ControlInstancesModel(GenericListActivity listActivity, HashMap<String, String> connectionData,
            ControlType operationType, List<String> ec2Tagnames) {
        super(listActivity);

        this.connectionData = connectionData;
        this.operationType = operationType;

        ec2Tags = new ArrayList<Tag>();
        //create a list of Tags.
        for (String ec2Tagname : ec2Tagnames) {
            ec2Tags.add(new Tag("Name", ec2Tagname));
        }
    }

    /**
     * @param instances List of instances to stop or start
     * @return @see {@link ControlInstancesModel#controlInstances(List)}
     */
    @Override
    protected Object doInBackground(String... instances) {
        //TODO remove
        try {
            Thread.sleep(4000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        //call controlInstances to do the actual job.
        if ((operationType == ControlType.START_INSTANCE) || (operationType == ControlType.STOP_INSTANCE)) {
            return controlInstances(Arrays.asList(instances));
        } else {
            if (ec2Tags.size() == 0) {
                Log.v(TAG, "Deleting tags...");
                return deleteTags(Arrays.asList(instances));
            } else {
                //tag instance otherwise.
                return tagInstance(Arrays.asList(instances));
            }
        }
    }

    /**
     * Method that does the actual work of starting or stopping the instances
     * 
     * This method uses the stop boolean to identify whether the instances should be stopped 
     * (stop = true) or started (stop = false).
     * 
     * @return Returns one of the following:
     * <ul>
     *    <li>newInstanceStates: Returns a list of stateCodes and state names for all of the instances
     *    </li>
     *    <li> AmazonServiceException</li>
     *    <li> AmazonClientException</li>
     * </ul>
     * 
     */
    public Object controlInstances(List<String> instances) {

        for (String instance : instances) {
            Log.v(TAG, "Starting instance: " + instance);
        }

        //create credentials using the BasicAWSCredentials class
        BasicAWSCredentials credentials = new BasicAWSCredentials(connectionData.get("accessKey"),
                connectionData.get("secretAccessKey"));
        //create Amazon EC2 Client object, and set tye end point to the region. params[3]
        //contains endpoint
        AmazonEC2Client amazonEC2Client = new AmazonEC2Client(credentials);
        //override the default connection endpoint if provided.
        if (connectionData.get("endpoint") != null) {
            amazonEC2Client.setEndpoint(connectionData.get("endpoint"));
        }

        //if you want to start an instance
        if (operationType == ControlType.START_INSTANCE) {
            StartInstancesRequest request = new StartInstancesRequest(instances);
            StartInstancesResult result = null;
            try {
                result = amazonEC2Client.startInstances(request);
            } catch (AmazonServiceException amazonServiceException) {
                return amazonServiceException;
            } catch (AmazonClientException amazonClientException) {
                return amazonClientException;
            }
            //redundant check.
            if (result != null) {
                return result.getStartingInstances();
            }
        }
        //stop = true, start the instance.
        else {
            StopInstancesRequest request = new StopInstancesRequest(instances);
            StopInstancesResult result = null;

            try {
                result = amazonEC2Client.stopInstances(request);
            } catch (AmazonServiceException amazonServiceException) {
                return amazonServiceException;
            } catch (AmazonClientException amazonClientException) {
                return amazonClientException;
            }

            if (result != null) {
                return result.getStoppingInstances();
            }
        }

        return null;
    }

    /**
     * Create/override tags of key name for the instances.
     * @param instances: list of instances
     * @return
     * <ul>
     *    <li> true: to indicate success in reassigning the tags </li>
     *    <li>IllegalArgumentException: If the number of instances != number of tags</li>
     * <li>AmazonServicesException: Serverside issues with AWS</li>
     * <li>AmazonClientException: (Probably) connectivity issues</li>
     * </ul>
     */
    public Object tagInstance(List<String> instances) {
        if (instances.size() != ec2Tags.size()) {
            return new IllegalArgumentException("The number of instances should be equal to be " + "the number");
        }
        //create credentials using the BasicAWSCredentials class
        BasicAWSCredentials credentials = new BasicAWSCredentials(connectionData.get("accessKey"),
                connectionData.get("secretAccessKey"));
        //create Amazon EC2 Client object, and set tye end point to the region. params[3]
        //contains endpoint
        AmazonEC2Client amazonEC2Client = new AmazonEC2Client(credentials);

        //override the default connection endpoint if provided.
        if (connectionData.get("endpoint") != null) {
            amazonEC2Client.setEndpoint(connectionData.get("endpoint"));
        }

        //create a TagsRequest
        for (String instance : instances) {
            Log.v(TAG, "Tagging " + instance);
        }
        CreateTagsRequest request = new CreateTagsRequest(instances, ec2Tags);

        //okay, tag the instance
        try {
            amazonEC2Client.createTags(request);
        } catch (AmazonServiceException amazonServiceException) {
            return amazonServiceException;
        } catch (AmazonClientException amazonClientException) {
            return amazonClientException;
        }

        return new Boolean(true); //return true to indicate success!
    }

    public Object deleteTags(List<String> instances) {

        //create credentials using the BasicAWSCredentials class
        BasicAWSCredentials credentials = new BasicAWSCredentials(connectionData.get("accessKey"),
                connectionData.get("secretAccessKey"));
        //create Amazon EC2 Client object, and set tye end point to the region. params[3]
        //contains endpoint
        AmazonEC2Client amazonEC2Client = new AmazonEC2Client(credentials);

        //override the default connection endpoint if provided.
        if (connectionData.get("endpoint") != null) {
            amazonEC2Client.setEndpoint(connectionData.get("endpoint"));
        }

        //create empty tags for each of the instances from which the name tag is to be deleted.
        for (String instance : instances) {
            Log.v(TAG, "Tagging " + instance);
            //create a tag with Name for each instance from which Name tag is to be deleted.
            ec2Tags.add(new Tag("Name"));
        }

        DeleteTagsRequest request = new DeleteTagsRequest(instances);
        request.setTags(ec2Tags);

        //okay, tag the instance
        try {
            amazonEC2Client.deleteTags(request);
        } catch (AmazonServiceException amazonServiceException) {
            return amazonServiceException;
        } catch (AmazonClientException amazonClientException) {
            return amazonClientException;
        }

        return new Boolean(true); //return true to indicate success!
    }
}