Repository: incubator-stratos
Updated Branches:
  refs/heads/master a3fae8e90 -> cbf7c38f0


fixing https://issues.apache.org/jira/browse/STRATOS-493 - patch from Martin 
Eppel


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

Branch: refs/heads/master
Commit: cbf7c38f05399af1fe611be337d2c989d4f04b10
Parents: a3fae8e
Author: Martin Eppel <[email protected]>
Authored: Wed Mar 26 15:45:37 2014 +0530
Committer: Nirmal Fernando <[email protected]>
Committed: Wed Mar 26 15:45:37 2014 +0530

----------------------------------------------------------------------
 .../cloud/controller/iaases/AWSEC2Iaas.java     |  5 ++
 .../controller/iaases/OpenstackNovaIaas.java    | 94 ++++++++++++++++++++
 .../cloud/controller/iaases/VCloudIaas.java     |  5 ++
 .../impl/CloudControllerServiceImpl.java        | 86 ++++++++++++++----
 .../cloud/controller/interfaces/Iaas.java       | 10 +++
 .../util/CloudControllerConstants.java          |  2 +
 6 files changed, 186 insertions(+), 16 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/cbf7c38f/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/AWSEC2Iaas.java
----------------------------------------------------------------------
diff --git 
a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/AWSEC2Iaas.java
 
b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/AWSEC2Iaas.java
index d536672..0702ace 100644
--- 
a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/AWSEC2Iaas.java
+++ 
b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/AWSEC2Iaas.java
@@ -309,6 +309,11 @@ public class AWSEC2Iaas extends Iaas {
                return ip;
 
        }
