Repository: incubator-stratos
Updated Branches:
  refs/heads/master 9ae460179 -> 989cad967


ability to define multiple volumes and fixing some openstack concept issues


Project: http://git-wip-us.apache.org/repos/asf/incubator-stratos/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-stratos/commit/0818d344
Tree: http://git-wip-us.apache.org/repos/asf/incubator-stratos/tree/0818d344
Diff: http://git-wip-us.apache.org/repos/asf/incubator-stratos/diff/0818d344

Branch: refs/heads/master
Commit: 0818d344c63e0ca845dd68de15a64f08952487fa
Parents: 4abba97
Author: Nirmal Fernando <[email protected]>
Authored: Tue Feb 18 10:07:32 2014 +0530
Committer: Nirmal Fernando <[email protected]>
Committed: Tue Feb 18 10:07:32 2014 +0530

----------------------------------------------------------------------
 .../controller/iaases/OpenstackNovaIaas.java    |  23 ++-
 .../impl/CloudControllerServiceImpl.java        | 164 +++++++++++++------
 .../cloud/controller/pojo/ClusterContext.java   |  53 ++----
 .../stratos/cloud/controller/pojo/Volume.java   |  45 ++++-
 .../OpenstackNovaPartitionValidator.java        |   8 +-
 5 files changed, 199 insertions(+), 94 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/0818d344/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/OpenstackNovaIaas.java
----------------------------------------------------------------------
diff --git 
a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/OpenstackNovaIaas.java
 
b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/OpenstackNovaIaas.java
index 1220526..26e0f24 100644
--- 
a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/OpenstackNovaIaas.java
+++ 
b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/OpenstackNovaIaas.java
@@ -51,6 +51,8 @@ import org.jclouds.openstack.nova.v2_0.domain.HostAggregate;
 import org.jclouds.openstack.nova.v2_0.domain.KeyPair;
 import org.jclouds.openstack.nova.v2_0.domain.Volume;
 import org.jclouds.openstack.nova.v2_0.domain.VolumeAttachment;
+import org.jclouds.openstack.nova.v2_0.domain.zonescoped.AvailabilityZone;
+import org.jclouds.openstack.nova.v2_0.extensions.AvailabilityZoneAPI;
 import org.jclouds.openstack.nova.v2_0.extensions.FloatingIPApi;
 import org.jclouds.openstack.nova.v2_0.extensions.HostAggregateApi;
 import org.jclouds.openstack.nova.v2_0.extensions.KeyPairApi;
