http://git-wip-us.apache.org/repos/asf/stratos/blob/218b5fdc/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/services/impl/CloudControllerServiceImpl.java
----------------------------------------------------------------------
diff --git 
a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/services/impl/CloudControllerServiceImpl.java
 
b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/services/impl/CloudControllerServiceImpl.java
index 6518607..d7a5916 100644
--- 
a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/services/impl/CloudControllerServiceImpl.java
+++ 
b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/services/impl/CloudControllerServiceImpl.java
@@ -55,1585 +55,1616 @@ import java.util.concurrent.locks.Lock;
  */
 public class CloudControllerServiceImpl implements CloudControllerService {
 
-       private static final Log log = 
LogFactory.getLog(CloudControllerServiceImpl.class);
-
-       private static final String PERSISTENCE_MAPPING = "PERSISTENCE_MAPPING";
-       public static final String PAYLOAD_PARAMETER = "payload_parameter.";
-
-       private CloudControllerContext cloudControllerContext = 
CloudControllerContext.getInstance();
-       private ExecutorService executorService;
-
-       public CloudControllerServiceImpl() {
-               executorService = 
StratosThreadPool.getExecutorService("cloud.controller.instance.manager.thread.pool",
 50);
-
-       }
-
-       public boolean addCartridge(Cartridge cartridgeConfig)
-                       throws InvalidCartridgeDefinitionException, 
InvalidIaasProviderException, CartridgeAlreadyExistsException {
-
-               handleNullObject(cartridgeConfig, "Cartridge definition is 
null");
-
-               if (log.isInfoEnabled()) {
-                       log.info("Adding cartridge: [cartridge-type] " + 
cartridgeConfig.getType());
-               }
-               if (log.isDebugEnabled()) {
-                       log.debug("Cartridge definition: " + 
cartridgeConfig.toString());
-               }
-
-               try {
-                       
CloudControllerUtil.extractIaaSProvidersFromCartridge(cartridgeConfig);
-               } catch (Exception e) {
-                       String message = "Invalid cartridge definition: 
[cartridge-type] " + cartridgeConfig.getType();
-                       log.error(message, e);
-                       throw new InvalidCartridgeDefinitionException(message, 
e);
-               }
-
-               String cartridgeType = cartridgeConfig.getType();
-               if (cloudControllerContext.getCartridge(cartridgeType) != null) 
{
-                       String message = "Cartridge already exists: 
[cartridge-type] " + cartridgeType;
-                       log.error(message);
-                       throw new CartridgeAlreadyExistsException(message);
-               }
-
-               // Add cartridge to the cloud controller context and persist
-               
CloudControllerContext.getInstance().addCartridge(cartridgeConfig);
-               CloudControllerContext.getInstance().persist();
-
-               List<Cartridge> cartridgeList = new ArrayList<Cartridge>();
-               cartridgeList.add(cartridgeConfig);
-
-               TopologyBuilder.handleServiceCreated(cartridgeList);
-
-               if (log.isInfoEnabled()) {
-                       log.info("Successfully added cartridge: 
[cartridge-type] " + cartridgeType);
-               }
-               return true;
-       }
-
-       @Override public boolean updateCartridge(Cartridge cartridge)
-                       throws InvalidCartridgeDefinitionException, 
InvalidIaasProviderException,
-                              CartridgeDefinitionNotExistsException {
-
-               handleNullObject(cartridge, "Cartridge definition is null");
-
-               if (log.isInfoEnabled()) {
-                       log.info("Updating cartridge: [cartridge-type] " + 
cartridge.getType());
-               }
-               if (log.isDebugEnabled()) {
-                       log.debug("Cartridge definition: " + 
cartridge.toString());
-               }
-
-               try {
-                       
CloudControllerUtil.extractIaaSProvidersFromCartridge(cartridge);
-               } catch (Exception e) {
-                       String msg = "Invalid cartridge definition: 
[cartridge-type] " + cartridge.getType();
-                       log.error(msg, e);
-                       throw new InvalidCartridgeDefinitionException(msg, e);
-               }
-
-               String cartridgeType = cartridge.getType();
-               if (cloudControllerContext.getCartridge(cartridgeType) != null) 
{
-                       Cartridge cartridgeToBeRemoved = 
cloudControllerContext.getCartridge(cartridgeType);
-                       try {
-                               
removeCartridgeFromCC(cartridgeToBeRemoved.getType());
-                       } catch (InvalidCartridgeTypeException ignore) {
-                       }
-                       copyIaasProviders(cartridge, cartridgeToBeRemoved);
-               } else {
-                       throw new CartridgeDefinitionNotExistsException("This 
cartridge definition not exists");
-               }
-
-               // Add cartridge to the cloud controller context and persist
-               CloudControllerContext.getInstance().addCartridge(cartridge);
-               CloudControllerContext.getInstance().persist();
-               // transaction ends
-
-               if (log.isInfoEnabled()) {
-                       log.info("Successfully updated cartridge: 
[cartridge-type] " + cartridgeType);
-               }
-               return true;
-       }
-
-       private void copyIaasProviders(Cartridge destCartridge, Cartridge 
sourceCartridge) {
-
-               List<IaasProvider> newIaasProviders =
-                               
CloudControllerContext.getInstance().getIaasProviders(destCartridge.getType());
-
-               Map<String, IaasProvider> iaasProviderMap =
-                               
CloudControllerContext.getInstance().getPartitionToIaasProvider(sourceCartridge.getType());
-
-               if (iaasProviderMap != null) {
-                       for (Entry<String, IaasProvider> entry : 
iaasProviderMap.entrySet()) {
-                               if (entry == null) {
-                                       continue;
-                               }
-                               String partitionId = entry.getKey();
-                               IaasProvider iaasProvider = entry.getValue();
-                               if (newIaasProviders.contains(iaasProvider)) {
-                                       if (log.isDebugEnabled()) {
-                                               log.debug("Copying partition 
from the cartridge that is undeployed, to the new cartridge: " +
-                                                         "[partition-id] " + 
partitionId + " [cartridge-type] " + destCartridge.getType());
-                                       }
-                                       
CloudControllerContext.getInstance().addIaasProvider(destCartridge.getType(), 
partitionId,
-                                                                               
             newIaasProviders.get(newIaasProviders.indexOf(
-                                                                               
                             iaasProvider)));
-                               }
-                       }
-               }
-
-       }
-
-       public boolean removeCartridge(String cartridgeType) throws 
InvalidCartridgeTypeException {
-               //Removing the cartridge from CC
-               Cartridge cartridge = removeCartridgeFromCC(cartridgeType);
-               //removing the cartridge from Topology
-               removeCartridgeFromTopology(cartridge);
-
-               if (log.isInfoEnabled()) {
-                       log.info("Successfully removed cartridge: 
[cartridge-type] " + cartridgeType);
-               }
-               return true;
-       }
-
-       private Cartridge removeCartridgeFromCC(String cartridgeType) throws 
InvalidCartridgeTypeException {
-               Cartridge cartridge = null;
-               if ((cartridge = 
CloudControllerContext.getInstance().getCartridge(cartridgeType)) != null) {
-                       if 
(CloudControllerContext.getInstance().getCartridges().remove(cartridge)) {
-                               // invalidate partition validation cache
-                               
CloudControllerContext.getInstance().removeFromCartridgeTypeToPartitionIds(cartridgeType);
-
-                               if (log.isDebugEnabled()) {
-                                       log.debug("Partition cache invalidated 
for cartridge " + cartridgeType);
-                               }
-
-                               CloudControllerContext.getInstance().persist();
-
-                               if (log.isInfoEnabled()) {
-                                       log.info("Successfully removed 
cartridge: [cartridge-type] " + cartridgeType);
-                               }
-                               return cartridge;
-                       }
-               }
-               String msg = "Cartridge not found: [cartridge-type] " + 
cartridgeType;
-               log.error(msg);
-               throw new InvalidCartridgeTypeException(msg);
-       }
-
-       private void removeCartridgeFromTopology(Cartridge cartridge) throws 
InvalidCartridgeTypeException {
-               // sends the service removed event
-               List<Cartridge> cartridgeList = new ArrayList<Cartridge>();
-               cartridgeList.add(cartridge);
-               TopologyBuilder.handleServiceRemoved(cartridgeList);
-       }
-
-       public boolean addServiceGroup(ServiceGroup servicegroup) throws 
InvalidServiceGroupException {
-
-               if (servicegroup == null) {
-                       String msg = "Invalid ServiceGroup Definition: 
Definition is null.";
-                       log.error(msg);
-                       throw new IllegalArgumentException(msg);
-
-               }
-               
CloudControllerContext.getInstance().addServiceGroup(servicegroup);
-               CloudControllerContext.getInstance().persist();
-               return true;
-       }
-
-       public boolean removeServiceGroup(String name) throws 
InvalidServiceGroupException {
-               if (log.isDebugEnabled()) {
-                       
log.debug("CloudControllerServiceImpl:removeServiceGroup: " + name);
-               }
-
-               ServiceGroup serviceGroup = null;
-
-               serviceGroup = 
CloudControllerContext.getInstance().getServiceGroup(name);
-
-               if (serviceGroup != null) {
-                       if 
(CloudControllerContext.getInstance().getServiceGroups().remove(serviceGroup)) {
-                               CloudControllerContext.getInstance().persist();
-                               if (log.isInfoEnabled()) {
-                                       log.info("Successfully removed the 
cartridge group: [group-name] " + serviceGroup);
-                               }
-                               return true;
-                       }
-               }
-
-               String msg = "Cartridge group not found: [group-name] " + name;
-               log.error(msg);
-               throw new InvalidServiceGroupException(msg);
-
-       }
-
-       @Override public ServiceGroup getServiceGroup(String name) throws 
InvalidServiceGroupException {
-
-               if (log.isDebugEnabled()) {
-                       log.debug("getServiceGroupDefinition:" + name);
-               }
-
-               ServiceGroup serviceGroup = 
CloudControllerContext.getInstance().getServiceGroup(name);
-
-               if (serviceGroup == null) {
-                       String message = "Cartridge group not found: 
[group-name] " + name;
-                       if (log.isDebugEnabled()) {
-                               log.debug(message);
-                       }
-                       throw new InvalidServiceGroupException(message);
-               }
-
-               return serviceGroup;
-       }
-
-       public String[] getServiceGroupSubGroups(String name) throws 
InvalidServiceGroupException {
-               ServiceGroup serviceGroup = this.getServiceGroup(name);
-               if (serviceGroup == null) {
-                       throw new InvalidServiceGroupException("Invalid 
cartridge group: [group-name] " + serviceGroup);
-               }
-
-               return serviceGroup.getSubGroups();
-       }
-
-       /**
-        *
-        */
-       public String[] getServiceGroupCartridges(String name) throws 
InvalidServiceGroupException {
-               ServiceGroup serviceGroup = this.getServiceGroup(name);
-               if (serviceGroup == null) {
-                       throw new InvalidServiceGroupException("Invalid 
cartridge group: [group-name] " + serviceGroup);
-               }
-               String[] cs = serviceGroup.getCartridges();
-               return cs;
-
-       }
-
-       public Dependencies getServiceGroupDependencies(String name) throws 
InvalidServiceGroupException {
-               ServiceGroup serviceGroup = this.getServiceGroup(name);
-               if (serviceGroup == null) {
-                       throw new InvalidServiceGroupException("Invalid 
cartridge group: [group-name] " + serviceGroup);
-               }
-               return serviceGroup.getDependencies();
-       }
-
-       @Override public MemberContext[] startInstances(InstanceContext[] 
instanceContexts)
-                       throws CartridgeNotFoundException, 
InvalidIaasProviderException, CloudControllerException {
-
-               handleNullObject(instanceContexts, "Instance start-up failed, 
member contexts is null");
-
-               List<MemberContext> memberContextList = new 
ArrayList<MemberContext>();
-               for (InstanceContext instanceContext : instanceContexts) {
-                       if (instanceContext != null) {
-                               MemberContext memberContext = 
startInstance(instanceContext);
-                               memberContextList.add(memberContext);
-                       }
-               }
-               MemberContext[] memberContextsArray = 
memberContextList.toArray(new MemberContext[memberContextList.size()]);
-               return memberContextsArray;
-       }
-
-       public MemberContext startInstance(InstanceContext instanceContext)
-                       throws CartridgeNotFoundException, 
InvalidIaasProviderException, CloudControllerException {
-
-               try {
-                       // Validate instance context
-                       handleNullObject(instanceContext, "Could not start 
instance, instance context is null");
-                       if (log.isDebugEnabled()) {
-                               log.debug("Starting up instance: " + 
instanceContext);
-                       }
-
-                       // Validate partition
-                       Partition partition = instanceContext.getPartition();
-                       handleNullObject(partition, "Could not start instance, 
partition is null");
-
-                       // Validate cluster
-                       String partitionId = partition.getId();
-                       String clusterId = instanceContext.getClusterId();
-                       ClusterContext clusterContext = 
CloudControllerContext.getInstance().getClusterContext(clusterId);
-                       handleNullObject(clusterContext,
-                                        "Could not start instance, cluster 
context not found: [cluster-id] " + clusterId);
-
-                       // Validate cartridge
-                       String cartridgeType = 
clusterContext.getCartridgeType();
-                       Cartridge cartridge = 
CloudControllerContext.getInstance().getCartridge(cartridgeType);
-                       if (cartridge == null) {
-                               String msg = "Could not startup instance, 
cartridge not found: [cartridge-type] " + cartridgeType;
-                               log.error(msg);
-                               throw new CartridgeNotFoundException(msg);
-                       }
-
-                       // Validate iaas provider
-                       IaasProvider iaasProvider =
-                                       
CloudControllerContext.getInstance().getIaasProviderOfPartition(cartridge.getType(),
 partitionId);
-                       if (iaasProvider == null) {
-                               String msg = String.format("Could not start 
instance, " +
-                                                          "IaaS provider not 
found in cartridge %s for partition %s, " +
-                                                          "partitions found: 
%s ", cartridgeType, partitionId,
-                                                          
CloudControllerContext.getInstance()
-                                                                               
 .getPartitionToIaasProvider(cartridge.getType())
-                                                                               
 .keySet().toString());
-                               log.error(msg);
-                               throw new InvalidIaasProviderException(msg);
-                       }
-
-                       // Generate member ID
-                       String memberId = generateMemberId(clusterId);
-
-                       // Create member context
-                       String applicationId = 
clusterContext.getApplicationId();
-                       MemberContext memberContext = 
createMemberContext(applicationId, cartridgeType, memberId,
-                                                                         
CloudControllerUtil.getLoadBalancingIPTypeEnumFromString(
-                                                                               
          cartridge.getLoadBalancingIPType()),
-                                                                         
instanceContext);
-
-                       // Prepare payload
-                       StringBuilder payload = new 
StringBuilder(clusterContext.getPayload());
-                       addToPayload(payload, "MEMBER_ID", memberId);
-                       addToPayload(payload, "INSTANCE_ID", 
memberContext.getInstanceId());
-                       addToPayload(payload, "CLUSTER_INSTANCE_ID", 
memberContext.getClusterInstanceId());
-                       addToPayload(payload, "LB_CLUSTER_ID", 
memberContext.getLbClusterId());
-                       addToPayload(payload, "NETWORK_PARTITION_ID", 
memberContext.getNetworkPartitionId());
-                       addToPayload(payload, "PARTITION_ID", partitionId);
-                       addToPayload(payload, "INTERNAL", "false");
-
-                       if (memberContext.getProperties() != null) {
-                               org.apache.stratos.common.Properties properties 
= memberContext.getProperties();
-                               if (properties != null) {
-                                       for (Property prop : 
properties.getProperties()) {
-                                               addToPayload(payload, 
prop.getName(), String.valueOf(prop.getValue()));
-                                       }
-                               }
-                       }
-
-                       NetworkPartition networkPartition =
-                                       
CloudControllerContext.getInstance().getNetworkPartition(memberContext.getNetworkPartitionId());
-
-                       if (networkPartition.getProperties() != null) {
-                               if 
(networkPartition.getProperties().getProperties() != null) {
-                                       for (Property property : 
networkPartition.getProperties().getProperties()) {
-                                               // check if a property is 
related to the payload. Currently
-                                               // this is done by checking if 
the
-                                               // property name starts with 
'payload_parameter.' suffix. If
-                                               // so the payload param name 
will
-                                               // be taken as the substring 
from the index of '.' to the
-                                               // end of the property name.
-                                               if 
(property.getName().startsWith(PAYLOAD_PARAMETER)) {
-                                                       String propertyName = 
property.getName();
-                                                       String payloadParamName 
= propertyName.substring(propertyName.indexOf(".") + 1);
-                                                       if 
(payload.toString().contains(payloadParamName)) {
-                                                               
replaceInPayload(payloadParamName, payload, payloadParamName, 
property.getValue());
-                                                       } else {
-                                                               
addToPayload(payload, payloadParamName, property.getValue());
-                                                       }
-                                               }
-                                       }
-                               }
-                       }
-
-                       Iaas iaas = iaasProvider.getIaas();
-                       if (clusterContext.isVolumeRequired()) {
-                               addToPayload(payload, PERSISTENCE_MAPPING, 
getPersistencePayload(clusterContext, iaas).toString());
-                       }
-
-                       if (log.isDebugEnabled()) {
-                               log.debug("Payload: " + payload.toString());
-                       }
-
-                       if (clusterContext.isVolumeRequired()) {
-
-                               Volume[] volumes = clusterContext.getVolumes();
-                               if (volumes != null) {
-                                       for (int i = 0; i < volumes.length; 
i++) {
-
-                                               if (volumes[i].getId() == null) 
{
-                                                       // Create a new volume
-                                                       volumes[i] = 
createVolumeAndSetInClusterContext(volumes[i], iaasProvider);
-                                               }
-                                       }
-                               }
-                               clusterContext.setVolumes(volumes);
-                       }
-
-                       // Persist member context
-                       
CloudControllerContext.getInstance().addMemberContext(memberContext);
-                       CloudControllerContext.getInstance().persist();
-
-                       // Handle member created event
-                       TopologyBuilder.handleMemberCreatedEvent(memberContext);
-
-                       // Start instance in a new thread
-                       if (log.isDebugEnabled()) {
-                               log.debug(String.format("Starting instance 
creator thread: [cluster] %s [cluster-instance] %s " +
-                                                       "[member] %s 
[application-id] %s", instanceContext.getClusterId(),
-                                                       
instanceContext.getClusterInstanceId(), memberId, applicationId));
-                       }
-                       executorService.execute(new 
InstanceCreator(memberContext, iaasProvider, payload.toString().getBytes()));
-
-                       return memberContext;
-               } catch (Exception e) {
-                       String msg = String.format("Could not start instance: 
[cluster] %s [cluster-instance] %s",
-                                                  
instanceContext.getClusterId(), instanceContext.getClusterInstanceId());
-                       log.error(msg, e);
-                       throw new CloudControllerException(msg, e);
-               }
-       }
-
-       private MemberContext createMemberContext(String applicationId, String 
cartridgeType, String memberId,
-                                                 LoadBalancingIPType 
loadBalancingIPType,
-                                                 InstanceContext 
instanceContext) {
-               MemberContext memberContext =
-                               new MemberContext(applicationId, cartridgeType, 
instanceContext.getClusterId(), memberId);
-
-               
memberContext.setClusterInstanceId(instanceContext.getClusterInstanceId());
-               
memberContext.setNetworkPartitionId(instanceContext.getNetworkPartitionId());
-               
memberContext.setPartition(cloudControllerContext.getNetworkPartition(instanceContext.getNetworkPartitionId()).
-                               
getPartition(instanceContext.getPartition().getId()));
-               memberContext.setInitTime(instanceContext.getInitTime());
-               memberContext.setProperties(instanceContext.getProperties());
-               memberContext.setLoadBalancingIPType(loadBalancingIPType);
-               memberContext.setInitTime(System.currentTimeMillis());
-               
memberContext.setObsoleteExpiryTime(instanceContext.getObsoleteExpiryTime());
-
-               return memberContext;
-       }
-
-       private Volume createVolumeAndSetInClusterContext(Volume volume, 
IaasProvider iaasProvider) {
-               // iaas cannot be null at this state #startInstance method
-               Iaas iaas = iaasProvider.getIaas();
-               int sizeGB = volume.getSize();
-               String snapshotId = volume.getSnapshotId();
-               if (StringUtils.isNotEmpty(volume.getVolumeId())) {
-                       // volumeID is specified, so not creating additional 
volumes
-                       if (log.isDebugEnabled()) {
-                               log.debug("Volume creation is skipping since a 
volume ID is specified. [Volume ID] " +
-                                         volume.getVolumeId());
-                       }
-                       volume.setId(volume.getVolumeId());
-               } else {
-                       String volumeId = iaas.createVolume(sizeGB, snapshotId);
-                       volume.setId(volumeId);
-               }
-
-               volume.setIaasType(iaasProvider.getType());
-
-               return volume;
-       }
-
-       private StringBuilder getPersistencePayload(ClusterContext ctx, Iaas 
iaas) {
-               StringBuilder persistencePayload = new StringBuilder();
-               if (isPersistenceMappingAvailable(ctx)) {
-                       for (Volume volume : ctx.getVolumes()) {
-                               if (log.isDebugEnabled()) {
-                                       log.debug("Adding persistence mapping " 
+ volume.toString());
-                               }
-                               if (persistencePayload.length() != 0) {
-                                       persistencePayload.append("|");
-                               }
-
-                               
persistencePayload.append(iaas.getIaasDevice(volume.getDevice()));
-                               persistencePayload.append("|");
-                               persistencePayload.append(volume.getId());
-                               persistencePayload.append("|");
-                               
persistencePayload.append(volume.getMappingPath());
-                       }
-               }
-               if (log.isDebugEnabled()) {
-                       log.debug("Persistence payload: " + 
persistencePayload.toString());
-               }
-               return persistencePayload;
-       }
-
-       private boolean isPersistenceMappingAvailable(ClusterContext ctx) {
-               return ctx.getVolumes() != null && ctx.isVolumeRequired();
-       }
-
-       private void addToPayload(StringBuilder payload, String name, String 
value) {
-               payload.append(",");
-               payload.append(name + "=" + value);
-       }
-
-       private void replaceInPayload(String payloadParamName, StringBuilder 
payload, String name, String value) {
-
-               payload.replace(payload.indexOf(payloadParamName), 
payload.indexOf(",", payload.indexOf(payloadParamName)),
-                               "," + name + "=" + value);
-       }
-
-       private String generateMemberId(String clusterId) {
-               UUID memberId = UUID.randomUUID();
-               return clusterId + memberId.toString();
-       }
-
-       public boolean terminateInstanceForcefully(String memberId) {
-
-               log.info(String.format("Starting to forcefully terminate the 
member " + memberId));
-               boolean memberTerminated = true;
-               try {
-                       this.terminateInstance(memberId);
-               } catch (InvalidMemberException e) {
-                       memberTerminated = false;
-               } catch (CloudControllerException e) {
-                       memberTerminated = false;
-               } catch (InvalidCartridgeTypeException e) {
-                       memberTerminated = false;
-               }
-
-               if (memberTerminated) {
-                       log.info(String.format("Member terminated [member-id] 
%s ", memberId));
-               } else {
-                       log.warn(String.format("Stratos could not terminate the 
member [member-id] %s. This may due to a issue " +
-                                              "in the underlying IaaS, Please 
terminate the member manually if it is available",
-                                              memberId));
-                       MemberContext memberContext = 
CloudControllerContext.getInstance().getMemberContextOfMemberId(memberId);
-                       
CloudControllerServiceUtil.executeMemberTerminationPostProcess(memberContext);
-               }
-               return true;
-       }
-
-       @Override public boolean terminateInstance(String memberId)
-                       throws InvalidMemberException, 
InvalidCartridgeTypeException, CloudControllerException {
-
-               try {
-                       handleNullObject(memberId, "Could not terminate 
instance, member id is null.");
-
-                       MemberContext memberContext = 
CloudControllerContext.getInstance().getMemberContextOfMemberId(memberId);
-                       if (memberContext == null) {
-                               String msg = "Could not terminate instance, 
member context not found: [member-id] " + memberId;
-                               log.error(msg);
-                               throw new InvalidMemberException(msg);
-                       }
-
-                       if (StringUtils.isBlank(memberContext.getInstanceId())) 
{
-                               if (log.isErrorEnabled()) {
-                                       log.error(String.format("Could not 
terminate instance, instance id is blank: [member-id] %s " +
-                                                               ", removing 
member from topology...", memberContext.getMemberId()));
-                               }
-                               
CloudControllerServiceUtil.executeMemberTerminationPostProcess(memberContext);
-                       }
-
-                       // check if status == active, if true, then this is a 
termination on member faulty
-                       TopologyManager.acquireWriteLock();
-                       Topology topology = TopologyManager.getTopology();
-                       org.apache.stratos.messaging.domain.topology.Service 
service =
-                                       
topology.getService(memberContext.getCartridgeType());
-
-                       if (service != null) {
-                               Cluster cluster = 
service.getCluster(memberContext.getClusterId());
-                               if (cluster != null) {
-                                       Member member = 
cluster.getMember(memberId);
-                                       if (member != null) {
-
-                                               // check if ready to shutdown 
member is expired and send
-                                               // member terminated if it is.
-                                               if (isMemberExpired(member, 
memberContext.getObsoleteInitTime(),
-                                                                   
memberContext.getObsoleteExpiryTime())) {
-                                                       if 
(log.isInfoEnabled()) {
-                                                               
log.info(String.format(
-                                                                               
"Member pending termination in ReadyToShutdown state exceeded expiry time. " +
-                                                                               
"This member has to be manually deleted: %s", memberContext.getMemberId()));
-                                                       }
-
-                                                       
CloudControllerServiceUtil.executeMemberTerminationPostProcess(memberContext);
-                                                       return false;
-                                               }
-                                       }
-                               }
-                       }
-
-                       executorService.execute(new 
InstanceTerminator(memberContext));
-               } catch (InvalidMemberException e) {
-                       String message = "Could not terminate instance: 
[member-id] " + memberId;
-                       log.error(message, e);
-                       throw e;
-               } catch (Exception e) {
-                       String message = "Could not terminate instance: 
[member-id] " + memberId;
-                       log.error(message, e);
-                       throw new CloudControllerException(message, e);
-               } finally {
-                       TopologyManager.releaseWriteLock();
-               }
-               return true;
-       }
-
-       /**
-        * Check if a member has been in the ReadyToShutdown status for a 
specified expiry time
-        *
-        * @param member
-        * @param initTime
-        * @param expiryTime
-        * @return
-        */
-       private boolean isMemberExpired(Member member, long initTime, long 
expiryTime) {
-               if (member.getStatus() == MemberStatus.ReadyToShutDown) {
-                       if (initTime == 0) {
-                               // obsolete init time hasn't been set, i.e. not 
a member detected faulty.
-                               // this is a graceful shutdown
-                               return false;
-                       }
-
-                       // member detected faulty, calculate ready to shutdown 
waiting period
-                       long timeInReadyToShutdownStatus = 
System.currentTimeMillis() - initTime;
-                       return timeInReadyToShutdownStatus >= expiryTime;
-               }
-
-               return false;
-       }
-
-       @Override public boolean terminateInstances(String clusterId) throws 
InvalidClusterException {
-
-               log.info("Starting to terminate all instances of cluster : " + 
clusterId);
-
-               handleNullObject(clusterId, "Instance termination failed. 
Cluster id is null.");
-
-               List<MemberContext> memberContexts =
-                               
CloudControllerContext.getInstance().getMemberContextsOfClusterId(clusterId);
-               if (memberContexts == null) {
-                       String msg = "Instance termination failed. No members 
found for cluster id: " + clusterId;
-                       log.warn(msg);
-                       return false;
-               }
-
-               for (MemberContext memberContext : memberContexts) {
-                       executorService.execute(new 
InstanceTerminator(memberContext));
-               }
-               return true;
-       }
-
-       @Override public boolean registerService(Registrant registrant) throws 
CartridgeNotFoundException {
-
-               String cartridgeType = registrant.getCartridgeType();
-               handleNullObject(cartridgeType, "Service registration failed, 
cartridge Type is null.");
-
-               String clusterId = registrant.getClusterId();
-               handleNullObject(clusterId, "Service registration failed, 
cluster id is null.");
-
-               String payload = registrant.getPayload();
-               handleNullObject(payload, "Service registration failed, payload 
is null.");
-
-               String hostName = registrant.getHostName();
-               handleNullObject(hostName, "Service registration failed, 
hostname is null.");
-
-               Cartridge cartridge = null;
-               if ((cartridge = 
CloudControllerContext.getInstance().getCartridge(cartridgeType)) == null) {
-                       String msg = "Registration of cluster: " + clusterId +
-                                    " failed, cartridge not found: 
[cartridge-type] " + cartridgeType;
-                       log.error(msg);
-                       throw new CartridgeNotFoundException(msg);
-               }
-
-               CloudControllerContext.getInstance().persist();
-
-               log.info("Successfully registered service: " + registrant);
-               return true;
-       }
-
-       @Override public String[] getCartridges() {
-               // get the list of cartridges registered
-               Collection<Cartridge> cartridges = 
CloudControllerContext.getInstance().getCartridges();
-
-               if (cartridges == null) {
-                       log.info("No registered Cartridge found.");
-                       return new String[0];
-               }
-
-               String[] cartridgeTypes = new String[cartridges.size()];
-               int i = 0;
-
-               if (log.isDebugEnabled()) {
-                       log.debug("Registered Cartridges : \n");
-               }
-               for (Cartridge cartridge : cartridges) {
-                       if (log.isDebugEnabled()) {
-                               log.debug(cartridge);
-                       }
-                       cartridgeTypes[i] = cartridge.getType();
-                       i++;
-               }
-
-               return cartridgeTypes;
-       }
-
-       @Override public Cartridge getCartridge(String cartridgeType) throws 
CartridgeNotFoundException {
-               Cartridge cartridge = 
CloudControllerContext.getInstance().getCartridge(cartridgeType);
-               if (cartridge != null) {
-                       return cartridge;
-               }
-
-               String msg = "Could not find cartridge: [cartridge-type] " + 
cartridgeType;
-               throw new CartridgeNotFoundException(msg);
-       }
-
-       @Override public boolean unregisterService(String clusterId) throws 
UnregisteredClusterException {
-               final String clusterId_ = clusterId;
-
-               ClusterContext ctxt = 
CloudControllerContext.getInstance().getClusterContext(clusterId_);
-               handleNullObject(ctxt, "Service unregistration failed. Invalid 
cluster id: " + clusterId);
-
-               final String cartridgeType = ctxt.getCartridgeType();
-               Cartridge cartridge = 
CloudControllerContext.getInstance().getCartridge(cartridgeType);
-
-               if (cartridge == null) {
-                       String msg = String.format(
-                                       "Service unregistration failed. No 
matching cartridge found: [cartridge-type] %s " +
-                                       "[application-id] %s", cartridgeType, 
ctxt.getApplicationId());
-                       log.error(msg);
-                       throw new UnregisteredClusterException(msg);
-               }
-
-               Runnable terminateInTimeout = new Runnable() {
-                       @Override public void run() {
-                               ClusterContext ctxt = 
CloudControllerContext.getInstance().getClusterContext(clusterId_);
-                               if (ctxt == null) {
-                                       String msg = String.format("Service 
unregistration failed. Cluster not found: [cluster-id] %s " +
-                                                                  
"[application-id] %s", clusterId_, ctxt.getApplicationId());
-                                       log.error(msg);
-                                       return;
-                               }
-                               Collection<Member> members = 
TopologyManager.getTopology().
-                                               
getService(ctxt.getCartridgeType()).getCluster(clusterId_).getMembers();
-                               //finding the responding members from the 
existing members in the topology.
-                               int sizeOfRespondingMembers = 0;
-                               for (Member member : members) {
-                                       if (member.getStatus().getCode() >= 
MemberStatus.Active.getCode()) {
-                                               sizeOfRespondingMembers++;
-                                       }
-                               }
-
-                               long endTime = System.currentTimeMillis() + 
ctxt.getTimeoutInMillis() * sizeOfRespondingMembers;
-                               while (System.currentTimeMillis() < endTime) {
-                                       CloudControllerUtil.sleep(1000);
-
-                               }
-
-                               // if there are still alive members
-                               if (members.size() > 0) {
-                                       //forcefully terminate them
-                                       for (Member member : members) {
-
-                                               try {
-                                                       
terminateInstance(member.getMemberId());
-                                               } catch (Exception e) {
-                                                       // we are not gonna 
stop the execution due to errors.
-                                                       log.warn((String.format(
-                                                                       
"Instance termination failed of member [member-id] %s " + "[application-id] %s",
-                                                                       
member.getMemberId(), ctxt.getApplicationId())), e);
-
-                                               }
-                                       }
-                               }
-                       }
-               };
-               Runnable unregister = new Runnable() {
-                       public void run() {
-                               Lock lock = null;
-                               try {
-                                       lock = 
CloudControllerContext.getInstance().acquireClusterContextWriteLock();
-                                       ClusterContext ctxt = 
CloudControllerContext.getInstance().getClusterContext(clusterId_);
-                                       if (ctxt == null) {
-                                               String msg = String.format(
-                                                               "Service 
unregistration failed. Cluster not found: [cluster-id] %s " +
-                                                               
"[application-id] %s ", clusterId_, ctxt.getApplicationId());
-                                               log.error(msg);
-                                               return;
-                                       }
-                                       Collection<Member> members = 
TopologyManager.getTopology().
-                                                       
getService(ctxt.getCartridgeType()).getCluster(clusterId_).getMembers();
-
-                                       while (members.size() > 0) {
-                                               //waiting until all the members 
got removed from the Topology/ timed out
-                                               CloudControllerUtil.sleep(1000);
-                                       }
-
-                                       log.info(String.format("Unregistration 
of service cluster: [cluster-id] %s [application-id]",
-                                                              clusterId_, 
ctxt.getApplicationId()));
-                                       deleteVolumes(ctxt);
-                                       onClusterRemoval(clusterId_);
-                               } finally {
-                                       if (lock != null) {
-                                               
CloudControllerContext.getInstance().releaseWriteLock(lock);
-                                       }
-                               }
-                       }
-
-                       private void deleteVolumes(ClusterContext ctxt) {
-                               if (ctxt.isVolumeRequired()) {
-                                       Lock lock = null;
-                                       try {
-                                               lock = 
CloudControllerContext.getInstance().acquireCartridgesWriteLock();
-
-                                               Cartridge cartridge =
-                                                               
CloudControllerContext.getInstance().getCartridge(ctxt.getCartridgeType());
-                                               if (cartridge != null &&
-                                                   
CloudControllerContext.getInstance().getIaasProviders(cartridge.getType()) != 
null &&
-                                                   ctxt.getVolumes() != null) {
-                                                       for (Volume volume : 
ctxt.getVolumes()) {
-                                                               if 
(volume.getId() != null) {
-                                                                       String 
iaasType = volume.getIaasType();
-                                                                       Iaas 
iaas = CloudControllerContext.getInstance()
-                                                                               
                          .getIaasProvider(cartridge.getType(), iaasType)
-                                                                               
                          .getIaas();
-                                                                       if 
(iaas != null) {
-                                                                               
try {
-                                                                               
        // delete the volumes if remove on unsubscription is true.
-                                                                               
        if (volume.isRemoveOntermination()) {
-                                                                               
                iaas.deleteVolume(volume.getId());
-                                                                               
                volume.setId(null);
-                                                                               
        }
-                                                                               
} catch (Exception ignore) {
-                                                                               
        if (log.isErrorEnabled()) {
-                                                                               
                log.error((String.format("Error while deleting volume [id] %s " 
+
-                                                                               
                                         "[application-id]", volume.getId(),
-                                                                               
                                         ctxt.getApplicationId())), ignore);
-                                                                               
        }
-                                                                               
}
-                                                                       }
-                                                               }
-                                                       }
-                                                       
CloudControllerContext.getInstance().updateCartridge(cartridge);
-                                               }
-                                       } finally {
-                                               if (lock != null) {
-                                                       
CloudControllerContext.getInstance().releaseWriteLock(lock);
-                                               }
-                                       }
-                               }
-                       }
-               };
-               new Thread(terminateInTimeout).start();
-               new Thread(unregister).start();
-               return true;
-       }
-
-       /**
-        * FIXME: A validate method shouldn't persist data
-        */
-       @Override public boolean 
validateDeploymentPolicyNetworkPartition(String cartridgeType, String 
networkPartitionId)
-                       throws InvalidPartitionException, 
InvalidCartridgeTypeException {
-
-               NetworkPartition networkPartition =
-                               
CloudControllerContext.getInstance().getNetworkPartition(networkPartitionId);
-               Lock lock = null;
-               try {
-                       lock = 
CloudControllerContext.getInstance().acquireCartridgesWriteLock();
-
-                       List<String> validatedPartitions = 
CloudControllerContext.getInstance().getPartitionIds(cartridgeType);
-                       if (validatedPartitions != null) {
-                               // cache hit for this cartridge
-                               // get list of partitions
-                               if (log.isDebugEnabled()) {
-                                       log.debug("Partition validation cache 
hit for cartridge type: " + cartridgeType);
-                               }
-                       }
-
-                       Map<String, IaasProvider> partitionToIaasProviders = 
new ConcurrentHashMap<String, IaasProvider>();
-
-                       if (log.isDebugEnabled()) {
-                               log.debug("Deployment policy validation started 
for cartridge type: " + cartridgeType);
-                       }
-
-                       Cartridge cartridge = 
CloudControllerContext.getInstance().getCartridge(cartridgeType);
-                       if (cartridge == null) {
-                               String msg = "Cartridge not found: " + 
cartridgeType;
-                               log.error(msg);
-                               throw new InvalidCartridgeTypeException(msg);
-                       }
-
-                       Map<String, Future<IaasProvider>> jobList = new 
HashMap<String, Future<IaasProvider>>();
-                       for (Partition partition : 
networkPartition.getPartitions()) {
-                               if (validatedPartitions != null && 
validatedPartitions.contains(partition.getId())) {
-                                       // partition cache hit
-                                       String provider = 
partition.getProvider();
-                                       IaasProvider iaasProvider =
-                                                       
CloudControllerContext.getInstance().getIaasProvider(cartridge.getType(), 
provider);
-                                       
partitionToIaasProviders.put(partition.getId(), iaasProvider);
-                                       continue;
-                               }
-
-                               Callable<IaasProvider> worker = new 
PartitionValidatorCallable(partition, cartridge);
-                               Future<IaasProvider> job = 
CloudControllerContext.getInstance().getExecutorService().submit(worker);
-                               jobList.put(partition.getId(), job);
-                       }
-
-                       // Retrieve the results of the concurrently performed 
sanity checks.
-                       for (Entry<String, Future<IaasProvider>> entry : 
jobList.entrySet()) {
-                               if (entry == null) {
-                                       continue;
-                               }
-                               String partitionId = entry.getKey();
-                               Future<IaasProvider> job = entry.getValue();
-                               try {
-                                       // add to a temporary Map
-                                       IaasProvider iaasProvider = job.get();
-                                       if (iaasProvider != null) {
-                                               
partitionToIaasProviders.put(partitionId, iaasProvider);
-                                       }
-
-                                       // add to cache
-                                       
CloudControllerContext.getInstance().addToCartridgeTypeToPartitionIdMap(cartridgeType,
 partitionId);
-
-                                       if (log.isDebugEnabled()) {
-                                               log.debug("Partition " + 
partitionId + " added to the cache against cartridge: " +
-                                                         "[cartridge-type] " + 
cartridgeType);
-                                       }
-                               } catch (Exception e) {
-                                       String message =
-                                                       "Could not cache 
partitions against the cartridge: [cartridge-type] " + cartridgeType;
-                                       log.error(message, e);
-                                       throw new 
InvalidPartitionException(message, e);
-                               }
-                       }
-
-                       // if and only if the deployment policy valid
-                       
CloudControllerContext.getInstance().addIaasProviders(cartridgeType, 
partitionToIaasProviders);
-                       
CloudControllerContext.getInstance().updateCartridge(cartridge);
-
-                       // persist data
-                       CloudControllerContext.getInstance().persist();
-
-                       log.info("All partitions [" + 
CloudControllerUtil.getPartitionIds(networkPartition.getPartitions()) + "]" +
-                                " were validated successfully, against the 
cartridge: " + cartridgeType);
-
-                       return true;
-               } finally {
-                       if (lock != null) {
-                               
CloudControllerContext.getInstance().releaseWriteLock(lock);
-                       }
-               }
-       }
-
-       private void onClusterRemoval(final String clusterId) {
-               ClusterContext ctxt = 
CloudControllerContext.getInstance().getClusterContext(clusterId);
-               TopologyBuilder.handleClusterRemoved(ctxt);
-               
CloudControllerContext.getInstance().removeClusterContext(clusterId);
-               
CloudControllerContext.getInstance().removeMemberContextsOfCluster(clusterId);
-               CloudControllerContext.getInstance().persist();
-       }
-
-       @Override public boolean validatePartition(Partition partition) throws 
InvalidPartitionException {
-               handleNullObject(partition, "Partition validation failed. 
Partition is null.");
-
-               String provider = partition.getProvider();
-               String partitionId = partition.getId();
-
-               handleNullObject(provider, "Partition [" + partitionId + "] 
validation failed. Partition provider is null.");
-               IaasProvider iaasProvider = 
CloudControllerConfig.getInstance().getIaasProvider(provider);
-
-               return CloudControllerServiceUtil.validatePartition(partition, 
iaasProvider);
-       }
-
-       public ClusterContext getClusterContext(String clusterId) {
-               return 
CloudControllerContext.getInstance().getClusterContext(clusterId);
-       }
-
-       @Override public boolean updateClusterStatus(String serviceName, String 
clusterId, String instanceId,
-                                                    ClusterStatus status) {
-               //TODO
-               return true;
-       }
-
-       private void handleNullObject(Object obj, String errorMsg) {
-               if (obj == null) {
-                       log.error(errorMsg);
-                       throw new CloudControllerException(errorMsg);
-               }
-       }
-
-       @Override public boolean createApplicationClusters(String appId, 
ApplicationClusterContext[] appClustersContexts)
-                       throws ApplicationClusterRegistrationException {
-               if (appClustersContexts == null || appClustersContexts.length 
== 0) {
-                       String errorMsg = "No application cluster information 
found, unable to create clusters: " +
-                                         "[application-id] " + appId;
-                       log.error(errorMsg);
-                       throw new 
ApplicationClusterRegistrationException(errorMsg);
-               }
-
-               Lock lock = null;
-               try {
-                       lock = 
CloudControllerContext.getInstance().acquireClusterContextWriteLock();
-
-                       // Create a Cluster Context obj. for each of the 
Clusters in the Application
-                       List<Cluster> clusters = new ArrayList<Cluster>();
-                       Map<String, List<String>> accessUrls = new 
HashMap<String, List<String>>();
-
-                       for (ApplicationClusterContext appClusterCtxt : 
appClustersContexts) {
-                               String clusterId = 
appClusterCtxt.getClusterId();
-                               if (appClusterCtxt.isLbCluster()) {
-                                       String[] dependencyClusterIDs = 
appClusterCtxt.getDependencyClusterIds();
-                                       if (dependencyClusterIDs != null) {
-                                               for (int i = 0; i < 
dependencyClusterIDs.length; i++) {
-
-                                                       List<String> 
accessUrlPerCluster = new ArrayList();
-                                                       
Collection<ClusterPortMapping> clusterPortMappings =
-                                                                       
CloudControllerContext.getInstance().getClusterPortMappings(appId, clusterId);
-
-                                                       for (ClusterPortMapping 
clusterPortMapping : clusterPortMappings) {
-                                                               try {
-                                                                       if 
(clusterPortMapping.isKubernetes()) {
-                                                                               
URL accessUrl =
-                                                                               
                new URL(clusterPortMapping.getProtocol(), 
appClusterCtxt.getHostName(),
-                                                                               
                        clusterPortMapping.getKubernetesServicePort(), "");
-                                                                               
accessUrlPerCluster.add(accessUrl.toString());
-                                                                       } else {
-                                                                               
URL accessUrl =
-                                                                               
                new URL(clusterPortMapping.getProtocol(), 
appClusterCtxt.getHostName(),
-                                                                               
                        clusterPortMapping.getProxyPort(), "");
-                                                                               
accessUrlPerCluster.add(accessUrl.toString());
-                                                                       }
-                                                               } catch 
(MalformedURLException e) {
-                                                                       String 
message = "Could not generate access URL";
-                                                                       
log.error(message, e);
-                                                                       throw 
new ApplicationClusterRegistrationException(message, e);
-                                                               }
-                                                       }
-                                                       
accessUrls.put(dependencyClusterIDs[i], accessUrlPerCluster);
-                                               }
-                                       }
-                               }
-                       }
-
-                       for (ApplicationClusterContext appClusterCtxt : 
appClustersContexts) {
-                               ClusterContext clusterContext =
-                                               new ClusterContext(appId, 
appClusterCtxt.getCartridgeType(), appClusterCtxt.getClusterId(),
-                                                                  
appClusterCtxt.getTextPayload(), appClusterCtxt.getHostName(),
-                                                                  
appClusterCtxt.isLbCluster(), appClusterCtxt.getProperties());
-
-                               if (appClusterCtxt.isVolumeRequired()) {
-                                       clusterContext.setVolumeRequired(true);
-                                       
clusterContext.setVolumes(appClusterCtxt.getVolumes());
-                               }
-                               
CloudControllerContext.getInstance().addClusterContext(clusterContext);
-
-                               // Create cluster object
-                               Cluster cluster = new 
Cluster(appClusterCtxt.getCartridgeType(), appClusterCtxt.getClusterId(),
-                                                             
appClusterCtxt.getDeploymentPolicyName(),
-                                                             
appClusterCtxt.getAutoscalePolicyName(), appId);
-                               cluster.setLbCluster(false);
-                               
cluster.setTenantRange(appClusterCtxt.getTenantRange());
-                               
cluster.setHostNames(Arrays.asList(appClusterCtxt.getHostName()));
-                               
cluster.setAccessUrls(accessUrls.get(appClusterCtxt.getClusterId()));
-
-                               if (appClusterCtxt.getProperties() != null) {
-                                       Properties properties = 
CloudControllerUtil.toJavaUtilProperties(appClusterCtxt.getProperties());
-                                       cluster.setProperties(properties);
-                               }
-
-                               clusters.add(cluster);
-                       }
-                       TopologyBuilder.handleApplicationClustersCreated(appId, 
clusters);
-                       CloudControllerContext.getInstance().persist();
-               } finally {
-                       if (lock != null) {
-                               
CloudControllerContext.getInstance().releaseWriteLock(lock);
-                       }
-               }
-               return true;
-       }
-
-       public boolean createClusterInstance(String serviceType, String 
clusterId, String alias, String instanceId,
-                                            String partitionId, String 
networkPartitionId)
-                       throws ClusterInstanceCreationException {
-               Lock lock = null;
-               try {
-                       lock = 
CloudControllerContext.getInstance().acquireClusterContextWriteLock();
-                       
TopologyBuilder.handleClusterInstanceCreated(serviceType, clusterId, alias, 
instanceId, partitionId,
-                                                                    
networkPartitionId);
-
-                       CloudControllerContext.getInstance().persist();
-               } finally {
-                       if (lock != null) {
-                               
CloudControllerContext.getInstance().releaseWriteLock(lock);
-                       }
-               }
-               return true;
-       }
-
-       @Override public KubernetesCluster[] getKubernetesClusters() {
-               return 
CloudControllerContext.getInstance().getKubernetesClusters();
-       }
-
-       @Override public KubernetesCluster getKubernetesCluster(String 
kubernetesClusterId)
-                       throws NonExistingKubernetesClusterException {
-               return 
CloudControllerContext.getInstance().getKubernetesCluster(kubernetesClusterId);
-       }
-
-       @Override public KubernetesMaster getMasterForKubernetesCluster(String 
kubernetesClusterId)
-                       throws NonExistingKubernetesClusterException {
-               return 
CloudControllerContext.getInstance().getKubernetesMasterInGroup(kubernetesClusterId);
-       }
-
-       @Override public KubernetesHost[] getHostsForKubernetesCluster(String 
kubernetesClusterId)
-                       throws NonExistingKubernetesClusterException {
-               return 
CloudControllerContext.getInstance().getKubernetesHostsInGroup(kubernetesClusterId);
-       }
-
-       @Override public boolean addKubernetesCluster(KubernetesCluster 
kubernetesCluster)
-                       throws InvalidKubernetesClusterException, 
KubernetesClusterAlreadyExistsException {
-               if (kubernetesCluster == null) {
-                       throw new InvalidKubernetesClusterException("Kubernetes 
cluster cannot be null");
-               }
-
-               try {
-                       if 
(CloudControllerContext.getInstance().getKubernetesCluster(kubernetesCluster.getClusterId())
 != null) {
-                               throw new 
KubernetesClusterAlreadyExistsException("Kubernetes cluster already exists");
-                       }
-               } catch (NonExistingKubernetesClusterException ignore) {
-               }
-               Lock lock = null;
-               try {
-                       lock = 
CloudControllerContext.getInstance().acquireKubernetesClusterWriteLock();
-
-                       if (log.isInfoEnabled()) {
-                               log.info(String.format("Adding kubernetes 
cluster: [kubernetes-cluster-id] %s",
-                                                      
kubernetesCluster.getClusterId()));
-                       }
-                       
CloudControllerUtil.validateKubernetesCluster(kubernetesCluster);
-
-                       // Add to information model
-                       
CloudControllerContext.getInstance().addKubernetesCluster(kubernetesCluster);
-                       CloudControllerContext.getInstance().persist();
-
-                       if (log.isInfoEnabled()) {
-                               log.info(String.format("Kubernetes cluster 
added successfully: [kubernetes-cluster-id] %s",
-                                                      
kubernetesCluster.getClusterId()));
-                       }
-                       return true;
-               } catch (Exception e) {
-                       throw new 
InvalidKubernetesClusterException(e.getMessage(), e);
-               } finally {
-                       if (lock != null) {
-                               
CloudControllerContext.getInstance().releaseWriteLock(lock);
-                       }
-               }
-       }
-
-       @Override public boolean updateKubernetesCluster(KubernetesCluster 
kubernetesCluster)
-                       throws InvalidKubernetesClusterException {
-               if (kubernetesCluster == null) {
-                       throw new InvalidKubernetesClusterException("Kubernetes 
cluster cannot be null");
-               }
-               Lock lock = null;
-               try {
-                       lock = 
CloudControllerContext.getInstance().acquireKubernetesClusterWriteLock();
-
-                       if (log.isInfoEnabled()) {
-                               log.info(String.format("Updating kubernetes 
cluster: [kubernetes-cluster-id] %s",
-                                                      
kubernetesCluster.getClusterId()));
-                       }
-                       
CloudControllerUtil.validateKubernetesCluster(kubernetesCluster);
-
-                       // Updating the information model
-                       
CloudControllerContext.getInstance().updateKubernetesCluster(kubernetesCluster);
-                       CloudControllerContext.getInstance().persist();
-
-                       if (log.isInfoEnabled()) {
-                               log.info(String.format("Kubernetes cluster 
updated successfully: [kubernetes-cluster-id] %s",
-                                                      
kubernetesCluster.getClusterId()));
-                       }
-                       return true;
-               } catch (Exception e) {
-                       throw new 
InvalidKubernetesClusterException(e.getMessage(), e);
-               } finally {
-                       if (lock != null) {
-                               
CloudControllerContext.getInstance().releaseWriteLock(lock);
-                       }
-               }
-       }
-
-       @Override public boolean addKubernetesHost(String kubernetesClusterId, 
KubernetesHost kubernetesHost)
-                       throws InvalidKubernetesHostException, 
NonExistingKubernetesClusterException {
-               if (kubernetesHost == null) {
-                       throw new InvalidKubernetesHostException("Kubernetes 
host cannot be null");
-               }
-               if (StringUtils.isEmpty(kubernetesClusterId)) {
-                       throw new 
NonExistingKubernetesClusterException("Kubernetes cluster id cannot be null");
-               }
-
-               Lock lock = null;
-               try {
-                       lock = 
CloudControllerContext.getInstance().acquireKubernetesClusterWriteLock();
-
-                       if (log.isInfoEnabled()) {
-                               log.info(String.format(
-                                               "Adding kubernetes host for 
kubernetes cluster: [kubernetes-cluster-id] %s " + "[hostname] %s",
-                                               kubernetesClusterId, 
kubernetesHost.getHostname()));
-                       }
-                       
CloudControllerUtil.validateKubernetesHost(kubernetesHost);
-
-                       KubernetesCluster kubernetesCluster = 
getKubernetesCluster(kubernetesClusterId);
-                       ArrayList<KubernetesHost> kubernetesHostArrayList;
-
-                       if (kubernetesCluster.getKubernetesHosts() == null) {
-                               kubernetesHostArrayList = new 
ArrayList<KubernetesHost>();
-                       } else {
-                               if 
(CloudControllerContext.getInstance().kubernetesHostExists(kubernetesHost.getHostId()))
 {
-                                       throw new 
InvalidKubernetesHostException(
-                                                       "Kubernetes host 
already exists: [hostname] " + kubernetesHost.getHostId());
-                               }
-                               kubernetesHostArrayList =
-                                               new 
ArrayList<KubernetesHost>(Arrays.asList(kubernetesCluster.getKubernetesHosts()));
-                       }
-                       kubernetesHostArrayList.add(kubernetesHost);
-
-                       // Update information model
-                       kubernetesCluster.setKubernetesHosts(
-                                       kubernetesHostArrayList.toArray(new 
KubernetesHost[kubernetesHostArrayList.size()]));
-                       
CloudControllerContext.getInstance().updateKubernetesCluster(kubernetesCluster);
-                       CloudControllerContext.getInstance().persist();
-
-                       if (log.isInfoEnabled()) {
-                               log.info(
-                                               String.format("Kubernetes host 
added successfully: [id] %s", kubernetesCluster.getClusterId()));
-                       }
-
-                       return true;
-               } catch (Exception e) {
-                       throw new 
InvalidKubernetesHostException(e.getMessage(), e);
-               } finally {
-                       if (lock != null) {
-                               
CloudControllerContext.getInstance().releaseWriteLock(lock);
-                       }
-               }
-       }
-
-       @Override public boolean removeKubernetesCluster(String 
kubernetesClusterId)
-                       throws NonExistingKubernetesClusterException {
-               if (StringUtils.isEmpty(kubernetesClusterId)) {
-                       throw new 
NonExistingKubernetesClusterException("Kubernetes cluster id cannot be empty");
-               }
-
-               Lock lock = null;
-               try {
-                       lock = 
CloudControllerContext.getInstance().acquireKubernetesClusterWriteLock();
-
-                       if (log.isInfoEnabled()) {
-                               log.info("Removing Kubernetes cluster: " + 
kubernetesClusterId);
-                       }
-                       // Remove entry from information model
-                       
CloudControllerContext.getInstance().removeKubernetesCluster(kubernetesClusterId);
-
-                       if (log.isInfoEnabled()) {
-                               log.info(String.format("Kubernetes cluster 
removed successfully: [id] %s", kubernetesClusterId));
-                       }
-
-                       CloudControllerContext.getInstance().persist();
-
-               } finally {
-                       if (lock != null) {
-                               
CloudControllerContext.getInstance().releaseWriteLock(lock);
-                       }
-               }
-               return true;
-       }
-
-       @Override public boolean removeKubernetesHost(String kubernetesHostId) 
throws NonExistingKubernetesHostException {
-               if (kubernetesHostId == null) {
-                       throw new 
NonExistingKubernetesHostException("Kubernetes host id cannot be null");
-               }
-
-               Lock lock = null;
-               try {
-                       lock = 
CloudControllerContext.getInstance().acquireKubernetesClusterWriteLock();
-
-                       if (log.isInfoEnabled()) {
-                               log.info("Removing Kubernetes Host: " + 
kubernetesHostId);
-                       }
-                       try {
-                               KubernetesCluster kubernetesClusterStored =
-                                               
CloudControllerContext.getInstance().getKubernetesClusterContainingHost(kubernetesHostId);
-
-                               // Kubernetes master cannot be removed
-                               if 
(kubernetesClusterStored.getKubernetesMaster().getHostId().equals(kubernetesHostId))
 {
-                                       throw new 
NonExistingKubernetesHostException(
-                                                       "Kubernetes master is 
not allowed to be removed [id] " + kubernetesHostId);
-                               }
-
-                               List<KubernetesHost> kubernetesHostList = new 
ArrayList<KubernetesHost>();
-                               for (KubernetesHost kubernetesHost : 
kubernetesClusterStored.getKubernetesHosts()) {
-                                       if 
(!kubernetesHost.getHostId().equals(kubernetesHostId)) {
-                                               
kubernetesHostList.add(kubernetesHost);
-                                       }
-                               }
-                               // member count will be equal only when host 
object was not found
-                               if (kubernetesHostList.size() == 
kubernetesClusterStored.getKubernetesHosts().length) {
-                                       throw new 
NonExistingKubernetesHostException(
-                                                       "Kubernetes host not 
found for [id] " + kubernetesHostId);
-                               }
-                               KubernetesHost[] kubernetesHostsArray = new 
KubernetesHost[kubernetesHostList.size()];
-                               
kubernetesHostList.toArray(kubernetesHostsArray);
-
-                               // Update information model
-                               
kubernetesClusterStored.setKubernetesHosts(kubernetesHostsArray);
-
-                               if (log.isInfoEnabled()) {
-                                       log.info(String.format("Kubernetes host 
removed successfully: [id] %s", kubernetesHostId));
-                               }
-
-                               CloudControllerContext.getInstance().persist();
-
-                               return true;
-                       } catch (Exception e) {
-                               throw new 
NonExistingKubernetesHostException(e.getMessage(), e);
-                       }
-               } finally {
-                       if (lock != null) {
-                               
CloudControllerContext.getInstance().releaseWriteLock(lock);
-                       }
-               }
-       }
-
-       @Override public boolean updateKubernetesMaster(KubernetesMaster 
kubernetesMaster)
-                       throws InvalidKubernetesMasterException, 
NonExistingKubernetesMasterException {
-               Lock lock = null;
-               try {
-                       lock = 
CloudControllerContext.getInstance().acquireKubernetesClusterWriteLock();
-                       
CloudControllerUtil.validateKubernetesMaster(kubernetesMaster);
-                       if (log.isInfoEnabled()) {
-                               log.info("Updating Kubernetes master: " + 
kubernetesMaster);
-                       }
-                       try {
-                               KubernetesCluster kubernetesClusterStored = 
CloudControllerContext.getInstance()
-                                                                               
                  .getKubernetesClusterContainingHost(
-                                                                               
                                  kubernetesMaster.getHostId());
-
-                               // Update information model
-                               
kubernetesClusterStored.setKubernetesMaster(kubernetesMaster);
-
-                               CloudControllerContext.getInstance().persist();
-
-                               if (log.isInfoEnabled()) {
-                                       log.info(String.format("Kubernetes 
master updated successfully: [id] %s",
-                                                              
kubernetesMaster.getHostId()));
-                               }
-
-                               return true;
-                       } catch (Exception e) {
-                               throw new 
InvalidKubernetesMasterException(e.getMessage(), e);
-                       }
-               } finally {
-                       if (lock != null) {
-                               
CloudControllerContext.getInstance().releaseWriteLock(lock);
-                       }
-               }
-       }
-
-       @Override public boolean updateKubernetesHost(KubernetesHost 
kubernetesHost)
-                       throws InvalidKubernetesHostException, 
NonExistingKubernetesHostException {
-
-               Lock lock = null;
-               try {
-                       lock = 
CloudControllerContext.getInstance().acquireKubernetesClusterWriteLock();
-                       
CloudControllerUtil.validateKubernetesHost(kubernetesHost);
-                       if (log.isInfoEnabled()) {
-                               log.info("Updating Kubernetes Host: " + 
kubernetesHost);
-                       }
-
-                       try {
-                               KubernetesCluster kubernetesClusterStored = 
CloudControllerContext.getInstance()
-                                                                               
                  .getKubernetesClusterContainingHost(
-                                                                               
                                  kubernetesHost.getHostId());
-                               KubernetesHost[] kubernetesHosts = 
kubernetesClusterStored.getKubernetesHosts();
-                               for (int i = 0; i < kubernetesHosts.length; 
i++) {
-                                       if 
(kubernetesHosts[i].getHostId().equals(kubernetesHost.getHostId())) {
-                                               // Update the information model
-                                               kubernetesHosts[i] = 
kubernetesHost;
-
-                                               if (log.isInfoEnabled()) {
-                                                       
log.info(String.format("Kubernetes host updated successfully: [id] %s",
-                                                                              
kubernetesHost.getHostId()));
-                                               }
-
-                                               
CloudControllerContext.getInstance().updateKubernetesCluster(kubernetesClusterStored);
-                                               
CloudControllerContext.getInstance().persist();
-                                               return true;
-                                       }
-                               }
-                       } catch (Exception e) {
-                               throw new 
InvalidKubernetesHostException(e.getMessage(), e);
-                       }
-               } finally {
-                       if (lock != null) {
-                               
CloudControllerContext.getInstance().releaseWriteLock(lock);
-                       }
-               }
-               throw new NonExistingKubernetesHostException("Kubernetes host 
not found [id] " + kubernetesHost.getHostId());
-       }
-
-       @Override public boolean addNetworkPartition(NetworkPartition 
networkPartition)
-                       throws NetworkPartitionAlreadyExistsException, 
InvalidNetworkPartitionException {
-
-               handleNullObject(networkPartition, "Network Partition is null");
-               handleNullObject(networkPartition.getId(), "Network Partition 
ID is null");
-
-               if (log.isInfoEnabled()) {
-                       log.info(String.format("Adding network partition: 
[network-partition-id] %s", networkPartition.getId()));
-               }
-
-               String networkPartitionID = networkPartition.getId();
-               if 
(cloudControllerContext.getNetworkPartition(networkPartitionID) != null) {
-                       String message = "Network partition already exists: 
[network-partition-id] " + networkPartitionID;
-                       log.error(message);
-                       throw new 
NetworkPartitionAlreadyExistsException(message);
-               }
-
-               if (networkPartition.getPartitions() != null && 
networkPartition.getPartitions().length != 0) {
-                       for (Partition partition : 
networkPartition.getPartitions()) {
-                               if (partition != null) {
-                                       if (log.isInfoEnabled()) {
-                                               
log.info(String.format("Validating partition: [network-partition-id] %s 
[partition-id] %s",
-                                                                      
networkPartition.getId(), partition.getId()));
-                                       }
-                                       // Overwrites partition provider with 
network partition provider
-                                       
partition.setProvider(networkPartition.getProvider());
-                                       try {
-                                               validatePartition(partition);
-                                       } catch (InvalidPartitionException e) {
-                                               //Following message is shown to 
the end user in all the the API clients(GUI/CLI/Rest API)
-                                               throw new 
InvalidNetworkPartitionException(String.format(
-                                                               "Network 
partition " + " %s, is invalid since the partition %s is invalid",
-                                                               
networkPartition.getId(), partition.getId()), e);
-                                       }
-                                       if (log.isInfoEnabled()) {
-                                               log.info(String.format(
-                                                               "Partition 
validated successfully: [network-partition-id] %s " + "[partition-id] %s",
-                                                               
networkPartition.getId(), partition.getId()));
-                                       }
-                               }
-                       }
-               } else {
-                       //Following message is shown to the end user in all the 
the API clients(GUI/CLI/Rest API)
-                       throw new InvalidNetworkPartitionException(
-                                       String.format("Network partition: " + 
"%s doesn't not have any partitions ",
-                                                     
networkPartition.getId()));
-               }
-
-               // adding network partition to CC-Context
-               
CloudControllerContext.getInstance().addNetworkPartition(networkPartition);
-               // persisting CC-Context
-               CloudControllerContext.getInstance().persist();
-               if (log.isInfoEnabled()) {
-                       log.info(String.format("Network partition added 
successfully: [network-partition-id] %s",
-                                              networkPartition.getId()));
-               }
-               return true;
-       }
-
-       @Override public boolean removeNetworkPartition(String 
networkPartitionId)
-                       throws NetworkPartitionNotExistsException {
-
-               try {
-                       if (log.isInfoEnabled()) {
-                               log.info(String.format("Removing network 
partition: [network-partition-id] %s", networkPartitionId));
-                       }
-                       handleNullObject(networkPartitionId, "Network Partition 
ID is null");
-
-                       if 
(cloudControllerContext.getNetworkPartition(networkPartitionId) == null) {
-                               String message = "Network partition not found: 
[network-partition-id] " + networkPartitionId;
-                               log.error(message);
-                               throw new 
NetworkPartitionNotExistsException(message);
-                       }
-                       // removing from CC-Context
-                       
CloudControllerContext.getInstance().removeNetworkPartition(networkPartitionId);
-                       // persisting CC-Context
-                       CloudControllerContext.getInstance().persist();
-                       if (log.isInfoEnabled()) {
-                               log.info(String.format("Network partition 
removed successfully: [network-partition-id] %s",
-                                                      networkPartitionId));
-                       }
-               } catch (Exception e) {
-                       String message = e.getMessage();
-                       log.error(message);
-                       throw new CloudControllerException(message, e);
-               }
-               return true;
-       }
-
-       @Override public boolean updateNetworkPartition(NetworkPartition 
networkPartition)
-                       throws NetworkPartitionNotExistsException {
-               try {
-                       handleNullObject(networkPartition, "Network Partition 
is null");
-                       handleNullObject(networkPartition.getId(), "Network 
Partition ID is null");
-
-                       if (log.isInfoEnabled()) {
-                               log.info(String.format("Updating network 
partition: [network-partition-id] %s",
-                                                      
networkPartition.getId()));
-                       }
-
-                       String networkPartitionID = networkPartition.getId();
-                       if 
(cloudControllerContext.getNetworkPartition(networkPartitionID) == null) {
-                               String message = "Network partition not found: 
[network-partition-id] " + networkPartitionID;
-                               log.error(message);
-                               throw new 
NetworkPartitionNotExistsException(message);
-                       }
-
-                       if (networkPartition.getPartitions() != null) {
-                               for (Partition partition : 
networkPartition.getPartitions()) {
-                                       if (partition != null) {
-                                               if (log.isInfoEnabled()) {
-                                                       
log.info(String.format("Validating partition: [network-partition-id] %s 
[partition-id] %s",
-                                                                              
networkPartition.getId(), partition.getId()));
-                                               }
-                                               // Overwrites partition 
provider with network partition provider
-                                               
partition.setProvider(networkPartition.getProvider());
-                                               validatePartition(partition);
-                                               if (log.isInfoEnabled()) {
-                                                       
log.info(String.format("Partition validated successfully: 
[network-partition-id] %s " +
-                                                                              
"[partition-id] %s", networkPartition.getId(), partition.getId()));
-                                               }
-                                       }
-                               }
-                       }
-
-                       // overriding network partition to CC-Context
-                       
CloudControllerContext.getInstance().addNetworkPartition(networkPartition);
-                       // persisting CC-Context
-                       CloudControllerContext.getInstance().persist();
-                       if (log.isInfoEnabled()) {
-                               log.info(String.format("Network partition 
updated successfully: [network-partition-id] %s",
-                                                      
networkPartition.getId()));
-                       }
-                       return true;
-               } catch (Exception e) {
-                       String message = e.getMessage();
-                       log.error(message);
-                       throw new CloudControllerException(message, e);
-               }
-       }
-
-       @Override public NetworkPartition[] getNetworkPartitions() {
-               try {
-                       Collection<NetworkPartition> networkPartitionList = 
cloudControllerContext.getNetworkPartitions();
-                       return networkPartitionList.toArray(new 
NetworkPartition[networkPartitionList.size()]);
-               } catch (Exception e) {
-                       String message = "Could not get network partitions";
-                       log.error(message);
-                       throw new CloudControllerException(message, e);
-               }
-       }
-
-       @Override public NetworkPartition getNetworkPartition(String 
networkPartitionId) {
-               try {
-                       return 
CloudControllerContext.getInstance().getNetworkPartition(networkPartitionId);
-               } catch (Exception e) {
-                       String message =
-                                       String.format("Could not get network 
partition: [network-partition-id] %s", networkPartitionId);
-                       log.error(message);
-                       throw new CloudControllerException(message, e);
-               }
-       }
-
-       @Override public String[] getIaasProviders() {
-
-               try {
-                       Collection<IaasProvider> iaasProviders = 
CloudControllerConfig.getInstance().getIaasProviders();
-                       List<String> iaases = new ArrayList<String>();
-
-                       for (IaasProvider iaas : iaasProviders) {
-                               iaases.add(iaas.getType());
-                       }
-
-                       return iaases.toArray(new String[iaases.size()]);
-               } catch (Exception e) {
-                       String message = String.format("Could not get Iaas 
Providers");
-                       log.error(message);
-                       throw new CloudControllerException(message, e);
-               }
-
-       }
+    private static final Log log = 
LogFactory.getLog(CloudControllerServiceImpl.class);
+
+    private static final String PERSISTENCE_MAPPING = "PERSISTENCE_MAPPING";
+    public static final String PAYLOAD_PARAMETER = "payload_parameter.";
+
+    private CloudControllerContext cloudControllerContext = 
CloudControllerContext.getInstance();
+    private ExecutorService executorService;
+
+    public CloudControllerServiceImpl() {
+        executorService = 
StratosThreadPool.getExecutorService("cloud.controller.instance.manager.thread.pool",
 50);
+
+    }
+
+    public boolean addCartridge(Cartridge cartridgeConfig)
+            throws InvalidCartridgeDefinitionException, 
InvalidIaasProviderException, CartridgeAlreadyExistsException {
+
+        handleNullObject(cartridgeConfig, "Cartridge definition is null");
+
+        if (log.isInfoEnabled()) {
+            log.info("Adding cartridge: [cartridge-type] " + 
cartridgeConfig.getType());
+        }
+        if (log.isDebugEnabled()) {
+            log.debug("Cartridge definition: " + cartridgeConfig.toString());
+        }
+
+        try {
+            
CloudControllerUtil.extractIaaSProvidersFromCartridge(cartridgeConfig);
+        } catch (Exception e) {
+            String message = "Invalid cartridge definition: [cartridge-type] " 
+ cartridgeConfig.getType();
+            log.error(message, e);
+            throw new InvalidCartridgeDefinitionException(message, e);
+        }
+
+        String cartridgeType = cartridgeConfig.getType();
+        if (cloudControllerContext.getCartridge(cartridgeType) != null) {
+            String message = "Cartridge already exists: [cartridge-type] " + 
cartridgeType;
+            log.error(message);
+            throw new CartridgeAlreadyExistsException(message);
+        }
+
+        // Add cartridge to the cloud controller context and persist
+        CloudControllerContext.getInstance().addCartridge(cartridgeConfig);
+        CloudControllerContext.getInstance().persist();
+
+        List<Cartridge> cartridgeList = new ArrayList<Cartridge>();
+        cartridgeList.add(cartridgeConfig);
+
+        TopologyBuilder.handleServiceCreated(cartridgeList);
+
+        if (log.isInfoEnabled()) {
+            log.info("Successfully added cartridge: [cartridge-type] " + 
cartridgeType);
+        }
+        return true;
+    }
+
+    @Override
+    public boolean updateCartridge(Cartridge cartridge)
+            throws InvalidCartridgeDefinitionException, 
InvalidIaasProviderException,
+            CartridgeDefinitionNotExistsException {
+
+        handleNullObject(cartridge, "Cartridge definition is null");
+
+        if (log.isInfoEnabled()) {
+            log.info("Updating cartridge: [cartridge-type] " + 
cartridge.getType());
+        }
+        if (log.isDebugEnabled()) {
+            log.debug("Cartridge definition: " + cartridge.toString());
+        }
+
+        try {
+            CloudControllerUtil.extractIaaSProvidersFromCartridge(cartridge);
+        } catch (Exception e) {
+            String msg = "Invalid cartridge definition: [cartridge-type] " + 
cartridge.getType();
+            log.error(msg, e);
+            throw new InvalidCartridgeDefinitionException(msg, e);
+        }
+
+        String cartridgeType = cartridge.getType();
+        if (cloudControllerContext.getCartridge(cartridgeType) != null) {
+            Cartridge cartridgeToBeRemoved = 
cloudControllerContext.getCartridge(cartridgeType);
+            try {
+                removeCartridgeFromCC(cartridgeToBeRemoved.getType());
+            } catch (InvalidCartridgeTypeException ignore) {
+            }
+            copyIaasProviders(cartridge, cartridgeToBeRemoved);
+        } else {
+            throw new CartridgeDefinitionNotExistsException("This cartridge 
definition not exists");
+        }
+
+        // Add cartridge to the cloud controller context and persist
+        CloudControllerContext.getInstance().addCartridge(cartridge);
+        CloudControllerContext.getInstance().persist();
+        // transaction ends
+
+        if (log.isInfoEnabled()) {
+            log.info("Successfully updated cartridge: [cartridge-type] " + 
cartridgeType);
+        }
+        return true;
+    }
+
+    private void copyIaasProviders(Cartridge destCartridge, Cartridge 
sourceCartridge) {
+
+        List<IaasProvider> newIaasProviders =
+                
CloudControllerContext.getInstance().getIaasProviders(destCartridge.getType());
+
+        Map<String, IaasProvider> iaasProviderMap =
+                
CloudControllerContext.getInstance().getPartitionToIaasProvider(sourceCartridge.getType());
+
+        if (iaasProviderMap != null) {
+            for (Entry<String, IaasProvider> entry : 
iaasProviderMap.entrySet()) {
+                if (entry == null) {
+                    continue;
+                }
+                String partitionId = entry.getKey();
+                IaasProvider iaasProvider = entry.getValue();
+                if (newIaasProviders.contains(iaasProvider)) {
+                    if (log.isDebugEnabled()) {
+                        log.debug("Copying partition from the cartridge that 
is undeployed, to the new cartridge: " +
+                                "[partition-id] " + partitionId + " 
[cartridge-type] " + destCartridge.getType());
+                    }
+                    
CloudControllerContext.getInstance().addIaasProvider(destCartridge.getType(), 
partitionId,
+                            newIaasProviders.get(newIaasProviders.indexOf(
+                                    iaasProvider)));
+                }
+            }
+        }
+
+    }
+
+    public boolean removeCartridge(String cartridgeType) throws 
InvalidCartridgeTypeException {
+        //Removing the cartridge from CC
+        Cartridge cartridge = removeCartridgeFromCC(cartridgeType);
+        //removing the cartridge from Topology
+        removeCartridgeFromTopology(cartridge);
+
+        if (log.isInfoEnabled()) {
+            log.info("Successfully removed cartridge: [cartridge-type] " + 
cartridgeType);
+        }
+        return true;
+    }
+
+    private Cartridge removeCartridgeFromCC(String cartridgeType) throws 
InvalidCartridgeTypeException {
+        Cartridge cartridge = null;
+        if ((cartridge = 
CloudControllerContext.getInstance().getCartridge(cartridgeType)) != null) {
+            if 
(CloudControllerContext.getInstance().getCartridges().remove(cartridge)) {
+                // invalidate partition validation cache
+                
CloudControllerContext.getInstance().removeFromCartridgeTypeToPartitionIds(cartridgeType);
+
+                if (log.isDebugEnabled()) {
+                    log.debug("Partition cache invalidated for cartridge " + 
cartridgeType);
+                }
+
+                CloudControllerContext.getInstance().persist();
+
+                if (log.isInfoEnabled()) {
+                    log.info("Successfully removed cartridge: [cartridge-type] 
" + cartridgeType);
+                }
+                return cartridge;
+            }
+        }
+        String msg = "Cartridge not found: [cartridge-type] " + cartridgeType;
+        log.error(msg);
+        throw new InvalidCartridgeTypeException(msg);
+    }
+
+    private void removeCartridgeFromTopology(Cartridge cartridge) throws 
InvalidCartridgeTypeException {
+        // sends the service removed event
+        List<Cartridge> cartridgeList = new ArrayList<Cartridge>();
+        cartridgeList.add(cartridge);
+        TopologyBuilder.handleServiceRemoved(cartridgeList);
+    }
+
+    public boolean addServiceGroup(ServiceGroup servicegroup) throws 
InvalidServiceGroupException {
+
+        if (servicegroup == null) {
+            String msg = "Invalid ServiceGroup Definition: Definition is 
null.";
+            log.error(msg);
+            throw new IllegalArgumentException(msg);
+
+        }
+        CloudControllerContext.getInstance().addServiceGroup(servicegroup);
+        CloudControllerContext.getInstance().persist();
+        return true;
+    }
+
+    public boolean removeServiceGroup(String name) throws 
InvalidServiceGroupException {
+        if (log.isDebugEnabled()) {
+            log.debug("CloudControllerServiceImpl:removeServiceGroup: " + 
name);
+        }
+
+        ServiceGroup serviceGroup = null;
+
+        serviceGroup = 
CloudControllerContext.getInstance().getServiceGroup(name);
+
+        if (serviceGroup != null) {
+            if 
(CloudControllerContext.getInstance().getServiceGroups().remove(serviceGroup)) {
+                CloudControllerContext.getInstance().persist();
+                if (log.isInfoEnabled()) {
+                    log.info("Successfully removed the cartridge group: 
[group-name] " + serviceGroup);
+                }
+                return true;
+            }
+        }
+
+        String msg = "Cartridge group not found: [group-name] " + name;
+        log.error(msg);
+        throw new InvalidServiceGroupException(msg);
+
+    }
+
+    @Override
+    public ServiceGroup getServiceGroup(String name) throws 
InvalidServiceGroupException {
+
+        if (log.isDebugEnabled()) {
+            log.debug("getServiceGroupDefinition:" + name);
+        }
+
+        ServiceGroup serviceGroup = 
CloudControllerContext.getInstance().getServiceGroup(name);
+
+        if (serviceGroup == null) {
+            String message = "Cartridge group not found: [group-name] " + name;
+            if (log.isDebugEnabled()) {
+                log.debug(message);
+            }
+            throw new InvalidServiceGroupException(message);
+        }
+
+        return serviceGroup;
+    }
+
+    public String[] getServiceGroupSubGroups(String name) throws 
InvalidServiceGroupException {
+        ServiceGroup serviceGroup = this.getServiceGroup(name);
+        if (serviceGroup == null) {
+            throw new InvalidServiceGroupException("Invalid cartridge group: 
[group-name] " + serviceGroup);
+        }
+
+        return serviceGroup.getSubGroups();
+    }
+
+    /**
+     *
+     */
+    public String[] getServiceGroupCartridges(String name) throws 
InvalidServiceGroupException {
+        ServiceGroup serviceGroup = this.getServiceGroup(name);
+        if (serviceGroup == null) {
+            throw new InvalidServiceGroupException("Invalid cartridge group: 
[group-name] " + serviceGroup);
+        }
+        String[] cs = serviceGroup.getCartridges();
+        return cs;
+
+    }
+
+    public Dependencies getServiceGroupDependencies(String name) throws 
InvalidServiceGroupException {
+        ServiceGroup serviceGroup = this.getServiceGroup(name);
+        if (serviceGroup == null) {
+            throw new InvalidServiceGroupException("Invalid cartridge group: 
[group-name] " + serviceGroup);
+        }
+        return serviceGroup.getDependencies();
+    }
+
+    @Override
+    public MemberContext[] startInstances(InstanceContext[] instanceContexts)
+            throws CartridgeNotFoundException, InvalidIaasProviderException, 
CloudControllerException {
+
+        handleNullObject(instanceContexts, "Instance start-up failed, member 
contexts is null");
+
+        List<MemberContext> memberContextList = new ArrayList<MemberContext>();
+        for (InstanceContext instanceContext : instanceContexts) {
+            if (instanceContext != null) {
+                MemberContext memberContext = startInstance(instanceContext);
+                memberContextList.add(memberContext);
+            }
+        }
+        MemberContext[] memberContextsArray = memberContextList.toArray(new 
MemberContext[memberContextList.size()]);
+        return memberContextsArray;
+    }
+
+    public MemberContext startInstance(InstanceContext instanceContext)
+            throws CartridgeNotFoundException, InvalidIaasProviderException, 
CloudControllerException {
+
+        try {
+            // Validate instance context
+            handleNullObject(instanceContext, "Could not start instance, 
instance context is null");
+            if (log.isDebugEnabled()) {
+                log.debug("Starting up instance: " + instanceContext);
+            }
+
+            // Validate partition
+            Partition partition = instanceContext.getPartition();
+            handleNullObject(partition, "Could not start instance, partition 
is null");
+
+            // Validate cluster
+            String partitionId = partition.getId();
+            String clusterId = instanceContext.getClusterId();
+            ClusterContext clusterContext = 
CloudControllerContext.getInstance().getClusterContext(clusterId);
+            handleNullObject(clusterContext,
+                    "Could not start instance, cluster context not found: 
[cluster-id] " + clusterId);
+
+            // Validate cartridge
+            String cartridgeType = clusterContext.getCartridgeType();
+            Cartridge cartridge = 
CloudControllerContext.getInstance().getCartridge(cartridgeType);
+            if (cartridge == null) {
+                String msg = "Could not startup instance, cartridge not found: 
[cartridge-type] " + cartridgeType;
+                log.error(msg);
+                throw new CartridgeNotFoundException(msg);
+            }
+
+            // Validate iaas provider
+            IaasProvider iaasProvider =
+                    
CloudControllerContext.getInstance().getIaasProviderOfPartition(cartridge.getType(),
 partitionId);
+            if (iaasProvider == null) {
+                String msg = String.format("Could not start instance, " +
+                                "IaaS provider not found in cartridge %s for 
partition %s, " +
+                                "partitions found: %s ", cartridgeType, 
partitionId,
+                        CloudControllerContext.getInstance()
+                                
.getPartitionToIaasProvider(cartridge.getType())
+                                .keySet().toString());
+                log.error(msg);
+                throw new InvalidIaasProviderException(msg);
+            }
+
+            // Generate member ID
+            String memberId = generateMemberId(clusterId);
+
+            // Create member context
+            String applicationId = clusterContext.getApplicationId();
+            MemberContext memberContext = createMemberContext(applicationId, 
cartridgeType, memberId,
+                    CloudControllerUtil.getLoadBalancingIPTypeEnumFromString(
+                            cartridge.getLoadBalancingIPType()),
+                    instanceContext);
+
+            // Prepare payload
+            StringBuilder payload = new 
StringBuilder(clusterContext.getPayload());
+            addToPayload(payload, "MEMBER_ID", memberId);
+            addToPayload(payload, "INSTANCE_ID", 
memberContext.getInstanceId());
+            addToPayload(payload, "CLUSTER_INSTANCE_ID", 
memberContext.getClusterInstanceId());
+            addToPayload(payload, "LB_CLUSTER_ID", 
memberContext.getLbClusterId());
+            addToPayload(payload, "NETWORK_PARTITION_ID", 
memberContext.getNetworkPartitionId());
+            addToPayload(payload, "PARTITION_ID", partitionId);
+            addToPayload(payload, "INTERNAL", "false");
+
+            if (memberContext.getProperties() != null) {
+                org.apache.stratos.common.Properties properties = 
memberContext.getProperties();
+                if (properties != null) {
+                    for (Property prop : properties.getProperties()) {
+                        addToPayload(payload, prop.getName(), 
String.valueOf(prop.getValue()));
+                    }
+                }
+            }
+
+            NetworkPartition networkPartition =
+                    
CloudControllerContext.getInstance().getNetworkPartition(memberContext.getNetworkPartitionId());
+
+            if (networkPartition.getProperties() != null) {
+                if (networkPartition.getProperties().getProperties() != null) {
+                    for (Property property : 
networkPartition.getProperties().getProperties()) {
+                        // check if a property is related to the payload. 
Currently
+                        // this is done by checking if the
+                        // property name starts with 'payload_parameter.' 
suffix. If
+                        // so the payload param name will
+                        // be taken as the substring from the index of '.' to 
the
+                        // end of the property name.
+                        if (property.getName().startsWith(PAYLOAD_PARAMETER)) {
+                            String propertyName = property.getName();
+                            String payloadParamName = 
propertyName.substring(propertyName.indexOf(".") + 1);
+                            if (payload.toString().contains(payloadParamName)) 
{
+                                replaceInPayload(payloadParamName, payload, 
payloadParamName, property.getValue());
+                            } else {
+                                addToPayload(payload, payloadParamName, 
property.getValue());
+                            }
+                        }
+                    }
+                }
+            }
+
+            Iaas iaas = iaasProvider.getIaas();
+            if (clusterContext.isVolumeRequired()) {
+                addToPayload(payload, PERSISTENCE_MAPPING, 
getPersistencePayload(clusterContext, iaas).toString());
+            }
+
+            if (log.isDebugEnabled()) {
+                log.debug("Payload: " + payload.toString());
+            }
+
+            if (clusterContext.isVolumeRequired()) {
+
+                Volume[] volumes = clusterContext.getVolumes();
+                if (volumes != null) {
+                    for (int i = 0; i < volumes.length; i++) {
+
+                        if (volumes[i].getId() == null) {
+                            // Create a new volume
+                            volumes[i] = 
createVolumeAndSetInClusterContext(volumes[i], iaasProvider);
+                        }
+                    }
+                }
+                clusterContext.setVolumes(volumes);
+            }
+
+            // Persist member context
+            
CloudControllerContext.getInstance().addMemberContext(memberContext);
+            CloudControllerContext.getInstance().persist();
+
+            // Handle member created event
+            TopologyBuilder.handleMemberCreatedEvent(memberContext);
+
+            // Start instance in a new thread
+            if (log.isDebugEnabled()) {
+                log.debug(String.format("Starting instance creator thread: 
[cluster] %s [cluster-instance] %s " +
+                                "[member] %s [application-id] %s", 
instanceContext.getClusterId(),
+                        instanceContext.getClusterInstanceId(), memberId, 
applicationId));
+            }
+            executorService.execute(new InstanceCreator(memberContext, 
iaasProvider, payload.toString().getBytes()));
+
+            return memberContext;
+        } catch (Exception e) {
+            String msg = String.format("Could not start instance: [cluster] %s 
[cluster-instance] %s",
+                    instanceContext.getClusterId(), 
instanceContext.getClusterInstanceId());
+            log.error(msg, e);
+            throw new CloudControllerException(msg, e);
+        }
+    }
+
+    private MemberContext createMemberContext(String applicationId, String 
cartridgeType, String memberId,
+                                              LoadBalancingIPType 
loadBalancingIPType,
+                                              InstanceContext instanceContext) 
{
+        MemberContext memberContext =
+                new MemberContext(applicationId, cartridgeType, 
instanceContext.getClusterId(), memberId);
+
+        
memberContext.setClusterInstanceId(instanceContext.getClusterInstanceId());
+        
memberContext.setNetworkPartitionId(instanceContext.getNetworkPartitionId());
+        
memberContext.setPartition(cloudControllerContext.getNetworkPartition(instanceContext.getNetworkPartitionId()).
+                getPartition(instanceContext.getPartition().getId()));
+        memberContext.setInitTime(instanceContext.getInitTime());
+        memberContext.setProperties(instanceContext.getProperties());
+        memberContext.setLoadBalancingIPType(loadBalancingIPType);
+        memberContext.setInitTime(System.currentTimeMillis());
+        
memberContext.setObsoleteExpiryTime(instanceContext.getObsoleteExpiryTime());
+
+        return memberContext;
+    }
+
+    private Volume createVolumeAndSetInClusterContext(Volume volume, 
IaasProvider iaasProvider) {
+        // iaas cannot be null at this state #startInstance method
+        Iaas iaas = iaasProvider.getIaas();
+        int sizeGB = volume.getSize();
+        String snapshotId = volume.getSnapshotId();
+        if (StringUtils.isNotEmpty(volume.getVolumeId())) {
+            // volumeID is specified, so not creating additional volumes
+            if (log.isDebugEnabled()) {
+                log.debug("Volume creation is skipping since a volume ID is 
specified. [Volume ID] " +
+                        volume.getVolumeId());
+            }
+            volume.setId(volume.getVolumeId());
+        } else {
+            String volumeId = iaas.createVolume(sizeGB, snapshotId);
+            volume.setId(volumeId);
+        }
+
+        volume.setIaasType(iaasProvider.getType());
+
+        return volume;
+    }
+
+    private StringBuilder getPersistencePayload(ClusterContext ctx, Iaas iaas) 
{
+        StringBuilder persistencePayload = new StringBuilder();
+        if (isPersistenceMappingAvailable(ctx)) {
+            for (Volume volume : ctx.getVolumes()) {
+                if (log.isDebugEnabled()) {
+                    log.debug("Adding persistence mapping " + 
volume.toString());
+                }
+                if (persistencePayload.length() != 0) {
+                    persistencePayload.append("|");
+                }
+
+                
persistencePayload.append(iaas.getIaasDevice(volume.getDevice()));
+                persistencePayload.append("|");
+                persistencePayload.append(volume.getId());
+                persistencePayload.append("|");
+                persistencePayload.append(volume.getMappingPath());
+            }
+        }
+        if (log.isDebugEnabled()) {
+            log.debug("Persistence payload: " + persistencePayload.toString());
+        }
+        return persistencePayload;
+    }
+
+    private boolean isPersistenceMappingAvailable(ClusterContext ctx) {
+        return ctx.getVolumes() != null && ctx.isVolumeRequired();
+    }
+
+    private void addToPayload(StringBuilder payload, String name, String 
value) {
+        payload.append(",");
+        payload.append(name + "=" + value);
+    }
+
+    private void replaceInPayload(String payloadParamName, StringBuilder 
payload, String name, String value) {
+
+        payload.replace(payload.indexOf(payloadParamName), 
payload.indexOf(",", payload.indexOf(payloadParamName)),
+                "," + name + "=" + value);
+    }
+
+    private String generateMemberId(String clusterId) {
+        UUID memberId = UUID.randomUUID();
+        return clusterId + memberId.toString();
+    }
+
+    public boolean terminateInstanceForcefully(String memberId) {
+
+        log.info(String.format("Starting to forcefully terminate the member " 
+ memberId));
+        boolean memberTerminated = true;
+        try {
+            this.terminateInstance(memberId);
+        } catch (InvalidMemberException e) {
+            memberTerminated = false;
+        } catch (CloudControllerException e) {
+            memberTerminated = false;
+        } catch (InvalidCartridgeTypeException e) {
+            memberTerminated = false;
+        }
+
+        if (memberTerminated) {
+            log.info(String.format("Member terminated [member-id] %s ", 
memberId));
+        } else {
+            log.warn(String.format("Stratos could not terminate the member 
[member-id] %s. This may due to a issue " +
+                            "in the underlying IaaS, Please terminate the 
member manually if it is available",
+                    memberId));
+            MemberContext memberContext = 
CloudControllerContext.getInstance().getMemberContextOfMemberId(memberId);
+            
CloudControllerServiceUtil.executeMemberTerminationPostProcess(memberContext);
+        }
+        return true;
+    }
+
+    @Override
+    public boolean terminateInstance(String memberId)
+            throws InvalidMemberException, InvalidCartridgeTypeException, 
CloudControllerException {
+
+        try {
+            handleNullObject(memberId, "Could not terminate instance, member 
id is null.");
+
+            MemberContext memberContext = 
CloudControllerContext.getInstance().getMemberContextOfMemberId(memberId);
+            if (memberContext == null) {
+                String msg = "Could not terminate instance, member context not 
found: [member-id] " + memberId;
+                log.error(msg);
+                throw new InvalidMemberException(msg);
+            }
+
+            if (StringUtils.isBlank(memberContext.getInstanceId())) {
+                if (log.isErrorEnabled()) {
+                    log.error(String.format("Could not terminate instance, 
instance id is blank: [member-id] %s " +
+                            ", removing member from topology...", 
memberContext.getMemberId()));
+                }
+                
CloudControllerServiceUtil.executeMemberTerminationPostProcess(memberContext);
+            }
+
+            // check if status == active, if true, then this is a termination 
on member faulty
+            TopologyManager.acquireWriteLock();
+            Topology topology = TopologyManager.getTopology();
+            org.apache.stratos.messaging.domain.topology.Service service =
+                    topology.getService(memberContext.getCartridgeType());
+
+            if (service != null) {
+                Cluster cluster = 
service.getCluster(memberContext.getClusterId());
+                if (cluster != null) {
+                    

<TRUNCATED>

Reply via email to