+       
+       @Override
+       public String associatePredefinedAddress(NodeMetadata node, String ip) {
+       return "";
+    }
 
        /**
         * @param addressApi

http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/cbf7c38f/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 e7ee43f..6a5d221 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
@@ -297,6 +297,100 @@ public class OpenstackNovaIaas extends Iaas {
 
                return ip;
        }
+       
+       @Override
+       public synchronized String associatePredefinedAddress (NodeMetadata 
node, String ip) {
+               if(log.isDebugEnabled()) {
+                       
log.debug("OpenstackNovaIaas:associatePredefinedAddress:ip:" + ip);
+               }
+               
+               IaasProvider iaasInfo = getIaasProvider();
+               
+               ComputeServiceContext context = iaasInfo.getComputeService()
+                               .getContext();
+
+               @SuppressWarnings("deprecation")
+        NovaApi novaClient = 
context.unwrap(NovaApiMetadata.CONTEXT_TOKEN).getApi();
+               String region = 
ComputeServiceBuilderUtil.extractRegion(iaasInfo);
+
+               FloatingIPApi floatingIp = 
novaClient.getFloatingIPExtensionForZone(
+                               region).get();
+
+               if(log.isDebugEnabled()) {
+                       
log.debug("OpenstackNovaIaas:associatePredefinedAddress:floatingip:" + 
floatingIp);
+               }
+               
+               // get the list of all unassigned IP.
+               ArrayList<FloatingIP> unassignedIps = 
Lists.newArrayList(Iterables
+                               .filter(floatingIp.list(),
+                                               new Predicate<FloatingIP>() {
+
+                                                       @Override
+                                                       public boolean 
apply(FloatingIP arg0) {
+                                                               // FIXME is 
this the correct filter?
+                                                               return 
arg0.getFixedIp() == null;
+                                                       }
+
+                                               }));
+               
+               boolean isAvailable = false;
+               for (FloatingIP fip : unassignedIps) {
+                       if(log.isDebugEnabled()) {
+                               
log.debug("penstackNovaIaas:associatePredefinedAddress:iterating over available 
floatingip:" + fip);
+                       }
+                       if (ip.equals(fip.getIp())) {
+                               if(log.isDebugEnabled()) {
+                                       
log.debug("OpenstackNovaIaas:associatePredefinedAddress:floating ip in use:" + 
fip + " /ip:" + ip);
+                               }
+                               isAvailable = true;
+                               break;
+                       }
+               }
+               
+               if (isAvailable) {
+                       // assign ip
+                       if(log.isDebugEnabled()) {
+                               
log.debug("OpenstackNovaIaas:associatePredefinedAddress:assign floating ip:" + 
ip);
+                       }
+                       // exercise same code as in associateAddress()
+                       // 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 < 5
+                                       && !associateIp(floatingIp, ip, 
node.getProviderId())) {
+
+                               // wait for 5s
+                               CloudControllerUtil.sleep(5000);
+                               retries++;
+                       }
+
+                       NodeMetadataBuilder.fromNodeMetadata(node)
+                                       
.publicAddresses(ImmutableSet.of(ip)).build();
+
+                       
log.info("OpenstackNovaIaas:associatePredefinedAddress:Successfully associated 
an IP address " + ip
+                                       + " for node with id: " + node.getId());
+               } else {
+                       // unable to allocate predefined ip,
+                       
log.info("OpenstackNovaIaas:associatePredefinedAddress:Unable to allocate 
predefined ip:" 
+                                       + " for node with id: " + node.getId());
+                       return "";
+               }
+
+               
+               NodeMetadataBuilder.fromNodeMetadata(node)
+                               .publicAddresses(ImmutableSet.of(ip)).build();
+
+               
log.info("OpenstackNovaIaas:associatePredefinedAddress::Successfully associated 
an IP address " + ip
+                               + " for node with id: " + node.getId());
+
+               return ip;
+               
+       }       
 
        @Override
        public synchronized void releaseAddress(String ip) {

http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/cbf7c38f/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/VCloudIaas.java
----------------------------------------------------------------------
diff --git 
a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/VCloudIaas.java
 
b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/VCloudIaas.java
index 56618b7..9332d7f 100644
--- 
a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/VCloudIaas.java
+++ 
b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/VCloudIaas.java
@@ -198,6 +198,11 @@ public class VCloudIaas extends Iaas {
        }
 
        @Override
+       public String associatePredefinedAddress(NodeMetadata node, String ip) {
+       return "";
+    }
+
+       @Override
        public void releaseAddress(String ip) {
                // TODO
        }

http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/cbf7c38f/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 61187d6..adff085 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
@@ -48,6 +48,8 @@ import java.util.*;
 import java.util.Properties;
 import java.util.concurrent.ConcurrentHashMap;
 
+import com.google.common.net.InetAddresses;
+
 /**
  * Cloud Controller Service is responsible for starting up new server 
instances,
  * terminating already started instances, providing pending instance count etc.
@@ -208,7 +210,11 @@ public class CloudControllerServiceImpl implements 
CloudControllerService {
     
     @Override
     public MemberContext startInstance(MemberContext memberContext) throws 
IllegalArgumentException,
-        UnregisteredCartridgeException, InvalidIaasProviderException, 
IllegalStateException {
+        UnregisteredCartridgeException, InvalidIaasProviderException {
+       
+       if(log.isDebugEnabled()) {
+               log.debug("CloudControllerServiceImpl:startInstance");
+       }
 
         if (memberContext == null) {
             String msg = "Instance start-up failed. Member is null.";
@@ -219,7 +225,9 @@ public class CloudControllerServiceImpl implements 
CloudControllerService {
         String clusterId = memberContext.getClusterId();
         Partition partition = memberContext.getPartition();
 
-               log.debug("Received an instance spawn request : " + 
memberContext.toString());
+        if(log.isDebugEnabled()) {
+               log.debug("Received an instance spawn request : " + 
memberContext.toString());
+        }
 
         ComputeService computeService = null;
         Template template = null;
@@ -571,23 +579,64 @@ public class CloudControllerServiceImpl implements 
CloudControllerService {
 
                 String autoAssignIpProp =
                                           
iaasProvider.getProperty(CloudControllerConstants.AUTO_ASSIGN_IP_PROPERTY);
-
-                    // reset ip
-                    String ip = "";
+                
+                String pre_defined_ip =
+                        
iaasProvider.getProperty(CloudControllerConstants.FLOATING_IP_PROPERTY);
+                    
+                       // reset ip
+                       String ip = "";
+                    
                     // default behavior is autoIpAssign=false
                     if (autoAssignIpProp == null ||
                         (autoAssignIpProp != null && 
autoAssignIpProp.equals("false"))) {
-
-                        Iaas iaas = iaasProvider.getIaas();
-                        // allocate an IP address - manual IP assigning mode
-                        ip = iaas.associateAddress(node);
-                        
-                                               if (ip != null) {
-                                                       
memberContext.setAllocatedIpAddress(ip);
-                                                       log.info("Allocated an 
ip address: "
-                                                                       + 
memberContext.toString());
-                                               }
-                    }
+                       
+                       // check if floating ip is well defined in cartridge 
definition
+                       if (pre_defined_ip != null) {
+                               if (isValidIpAddress(pre_defined_ip)) {
+                                       if(log.isDebugEnabled()) {
+                                               
log.debug("CloudControllerServiceImpl:IpAllocator:pre_defined_ip: invoking 
associatePredefinedAddress" + pre_defined_ip);
+                                       }
+                                       Iaas iaas = iaasProvider.getIaas();
+                                       ip = 
iaas.associatePredefinedAddress(node, pre_defined_ip);
+                      
+                                       if (ip == null || "".equals(ip) || 
!pre_defined_ip.equals(ip)) {
+                                               // throw exception and stop 
instance creation
+                                               String msg = "Error occurred 
while allocating predefined floating ip address: " + pre_defined_ip + 
+                                                                        " / 
allocated ip:" + ip + 
+                                                                    " - 
terminating node:"  + memberContext.toString();
+                                       log.error(msg);
+                                               // terminate instance
+                                       terminate(iaasProvider, 
+                                                       node.getId(), 
memberContext);
+                                       throw new CloudControllerException(msg);
+                                       }
+                               } else {
+                                       String msg = "Invalid floating ip 
address configured: " + pre_defined_ip +  
+                                                            " - terminating 
node:"  + memberContext.toString();
+                                       log.error(msg);
+                                       // terminate instance
+                                       terminate(iaasProvider, 
+                                               node.getId(), memberContext);
+                                       throw new CloudControllerException(msg);
+                               }
+                                       
+                        } else {
+                               if(log.isDebugEnabled()) {
+                                       
log.debug("CloudControllerServiceImpl:IpAllocator:no (valid) predefined 
floating ip configured, " + pre_defined_ip
+                                               + ", selecting available one 
from pool");
+                               }
+                               Iaas iaas = iaasProvider.getIaas();
+                            // allocate an IP address - manual IP assigning 
mode
+                            ip = iaas.associateAddress(node);
+                            
+                                               if (ip != null) {
+                                                       
memberContext.setAllocatedIpAddress(ip);
+                                                       log.info("Allocated an 
ip address: "
+                                                                       + 
memberContext.toString());
+                                               }
+                        }                        
+                    } 
+                    
 
                     // public ip
                     if (node.getPublicAddresses() != null &&
@@ -639,6 +688,11 @@ public class CloudControllerServiceImpl implements 
CloudControllerService {
 
         }
     }
+    
+    private boolean isValidIpAddress (String ip) {
+       boolean isValid = InetAddresses.isInetAddress(ip);
+       return isValid;
+    }
 
        @Override
        public void terminateAllInstances(String clusterId) throws 
IllegalArgumentException, InvalidClusterException {

http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/cbf7c38f/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/interfaces/Iaas.java
----------------------------------------------------------------------
diff --git 
a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/interfaces/Iaas.java
 
b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/interfaces/Iaas.java
index f45d32e..56be59c 100644
--- 
a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/interfaces/Iaas.java
+++ 
b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/interfaces/Iaas.java
@@ -71,6 +71,16 @@ public abstract class Iaas {
     public abstract String associateAddress(NodeMetadata node);
     
     /**
+     * This will obtain a predefined IP address and associate that IP with 
this node, if ip is already in use allocate ip from pool 
+     * (through associateAddress())
+     * @param node Node to be associated with an IP.
+     * @ip preallocated floating Ip
+     * @return associated public IP.
+     */
+
+    abstract public String associatePredefinedAddress(NodeMetadata node, 
String ip);
+    
+    /**
      * This will deallocate/release the given IP address back to pool.
      * @param iaasInfo corresponding {@link IaasProvider}
      * @param ip public IP address to be released.

http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/cbf7c38f/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/util/CloudControllerConstants.java
----------------------------------------------------------------------
diff --git 
a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/util/CloudControllerConstants.java
 
b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/util/CloudControllerConstants.java
index 42c30d9..0418078 100644
--- 
a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/util/CloudControllerConstants.java
+++ 
b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/util/CloudControllerConstants.java
@@ -140,6 +140,8 @@ public final class CloudControllerConstants {
     public static final String AMQP_INITIAL_CONTEXT_FACTORY_PROPERTY = 
"amqpInitialContextFactory";
     public static final String AMQP_TOPIC_CONNECTION_FACTORY_PROPERTY = 
"amqpTopicConnectionFactory";
     public static final String INSTANCE_TOPIC = "instance-status";
+    // pre define a floating ip
+    public static final String FLOATING_IP_PROPERTY = "floatingIp";
     
     
     /**

Reply via email to