@@ -351,7 +353,26 @@ public class OpenstackNovaIaas extends Iaas {
     public boolean isValidZone(String region, String zone) throws 
InvalidZoneException {
        IaasProvider iaasInfo = getIaasProvider();
        
-        // jclouds doesn't support zone in Openstack-Nova API
+       // jclouds availability zone = stratos zone
+       if (region == null || zone == null || iaasInfo == null) {
+            String msg = "Host or Zone or IaaSProvider is null: region: " + 
region + " - zone: " +
+                    zone + " - IaaSProvider: " + iaasInfo;
+            log.error(msg);
+            throw new InvalidZoneException(msg);
+        }
+        ComputeServiceContext context = 
iaasInfo.getComputeService().getContext();
+        RestContext<NovaApi, NovaAsyncApi> nova = context.unwrap();
+        AvailabilityZoneAPI zoneApi = 
nova.getApi().getAvailabilityZoneApi(region);
+        for (AvailabilityZone z : zoneApi.list()) {
+                       
+               if (zone.equalsIgnoreCase(z.getName())) {
+                       if (log.isDebugEnabled()) {
+                               log.debug("Found a matching availability 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);

http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/0818d344/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/impl/CloudControllerServiceImpl.java
----------------------------------------------------------------------
diff --git 
a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/impl/CloudControllerServiceImpl.java
 
b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/impl/CloudControllerServiceImpl.java
index 48ff77b..e016928 100644
--- 
a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/impl/CloudControllerServiceImpl.java
+++ 
b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/impl/CloudControllerServiceImpl.java
@@ -296,10 +296,15 @@ public class CloudControllerServiceImpl implements 
CloudControllerService {
             String group = str.replaceAll("[^a-z0-9-]", "");
             
             if(ctxt.isVolumeRequired()) {
-               if (ctxt.getVolumeId() == null) {
-                       // create a new volume
-                       createVolumeAndSetInClusterContext(ctxt, iaasProvider);
-               } 
+               if (!ctxt.getListOfVolumes().isEmpty()) {
+                       for (Volume volume : ctxt.getListOfVolumes()) {
+                                               
+                               if (volume.getId() == null) {
+                                       // create a new volume
+                                       
createVolumeAndSetInClusterContext(volume, iaasProvider);
+                               } 
+                                       }
+               }
             }
             
             NodeMetadata node;
@@ -328,14 +333,19 @@ public class CloudControllerServiceImpl implements 
CloudControllerService {
                     log.debug("Node id was set. "+memberContext.toString());
                 }
                 
-                // attach volume
+                // attach volumes
                        if (ctxt.isVolumeRequired()) {
                                // remove region prefix
                                String instanceId = nodeId.indexOf('/') != -1 ? 
nodeId
                                                .substring(nodeId.indexOf('/') 
+ 1, nodeId.length())
                                                : nodeId;
                                memberContext.setInstanceId(instanceId);
-                               iaas.attachVolume(instanceId, 
ctxt.getVolumeId(), ctxt.getDeviceName());
+                               if (!ctxt.getListOfVolumes().isEmpty()) {
+                       for (Volume volume : ctxt.getListOfVolumes()) {
+                               
+                               iaas.attachVolume(instanceId, volume.getId(), 
volume.getDevice());
+                       }
+                               }
                        }
 
             log.info("Instance is successfully starting up. 
"+memberContext.toString());
@@ -350,7 +360,7 @@ public class CloudControllerServiceImpl implements 
CloudControllerService {
 
     }
 
-       private void createVolumeAndSetInClusterContext(ClusterContext ctxt,
+       private void createVolumeAndSetInClusterContext(Volume volume,
                        IaasProvider iaasProvider) {
 
                Iaas iaas = iaasProvider.getIaas();
@@ -364,9 +374,10 @@ public class CloudControllerServiceImpl implements 
CloudControllerService {
                                throw new CloudControllerException(msg, e);
                        }
                }
-               int sizeGB = ctxt.getVolumeSize();
+               int sizeGB = volume.getSize();
                String volumeId = iaas.createVolume(sizeGB);
-               ctxt.setVolumeId(volumeId);
+               volume.setId(volumeId);
+               volume.setIaasType(iaasProvider.getType());
        }
 
        private StringBuilder getPersistencePayload(Cartridge cartridge) {
@@ -834,18 +845,23 @@ public class CloudControllerServiceImpl implements 
CloudControllerService {
        }
 
        private void detachVolume(IaasProvider iaasProvider, MemberContext 
ctxt) {
-               try {
                String clusterId = ctxt.getClusterId();
                ClusterContext clusterCtxt = 
dataHolder.getClusterContext(clusterId);
-               String volumeId = clusterCtxt.getVolumeId();
-               if(volumeId == null) {
-                       return;
-               }
-               Iaas iaas = iaasProvider.getIaas();
-               iaas.detachVolume(ctxt.getInstanceId(), volumeId);
-               } catch (ResourceNotFoundException ignore) {
-                       if(log.isDebugEnabled()) {
-                               log.debug(ignore);
+               if (clusterCtxt.getListOfVolumes() != null) {
+                       for (Volume volume : clusterCtxt.getListOfVolumes()) {
+                               
+                               try {
+                                       String volumeId = volume.getId();
+                                       if (volumeId == null) {
+                                               return;
+                                       }
+                                       Iaas iaas = iaasProvider.getIaas();
+                                       iaas.detachVolume(ctxt.getInstanceId(), 
volumeId);
+                               } catch (ResourceNotFoundException ignore) {
+                                       if(log.isDebugEnabled()) {
+                                               log.debug(ignore);
+                                       }
+                               }
                        }
                }
        }
@@ -888,7 +904,8 @@ public class CloudControllerServiceImpl implements 
CloudControllerService {
                throw new IllegalArgumentException(msg);
            }
            
-        if (dataHolder.getCartridge(cartridgeType) == null) {
+        Cartridge cartridge = null;
+        if ((cartridge = dataHolder.getCartridge(cartridgeType)) == null) {
 
             String msg = "Registration of cluster: "+clusterId+
                     " failed. - Unregistered Cartridge type: " + cartridgeType;
@@ -900,25 +917,8 @@ public class CloudControllerServiceImpl implements 
CloudControllerService {
         String property = props.getProperty(Constants.IS_LOAD_BALANCER);
         boolean isLb = property != null ? Boolean.parseBoolean(property) : 
false;
 
-        property = props.getProperty(Constants.IS_VOLUME_REQUIRED);
-        boolean isVolumeRequired = property != null ? 
Boolean.parseBoolean(property) : false;
-
-        property = props.getProperty(Constants.SHOULD_DELETE_VOLUME);
-        boolean shouldDeleteVolume = property != null ? 
Boolean.parseBoolean(property) : false;
-        
-        property = props.getProperty(Constants.VOLUME_SIZE);
-        int volumeSize = property != null ? Integer.parseInt(property) : 0;
-        
-        property = props.getProperty(Constants.GRACEFUL_SHUTDOWN_TIMEOUT);
-        long timeout = property != null ? Long.parseLong(property) : 30000;
-        
-           ClusterContext ctxt = new ClusterContext(clusterId, cartridgeType, 
payload, 
-                       hostName, isLb);
-           ctxt.setVolumeRequired(isVolumeRequired);
-           ctxt.setShouldDeleteVolume(shouldDeleteVolume);
-           //ctxt.setDeviceName(deviceName);
-           ctxt.setVolumeSize(volumeSize);
-           ctxt.setTimeoutInMillis(timeout);
+        ClusterContext ctxt = buildClusterContext(cartridge, clusterId,
+                               payload, hostName, props, isLb);
            
                dataHolder.addClusterContext(ctxt);
            TopologyBuilder.handleClusterCreated(registrant, isLb);
@@ -928,6 +928,55 @@ public class CloudControllerServiceImpl implements 
CloudControllerService {
                return true;
        }
 
+       private ClusterContext buildClusterContext(Cartridge cartridge,
+                       String clusterId, String payload, String hostName,
+                       Properties props, boolean isLb) {
+               
+               // initialize ClusterContext
+               ClusterContext ctxt = new ClusterContext(clusterId, 
cartridge.getType(), payload, 
+                               hostName, isLb);
+               
+               String property;
+               property = 
props.getProperty(Constants.GRACEFUL_SHUTDOWN_TIMEOUT);
+               long timeout = property != null ? Long.parseLong(property) : 
30000;
+               
+               property = props.getProperty(Constants.IS_VOLUME_REQUIRED);
+        boolean isVolumeRequired = property != null ? 
Boolean.parseBoolean(property) : false;
+        
+        if(isVolumeRequired) {
+               Persistence persistenceData = cartridge.getPersistence();
+               
+               if(persistenceData != null) {
+                       Volume[] volumes = persistenceData.getVolumes();
+                       
+                       property = 
props.getProperty(Constants.SHOULD_DELETE_VOLUME);
+                       property = props.getProperty(Constants.VOLUME_SIZE);
+                       
+                       for (Volume volume : volumes) {
+                               int volumeSize = property != null ? 
Integer.parseInt(property) : volume.getSize();
+                               boolean shouldDeleteVolume = property != null ? 
Boolean.parseBoolean(property) : volume.isRemoveOntermination();
+                               
+                               Volume v = new Volume();
+                               v.setSize(volumeSize);
+                               v.setRemoveOntermination(shouldDeleteVolume);
+                               v.setDevice(volume.getDevice());
+                               v.setMappingPath(volume.getMappingPath());
+                               ctxt.addVolume(v);
+                                       
+                               }
+               } else {
+                       // if we cannot find necessary data, we would not 
consider 
+                       // this as a volume required instance.
+                       isVolumeRequired = false;
+               }
+               
+               ctxt.setVolumeRequired(isVolumeRequired);
+        }
+        
+           ctxt.setTimeoutInMillis(timeout);
+               return ctxt;
+       }
+
        @Override
        public String[] getRegisteredCartridges() {
                // get the list of cartridges registered
@@ -1001,23 +1050,36 @@ public class CloudControllerServiceImpl implements 
CloudControllerService {
                      }
                      
                      log.info("Unregistration of service cluster: " + 
clusterId_);
-                     if(ctxt.shouldDeleteVolume()) {
-                        Cartridge cartridge = 
dataHolder.getCartridge(ctxt.getCartridgeType());
-                        if(cartridge != null && cartridge.getIaases() != null) 
{
-                                for (IaasProvider prov : 
cartridge.getIaases()) {
-                                                               if (prov != 
null) {
-                                                                       Iaas 
iaas = prov.getIaas();
-                                                                       
iaas.deleteVolume(ctxt.getVolumeId());
-                                                               }
-                                                       }
-                                
-                        }
-                     }
+                     deleteVolumes(ctxt);
                      TopologyBuilder.handleClusterRemoved(ctxt);
                      dataHolder.removeClusterContext(clusterId_);
                      dataHolder.removeMemberContextsOfCluster(clusterId_);
                      persist();
                  }
+
+                               private void deleteVolumes(ClusterContext ctxt) 
{
+                                       if(ctxt.isVolumeRequired()) {
+                        Cartridge cartridge = 
dataHolder.getCartridge(ctxt.getCartridgeType());
+                        if(cartridge != null && cartridge.getIaases() != null 
&& !ctxt.getListOfVolumes().isEmpty()) {
+                                for (Volume volume : ctxt.getListOfVolumes()) {
+                                                               
if(volume.getId() != null) {
+                                                                       String 
iaasType = volume.getIaasType();
+                                                                       Iaas 
iaas = dataHolder.getIaasProvider(iaasType).getIaas();
+                                                                       if(iaas 
!= null) {
+                                                                               
try {
+                                                                               
// delete the volume
+                                                                               
iaas.deleteVolume(volume.getId());
+                                                                               
} catch(Exception ignore) {
+                                                                               
        if(log.isDebugEnabled()) {
+                                                                               
                log.debug(ignore);
+                                                                               
        }
+                                                                               
}
+                                                                       }
+                                                               }
+                                                       }
+                        }
+                     }
+                               }
             };
         new Thread(r).start();
         

http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/0818d344/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/pojo/ClusterContext.java
----------------------------------------------------------------------
diff --git 
a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/pojo/ClusterContext.java
 
b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/pojo/ClusterContext.java
index 96a2a1d..d3414e4 100644
--- 
a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/pojo/ClusterContext.java
+++ 
b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/pojo/ClusterContext.java
@@ -19,6 +19,8 @@
 package org.apache.stratos.cloud.controller.pojo;
 
 import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
 
 /**
  * Holds runtime data of a Cluster.
@@ -37,11 +39,7 @@ public class ClusterContext implements Serializable{
     private String hostName;
     private boolean isLbCluster;
     private boolean isVolumeRequired;
-    private boolean shouldDeleteVolume;
-    private int volumeSize;
-    private String deviceName;
-    // optional volume id
-    private String volumeId;
+    private List<Volume> listOfVolumes;
     // timeout in milliseconds - this would be the per member time that CC 
waits before forcefully terminate instances on an unregistration.
     private long timeoutInMillis;
 
@@ -52,6 +50,11 @@ public class ClusterContext implements Serializable{
         this.payload = payload;
         this.setHostName(hostName);
         this.isLbCluster = isLbCluster;
+        this.setListOfVolumes(new ArrayList<Volume>());
+    }
+    
+    public void addVolume(Volume volume) {
+       this.getListOfVolumes().add(volume);
     }
     
     public String getClusterId() {
@@ -97,38 +100,6 @@ public class ClusterContext implements Serializable{
                this.isVolumeRequired = isVolumeRequired;
        }
 
-       public String getVolumeId() {
-               return volumeId;
-       }
-
-       public void setVolumeId(String volumeId) {
-               this.volumeId = volumeId;
-       }
-
-       public boolean shouldDeleteVolume() {
-               return shouldDeleteVolume;
-       }
-
-       public void setShouldDeleteVolume(boolean shouldDeleteVolume) {
-               this.shouldDeleteVolume = shouldDeleteVolume;
-       }
-
-       public int getVolumeSize() {
-               return volumeSize;
-       }
-
-       public void setVolumeSize(int volumeSize) {
-               this.volumeSize = volumeSize;
-       }
-
-       public String getDeviceName() {
-               return deviceName;
-       }
-
-       public void setDeviceName(String deviceName) {
-               this.deviceName = deviceName;
-       }
-
        public long getTimeoutInMillis() {
                return timeoutInMillis;
        }
@@ -137,4 +108,12 @@ public class ClusterContext implements Serializable{
                this.timeoutInMillis = timeoutInMillis;
        }
 
+       public List<Volume> getListOfVolumes() {
+               return listOfVolumes;
+       }
+
+       public void setListOfVolumes(List<Volume> listOfVolumes) {
+               this.listOfVolumes = listOfVolumes;
+       }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/0818d344/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/pojo/Volume.java
----------------------------------------------------------------------
diff --git 
a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/pojo/Volume.java
 
b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/pojo/Volume.java
index 043da4b..b35f965 100644
--- 
a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/pojo/Volume.java
+++ 
b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/pojo/Volume.java
@@ -20,13 +20,15 @@ package org.apache.stratos.cloud.controller.pojo;
 
 import java.io.Serializable;
 
-public class Volume  implements Serializable {
+public class Volume implements Serializable {
     private static final long serialVersionUID = 3455729879991902731L;
 
+    private String id;
     private int size;
        private String device;
        private boolean removeOntermination;
     private String mappingPath;
+    private String iaasType;
 
     public String toString () {
         return "Persistence Required: " + ", Size: " + getSize() + ", device: 
" + getDevice() +
@@ -64,4 +66,45 @@ public class Volume  implements Serializable {
     public void setMappingPath(String mappingPath) {
         this.mappingPath = mappingPath;
     }
+
+       public String getId() {
+               return id;
+       }
+
+       public void setId(String id) {
+               this.id = id;
+       }
+
+       @Override
+       public int hashCode() {
+               final int prime = 31;
+               int result = 1;
+               result = prime * result + ((id == null) ? 0 : id.hashCode());
+               return result;
+       }
+
+       @Override
+       public boolean equals(Object obj) {
+               if (this == obj)
+                       return true;
+               if (obj == null)
+                       return false;
+               if (getClass() != obj.getClass())
+                       return false;
+               Volume other = (Volume) obj;
+               if (id == null) {
+                       if (other.id != null)
+                               return false;
+               } else if (!id.equals(other.id))
+                       return false;
+               return true;
+       }
+
+       public String getIaasType() {
+               return iaasType;
+       }
+
+       public void setIaasType(String iaasType) {
+               this.iaasType = iaasType;
+       }
 }

http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/0818d344/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/validate/OpenstackNovaPartitionValidator.java
----------------------------------------------------------------------
diff --git 
a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/validate/OpenstackNovaPartitionValidator.java
 
b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/validate/OpenstackNovaPartitionValidator.java
index 1df0887..b2c9904 100644
--- 
a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/validate/OpenstackNovaPartitionValidator.java
+++ 
b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/validate/OpenstackNovaPartitionValidator.java
@@ -64,11 +64,11 @@ public class OpenstackNovaPartitionValidator implements 
PartitionValidator {
                 Iaas updatedIaas = 
CloudControllerUtil.getIaas(updatedIaasProvider);
                 updatedIaas.setIaasProvider(updatedIaasProvider);
                 
-                if (properties.containsKey(Scope.host.toString())) {
-                    String host = 
properties.getProperty(Scope.host.toString());
-                    iaas.isValidHost(region, host);
+                if (properties.containsKey(Scope.zone.toString())) {
+                    String zone = 
properties.getProperty(Scope.zone.toString());
+                    iaas.isValidZone(region, zone);
                     
-                    
updatedIaasProvider.setProperty(CloudControllerConstants.HOST, host);
+                    
updatedIaasProvider.setProperty(CloudControllerConstants.ZONE_ELEMENT, zone);
                     updatedIaas.buildTemplate();
                 } 
                 

Reply via email to