stratos-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From im...@apache.org
Subject [05/12] stratos git commit: Renaming iaas classes and moving them to new packages
Date Wed, 24 Dec 2014 17:36:28 GMT
http://git-wip-us.apache.org/repos/asf/stratos/blob/e195f2f1/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/cloudstack/CloudStackIaas.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/cloudstack/CloudStackIaas.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/cloudstack/CloudStackIaas.java
new file mode 100644
index 0000000..0e31801
--- /dev/null
+++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/cloudstack/CloudStackIaas.java
@@ -0,0 +1,548 @@
+package org.apache.stratos.cloud.controller.iaases.cloudstack;
+
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.stratos.cloud.controller.exception.CloudControllerException;
+import org.apache.stratos.cloud.controller.exception.InvalidHostException;
+import org.apache.stratos.cloud.controller.exception.InvalidRegionException;
+import org.apache.stratos.cloud.controller.exception.InvalidZoneException;
+import org.apache.stratos.cloud.controller.iaases.JcloudsIaas;
+import org.apache.stratos.cloud.controller.util.ComputeServiceBuilderUtil;
+import org.apache.stratos.cloud.controller.domain.IaasProvider;
+import org.apache.stratos.cloud.controller.util.CloudControllerConstants;
+import org.apache.stratos.cloud.controller.iaases.PartitionValidator;
+import org.jclouds.cloudstack.CloudStackApi;
+import org.jclouds.cloudstack.compute.options.CloudStackTemplateOptions;
+import org.jclouds.cloudstack.domain.*;
+import org.jclouds.cloudstack.features.VolumeApi;
+import org.jclouds.cloudstack.options.ListPublicIPAddressesOptions;
+import org.jclouds.cloudstack.options.ListZonesOptions;
+import org.jclouds.compute.ComputeService;
+import org.jclouds.compute.ComputeServiceContext;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.Template;
+import org.jclouds.compute.domain.TemplateBuilder;
+import org.jclouds.compute.options.TemplateOptions;
+import org.jclouds.domain.Location;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.TimeoutException;
+
+public class CloudStackIaas extends JcloudsIaas {
+
+    private static final Log log = LogFactory.getLog(CloudStackIaas.class);
+
+    public CloudStackIaas(IaasProvider iaasProvider) {
+        super(iaasProvider);
+    }
+
+    @Override
+    public void buildComputeServiceAndTemplate() {
+        // builds and sets Compute Service
+        ComputeService computeService = ComputeServiceBuilderUtil.buildDefaultComputeService(getIaasProvider());
+        getIaasProvider().setComputeService(computeService);
+
+        // builds and sets Template
+        buildTemplate();
+    }
+
+    @Override
+    public void buildTemplate() {
+
+        IaasProvider iaasInfo = getIaasProvider();
+
+        //if compute service is not available
+        if (iaasInfo.getComputeService() == null) {
+            String msg = "Compute service is null for IaaS provider: "
+                    + iaasInfo.getName();
+            log.error(msg);
+            throw new CloudControllerException(msg);
+        }
+
+        //create templateBuilder
+        TemplateBuilder templateBuilder = iaasInfo.getComputeService()
+                .templateBuilder();
+
+        //**SET PROPERTIES TO templateBuilder OBJECT**//
+
+        /**
+         * PROPERTY - 1
+         * set image id specified
+         */
+        templateBuilder.imageId(iaasInfo.getImage());
+
+        /**
+         *  PROPERTY-2
+         *  if user has specified a zone in cloud-controller.xml, set the zone into templateBuilder object
+         *  (user should provide the zone id for this, because zone name is not unique in cloudstack)
+         */
+        if (iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE) != null) {
+            Set<? extends Location> locations = iaasInfo.getComputeService().listAssignableLocations();
+            for (Location location : locations) {
+                if (location.getId().equals(iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE))) {
+                    //if the zone is valid set the zone to templateBuilder Object
+                    templateBuilder.locationId(location.getId());
+                    log.info("Zone has been set as " + iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE)
+                            + " with id: " + location.getId());
+                    break;
+                }
+            }
+        }
+
+        /**
+         * PROPERTY-3
+         * if user has specified an instance type in cloud-controller.xml, set the instance type into templateBuilder
+         * object.(service offering)
+         *Important:Specify the Service Offering type ID. Not the name. Because the name is not unique in cloudstack.
+         */
+        if (iaasInfo.getProperty(CloudControllerConstants.INSTANCE_TYPE) != null) {
+            templateBuilder.hardwareId(iaasInfo.getProperty(CloudControllerConstants.INSTANCE_TYPE));
+        }
+
+        //build the template
+        Template template = templateBuilder.build();
+
+        /**if you wish to auto assign IPs, instance spawning call should be
+         * blocking, but if you
+         * wish to assign IPs manually, it can be non-blocking.
+         * is auto-assign-ip mode or manual-assign-ip mode?
+         */
+        boolean blockUntilRunning = Boolean.parseBoolean(iaasInfo
+                .getProperty(CloudControllerConstants.AUTO_ASSIGN_IP));
+        template.getOptions().as(TemplateOptions.class)
+                .blockUntilRunning(blockUntilRunning);
+
+        // this is required in order to avoid creation of additional security
+        // groups by Jclouds.
+        template.getOptions().as(TemplateOptions.class)
+                .inboundPorts(new int[]{});
+
+
+        //**SET CLOUDSTACK SPECIFIC PROPERTIES TO TEMPLATE OBJECT**//
+
+        //set security group - If you are using basic zone
+        if (iaasInfo.getProperty(CloudControllerConstants.SECURITY_GROUP_IDS) != null) {
+            template.getOptions()
+                    .as(CloudStackTemplateOptions.class)
+                    .securityGroupIds(Arrays.asList(iaasInfo.getProperty(CloudControllerConstants.SECURITY_GROUP_IDS)
+                            .split(CloudControllerConstants.ENTRY_SEPARATOR)));
+        }
+
+
+        /**
+         * set network ID - If you are using advanced zone
+         * in cloudstack sometimes we get unautorized exception if we didn't specify the
+         * domain ID and user name
+         */
+        if (iaasInfo.getProperty(CloudControllerConstants.NETWORK_IDS) != null) {
+            template.getOptions()
+                    .as(CloudStackTemplateOptions.class)
+                    .networks(Arrays.asList(iaasInfo.getProperty(CloudControllerConstants.NETWORK_IDS)
+                            .split(CloudControllerConstants.ENTRY_SEPARATOR)));
+        }
+
+        //set user name
+        if (iaasInfo.getProperty(CloudControllerConstants.USER_NAME) != null) {
+            template.getOptions().as(CloudStackTemplateOptions.class)
+                    .account(iaasInfo.getProperty(CloudControllerConstants.USER_NAME));
+        }
+        //set domain ID
+        if (iaasInfo.getProperty(CloudControllerConstants.DOMAIN_ID) != null) {
+            template.getOptions().as(CloudStackTemplateOptions.class)
+                    .domainId(iaasInfo.getProperty(CloudControllerConstants.DOMAIN_ID));
+        }
+
+        /**
+         *Set key pair
+         * in cloudstack sometimes we get unauthorized exception if we didn't specify the
+         * domain ID and user name
+         */
+        if (iaasInfo.getProperty(CloudControllerConstants.KEY_PAIR) != null) {
+            template.getOptions().as(CloudStackTemplateOptions.class)
+                    .keyPair(iaasInfo.getProperty(CloudControllerConstants.KEY_PAIR));
+        }
+
+        // ability to define tags
+        if (iaasInfo.getProperty(CloudControllerConstants.TAGS) != null) {
+            template.getOptions()
+                    .as(CloudStackTemplateOptions.class)
+                    .tags(Arrays.asList(iaasInfo.getProperty(CloudControllerConstants.TAGS)
+                            .split(CloudControllerConstants.ENTRY_SEPARATOR)));
+        }
+        //set disk offering to the instance
+        if (iaasInfo.getProperty(CloudControllerConstants.DISK_OFFERING) != null) {
+            template.getOptions()
+                    .as(CloudStackTemplateOptions.class)
+                    .diskOfferingId(iaasInfo.getProperty(CloudControllerConstants.DISK_OFFERING));
+        }
+
+        // set Template
+        iaasInfo.setTemplate(template);
+    }
+
+    @Override
+    public void setDynamicPayload(byte[] payload) {
+        IaasProvider iaasProvider = getIaasProvider();
+        if (iaasProvider.getTemplate() != null) {
+            iaasProvider.getTemplate().getOptions().as(CloudStackTemplateOptions.class)
+                    .userMetadata(convertByteArrayToHashMap(payload));
+        }
+    }
+
+    /**
+     * IMPORTANT
+     * In cloudstack we can assign public IPs, if we are using an advanced zone only. If we are using a basic zone
+     * we cannot assign public ips.
+     * <p/>
+     * When we use an advanced zone, a public IP address will get automatically assigned to the vm. So we don't need
+     * to find an unallocated IP address and assign that address to the vm. If you are using a basic zone you cannot
+     * assign public IPs
+     * <p/>
+     * So  this method will find the IP that has been assigned to the vm and return it.
+     */
+    @Override
+    public List<String> associateAddresses(NodeMetadata node) {
+
+        IaasProvider iaasInfo = getIaasProvider();
+        ComputeServiceContext context = iaasInfo.getComputeService().getContext();
+        CloudStackApi cloudStackApi = context.unwrapApi(CloudStackApi.class);
+        String ip = null;
+
+        // get all allocated IPs
+        ListPublicIPAddressesOptions listPublicIPAddressesOptions = new ListPublicIPAddressesOptions();
+        listPublicIPAddressesOptions.zoneId(iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE));
+
+        Set<PublicIPAddress> publicIPAddresses = cloudStackApi.getAddressApi()
+                .listPublicIPAddresses(listPublicIPAddressesOptions);
+
+        String id = node.getProviderId(); //vm ID
+
+        for (PublicIPAddress publicIPAddress : publicIPAddresses) {
+            if (publicIPAddress.getVirtualMachineId().equals(id)) { //check whether this instance has
+                // already got an public ip or not
+                ip = publicIPAddress.getIPAddress(); //A public ip has been successfully assigned to the vm
+                log.info("Successfully associated an IP address " + ip
+                        + " for node with id: " + node.getId());
+                break;
+            }
+
+        }
+
+        if (ip == null || ip.isEmpty()) { //IP has not been successfully assigned to VM(That means there are
+            //  no more IPs  available for the VM)
+            String msg = "No address associated for node with id: " + node.getId();
+            log.warn(msg);
+            throw new CloudControllerException(msg);
+        }
+
+        List<String> associatedIPs = new ArrayList<String>();
+        associatedIPs.add(ip);
+        
+        return associatedIPs;
+    }
+
+    @Override
+    public String associatePredefinedAddress(NodeMetadata node, String ip) {
+        return "";
+    }
+
+    @Override
+    public void releaseAddress(String ip) {
+        IaasProvider iaasInfo = getIaasProvider();
+        ComputeServiceContext context = iaasInfo.getComputeService().getContext();
+        CloudStackApi cloudStackApi = context.unwrapApi(CloudStackApi.class);
+        cloudStackApi.getAddressApi().disassociateIPAddress(ip);
+    }
+
+    @Override
+    public boolean createKeyPairFromPublicKey(String region, String keyPairName, String publicKey) {
+
+        IaasProvider iaasInfo = getIaasProvider();
+        ComputeServiceContext context = iaasInfo.getComputeService().getContext();
+        CloudStackApi cloudStackApi = context.unwrapApi(CloudStackApi.class);
+        SshKeyPair sshKeyPair = cloudStackApi.getSSHKeyPairApi().createSSHKeyPair(keyPairName);
+
+        if (sshKeyPair != null) {
+
+            iaasInfo.getTemplate().getOptions().as(CloudStackTemplateOptions.class)
+                    .keyPair(sshKeyPair.getName());
+
+            log.info("A key-pair is created successfully - Key Pair Name: " + sshKeyPair.getName());
+            return true;
+        }
+        log.error("Key-pair is unable to create");
+        return false;
+    }
+
+    @Override
+    public boolean isValidRegion(String region) throws InvalidRegionException {
+
+        IaasProvider iaasInfo = getIaasProvider();
+        //no such method in Jclouds cloudstack api
+        String msg = "Invalid region: " + region + " in the iaas: " + iaasInfo.getType();
+        log.error(msg);
+        throw new InvalidRegionException(msg);
+    }
+
+    @Override
+    public boolean isValidZone(String region, String zone) throws InvalidZoneException {
+
+        IaasProvider iaasInfo = getIaasProvider();
+        ComputeServiceContext context = iaasInfo.getComputeService().getContext();
+        CloudStackApi cloudStackApi = context.unwrapApi(CloudStackApi.class);
+        ListZonesOptions listZonesOptions = new ListZonesOptions();
+        listZonesOptions.available(true);
+        Set<Zone> zoneSet = cloudStackApi.getZoneApi().listZones(listZonesOptions);
+
+        for (org.jclouds.cloudstack.domain.Zone configuredZone : zoneSet) {
+            if (configuredZone.getName().equalsIgnoreCase(zone)) {
+                return true;
+            }
+        }
+        String msg = "Invalid zone: " + zone + " in the iaas: " + iaasInfo.getType();
+        log.error(msg);
+        throw new InvalidZoneException(msg);
+    }
+
+    @Override
+    public boolean isValidHost(String zone, String host) throws InvalidHostException {
+
+        IaasProvider iaasInfo = getIaasProvider();
+        // there's no such method in jclouds cloustack api
+        String msg = "Invalid host: " + host + " in the zone: " + zone + " and of the iaas: " + iaasInfo.getType();
+        log.error(msg);
+        throw new InvalidHostException(msg);
+
+    }
+
+    @Override
+    public PartitionValidator getPartitionValidator() {
+        return new CloudStackPartitionValidator();
+    }
+
+    @Override
+    public String createVolume(int sizeGB, String snapshotId) {
+
+        // Snapshot id is not there in IaaS.createVolume() method in stratos 4.0.0
+        //todo return volume ID if volume is created
+        IaasProvider iaasInfo = getIaasProvider();
+        ComputeServiceContext context = iaasInfo.getComputeService()
+                .getContext();
+
+        String zone = ComputeServiceBuilderUtil.extractZone(iaasInfo);
+        String diskOfferingID = iaasInfo.getTemplate().getOptions().as(CloudStackTemplateOptions.class)
+                .getDiskOfferingId();
+        if (zone == null && diskOfferingID == null) {
+            log.error("Could not create a volume in the , [zone] : " + zone + " of Iaas : " + iaasInfo);
+            return null;
+        }
+
+        VolumeApi volumeApi = context.unwrapApi(CloudStackApi.class).getVolumeApi();
+
+        Volume volume;
+        if (StringUtils.isEmpty(snapshotId)) {
+            if (log.isInfoEnabled()) {
+                log.info("Creating a volume in the zone " + zone);
+            }
+
+            //cloudstack jcloud api does not return a volume object
+            volumeApi.createVolumeFromCustomDiskOfferingInZone(null, diskOfferingID, zone, sizeGB);
+
+            //  volume = blockStoreApi.createVolumeInAvailabilityZone(zone, sizeGB);
+        } else {
+            if (log.isInfoEnabled()) {
+                log.info("Creating a volume in the zone " + zone + " from the snapshot " + snapshotId);
+            }
+            volumeApi.createVolumeFromSnapshotInZone(null, diskOfferingID, zone);
+        }
+
+        return null;
+    }
+
+    @Override
+    public String attachVolume(String instanceId, String volumeId, String deviceName) {
+        IaasProvider iaasInfo = getIaasProvider();
+        ComputeServiceContext context = iaasInfo.getComputeService()
+                .getContext();
+        CloudStackApi cloudStackApi = context.unwrapApi(CloudStackApi.class);
+
+        //get volume
+        org.jclouds.cloudstack.domain.Volume volume = cloudStackApi.getVolumeApi().getVolume(volumeId);
+
+        //get current volume state
+        Volume.State volumeState = volume.getState();
+
+        if (log.isDebugEnabled()) {
+            log.debug("Volume " + volumeId + " is in state " + volumeState);
+        }
+
+        //if volume is not available, not allocated or cannot use
+        //volume state ALLOCATED   means that volume has not been attached to any instance.
+
+        //TODO there is an error with logic.
+        if (!(volumeState == Volume.State.ALLOCATED || volumeState == Volume.State.CREATING
+                || volumeState == Volume.State.READY)) {
+            log.error(String.format("Volume %s can not be attached. Volume status is %s", volumeId, volumeState));
+        }
+
+        //check whether the account of volume and instance is same
+        if (!volume.getAccount().equals(cloudStackApi.getVirtualMachineApi()
+                .getVirtualMachine(instanceId).getAccount())) {
+            log.error(String.format("Volume %s can not be attached. Instance account and Volume account " +
+                    "are not the same ", volumeId));
+        }
+
+        boolean volumeBecameAvailable = false, volumeBecameAttached = false;
+
+        try {
+            if (volumeState == Volume.State.CREATING) {
+
+                volumeBecameAvailable = waitForStatus(volumeId, Volume.State.ALLOCATED, 5);
+
+            } else if (volumeState == Volume.State.READY) {
+                volumeBecameAvailable = true;
+            }
+
+        } catch (TimeoutException e) {
+            log.error("[Volume ID] " + volumeId + "did not become ALLOCATED within expected timeout");
+        }
+
+        //if volume state is 'ALLOCATED'
+        if (volumeBecameAvailable) {
+
+            //attach volume into instance
+            cloudStackApi.getVolumeApi().attachVolume(volumeId, instanceId);
+
+            try {
+                volumeBecameAttached = waitForStatus(volumeId, Volume.State.READY, 2);
+            } catch (TimeoutException e) {
+                log.error("[Volume ID] " + volumeId + "did not become READY within expected timeout");
+            }
+        }
+
+        try {
+            // waiting 5seconds till volumes are actually attached.
+            Thread.sleep(5000);
+        } catch (InterruptedException ignored) {
+
+        }
+
+        //If volume state is not 'READY'
+        if (!volumeBecameAttached) {
+            log.error(String.format("[Volume ID] %s attachment is called, but not yet became attached", volumeId));
+        }
+
+        log.info(String.format("Volume [id]: %s attachment for instance [id]: %s was successful [status]: Attaching." +
+                " of Iaas : %s", volumeId, instanceId, iaasInfo));
+
+        return "Attaching";
+
+    }
+
+    @Override
+    public void detachVolume(String instanceId, String volumeId) {
+
+
+        IaasProvider iaasInfo = getIaasProvider();
+
+        ComputeServiceContext context = iaasInfo.getComputeService()
+                .getContext();
+
+        if (log.isDebugEnabled()) {
+            log.debug(String.format("Starting to detach volume %s from the instance %s", volumeId, instanceId));
+        }
+
+        CloudStackApi cloudStackApi = context.unwrapApi(CloudStackApi.class);
+
+        cloudStackApi.getVolumeApi().detachVolume(volumeId);
+
+        try {
+            //TODO this is true only for newly created volumes
+            if (waitForStatus(volumeId, Volume.State.ALLOCATED, 5)) {
+                log.info(String.format("Detachment of Volume [id]: %s from instance [id]: %s was successful of Iaas : %s", volumeId, instanceId, iaasInfo));
+            }
+        } catch (TimeoutException e) {
+            log.error(String.format("Detachment of Volume [id]: %s from instance [id]: %s was unsuccessful. [volume Status] : %s", volumeId, instanceId, iaasInfo));
+        }
+
+    }
+
+    @Override
+    public void deleteVolume(String volumeId) {
+        IaasProvider iaasInfo = getIaasProvider();
+        ComputeServiceContext context = iaasInfo.getComputeService()
+                .getContext();
+        CloudStackApi cloudStackApi = context.unwrapApi(CloudStackApi.class);
+        cloudStackApi.getVolumeApi().deleteVolume(volumeId);
+        log.info("Deletion of Volume [id]: " + volumeId + " was successful. "
+                + " of Iaas : " + iaasInfo);
+    }
+
+    @Override
+    public String getIaasDevice(String device) {//todo implement this method(auto generated method)
+        return null;
+    }
+
+    private boolean waitForStatus(String volumeId, Volume.State expectedStatus, int timeoutInMilliseconds) throws TimeoutException {
+        int timeout = 1000 * 60 * timeoutInMilliseconds;
+        long timout = System.currentTimeMillis() + timeout;
+
+        IaasProvider iaasInfo = getIaasProvider();
+        ComputeServiceContext context = iaasInfo.getComputeService().getContext();
+        CloudStackApi cloudStackApi = context.unwrapApi(CloudStackApi.class);
+
+        //get volume
+        org.jclouds.cloudstack.domain.Volume volume = cloudStackApi.getVolumeApi().getVolume(volumeId);
+
+        Volume.State volumeState = volume.getState();
+
+        while (volumeState != expectedStatus) {
+            try {
+                if (log.isDebugEnabled()) {
+                    log.debug(String.format("Volume %s is still NOT in %s. Current State=%s", volumeId, expectedStatus, volumeState));
+                }
+                if (volumeState == Volume.State.FAILED || volumeState == Volume.State.DESTROYED || volumeState == Volume.State.UNRECOGNIZED) {
+                    log.error("Volume " + volumeId + " is in state" + volumeState);
+                    return false;
+                }
+
+                Thread.sleep(1000);
+                volumeState = volume.getState();
+                if (System.currentTimeMillis() > timout) {
+                    throw new TimeoutException();
+                }
+            } catch (InterruptedException e) {
+                // Ignoring the exception
+            }
+        }
+        if (log.isDebugEnabled()) {
+            log.debug(String.format("Volume %s status became %s", volumeId, expectedStatus));
+        }
+
+        return true;
+    }
+
+    private Map<String, String> convertByteArrayToHashMap(byte[] byteArray) {
+
+        Map<String, String> map = new HashMap<String, String>();
+
+        String stringFromByteArray = new String(byteArray);
+        String[] keyValuePairs = stringFromByteArray.split(",");
+
+        for (String keyValuePair : keyValuePairs) {
+            String[] keyValue = keyValuePair.split("=");
+            if (keyValue.length > 1) {
+                map.put(keyValue[0], keyValue[1]);
+            }
+        }
+
+        return map;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/stratos/blob/e195f2f1/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/cloudstack/CloudstackPartitionValidator.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/cloudstack/CloudstackPartitionValidator.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/cloudstack/CloudstackPartitionValidator.java
new file mode 100644
index 0000000..4245a4b
--- /dev/null
+++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/cloudstack/CloudstackPartitionValidator.java
@@ -0,0 +1,54 @@
+package org.apache.stratos.cloud.controller.iaases.cloudstack;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.stratos.cloud.controller.domain.Partition;
+import org.apache.stratos.cloud.controller.exception.InvalidPartitionException;
+import org.apache.stratos.cloud.controller.iaases.Iaas;
+import org.apache.stratos.cloud.controller.domain.IaasProvider;
+import org.apache.stratos.cloud.controller.iaases.ec2.EC2PartitionValidator;
+import org.apache.stratos.cloud.controller.iaases.PartitionValidator;
+import org.apache.stratos.cloud.controller.services.impl.CloudControllerServiceUtil;
+import org.apache.stratos.cloud.controller.util.CloudControllerConstants;
+import org.apache.stratos.messaging.domain.topology.Scope;
+
+import java.util.Properties;
+
+
+public class CloudStackPartitionValidator implements PartitionValidator {
+
+    private static final Log log = LogFactory.getLog(EC2PartitionValidator.class);
+
+    private IaasProvider iaasProvider;
+    private Iaas iaas;
+
+    @Override
+    public void setIaasProvider(IaasProvider iaas) {
+        this.iaasProvider = iaas;
+        this.iaas = iaas.getIaas();
+    }
+
+    @Override
+    public IaasProvider validate(Partition partition, Properties properties) throws InvalidPartitionException {
+
+        try {
+            IaasProvider updatedIaasProvider = new IaasProvider(iaasProvider);
+            Iaas updatedIaas = CloudControllerServiceUtil.buildIaas(updatedIaasProvider);
+            updatedIaas.setIaasProvider(updatedIaasProvider);
+
+            if (properties.containsKey(Scope.zone.toString())) {
+                String zone = properties.getProperty(Scope.zone.toString());
+                iaas.isValidZone(null, zone);
+                updatedIaasProvider.setProperty(CloudControllerConstants.AVAILABILITY_ZONE, zone);
+                updatedIaas = CloudControllerServiceUtil.buildIaas(updatedIaasProvider);
+                updatedIaas.setIaasProvider(updatedIaasProvider);
+            }
+
+        } catch (Exception e) {
+            String msg = "Invalid partition detected: [partition-id] " + partition.getId() + e.getMessage();
+            log.error(msg, e);
+            throw new InvalidPartitionException(msg, e);
+        }
+        return iaasProvider;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/stratos/blob/e195f2f1/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/docker/DockerIaas.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/docker/DockerIaas.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/docker/DockerIaas.java
new file mode 100644
index 0000000..0ec1f6b
--- /dev/null
+++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/docker/DockerIaas.java
@@ -0,0 +1,154 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License 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 org.apache.stratos.cloud.controller.iaases.docker;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.stratos.cloud.controller.exception.CloudControllerException;
+import org.apache.stratos.cloud.controller.exception.InvalidHostException;
+import org.apache.stratos.cloud.controller.exception.InvalidRegionException;
+import org.apache.stratos.cloud.controller.exception.InvalidZoneException;
+import org.apache.stratos.cloud.controller.iaases.JcloudsIaas;
+import org.apache.stratos.cloud.controller.iaases.ec2.EC2Iaas;
+import org.apache.stratos.cloud.controller.util.ComputeServiceBuilderUtil;
+import org.apache.stratos.cloud.controller.domain.IaasProvider;
+import org.apache.stratos.cloud.controller.iaases.PartitionValidator;
+import org.jclouds.compute.ComputeService;
+import org.jclouds.compute.domain.Image;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.Template;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Docker iaas provider definition.
+ */
+public class DockerIaas extends JcloudsIaas {
+
+    private static final Log log = LogFactory.getLog(EC2Iaas.class);
+
+    public DockerIaas(IaasProvider iaasProvider) {
+        super(iaasProvider);
+    }
+
+    @Override
+    public void buildComputeServiceAndTemplate() {
+        // builds and sets Compute Service
+        ComputeService computeService = ComputeServiceBuilderUtil.buildDefaultComputeService(getIaasProvider());
+        getIaasProvider().setComputeService(computeService);
+
+        // builds and sets Template
+        buildTemplate();
+    }
+
+    @Override
+    public void setDynamicPayload(byte[] payload) {
+        log.warn("Not implemented: DockerIaas.setDynamicPayload()");
+    }
+
+    @Override
+    public List<String> associateAddresses(NodeMetadata node) {
+        log.warn("Not implemented: DockerIaas.associateAddress()");
+        return null;
+    }
+
+    @Override
+    public String associatePredefinedAddress(NodeMetadata node, String ip) {
+        log.warn("Not implemented: DockerIaas.associatePredefinedAddress()");
+        return null;
+    }
+
+    @Override
+    public void releaseAddress(String ip) {
+        log.warn("Not implemented: DockerIaas.releaseAddress()");
+    }
+
+    @Override
+    public boolean createKeyPairFromPublicKey(String region, String keyPairName, String publicKey) {
+        return false;
+    }
+
+    @Override
+    public boolean isValidRegion(String region) throws InvalidRegionException {
+        return true;
+    }
+
+    @Override
+    public boolean isValidZone(String region, String zone) throws InvalidZoneException {
+        return true;
+    }
+
+    @Override
+    public boolean isValidHost(String zone, String host) throws InvalidHostException {
+        return true;
+    }
+
+    @Override
+    public PartitionValidator getPartitionValidator() {
+        return new DockerPartitionValidator();
+    }
+
+    @Override
+    public void buildTemplate() {
+        IaasProvider iaasProvider = getIaasProvider();
+        ComputeService computeService = iaasProvider.getComputeService();
+        Set<? extends Image> images = computeService.listImages();
+        Image image = findImage(images, iaasProvider.getImage());
+        if(image == null) {
+            throw new CloudControllerException(String.format("Docker image not found: %s", iaasProvider.getImage()));
+        }
+        Template template = computeService.templateBuilder().fromImage(image).build();
+        iaasProvider.setTemplate(template);
+    }
+
+    private Image findImage(Set<? extends Image> images, String name) {
+        for(Image image : images) {
+            if(image.getDescription().contains(name))
+                return image;
+        }
+        return null;
+    }
+
+    @Override
+    public String createVolume(int sizeGB, String snapshotId) {
+        return null;
+    }
+
+    @Override
+    public String attachVolume(String instanceId, String volumeId, String deviceName) {
+        return null;
+    }
+
+    @Override
+    public void detachVolume(String instanceId, String volumeId) {
+
+    }
+
+    @Override
+    public void deleteVolume(String volumeId) {
+
+    }
+
+    @Override
+    public String getIaasDevice(String device) {
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/e195f2f1/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/docker/DockerPartitionValidator.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/docker/DockerPartitionValidator.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/docker/DockerPartitionValidator.java
new file mode 100644
index 0000000..b80c017
--- /dev/null
+++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/docker/DockerPartitionValidator.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License 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 org.apache.stratos.cloud.controller.iaases.docker;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.stratos.cloud.controller.domain.IaasProvider;
+import org.apache.stratos.cloud.controller.domain.Partition;
+import org.apache.stratos.cloud.controller.exception.InvalidIaasProviderException;
+import org.apache.stratos.cloud.controller.exception.InvalidPartitionException;
+import org.apache.stratos.cloud.controller.iaases.Iaas;
+import org.apache.stratos.cloud.controller.iaases.PartitionValidator;
+import org.apache.stratos.cloud.controller.services.impl.CloudControllerServiceUtil;
+
+import java.util.Properties;
+
+/**
+ * Docker partition validator definition.
+ */
+public class DockerPartitionValidator implements PartitionValidator {
+
+	private static final Log log = LogFactory.getLog(DockerPartitionValidator.class);
+
+    private IaasProvider iaasProvider;
+
+    @Override
+    public void setIaasProvider(IaasProvider iaasProvider) {
+        this.iaasProvider = iaasProvider;
+    }
+
+    @Override
+    public IaasProvider validate(Partition partition, Properties properties) throws InvalidPartitionException {
+    	// in Docker case currently we only update the custom properties passed via Partitions, and
+    	// no validation done as of now.
+    	IaasProvider updatedIaasProvider = new IaasProvider(iaasProvider);
+    	updateOtherProperties(updatedIaasProvider, properties);
+        return updatedIaasProvider;
+    }
+    
+    private void updateOtherProperties(IaasProvider updatedIaasProvider,
+			Properties properties) {
+    	Iaas updatedIaas;
+		try {
+			updatedIaas = CloudControllerServiceUtil.buildIaas(updatedIaasProvider);
+
+			for (Object property : properties.keySet()) {
+				if (property instanceof String) {
+					String key = (String) property;
+					updatedIaasProvider.setProperty(key,
+							properties.getProperty(key));
+					if (log.isDebugEnabled()) {
+						log.debug("Added property " + key
+								+ " to the IaasProvider.");
+					}
+				}
+			}
+			updatedIaas = CloudControllerServiceUtil.buildIaas(updatedIaasProvider);
+			updatedIaas.setIaasProvider(updatedIaasProvider);
+		} catch (InvalidIaasProviderException ignore) {
+		}
+    	
+	}
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/e195f2f1/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/ec2/EC2Iaas.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/ec2/EC2Iaas.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/ec2/EC2Iaas.java
new file mode 100644
index 0000000..f3354ea
--- /dev/null
+++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/ec2/EC2Iaas.java
@@ -0,0 +1,635 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one 
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License 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 org.apache.stratos.cloud.controller.iaases.ec2;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.stratos.cloud.controller.exception.CloudControllerException;
+import org.apache.stratos.cloud.controller.exception.InvalidHostException;
+import org.apache.stratos.cloud.controller.exception.InvalidRegionException;
+import org.apache.stratos.cloud.controller.exception.InvalidZoneException;
+import org.apache.stratos.cloud.controller.iaases.JcloudsIaas;
+import org.apache.stratos.cloud.controller.util.ComputeServiceBuilderUtil;
+import org.apache.stratos.cloud.controller.domain.IaasProvider;
+import org.apache.stratos.cloud.controller.domain.NetworkInterface;
+import org.apache.stratos.cloud.controller.util.CloudControllerConstants;
+import org.apache.stratos.cloud.controller.util.CloudControllerUtil;
+import org.apache.stratos.cloud.controller.iaases.PartitionValidator;
+import org.jclouds.aws.ec2.AWSEC2Api;
+import org.jclouds.aws.ec2.compute.AWSEC2TemplateOptions;
+import org.jclouds.aws.ec2.features.AWSKeyPairApi;
+import org.jclouds.compute.ComputeService;
+import org.jclouds.compute.ComputeServiceContext;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.Template;
+import org.jclouds.compute.domain.TemplateBuilder;
+import org.jclouds.compute.options.TemplateOptions;
+import org.jclouds.domain.Location;
+import org.jclouds.ec2.domain.Attachment;
+import org.jclouds.ec2.domain.AvailabilityZoneInfo;
+import org.jclouds.ec2.domain.KeyPair;
+import org.jclouds.ec2.domain.PublicIpInstanceIdPair;
+import org.jclouds.ec2.domain.Volume;
+import org.jclouds.ec2.features.AvailabilityZoneAndRegionApi;
+import org.jclouds.ec2.features.ElasticBlockStoreApi;
+import org.jclouds.ec2.features.ElasticIPAddressApi;
+import org.jclouds.ec2.options.DetachVolumeOptions;
+
+import java.util.*;
+
+public class EC2Iaas extends JcloudsIaas {
+
+	public EC2Iaas(IaasProvider iaasProvider) {
+		super(iaasProvider);
+	}
+
+	private static final Log log = LogFactory.getLog(EC2Iaas.class);
+	private static final String SUCCESSFUL_LOG_LINE = "A key-pair is created successfully in ";
+	private static final String FAILED_LOG_LINE = "Key-pair is unable to create in ";
+
+	@Override
+	public void buildComputeServiceAndTemplate() {
+		// builds and sets Compute Service
+		ComputeService computeService = ComputeServiceBuilderUtil.buildDefaultComputeService(getIaasProvider());
+        getIaasProvider().setComputeService(computeService);
+
+		// builds and sets Template
+		buildTemplate();
+	}
+
+	public void buildTemplate() {
+		IaasProvider iaasInfo = getIaasProvider();
+		if (iaasInfo.getComputeService() == null) {
+			String msg = "Compute service is null for IaaS provider: "
+					+ iaasInfo.getName();
+			log.fatal(msg);
+			throw new CloudControllerException(msg);
+		}
+
+		TemplateBuilder templateBuilder = iaasInfo.getComputeService().templateBuilder();
+
+		// set image id specified
+		templateBuilder.imageId(iaasInfo.getImage());
+
+        if(!(iaasInfo instanceof IaasProvider)) {
+           templateBuilder.locationId(iaasInfo.getType());
+        }
+
+        if(iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE) != null) {
+            Set<? extends Location> locations = iaasInfo.getComputeService().listAssignableLocations();
+            for(Location location : locations) {
+                if(location.getScope().toString().equalsIgnoreCase(CloudControllerConstants.ZONE_ELEMENT) &&
+                        location.getId().equals(iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE))) {
+                    templateBuilder.locationId(location.getId());
+                    log.info("ZONE has been set as " + iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE)
+                            + " with id: " + location.getId());
+                    break;
+                }
+            }
+        }
+
+		if (iaasInfo.getProperty(CloudControllerConstants.INSTANCE_TYPE) != null) {
+			// set instance type eg: m1.large
+			templateBuilder.hardwareId(iaasInfo.getProperty(CloudControllerConstants.INSTANCE_TYPE));
+		}
+
+		// build the Template
+		Template template = templateBuilder.build();
+
+        if(iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE) != null) {
+            if(!template.getLocation().getId().equals(iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE))) {
+                log.warn("couldn't find assignable ZONE of id :" +
+                        iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE) + " in the IaaS. " +
+                        "Hence using the default location as " + template.getLocation().getScope().toString() +
+                        " with the id " + template.getLocation().getId());
+            }
+        }
+
+		// if you wish to auto assign IPs, instance spawning call should be
+		// blocking, but if you
+		// wish to assign IPs manually, it can be non-blocking.
+		// is auto-assign-ip mode or manual-assign-ip mode?
+		boolean blockUntilRunning = Boolean.parseBoolean(iaasInfo
+				.getProperty(CloudControllerConstants.AUTO_ASSIGN_IP));
+		template.getOptions().as(TemplateOptions.class)
+				.blockUntilRunning(blockUntilRunning);
+
+		// this is required in order to avoid creation of additional security
+		// groups by jclouds.
+		template.getOptions().as(TemplateOptions.class)
+				.inboundPorts(new int[] {});
+
+		// set EC2 specific options
+
+
+        if (iaasInfo.getProperty(CloudControllerConstants.ASSOCIATE_PUBLIC_IP_ADDRESS) != null) {
+              boolean associatePublicIp =  Boolean.parseBoolean(iaasInfo.getProperty(
+                      CloudControllerConstants.ASSOCIATE_PUBLIC_IP_ADDRESS));
+            if(associatePublicIp){
+                  template.getOptions().as(AWSEC2TemplateOptions.class)
+                      .associatePublicIpAddress();
+              }
+        }
+
+		if (iaasInfo.getProperty(CloudControllerConstants.SUBNET_ID) != null) {
+			template.getOptions().as(AWSEC2TemplateOptions.class)
+					.subnetId(iaasInfo.getProperty(CloudControllerConstants.SUBNET_ID));
+		}
+
+		if (iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE) != null) {
+			template.getOptions().as(AWSEC2TemplateOptions.class)
+					.placementGroup(iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE));
+		}
+
+        // security group names
+		if (iaasInfo.getProperty(CloudControllerConstants.SECURITY_GROUPS) != null) {
+			template.getOptions()
+					.as(AWSEC2TemplateOptions.class)
+					.securityGroups(iaasInfo.getProperty(CloudControllerConstants.SECURITY_GROUPS).split(
+                            CloudControllerConstants.ENTRY_SEPARATOR));
+
+		}
+
+        // ability to define tags
+        if (iaasInfo.getProperty(CloudControllerConstants.TAGS) != null) {
+            template.getOptions()
+                    .as(AWSEC2TemplateOptions.class)
+                    .tags(Arrays.asList(iaasInfo.getProperty(CloudControllerConstants.TAGS)
+                                        .split(CloudControllerConstants.ENTRY_SEPARATOR)));
+
+        }
+
+        // ability to define tags with Key-value pairs
+        Map<String, String> keyValuePairTagsMap = new HashMap<String, String>();
+
+        for (String propertyKey : iaasInfo.getProperties().keySet()){
+            if(propertyKey.startsWith(CloudControllerConstants.TAGS_AS_KEY_VALUE_PAIRS_PREFIX)) {
+                keyValuePairTagsMap.put(propertyKey.substring(CloudControllerConstants.TAGS_AS_KEY_VALUE_PAIRS_PREFIX.length()),
+                        iaasInfo.getProperties().get(propertyKey));
+                template.getOptions()
+                    .as(AWSEC2TemplateOptions.class)
+                    .userMetadata(keyValuePairTagsMap);
+            }
+
+        }
+        
+
+        if (iaasInfo.getProperty(CloudControllerConstants.SECURITY_GROUP_IDS) != null) {
+            template.getOptions()
+                    .as(AWSEC2TemplateOptions.class)
+                    .securityGroupIds(iaasInfo.getProperty(CloudControllerConstants.SECURITY_GROUP_IDS)
+                                        .split(CloudControllerConstants.ENTRY_SEPARATOR));
+
+        }
+
+
+		if (iaasInfo.getProperty(CloudControllerConstants.KEY_PAIR) != null) {
+			template.getOptions().as(AWSEC2TemplateOptions.class)
+					.keyPair(iaasInfo.getProperty(CloudControllerConstants.KEY_PAIR));
+		}
+
+
+
+        if (iaasInfo.getNetworkInterfaces() != null) {
+            List<String> networks = new ArrayList<String>(iaasInfo.getNetworkInterfaces().length);
+            for (NetworkInterface ni:iaasInfo.getNetworkInterfaces()) {
+                networks.add(ni.getNetworkUuid());
+            }
+            template.getOptions().as(AWSEC2TemplateOptions.class).networks(networks);
+        }
+
+		// set Template
+		iaasInfo.setTemplate(template);
+	}
+
+	@Override
+	public void setDynamicPayload(byte[] payload) {
+		IaasProvider iaasProvider = getIaasProvider();
+		if (iaasProvider.getTemplate() != null) {
+			iaasProvider.getTemplate().getOptions().as(AWSEC2TemplateOptions.class).userData(payload);
+		}
+	}
+
+	@Override
+	public synchronized boolean createKeyPairFromPublicKey(String region, String keyPairName,
+			String publicKey) {
+		
+		IaasProvider iaasInfo = getIaasProvider();
+
+		String ec2Msg = " ec2. Region: " + region + " - Key Pair Name: ";
+
+		ComputeServiceContext context = iaasInfo.getComputeService()
+				.getContext();
+		
+		AWSKeyPairApi keyPairApi = context.unwrapApi(AWSEC2Api.class).getKeyPairApiForRegion(region).get();
+
+		KeyPair keyPair = keyPairApi.importKeyPairInRegion(region, keyPairName, publicKey);
+		
+		if (keyPair != null) {
+
+			iaasInfo.getTemplate().getOptions().as(AWSEC2TemplateOptions.class)
+					.keyPair(keyPair.getKeyName());
+
+			log.info(SUCCESSFUL_LOG_LINE + ec2Msg + keyPair.getKeyName());
+			return true;
+		}
+
+		log.error(FAILED_LOG_LINE + ec2Msg);
+
+		return false;
+	}
+
+	@Override
+	public synchronized List<String> associateAddresses(NodeMetadata node) {
+
+		IaasProvider iaasInfo = getIaasProvider();
+		
+		ComputeServiceContext context = iaasInfo.getComputeService()
+				.getContext();
+		
+		ElasticIPAddressApi elasticIPAddressApi = context.unwrapApi(AWSEC2Api.class).getElasticIPAddressApi().get();
+		String region = ComputeServiceBuilderUtil.extractRegion(iaasInfo);
+		
+		String ip = null;
+
+		// first try to find an unassigned IP.
+		ArrayList<PublicIpInstanceIdPair> unassignedIps = Lists
+				.newArrayList(Iterables.filter(elasticIPAddressApi.describeAddressesInRegion(region),
+						new Predicate<PublicIpInstanceIdPair>() {
+
+							@Override
+							public boolean apply(PublicIpInstanceIdPair arg0) {
+								return arg0.getInstanceId() == null;
+							}
+
+						}));
+
+		if (!unassignedIps.isEmpty()) {
+			// try to prevent multiple parallel launches from choosing the same
+			// ip.
+			Collections.shuffle(unassignedIps);
+			ip = Iterables.getLast(unassignedIps).getPublicIp();
+		}
+
+		// if no unassigned IP is available, we'll try to allocate an IP.
+		if (ip == null || ip.isEmpty()) {
+			try {
+				ip = elasticIPAddressApi
+						.allocateAddressInRegion(region);
+				log.info("Allocated ip [" + ip + "]");
+
+			} catch (Exception e) {
+				String msg = "Failed to allocate an IP address. All IP addresses are in use.";
+				log.error(msg, e);
+				throw new CloudControllerException(msg, e);
+			}
+		}
+
+		String id = node.getProviderId();
+
+		// wait till the fixed IP address gets assigned - this is needed before
+		// we associate a
+		// public IP
+
+		while (node.getPrivateAddresses() == null) {
+			CloudControllerUtil.sleep(1000);
+		}
+
+		int retries = 0;
+		while (retries < 12 && !associatePublicIp(elasticIPAddressApi, region, ip, id)) {
+
+			// wait for 5s
+			CloudControllerUtil.sleep(5000);
+			retries++;
+		}
+
+		log.debug("Successfully associated an IP address " + ip
+				+ " for node with id: " + node.getId());
+
+		List<String> associatedIPs = new ArrayList<String>();
+		associatedIPs.add(ip);
+		return associatedIPs;
+
+	}
+	
+	@Override
+	public String associatePredefinedAddress(NodeMetadata node, String ip) {
+    	return "";
+    }
+
+	/**
+	 * @param addressApi
+	 * @param region
+	 * @param ip
+	 * @param id
+	 */
+	private boolean associatePublicIp(ElasticIPAddressApi addressApi, String region,
+			String ip, String id) {
+		try {
+			addressApi.associateAddressInRegion(
+					region, ip, id);
+			log.info("Successfully associated public IP ");
+			return true;
+		} catch (Exception e) {
+			log.debug("Exception in associating public IP " + e.getMessage());
+			return false;
+		}
+	}
+
+	@Override
+	public synchronized void releaseAddress(String ip) {
+
+		IaasProvider iaasInfo = getIaasProvider();
+		
+		ComputeServiceContext context = iaasInfo.getComputeService()
+				.getContext();
+		ElasticIPAddressApi elasticIPAddressApi = context.unwrapApi(AWSEC2Api.class).getElasticIPAddressApi().get();
+		String region = ComputeServiceBuilderUtil.extractRegion(iaasInfo);
+
+		elasticIPAddressApi.disassociateAddressInRegion(
+				region, ip);
+		elasticIPAddressApi.releaseAddressInRegion(region,
+				ip);
+	}
+
+    @Override
+    public boolean isValidRegion(String region) throws InvalidRegionException {
+    	
+    	IaasProvider iaasInfo = getIaasProvider();
+    	
+        if (region == null || iaasInfo == null) {
+            String msg =
+                         "Region or IaaSProvider is null: region: " + region + " - IaaSProvider: " +
+                                 iaasInfo;
+            log.error(msg);
+            throw new InvalidRegionException(msg);
+        }
+        
+        ComputeServiceContext context = iaasInfo.getComputeService().getContext();
+        Set<String> regions = context.unwrapApi(AWSEC2Api.class).getConfiguredRegions();
+        for (String configuredRegion : regions) {
+            if (region.equalsIgnoreCase(configuredRegion)) {
+                if (log.isDebugEnabled()) {
+                    log.debug("Found a matching region: " + region);
+                }
+                return true;
+            }
+        }
+        String msg = "Invalid region: " + region +" in the iaas: "+iaasInfo.getType();
+        log.error(msg);
+        throw new InvalidRegionException(msg);
+    }
+
+    @Override
+    public boolean isValidZone(String region, String zone) throws InvalidZoneException {
+    	
+    	IaasProvider iaasInfo = getIaasProvider();
+    	
+        if (zone == null || iaasInfo == null) {
+            String msg =
+                         "Zone or IaaSProvider is null: zone: " + zone + " - IaaSProvider: " +
+                                 iaasInfo;
+            log.error(msg);
+            throw new InvalidZoneException(msg);
+        }
+        ComputeServiceContext context = iaasInfo.getComputeService().getContext();
+        AvailabilityZoneAndRegionApi zoneRegionApi = context.unwrapApi(AWSEC2Api.class).
+        		getAvailabilityZoneAndRegionApiForRegion(region).get();
+        
+        Set<AvailabilityZoneInfo> availabilityZones =
+                                                      zoneRegionApi.describeAvailabilityZonesInRegion(region
+													  );
+        for (AvailabilityZoneInfo zoneInfo : availabilityZones) {
+            String configuredZone = zoneInfo.getZone();
+            if (zone.equalsIgnoreCase(configuredZone)) {
+                if (log.isDebugEnabled()) {
+                    log.debug("Found a matching zone: " + zone);
+                }
+                return true;
+            }
+        }
+
+        String msg = "Invalid zone: " + zone +" in the region: "+region+ " and of the iaas: "+iaasInfo.getType();
+        log.error(msg);
+        throw new InvalidZoneException(msg);
+
+    }
+
+    @Override
+    public boolean isValidHost(String zone, String host) throws InvalidHostException {
+    	
+    	IaasProvider iaasInfo = getIaasProvider();
+    	
+        // there's no such concept in EC2
+        String msg = "Invalid host: " + host +" in the zone: "+zone+ " and of the iaas: "+iaasInfo.getType();
+        log.error(msg);
+        throw new InvalidHostException(msg);
+    }
+
+    @Override
+    public PartitionValidator getPartitionValidator() {
+        return new EC2PartitionValidator();
+    }
+
+	@Override
+	public String createVolume(int sizeGB, String snapshotId) {
+		IaasProvider iaasInfo = getIaasProvider();
+
+		ComputeServiceContext context = iaasInfo.getComputeService()
+				.getContext();
+		
+		String region = ComputeServiceBuilderUtil.extractRegion(iaasInfo);
+		String zone = ComputeServiceBuilderUtil.extractZone(iaasInfo);
+		
+		if(region == null || zone == null) {
+			log.fatal("Cannot create a new volume in the [region] : "+region
+					+", [zone] : "+zone+" of Iaas : "+iaasInfo);
+			return null;
+		}
+		
+		ElasticBlockStoreApi blockStoreApi = context.unwrapApi(AWSEC2Api.class).getElasticBlockStoreApiForRegion(region).get();
+		
+		Volume volume;
+		if(StringUtils.isEmpty(snapshotId)){
+			if(log.isDebugEnabled()){
+        		log.info("Creating a volume in the zone " + zone);
+        	}
+			volume = blockStoreApi.createVolumeInAvailabilityZone(zone, sizeGB);
+		}else{
+			if(log.isDebugEnabled()){
+        		log.info("Creating a volume in the zone " + zone + " from the shanpshot " + snapshotId);
+        	}
+			volume = blockStoreApi.createVolumeFromSnapshotInAvailabilityZone(zone, snapshotId);
+		}
+		 
+		
+		if (volume == null) {
+			log.fatal("Volume creation was unsuccessful. [region] : " + region
+					+ ", [zone] : " + zone + " of Iaas : " + iaasInfo);
+			return null;
+		}
+		
+		log.info("Successfully created a new volume [id]: "+volume.getId()
+				+" in [region] : "+region+", [zone] : "+zone+" of Iaas : "+iaasInfo);
+		return volume.getId();
+	}
+
+	@Override
+	public String attachVolume(String instanceId, String volumeId, String deviceName) {
+		IaasProvider iaasInfo = getIaasProvider();
+
+		ComputeServiceContext context = iaasInfo.getComputeService()
+				.getContext();
+		
+		String region = ComputeServiceBuilderUtil.extractRegion(iaasInfo);
+		String zone = ComputeServiceBuilderUtil.extractZone(iaasInfo);
+		String device = deviceName == null ? "/dev/sdh" : deviceName;
+		
+		if(region == null || zone == null) {
+			log.fatal("Cannot attach the volume [id]: "+volumeId+" in the [region] : "+region
+					+", [zone] : "+zone+" of Iaas : "+iaasInfo);
+			return null;
+		}
+		
+		ElasticBlockStoreApi blockStoreApi = context.unwrapApi(AWSEC2Api.class).getElasticBlockStoreApiForRegion(region).get();
+
+        Volume.Status volumeStatus = this.getVolumeStatus(blockStoreApi, region, volumeId);
+
+        if(log.isDebugEnabled()){
+            log.debug("Volume " + volumeId + " is in state " + volumeStatus);
+        }
+
+        while(volumeStatus != Volume.Status.AVAILABLE){
+            try {
+                // TODO Use a proper mechanism to wait till volume becomes available.
+                Thread.sleep(1000);
+                volumeStatus = this.getVolumeStatus(blockStoreApi, region, volumeId);
+                if(log.isDebugEnabled()){
+                    log.debug("Volume " + volumeId + " is still NOT in AVAILABLE. Current State=" + volumeStatus);
+                }
+            } catch (InterruptedException e) {
+                // Ignoring the exception
+            }
+        }
+        if(log.isDebugEnabled()){
+            log.debug("Volume " + volumeId + " became  AVAILABLE");
+        }
+
+		Attachment attachment = blockStoreApi.attachVolumeInRegion(region, volumeId, instanceId, device);
+
+		if (attachment == null) {
+			log.fatal("Volume [id]: "+volumeId+" attachment for instance [id]: "+instanceId
+					+" was unsuccessful. [region] : " + region
+					+ ", [zone] : " + zone + " of Iaas : " + iaasInfo);
+			return null;
+		}
+		
+		log.info("Volume [id]: "+volumeId+" attachment for instance [id]: "+instanceId
+				+" was successful [status]: "+attachment.getStatus().value()+". [region] : " + region
+				+ ", [zone] : " + zone + " of Iaas : " + iaasInfo);
+		return attachment.getStatus().value();
+	}
+
+    private Volume.Status getVolumeStatus(ElasticBlockStoreApi blockStoreApi, String region, String volumeId){
+        Set<Volume> volumeDescriptions = blockStoreApi.describeVolumesInRegion(region, volumeId);
+        Iterator<Volume> it = volumeDescriptions.iterator();
+        return it.next().getStatus();
+    }
+
+	@Override
+	public void detachVolume(String instanceId, String volumeId) {
+		IaasProvider iaasInfo = getIaasProvider();
+
+		ComputeServiceContext context = iaasInfo.getComputeService()
+				.getContext();
+		
+		String region = ComputeServiceBuilderUtil.extractRegion(iaasInfo);
+		
+		if(region == null) {
+			log.fatal("Cannot detach the volume [id]: "+volumeId+" from the instance [id]: "+instanceId
+					+" of the [region] : "+region
+					+" of Iaas : "+iaasInfo);
+			return;
+		}
+
+		ElasticBlockStoreApi blockStoreApi = context.unwrapApi(AWSEC2Api.class).getElasticBlockStoreApiForRegion(region).get();
+
+        Set<Volume> volumeDescriptions = blockStoreApi.describeVolumesInRegion(region, volumeId);
+        Iterator<Volume> it = volumeDescriptions.iterator();
+
+        while(it.hasNext()){
+            Volume.Status status  = it.next().getStatus();
+
+            if(status == Volume.Status.AVAILABLE){
+                log.warn(String.format("Volume %s is already in AVAILABLE state. Volume seems to be detached somehow", volumeId));
+                return;
+            }
+        }
+
+		blockStoreApi.detachVolumeInRegion(region, volumeId, true, DetachVolumeOptions.Builder.fromInstance(instanceId));
+
+		log.info("Detachment of Volume [id]: "+volumeId+" from instance [id]: "+instanceId
+				+" was successful. [region] : " + region
+				+ " of Iaas : " + iaasInfo);
+	}
+
+	@Override
+	public void deleteVolume(String volumeId) {
+		IaasProvider iaasInfo = getIaasProvider();
+
+		ComputeServiceContext context = iaasInfo.getComputeService()
+				.getContext();
+		
+		String region = ComputeServiceBuilderUtil.extractRegion(iaasInfo);
+		
+		if(region == null) {
+			log.fatal("Cannot delete the volume [id]: "+volumeId+" of the [region] : "+region
+					+" of Iaas : "+iaasInfo);
+			return;
+		}
+		
+		ElasticBlockStoreApi blockStoreApi = context.unwrapApi(AWSEC2Api.class).getElasticBlockStoreApiForRegion(region).get();
+		blockStoreApi.deleteVolumeInRegion(region, volumeId);
+		
+		log.info("Deletion of Volume [id]: "+volumeId+" was successful. [region] : " + region
+				+ " of Iaas : " + iaasInfo);
+	}
+
+    @Override
+    /*
+        Converts the user defined volume device to Ec2 specific device.
+        For example /dev/sdf is converted to /dev/xvdf
+     */
+    public String getIaasDevice(String device) {
+        String[] split = device.split("/");
+        String x = split[split.length-1];
+        StringBuilder ec2Device = new StringBuilder();
+        ec2Device.append("/" + split[1]);
+        ec2Device.append("/xvd");
+        ec2Device.append(x.charAt(x.length()-1));
+        return  ec2Device.toString();
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/e195f2f1/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/ec2/EC2PartitionValidator.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/ec2/EC2PartitionValidator.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/ec2/EC2PartitionValidator.java
new file mode 100644
index 0000000..812257b
--- /dev/null
+++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/ec2/EC2PartitionValidator.java
@@ -0,0 +1,120 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one 
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License 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 org.apache.stratos.cloud.controller.iaases.ec2;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.stratos.cloud.controller.domain.Partition;
+import org.apache.stratos.cloud.controller.exception.InvalidIaasProviderException;
+import org.apache.stratos.cloud.controller.exception.InvalidPartitionException;
+import org.apache.stratos.cloud.controller.iaases.Iaas;
+import org.apache.stratos.cloud.controller.domain.IaasProvider;
+import org.apache.stratos.cloud.controller.iaases.PartitionValidator;
+import org.apache.stratos.cloud.controller.services.impl.CloudControllerServiceUtil;
+import org.apache.stratos.cloud.controller.util.CloudControllerConstants;
+import org.apache.stratos.messaging.domain.topology.Scope;
+
+import java.util.Properties;
+
+
+/**
+ * AWS-EC2 {@link org.apache.stratos.cloud.controller.iaases.PartitionValidator} implementation.
+ *
+ *
+ */
+public class EC2PartitionValidator implements PartitionValidator {
+    
+    private static final Log log = LogFactory.getLog(EC2PartitionValidator.class);
+    private IaasProvider iaasProvider;
+    private Iaas iaas;
+
+    @Override
+    public IaasProvider validate(Partition partition, Properties properties) throws InvalidPartitionException {
+        // validate the existence of the region and zone properties.
+        try {
+            if (properties.containsKey(Scope.region.toString())) {
+                String region = properties.getProperty(Scope.region.toString());
+                
+                if (iaasProvider.getImage() != null && !iaasProvider.getImage().contains(region)) {
+
+                    String message = "Invalid partition detected, invalid region: [partition-id] " + partition.getId() +
+                                         " [region] " + region;
+                    log.error(message);
+                    throw new InvalidPartitionException(message);
+                } 
+                
+                iaas.isValidRegion(region);
+                
+                IaasProvider updatedIaasProvider = new IaasProvider(iaasProvider);
+                Iaas updatedIaas = CloudControllerServiceUtil.buildIaas(updatedIaasProvider);
+                updatedIaas.setIaasProvider(updatedIaasProvider);
+                
+                if (properties.containsKey(Scope.zone.toString())) {
+                    String zone = properties.getProperty(Scope.zone.toString());
+                    iaas.isValidZone(region, zone);
+                    updatedIaasProvider.setProperty(CloudControllerConstants.AVAILABILITY_ZONE, zone);
+                    updatedIaas = CloudControllerServiceUtil.buildIaas(updatedIaasProvider);
+                    updatedIaas.setIaasProvider(updatedIaasProvider);
+                } 
+                
+                updateOtherProperties(updatedIaasProvider, properties);
+                return updatedIaasProvider;
+                
+            } else {
+                
+                return iaasProvider;
+            }
+        } catch (Exception ex) {
+            String message = "Invalid partition detected: [partition-id] " + partition.getId();
+            log.error(message, ex);
+            throw new InvalidPartitionException(message, ex);
+        }
+    }
+
+    private void updateOtherProperties(IaasProvider updatedIaasProvider,
+			Properties properties) {
+    	Iaas updatedIaas;
+		try {
+			updatedIaas = CloudControllerServiceUtil.buildIaas(updatedIaasProvider);
+
+			for (Object property : properties.keySet()) {
+				if (property instanceof String) {
+					String key = (String) property;
+					updatedIaasProvider.setProperty(key,
+							properties.getProperty(key));
+					if (log.isDebugEnabled()) {
+						log.debug("Added property " + key
+								+ " to the IaasProvider.");
+					}
+				}
+			}
+			updatedIaas = CloudControllerServiceUtil.buildIaas(updatedIaasProvider);
+			updatedIaas.setIaasProvider(updatedIaasProvider);
+		} catch (InvalidIaasProviderException ignore) {
+		}
+    	
+	}
+
+	@Override
+    public void setIaasProvider(IaasProvider iaas) {
+        this.iaasProvider = iaas;
+        this.iaas = iaas.getIaas();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/e195f2f1/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/gce/GCEIaas.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/gce/GCEIaas.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/gce/GCEIaas.java
new file mode 100644
index 0000000..de14e1e
--- /dev/null
+++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/gce/GCEIaas.java
@@ -0,0 +1,456 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one 
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License 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 org.apache.stratos.cloud.controller.iaases.gce;
+
+import java.util.*;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.stratos.cloud.controller.exception.CloudControllerException;
+import org.apache.stratos.cloud.controller.iaases.JcloudsIaas;
+import org.apache.stratos.cloud.controller.util.ComputeServiceBuilderUtil;
+import org.apache.stratos.cloud.controller.domain.IaasProvider;
+import org.apache.stratos.cloud.controller.domain.NetworkInterface;
+import org.apache.stratos.cloud.controller.iaases.PartitionValidator;
+import org.apache.stratos.cloud.controller.exception.InvalidHostException;
+import org.apache.stratos.cloud.controller.exception.InvalidRegionException;
+import org.apache.stratos.cloud.controller.exception.InvalidZoneException;
+import org.jclouds.ContextBuilder;
+import org.jclouds.compute.ComputeService;
+import org.jclouds.compute.ComputeServiceContext;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.Template;
+import org.jclouds.compute.domain.TemplateBuilder;
+import org.jclouds.compute.options.TemplateOptions;
+import org.jclouds.domain.Location;
+import org.apache.stratos.cloud.controller.util.CloudControllerConstants;
+import org.jclouds.collect.IterableWithMarker;
+import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
+import org.jclouds.googlecomputeengine.features.DiskApi;
+import org.jclouds.googlecomputeengine.features.InstanceApi;
+import org.jclouds.googlecomputeengine.features.RegionApi;
+import org.jclouds.googlecomputeengine.features.ZoneApi;
+import org.jclouds.googlecomputeengine.domain.Disk;
+import org.jclouds.googlecomputeengine.domain.Instance;
+import org.jclouds.googlecomputeengine.domain.Region;
+import org.jclouds.googlecomputeengine.domain.Zone;
+import org.jclouds.googlecomputeengine.domain.Operation;
+import org.jclouds.googlecomputeengine.options.AttachDiskOptions;
+import org.jclouds.googlecomputeengine.options.AttachDiskOptions.DiskType;
+
+import com.google.inject.Key;
+import com.google.inject.Injector;
+import com.google.inject.TypeLiteral;
+import com.google.inject.name.Names;
+
+import static org.jclouds.util.Predicates2.retry;
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+import com.google.common.base.Predicate;
+
+import java.util.concurrent.atomic.AtomicReference;
+
+import com.google.common.util.concurrent.Atomics;
+
+public class GCEIaas extends JcloudsIaas {
+
+
+	private static final Log log = LogFactory.getLog(GCEIaas.class);
+	
+	private static final String PROJECTNAME = "projectName";
+	
+	public GCEIaas(IaasProvider iaasProvider) {
+		super(iaasProvider);
+	}
+
+	@Override
+	public void buildComputeServiceAndTemplate() {
+		// builds and sets Compute Service
+        ComputeService computeService = ComputeServiceBuilderUtil.buildDefaultComputeService(getIaasProvider());
+        getIaasProvider().setComputeService(computeService);
+
+		// builds and sets Template
+		buildTemplate();
+	}
+
+	public void buildTemplate() {
+		IaasProvider iaasInfo = getIaasProvider();
+		
+		if (iaasInfo.getComputeService() == null) {
+			String msg = "Compute service is null for IaaS provider: "
+					+ iaasInfo.getName();
+			log.fatal(msg);
+			throw new CloudControllerException(msg);
+		}
+
+		log.info("gce buildTemplate");
+
+		TemplateBuilder templateBuilder = iaasInfo.getComputeService()
+				.templateBuilder();
+
+		// set image id specified
+		templateBuilder.imageId(iaasInfo.getImage());
+
+		String zone = iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE);
+		if(zone != null) {
+			Set<? extends Location> locations = iaasInfo.getComputeService().listAssignableLocations();
+			for(Location location : locations) {
+				if(location.getScope().toString().equalsIgnoreCase(CloudControllerConstants.ZONE_ELEMENT) &&
+					location.getId().equals(zone)) {
+					templateBuilder.locationId(location.getId());
+					log.info("ZONE has been set as " + zone
+						+ " with id: " + location.getId());
+					break;
+				}
+			}
+		}
+
+		if (iaasInfo.getProperty(CloudControllerConstants.INSTANCE_TYPE) != null) {
+			// set instance type eg: m1.large
+			templateBuilder.hardwareId(iaasInfo.getProperty(CloudControllerConstants.INSTANCE_TYPE));
+		}
+
+		// build the Template
+		Template template = templateBuilder.build();
+
+		if(zone != null) {
+			if(!template.getLocation().getId().equals(zone)) {
+				log.warn("couldn't find assignable ZONE of id :" + zone +
+				" in the IaaS. Hence using the default location as " + template.getLocation().getScope().toString() +
+				" with the id " + template.getLocation().getId());
+			}
+		}
+
+		// if you wish to auto assign IPs, instance spawning call should be
+		// blocking, but if you
+		// wish to assign IPs manually, it can be non-blocking.
+		// is auto-assign-ip mode or manual-assign-ip mode? - default mode is
+		// non-blocking
+		boolean blockUntilRunning = Boolean.parseBoolean(iaasInfo
+				.getProperty("autoAssignIp"));
+		template.getOptions().as(TemplateOptions.class)
+				.blockUntilRunning(blockUntilRunning);
+
+		// this is required in order to avoid creation of additional security
+		// groups by Jclouds.
+		template.getOptions().as(TemplateOptions.class)
+                                .inboundPorts(22, 80, 8080, 443, 8243);
+
+		if (zone != null) {
+			templateBuilder.locationId(zone);
+			log.debug("setting location to " + zone);
+		}
+
+		// ability to define tags with Key-value pairs
+		Map<String, String> keyValuePairTagsMap = new HashMap<String, String>();
+
+		for (String propertyKey : iaasInfo.getProperties().keySet()){
+			if(propertyKey.startsWith(CloudControllerConstants.TAGS_AS_KEY_VALUE_PAIRS_PREFIX)) {
+				keyValuePairTagsMap.put(propertyKey.substring(CloudControllerConstants.TAGS_AS_KEY_VALUE_PAIRS_PREFIX.length()),
+					iaasInfo.getProperties().get(propertyKey));
+				template.getOptions()
+				    .userMetadata(keyValuePairTagsMap);
+			}
+			log.info("usermeta data key:"+ propertyKey + " value: " + iaasInfo.getProperties().get(propertyKey));
+		}
+
+		if (iaasInfo.getNetworkInterfaces() != null) {
+			List<String> networks = new ArrayList<String>(iaasInfo.getNetworkInterfaces().length);
+			for (NetworkInterface ni:iaasInfo.getNetworkInterfaces()) {
+				networks.add(ni.getNetworkUuid());
+				log.info("using network interface " + ni.getNetworkUuid());
+			}
+			template.getOptions().as(TemplateOptions.class).networks(networks);
+			log.info("using network interface " + networks);
+		}
+
+		// set Template
+		iaasInfo.setTemplate(template);
+	}
+
+	@Override
+	public void setDynamicPayload(byte[] payload) {
+		// in vCloud case we need to run a script
+		IaasProvider iaasInfo = getIaasProvider();
+
+		if (iaasInfo.getTemplate() == null || iaasInfo.getPayload() == null) {
+			if (log.isDebugEnabled()) {
+				log.debug("Payload for GCE not found");
+			}
+			return;
+		}
+
+		// Payload is a String value
+		String payloadStr = new String(payload);
+
+		log.info("setDynamicPayload " + payloadStr);
+
+		Map<String, String> keyValuePairTagsMap = new HashMap<String, String>();
+		keyValuePairTagsMap.put("stratos_usermetadata", payloadStr);
+		iaasInfo.getTemplate().getOptions().userMetadata(keyValuePairTagsMap);
+	}
+
+	@Override
+	public boolean createKeyPairFromPublicKey(String region, String keyPairName, String publicKey) {
+
+		// Not applicable for GCE - Not called by stratos cloud controller as well
+		return false;
+	}
+
+	@Override
+	public List<String> associateAddresses(NodeMetadata node) {
+
+		// TODO
+		return null;
+
+	}
+
+	@Override
+	public String associatePredefinedAddress(NodeMetadata node, String ip) {
+		return "";
+	}
+
+	@Override
+	public void releaseAddress(String ip) {
+		// TODO
+	}
+
+	@Override
+	public boolean isValidRegion(String region) throws InvalidRegionException {
+		IaasProvider iaasInfo = getIaasProvider();
+
+		if (region == null || iaasInfo == null) {
+			String msg = "Region or IaaSProvider is null: region: " + region + " - IaaSProvider: " + iaasInfo;
+			log.error(msg);
+			throw new InvalidRegionException(msg);
+		}
+
+		GoogleComputeEngineApi api = getGCEApi();
+		RegionApi regionApi = api.getRegionApiForProject(iaasInfo.getProperty(PROJECTNAME));
+
+		for(IterableWithMarker<Region> page : regionApi.list()) {
+			for(Region r : page) {
+				if (region.equalsIgnoreCase(r.getName())) {
+					log.debug("Found a matching region: " + region);
+					return true;
+				}
+			}
+		}
+
+		String msg = "Invalid region: " + region +" in the iaas: "+iaasInfo.getType();
+		log.error(msg);
+		throw new InvalidRegionException(msg);
+	}
+
+	@Override
+	public boolean isValidZone(String region, String zone) throws InvalidZoneException {
+		IaasProvider iaasInfo = getIaasProvider();
+
+		if (zone == null || iaasInfo == null) {
+			String msg = "Zone or IaaSProvider is null: region: " + region + 
+				     " zone: " + zone + " - IaaSProvider: " + iaasInfo;
+			log.error(msg);
+			throw new InvalidZoneException(msg);
+		}
+
+		GoogleComputeEngineApi api = getGCEApi();
+		ZoneApi zoneApi = api.getZoneApiForProject(iaasInfo.getProperty(PROJECTNAME));
+
+		for(IterableWithMarker<Zone> page : zoneApi.list()) {
+			for(Zone z : page) {
+				if (zone.equalsIgnoreCase(z.getName())) {
+					log.debug("Found a matching zone: " + zone);
+					return true;
+				}
+			}
+		}
+
+		String msg = "Invalid zone: " + zone + " in the region: " + region + " and of the iaas: " + iaasInfo.getType();
+		log.error(msg);
+		throw new InvalidZoneException(msg);
+	}
+
+	@Override
+	public boolean isValidHost(String zone, String host) throws InvalidHostException {
+		IaasProvider iaasInfo = getIaasProvider();
+
+		// Not called by cloud controller
+		// there's no such concept in GCE
+
+		String msg = "Invalid host: " + host + " in the zone: " + zone + " and of the iaas: " + iaasInfo.getType();
+		log.error(msg);
+		throw new InvalidHostException(msg);
+	}
+
+	@Override
+	public PartitionValidator getPartitionValidator() {
+		return new GCEPartitionValidator();
+	}
+
+	@Override
+        public String createVolume(int sizeGB, String snapshotId) {
+		// generate a random diskname
+		Random rand = new Random();
+		String diskName = "stratos-disk-" + rand.nextInt(100000);
+		DiskApi diskApi = getGCEDiskApi();
+		String zone = getZone();
+
+		log.debug("Creating volume: " + diskName + " in zone: " + zone + " of size: " + sizeGB);
+
+		Operation oper = diskApi.createInZone(diskName, sizeGB, zone);
+
+		oper = waitGCEOperationDone(oper);
+		if (oper.getStatus() != Operation.Status.DONE) {
+			log.error("Failed to create volume: " + diskName + " of size: " + sizeGB +
+				  " in zone: " + zone + " operation: " + oper);
+			return null;
+		}
+
+		return diskName;
+	}
+
+	@Override
+	public String attachVolume(String instanceId, String volumeId, String deviceName) {
+		DiskApi diskApi = getGCEDiskApi();
+		InstanceApi instApi = getGCEInstanceApi();
+		String zone = getZone();
+
+		log.debug("Trying to attach volume: " + volumeId + " to instance: " + instanceId +
+			  " in zone: " + zone + " at devicename: " + deviceName);
+
+		Disk disk = diskApi.getInZone(zone, volumeId);
+		if (disk == null) {
+			log.error("Failed to get volume: " + volumeId + " in zone: " + zone);
+			return null;
+		}
+
+		log.debug("Found volumeId: " + volumeId + " volume: " + disk);
+
+		Operation oper = instApi.attachDiskInZone(zone, instanceId,
+						new AttachDiskOptions().type(DiskType.PERSISTENT)
+							.source(disk.getSelfLink())
+							.mode(AttachDiskOptions.DiskMode.READ_WRITE)
+							.deviceName(deviceName));
+		oper = waitGCEOperationDone(oper);
+		if (oper.getStatus() != Operation.Status.DONE) {
+			log.error("Failed to attach volume: " + volumeId + " to instance: " + instanceId +
+				  " in zone: " + zone + " at device: " + deviceName + " operation: " + oper);
+			return null;
+		}
+
+		return volumeId;
+	}
+
+	@Override
+	public void detachVolume(String instanceId, String volumeId) {
+		InstanceApi instApi = getGCEInstanceApi();
+		String zone = getZone();
+		Instance inst = instApi.getInZone(zone, instanceId);
+
+		log.debug("Trying to detach volume: " + volumeId + " from instance: " + instanceId +
+			  " " + inst + " in zone: " + zone);
+
+		if (inst == null) {
+			log.error("Failed to find instance: " + instanceId + " in zone: " + zone);
+			return;
+		}
+
+		for(Instance.AttachedDisk disk : inst.getDisks()) {
+			Instance.PersistentAttachedDisk persistentDisk = (Instance.PersistentAttachedDisk)disk;
+
+			log.debug("Found disk - src: " + persistentDisk.getSourceDiskName() +
+				  " devicename: " + persistentDisk.getDeviceName());
+
+			if (persistentDisk.getSourceDiskName().equals(volumeId)) {
+				Operation oper = instApi.detachDiskInZone(zone, instanceId, persistentDisk.getDeviceName().get());
+				oper = waitGCEOperationDone(oper);
+				if (oper.getStatus() != Operation.Status.DONE) {
+					log.error("Failed to detach volume: " + volumeId + " to instance: " + instanceId +
+						  " in zone: " + zone + " at device: " + persistentDisk.getDeviceName() +
+						  " result operation: " + oper);
+				}
+				return;
+			}
+		}
+
+		log.error("Cannot find volume: " + volumeId + " in instance: " + instanceId);
+	}
+
+	@Override
+	public void deleteVolume(String volumeId) {
+		DiskApi diskApi = getGCEDiskApi();
+		String zone = getZone();
+
+		log.debug("Deleting volume: " + volumeId + " in zone: " + zone);
+
+		Operation oper = diskApi.deleteInZone(zone, volumeId);
+
+		oper = waitGCEOperationDone(oper);
+		if (oper.getStatus() != Operation.Status.DONE) {
+			log.error("Failed to delete volume: " + volumeId + " in zone: " + zone +
+				  " operation: " + oper);
+		}
+	}
+
+	@Override
+	public String getIaasDevice(String device) {
+		return device;
+	}
+
+	private String getZone() {
+                IaasProvider iaasInfo = getIaasProvider();
+		return iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE);
+	}
+
+	private GoogleComputeEngineApi getGCEApi() {
+		IaasProvider iaasInfo = getIaasProvider();
+		ComputeServiceContext context = iaasInfo.getComputeService().getContext();
+		GoogleComputeEngineApi api = context.unwrapApi(GoogleComputeEngineApi.class);
+
+		return api;
+	}
+
+	private DiskApi getGCEDiskApi() {
+		IaasProvider iaasInfo = getIaasProvider();
+		String projectName = iaasInfo.getProperty(PROJECTNAME);
+		return getGCEApi().getDiskApiForProject(projectName);
+	}
+
+	private InstanceApi getGCEInstanceApi() {
+		IaasProvider iaasInfo = getIaasProvider();
+		String projectName = iaasInfo.getProperty(PROJECTNAME);
+		return getGCEApi().getInstanceApiForProject(projectName);
+	}
+
+	private Operation waitGCEOperationDone(Operation operation) {
+		int maxWaitTime = 15; // 15 seconds
+                IaasProvider iaasInfo = getIaasProvider();
+		Injector injector = ContextBuilder.newBuilder(iaasInfo.getProvider())
+					  .credentials(iaasInfo.getIdentity(), iaasInfo.getCredential())
+					  .buildInjector();
+		Predicate<AtomicReference<Operation>> zoneOperationDonePredicate =
+			    injector.getInstance(Key.get(new TypeLiteral<Predicate<AtomicReference<Operation>>>() {
+				}, Names.named("zone")));
+		AtomicReference<Operation> operationReference = Atomics.newReference(operation);
+		retry(zoneOperationDonePredicate, maxWaitTime, 1, SECONDS).apply(operationReference);
+
+		return operationReference.get();
+	}
+}
+

http://git-wip-us.apache.org/repos/asf/stratos/blob/e195f2f1/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/gce/GCEPartitionValidator.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/gce/GCEPartitionValidator.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/gce/GCEPartitionValidator.java
new file mode 100644
index 0000000..dc2733b
--- /dev/null
+++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/gce/GCEPartitionValidator.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one 
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License 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 org.apache.stratos.cloud.controller.iaases.gce;
+
+import java.util.Properties;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.stratos.cloud.controller.domain.Partition;
+import org.apache.stratos.cloud.controller.exception.InvalidPartitionException;
+import org.apache.stratos.cloud.controller.domain.IaasProvider;
+import org.apache.stratos.cloud.controller.iaases.PartitionValidator;
+import org.apache.stratos.cloud.controller.iaases.vcloud.VCloudPartitionValidator;
+
+
+/**
+ * The VCloud {@link org.apache.stratos.cloud.controller.iaases.PartitionValidator} implementation.
+ *
+ */
+public class GCEPartitionValidator implements PartitionValidator {
+    
+    private static final Log log = LogFactory.getLog(VCloudPartitionValidator.class);
+
+    private IaasProvider iaasProvider;
+
+    @Override
+    public IaasProvider validate(Partition partition, Properties properties) throws InvalidPartitionException {
+        return iaasProvider;
+    }
+
+    @Override
+    public void setIaasProvider(IaasProvider iaasProvider) {
+        this.iaasProvider = iaasProvider;
+    }
+}


Mime
View raw message