http://git-wip-us.apache.org/repos/asf/stratos/blob/6e78131b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/component/ApplicationMonitor.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/component/ApplicationMonitor.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/component/ApplicationMonitor.java index 59b4d5f..68b4d28 100644 --- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/component/ApplicationMonitor.java +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/component/ApplicationMonitor.java @@ -101,7 +101,7 @@ public class ApplicationMonitor extends ParentComponentMonitor { public synchronized void monitor() { final Collection<NetworkPartitionContext> networkPartitionContexts = - this.networkPartitionCtxts.values(); + this.getNetworkPartitionCtxts().values(); Runnable monitoringRunnable = new Runnable() { @Override @@ -400,7 +400,7 @@ public class ApplicationMonitor extends ParentComponentMonitor { //adding to instance map this.instanceIdToInstanceMap.put(instanceId, instance); //adding ApplicationLevelNetworkPartitionContext to networkPartitionContexts map - this.networkPartitionCtxts.put(context.getId(), context); + this.getNetworkPartitionCtxts().put(context.getId(), context); return instanceId; } @@ -453,7 +453,7 @@ public class ApplicationMonitor extends ParentComponentMonitor { } for (String networkPartitionId : nextNetworkPartitions) { - if (!this.networkPartitionCtxts.containsKey(networkPartitionId)) { + if (!this.getNetworkPartitionCtxts().containsKey(networkPartitionId)) { ApplicationLevelNetworkPartitionContext context = new ApplicationLevelNetworkPartitionContext(networkPartitionId);
http://git-wip-us.apache.org/repos/asf/stratos/blob/6e78131b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/component/GroupMonitor.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/component/GroupMonitor.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/component/GroupMonitor.java index 7c80af1..1de7e90 100644 --- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/component/GroupMonitor.java +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/component/GroupMonitor.java @@ -109,7 +109,7 @@ public class GroupMonitor extends ParentComponentMonitor { public synchronized void monitor() { final Collection<NetworkPartitionContext> networkPartitionContexts = - this.networkPartitionCtxts.values(); + this.getNetworkPartitionCtxts().values(); Runnable monitoringRunnable = new Runnable() { @Override @@ -140,6 +140,23 @@ public class GroupMonitor extends ParentComponentMonitor { } } } + + int nonTerminatedInstancesCount = networkPartitionContext. + getNonTerminatedInstancesCount(); + int minInstances = ((GroupLevelNetworkPartitionContext)networkPartitionContext). + getMinInstanceCount(); + if(nonTerminatedInstancesCount < minInstances) { + int instancesToBeCreated = minInstances - nonTerminatedInstancesCount; + for(int i = 0; i < instancesToBeCreated; i++) { + for(InstanceContext parentInstanceContext : parent. + getNetworkPartitionContext(networkPartitionContext.getId()). + getInstanceIdToInstanceContextMap().values()) { + //Creating new group instance based on the existing parent instances + createInstanceOnDemand(parentInstanceContext.getId()); + } + + } + } } } }; @@ -468,7 +485,7 @@ public class GroupMonitor extends ParentComponentMonitor { //Parent notification always brings up new group instances in order to keep the ratio. String networkPartitionId = scalingEvent.getNetworkPartitionId(); final String parentInstanceId = scalingEvent.getInstanceId(); - final NetworkPartitionContext networkPartitionContext = this.networkPartitionCtxts. + final NetworkPartitionContext networkPartitionContext = this.getNetworkPartitionCtxts(). get(networkPartitionId); float factor = scalingEvent.getFactor(); @@ -544,8 +561,8 @@ public class GroupMonitor extends ParentComponentMonitor { DeploymentPolicy deploymentPolicy = PolicyManager.getInstance().getDeploymentPolicy(deploymentPolicyId); String networkPartitionId = parentInstanceContext.getNetworkPartitionId(); - if (this.networkPartitionCtxts.containsKey(networkPartitionId)) { - groupLevelNetworkPartitionContext = (GroupLevelNetworkPartitionContext) this.networkPartitionCtxts. + if (this.getNetworkPartitionCtxts().containsKey(networkPartitionId)) { + groupLevelNetworkPartitionContext = (GroupLevelNetworkPartitionContext) this.getNetworkPartitionCtxts(). get(networkPartitionId); } else { if (deploymentPolicy != null) { @@ -885,7 +902,7 @@ public class GroupMonitor extends ParentComponentMonitor { } public void addNetworkPartitionContext(GroupLevelNetworkPartitionContext clusterLevelNetworkPartitionContext) { - this.networkPartitionCtxts.put(clusterLevelNetworkPartitionContext.getId(), clusterLevelNetworkPartitionContext); + this.getNetworkPartitionCtxts().put(clusterLevelNetworkPartitionContext.getId(), clusterLevelNetworkPartitionContext); } @@ -915,7 +932,7 @@ public class GroupMonitor extends ParentComponentMonitor { if (!groupInstances.isEmpty()) { GroupLevelNetworkPartitionContext networkPartitionContext = - (GroupLevelNetworkPartitionContext) this.networkPartitionCtxts. + (GroupLevelNetworkPartitionContext) this.getNetworkPartitionCtxts(). get(networkPartitionId); int minInstances = networkPartitionContext.getMinInstanceCount(); //if terminated all the instances in this instances map should be in terminated state http://git-wip-us.apache.org/repos/asf/stratos/blob/6e78131b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/component/ParentComponentMonitor.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/component/ParentComponentMonitor.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/component/ParentComponentMonitor.java index eb5804c..6b69065 100644 --- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/component/ParentComponentMonitor.java +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/component/ParentComponentMonitor.java @@ -239,7 +239,7 @@ public abstract class ParentComponentMonitor extends Monitor implements Runnable String instanceId = scalingEvent.getInstanceId(); String id = scalingEvent.getId(); NetworkPartitionContext networkPartitionContext = - this.networkPartitionCtxts.get(networkPartitionId); + this.getNetworkPartitionCtxts().get(networkPartitionId); if (networkPartitionContext != null) { InstanceContext instanceContext = networkPartitionContext. getInstanceContext(instanceId); @@ -277,7 +277,7 @@ public abstract class ParentComponentMonitor extends Monitor implements Runnable String instanceId = scalingUpBeyondMaxEvent.getInstanceId(); String id = scalingUpBeyondMaxEvent.getId(); NetworkPartitionContext networkPartitionContext = - this.networkPartitionCtxts.get(networkPartitionId); + this.getNetworkPartitionCtxts().get(networkPartitionId); if (networkPartitionContext != null) { InstanceContext instanceContext = networkPartitionContext. getInstanceContext(instanceId); @@ -296,7 +296,7 @@ public abstract class ParentComponentMonitor extends Monitor implements Runnable } public NetworkPartitionContext getNetworkPartitionContext(String networkPartitionId) { - return this.networkPartitionCtxts.get(networkPartitionId); + return this.getNetworkPartitionCtxts().get(networkPartitionId); } @@ -752,6 +752,10 @@ public abstract class ParentComponentMonitor extends Monitor implements Runnable return startupDependencyTree; } + public Map<String, NetworkPartitionContext> getNetworkPartitionCtxts() { + return networkPartitionCtxts; + } + private class MonitorAdder implements Runnable { private final ApplicationChildContext context; http://git-wip-us.apache.org/repos/asf/stratos/blob/6e78131b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/services/AutoscalerService.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/services/AutoscalerService.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/services/AutoscalerService.java index ba38727..80b134b 100644 --- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/services/AutoscalerService.java +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/services/AutoscalerService.java @@ -88,6 +88,15 @@ public interface AutoscalerService { public void addApplication(ApplicationContext applicationContext) throws ApplicationDefinitionException; /** + * update an application + * + * @param applicationContext {@link org.apache.stratos.autoscaler.applications.pojo.ApplicationContext} + * @throws ApplicationDefinitionException if an error occurs + */ + public void updateApplication(ApplicationContext applicationContext) throws ApplicationDefinitionException; + + + /** * Get an application * * @param applicationId http://git-wip-us.apache.org/repos/asf/stratos/blob/6e78131b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/services/impl/AutoscalerServiceImpl.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/services/impl/AutoscalerServiceImpl.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/services/impl/AutoscalerServiceImpl.java index 589af4b..2b17a24 100644 --- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/services/impl/AutoscalerServiceImpl.java +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/services/impl/AutoscalerServiceImpl.java @@ -149,6 +149,55 @@ public class AutoscalerServiceImpl implements AutoscalerService { } @Override + public void updateApplication(ApplicationContext applicationContext) + throws ApplicationDefinitionException { + + String applicationId = applicationContext.getApplicationId(); + if (log.isInfoEnabled()) { + log.info(String.format("Updating application: [application-id] %s", + applicationContext.getApplicationId())); + } + + if(AutoscalerContext.getInstance().getApplicationContext(applicationId) == null) { + String msg = "Application is not found as ApplicationContext. Please add application before updating it"; + log.error(msg); + throw new ApplicationDefinitionException(msg); + } + + if(ApplicationHolder.getApplications().getApplication(applicationId) == null) { + String msg = "Application is not found as Application. Please add application before updating it"; + log.error(msg); + throw new ApplicationDefinitionException(msg); + } + + + ApplicationParser applicationParser = new DefaultApplicationParser(); + Application application = applicationParser.parse(applicationContext); + + //Need to update the application + AutoscalerUtil.getInstance().updateApplicationsTopology(application); + + //Update the clusterMonitors + AutoscalerUtil.getInstance().updateClusterMonitor(application); + + List<ApplicationClusterContext> applicationClusterContexts = applicationParser.getApplicationClusterContexts(); + ApplicationClusterContext[] applicationClusterContextsArray = applicationClusterContexts.toArray( + new ApplicationClusterContext[applicationClusterContexts.size()]); + applicationContext.getComponents().setApplicationClusterContexts(applicationClusterContextsArray); + + ApplicationContext existingApplicationContext = AutoscalerContext.getInstance(). + getApplicationContext(applicationId); + applicationContext.setStatus(existingApplicationContext.getStatus()); + //updating the applicationContext + AutoscalerContext.getInstance().updateApplicationContext(applicationContext); + + if (log.isInfoEnabled()) { + log.info(String.format("Application added successfully: [application-id] %s", + applicationId)); + } + } + + @Override public ApplicationContext getApplication(String applicationId) { return AutoscalerContext.getInstance().getApplicationContext(applicationId); } http://git-wip-us.apache.org/repos/asf/stratos/blob/6e78131b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/util/AutoscalerUtil.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/util/AutoscalerUtil.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/util/AutoscalerUtil.java index 0650bf2..1548e98 100644 --- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/util/AutoscalerUtil.java +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/util/AutoscalerUtil.java @@ -32,7 +32,13 @@ import org.apache.stratos.autoscaler.applications.pojo.CartridgeContext; import org.apache.stratos.autoscaler.applications.pojo.ComponentContext; import org.apache.stratos.autoscaler.applications.pojo.GroupContext; import org.apache.stratos.autoscaler.context.AutoscalerContext; +import org.apache.stratos.autoscaler.context.InstanceContext; +import org.apache.stratos.autoscaler.context.cluster.ClusterInstanceContext; +import org.apache.stratos.autoscaler.context.partition.network.ClusterLevelNetworkPartitionContext; +import org.apache.stratos.autoscaler.context.partition.network.GroupLevelNetworkPartitionContext; +import org.apache.stratos.autoscaler.context.partition.network.NetworkPartitionContext; import org.apache.stratos.autoscaler.exception.AutoScalerException; +import org.apache.stratos.autoscaler.exception.application.ApplicationDefinitionException; import org.apache.stratos.autoscaler.exception.application.DependencyBuilderException; import org.apache.stratos.autoscaler.exception.application.InvalidApplicationPolicyException; import org.apache.stratos.autoscaler.exception.application.TopologyInConsistentException; @@ -40,7 +46,9 @@ import org.apache.stratos.autoscaler.exception.policy.ApplicatioinPolicyNotExist import org.apache.stratos.autoscaler.exception.policy.PolicyValidationException; import org.apache.stratos.autoscaler.monitor.Monitor; import org.apache.stratos.autoscaler.monitor.MonitorFactory; +import org.apache.stratos.autoscaler.monitor.cluster.ClusterMonitor; import org.apache.stratos.autoscaler.monitor.component.ApplicationMonitor; +import org.apache.stratos.autoscaler.monitor.component.GroupMonitor; import org.apache.stratos.autoscaler.pojo.policy.PolicyManager; import org.apache.stratos.autoscaler.pojo.policy.deployment.ApplicationPolicy; import org.apache.stratos.autoscaler.pojo.policy.deployment.DeploymentPolicy; @@ -53,6 +61,7 @@ import org.apache.stratos.common.partition.NetworkPartition; import org.apache.stratos.messaging.domain.application.Application; import org.apache.stratos.messaging.domain.application.Applications; import org.apache.stratos.messaging.domain.application.ClusterDataHolder; +import org.apache.stratos.messaging.domain.application.Group; import org.apache.stratos.messaging.domain.topology.Service; import org.apache.stratos.messaging.domain.topology.Topology; import org.apache.stratos.messaging.message.receiver.topology.TopologyManager; @@ -477,7 +486,7 @@ public class AutoscalerUtil { /** * Get alias to deployment policy id map in the given application. * - * @param applicationId the application id + * @param applicationContext the application context * @return alias to deployment policy map */ public static Map<String, String> getAliasToDeploymentPolicyIdMapOfApplication(ApplicationContext applicationContext) { @@ -535,10 +544,14 @@ public class AutoscalerUtil { String deploymentPolicyId = groupContext.getDeploymentPolicy(); aliasToDeploymentPolicyIdMap.put(groupContext.getAlias(), deploymentPolicyId); if (groupContext.getCartridgeContexts() != null && groupContext.getCartridgeContexts().length != 0) { - setDeploymentPolicyIdToChildCartridgeContexts(aliasToDeploymentPolicyIdMap, deploymentPolicyId, groupContext.getCartridgeContexts()); + setDeploymentPolicyIdToChildCartridgeContexts(aliasToDeploymentPolicyIdMap, + deploymentPolicyId, + groupContext.getCartridgeContexts()); } if (groupContext.getGroupContexts() != null && groupContext.getGroupContexts().length != 0) { - setDeploymentPolicyIdToChildGroupContexts(aliasToDeploymentPolicyIdMap, deploymentPolicyId, groupContext.getGroupContexts()); + setDeploymentPolicyIdToChildGroupContexts(aliasToDeploymentPolicyIdMap, + deploymentPolicyId, + groupContext.getGroupContexts()); } } @@ -548,12 +561,14 @@ public class AutoscalerUtil { } private static void setDeploymentPolicyIdToChildCartridgeContexts( - Map<String, String> aliasToDeploymentPolicyIdMap, String deploymentPolicyId, CartridgeContext[] cartridgeContexts) { + Map<String, String> aliasToDeploymentPolicyIdMap, String deploymentPolicyId, + CartridgeContext[] cartridgeContexts) { if (cartridgeContexts != null && cartridgeContexts.length != 0) { for (CartridgeContext cartridgeContext : cartridgeContexts) { if (cartridgeContext != null) { - aliasToDeploymentPolicyIdMap.put(cartridgeContext.getSubscribableInfoContext().getAlias(), deploymentPolicyId); + aliasToDeploymentPolicyIdMap.put(cartridgeContext.getSubscribableInfoContext().getAlias(), + deploymentPolicyId); } } } @@ -566,10 +581,14 @@ public class AutoscalerUtil { for (GroupContext groupContext : groupContexts) { if (groupContext != null) { if (groupContext.getCartridgeContexts() != null && groupContext.getCartridgeContexts().length != 0) { - setDeploymentPolicyIdToChildCartridgeContexts(aliasToDeploymentPolicyIdMap, deploymentPolicyId, groupContext.getCartridgeContexts()); + setDeploymentPolicyIdToChildCartridgeContexts(aliasToDeploymentPolicyIdMap, + deploymentPolicyId, + groupContext.getCartridgeContexts()); } if (groupContext.getGroupContexts() != null && groupContext.getGroupContexts().length != 0) { - setDeploymentPolicyIdToChildGroupContexts(aliasToDeploymentPolicyIdMap, deploymentPolicyId, groupContext.getGroupContexts()); + setDeploymentPolicyIdToChildGroupContexts(aliasToDeploymentPolicyIdMap, + deploymentPolicyId, + groupContext.getGroupContexts()); } } } @@ -603,7 +622,8 @@ public class AutoscalerUtil { // network partition algorithm can't null or empty String algorithm = applicationPolicy.getAlgorithm(); if (algorithm == null || StringUtils.isBlank(algorithm)) { - String msg = "Invalid Application Policy. Cause -> Network partition algorithm is null or empty"; + String msg = "Invalid Application Policy. Cause -> Network " + + "partition algorithm is null or empty"; log.error(msg); throw new InvalidApplicationPolicyException(msg); } @@ -611,7 +631,8 @@ public class AutoscalerUtil { // network partition algorithm should be either one-after-another or all-at-once if (!algorithm.equals(StratosConstants.NETWORK_PARTITION_ONE_AFTER_ANOTHER_ALGORITHM_ID) && !algorithm.equals(StratosConstants.NETWORK_PARTITION_ALL_AT_ONCE_ALGORITHM_ID)) { - String msg = String.format("Invalid Application Policy. Cause -> Invalid network partition algorithm. " + String msg = String.format("Invalid Application Policy. Cause -> " + + "Invalid network partition algorithm. " + "It should be either %s or %s, but found %s", StratosConstants.NETWORK_PARTITION_ONE_AFTER_ANOTHER_ALGORITHM_ID, StratosConstants.NETWORK_PARTITION_ALL_AT_ONCE_ALGORITHM_ID, algorithm); @@ -640,9 +661,11 @@ public class AutoscalerUtil { } // network partitions should be added already - if (null == CloudControllerServiceClient.getInstance().getNetworkPartition(networkPartitionId)) { + if (null == CloudControllerServiceClient.getInstance(). + getNetworkPartition(networkPartitionId)) { String msg = String.format("Invalid Application Policy. " - + "Cause -> Network partition not found for network-partition-id : %s", networkPartitionId); + + "Cause -> Network partition not found for network-partition-id : %s", + networkPartitionId); log.error(msg); throw new InvalidApplicationPolicyException(msg); } @@ -652,28 +675,34 @@ public class AutoscalerUtil { // if networkPartitionGroups property is set, we need to validate that too Properties properties = applicationPolicy.getProperties(); if (properties != null) { - Property networkPartitionGroupsProperty = properties.getProperty(StratosConstants.APPLICATION_POLICY_NETWORK_PARTITION_GROUPS); + Property networkPartitionGroupsProperty = properties. + getProperty(StratosConstants.APPLICATION_POLICY_NETWORK_PARTITION_GROUPS); if (networkPartitionGroupsProperty != null) { String networkPartitionGroupsPropertyValue = networkPartitionGroupsProperty.getValue(); if (networkPartitionGroupsPropertyValue != null) { - String[] networkPartitionGroups = networkPartitionGroupsPropertyValue.split(StratosConstants.APPLICATION_POLICY_NETWORK_PARTITION_GROUPS_SPLITTER); + String[] networkPartitionGroups = networkPartitionGroupsPropertyValue. + split(StratosConstants.APPLICATION_POLICY_NETWORK_PARTITION_GROUPS_SPLITTER); if (networkPartitionGroups != null) { for (String networkPartitionIdsString : networkPartitionGroups) { - networkPartitionIds = networkPartitionIdsString.split(StratosConstants.APPLICATION_POLICY_NETWORK_PARTITIONS_SPLITTER); + networkPartitionIds = networkPartitionIdsString. + split(StratosConstants.APPLICATION_POLICY_NETWORK_PARTITIONS_SPLITTER); if (networkPartitionIds != null) { for (String networkPartitionId : networkPartitionIds) { // network-partition-id can't be null or empty if (null == networkPartitionId || networkPartitionId.isEmpty()) { String msg = String.format("Invalid Application Policy. " - + "Cause -> Invalid network-partition-id : %s", networkPartitionId); + + "Cause -> Invalid network-partition-id : %s", + networkPartitionId); log.error(msg); throw new InvalidApplicationPolicyException(msg); } // network partitions should be added already - if (null == CloudControllerServiceClient.getInstance().getNetworkPartition(networkPartitionId)) { + if (null == CloudControllerServiceClient.getInstance(). + getNetworkPartition(networkPartitionId)) { String msg = String.format("Invalid Application Policy. " - + "Cause -> Network partition not found for network-partition-id : %s", networkPartitionId); + + "Cause -> Network partition not found for " + + "network-partition-id : %s", networkPartitionId); log.error(msg); throw new InvalidApplicationPolicyException(msg); } @@ -736,4 +765,97 @@ public class AutoscalerUtil { } return false; } + + public void updateApplicationsTopology(Application application) + throws ApplicationDefinitionException{ + Application existingApplication = ApplicationHolder.getApplications(). + getApplication(application.getUniqueIdentifier()); + //Retrieve all the groups in order to update it + Set<Group> existingGroups = existingApplication.getAllGroupsRecursively(); + + //updating all the groups by traversing the existing application + for(Group existingGroup : existingGroups) { + Group newGroup = application.getGroupRecursively(existingGroup.getUniqueIdentifier()); + if(newGroup != null) { + //Finding the GroupMonitor based on ApplicationMonitor + GroupMonitor groupMonitor = (GroupMonitor) AutoscalerContext.getInstance(). + getAppMonitor(application.getUniqueIdentifier()). + findGroupMonitorWithId(existingGroup.getUniqueIdentifier()); + //Updating the GroupMonitor + for(NetworkPartitionContext networkPartitionContext : groupMonitor. + getNetworkPartitionCtxts().values()) { + ((GroupLevelNetworkPartitionContext)networkPartitionContext). + setMinInstanceCount(newGroup.getGroupMinInstances()); + ((GroupLevelNetworkPartitionContext)networkPartitionContext). + setMaxInstanceCount(newGroup.getGroupMaxInstances()); + } + + try{ + ApplicationHolder.acquireWriteLock(); + //update the min and max of Group instances + existingGroup.setGroupMinInstances(newGroup.getGroupMinInstances()); + //TODO applications Topology update + existingGroup.setGroupMaxInstances(newGroup.getGroupMaxInstances()); + } finally { + ApplicationHolder.releaseWriteLock(); + } + } else { + String msg = "Application is inconsistent. Please check whether the updated " + + "application has same structure as existing application"; + log.error(msg); + throw new ApplicationDefinitionException(msg); + } + + } + + } + + public void updateClusterMonitor(Application application) throws ApplicationDefinitionException{ + Application existingApplication = ApplicationHolder.getApplications(). + getApplication(application.getUniqueIdentifier()); + + Set<ClusterDataHolder> clusterDataHolders = application.getClusterDataRecursively(); + + for(ClusterDataHolder clusterDataHolder : clusterDataHolders) { + ClusterMonitor clusterMonitor = AutoscalerContext.getInstance(). + getClusterMonitor(clusterDataHolder.getClusterId()); + if(clusterMonitor != null) { + for(ClusterLevelNetworkPartitionContext networkPartitionContext : + clusterMonitor.getNetworkPartitionCtxts()) { + for(InstanceContext instanceContext : + networkPartitionContext.getInstanceIdToInstanceContextMap().values()) { + //Updating the min and max instances of cluster instance context + ((ClusterInstanceContext)instanceContext). + setMinInstanceCount(clusterDataHolder.getMinInstances()); + ((ClusterInstanceContext)instanceContext). + setMaxInstanceCount(clusterDataHolder.getMaxInstances()); + + try { + ApplicationHolder.acquireWriteLock(); + //Updating the existing application + ClusterDataHolder existingClusterDataHolder = existingApplication. + getClusterDataHolderRecursivelyByAlias( + AutoscalerUtil.getAliasFromClusterId( + clusterDataHolder.getClusterId())); + existingClusterDataHolder.setMinInstances(clusterDataHolder. + getMinInstances()); + existingClusterDataHolder.setMaxInstances(clusterDataHolder. + getMaxInstances()); + } finally { + ApplicationHolder.releaseWriteLock(); + } + } + } + } else { + String msg = "Application is inconsistent. Please check whether the updated " + + "application has same structure as existing application"; + log.error(msg); + throw new ApplicationDefinitionException(msg); + } + } + } + + public void updateMonitors() { + + } } http://git-wip-us.apache.org/repos/asf/stratos/blob/6e78131b/components/org.apache.stratos.common/src/main/java/org/apache/stratos/common/client/AutoscalerServiceClient.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.common/src/main/java/org/apache/stratos/common/client/AutoscalerServiceClient.java b/components/org.apache.stratos.common/src/main/java/org/apache/stratos/common/client/AutoscalerServiceClient.java index 3949bec..a89c1f6 100644 --- a/components/org.apache.stratos.common/src/main/java/org/apache/stratos/common/client/AutoscalerServiceClient.java +++ b/components/org.apache.stratos.common/src/main/java/org/apache/stratos/common/client/AutoscalerServiceClient.java @@ -90,10 +90,16 @@ public class AutoscalerServiceClient { return stub.getAutoscalingPolicy(autoscalingPolicyId); } - public void addApplication(ApplicationContext applicationContext) throws AutoscalerServiceApplicationDefinitionExceptionException, RemoteException { + public void addApplication(ApplicationContext applicationContext) + throws AutoscalerServiceApplicationDefinitionExceptionException, RemoteException { stub.addApplication(applicationContext); } + public void updateApplication(ApplicationContext applicationContext) + throws AutoscalerServiceApplicationDefinitionExceptionException, RemoteException { + stub.updateApplication(applicationContext); + } + public ApplicationContext getApplication(String applicationId) throws RemoteException { return stub.getApplication(applicationId); } http://git-wip-us.apache.org/repos/asf/stratos/blob/6e78131b/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/domain/application/ParentComponent.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/domain/application/ParentComponent.java b/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/domain/application/ParentComponent.java index c1b32d0..4a64357 100644 --- a/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/domain/application/ParentComponent.java +++ b/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/domain/application/ParentComponent.java @@ -264,6 +264,28 @@ public abstract class ParentComponent<T extends Instance> implements Serializabl } /** + * Collects the Group for the parent component and all the + * child components recursively + * + * @return Set of Group objects if available, else null + */ + public Set<Group> getAllGroupsRecursively() { + + Set<Group> appGroups = new HashSet<Group>(); + + // get top level Cluster Data + if (this.aliasToGroupMap != null && !this.aliasToGroupMap.isEmpty()) { + appGroups.addAll(this.aliasToGroupMap.values()); + } + + // find other nested Cluster Data (in the Groups) + if (getGroups() != null) { + getGroupsRecursively(appGroups, getGroups()); + } + + return appGroups; + } + /** * Adds InstanceContext of a child to the instanceIdToInstanceContextMap. * * @param instanceId instance id of child @@ -364,6 +386,18 @@ public abstract class ParentComponent<T extends Instance> implements Serializabl } } + protected void getGroupsRecursively(Set<Group> groupsSet, Collection<Group> groups) { + + for (Group group : groups) { + if (group.getGroups() != null && !group.getGroups().isEmpty()) { + groupsSet.addAll(group.getGroups()); + if (group.getGroups() != null) { + getGroupsRecursively(groupsSet, group.getGroups()); + } + } + } + } + public Map<String, T> getInstanceIdToInstanceContextMap() { return instanceIdToInstanceContextMap; http://git-wip-us.apache.org/repos/asf/stratos/blob/6e78131b/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/api/StratosApiV41.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/api/StratosApiV41.java b/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/api/StratosApiV41.java index 9c8b8c7..f1f4dfe 100644 --- a/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/api/StratosApiV41.java +++ b/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/api/StratosApiV41.java @@ -607,6 +607,35 @@ public class StratosApiV41 extends AbstractApi { } /** + * Add application + * + * @param applicationDefinition Application Definition + * @return 201 if application is successfully added + * @throws RestAPIException + */ + @PUT + @Path("/applications") + @Produces("application/json") + @Consumes("application/json") + @AuthorizationAction("/permission/protected/manage/addApplication") + public Response updateApplication(ApplicationBean applicationDefinition) throws RestAPIException { + try { + StratosApiV41Utils.updateApplication(applicationDefinition, getConfigContext(), getUsername(), getTenantDomain()); + + URI url = uriInfo.getAbsolutePathBuilder().path(applicationDefinition.getApplicationId()).build(); + return Response.created(url).entity(new SuccessResponseBean(Response.Status.CREATED.getStatusCode(), + String.format("Application added successfully: [application] %s", + applicationDefinition.getApplicationId()))).build(); + } catch (RestAPIException e) { + if (e.getMessage().contains("already exists")) { + return Response.status(Response.Status.CONFLICT).build(); + } else { + throw e; + } + } + } + + /** * Return applications * * @return 200 if applications are found http://git-wip-us.apache.org/repos/asf/stratos/blob/6e78131b/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/api/StratosApiV41Utils.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/api/StratosApiV41Utils.java b/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/api/StratosApiV41Utils.java index 987f147..c5b452e 100644 --- a/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/api/StratosApiV41Utils.java +++ b/components/org.apache.stratos.rest.endpoint/src/main/java/org/apache/stratos/rest/endpoint/api/StratosApiV41Utils.java @@ -1110,6 +1110,54 @@ public class StratosApiV41Utils { } } + /** + * Update the existence of the application and update it. + * + * @param appDefinition Application definition + * @param ctxt Configuration context + * @param userName Username + * @param tenantDomain Tenant Domain + * @throws RestAPIException + */ + public static void updateApplication(ApplicationBean appDefinition, ConfigurationContext ctxt, + String userName, String tenantDomain) + throws RestAPIException { + + if (StringUtils.isBlank(appDefinition.getApplicationId())) { + String message = "Please specify the application name"; + log.error(message); + throw new RestAPIException(message); + } + + validateApplication(appDefinition); + + ApplicationContext applicationContext = ObjectConverter.convertApplicationDefinitionToStubApplicationContext( + appDefinition); + applicationContext.setTenantId(ApplicationManagementUtil.getTenantId(ctxt)); + applicationContext.setTenantDomain(tenantDomain); + applicationContext.setTenantAdminUsername(userName); + + if (appDefinition.getProperty() != null) { + org.apache.stratos.autoscaler.stub.Properties properties = new org.apache.stratos.autoscaler.stub.Properties(); + for (PropertyBean propertyBean : appDefinition.getProperty()) { + org.apache.stratos.autoscaler.stub.Property property = new org.apache.stratos.autoscaler.stub.Property(); + property.setName(propertyBean.getName()); + property.setValue(propertyBean.getValue()); + properties.addProperties(property); + } + applicationContext.setProperties(properties); + } + + try { + AutoscalerServiceClient.getInstance().updateApplication(applicationContext); + } catch (AutoscalerServiceApplicationDefinitionExceptionException e) { + throw new RestAPIException(e); + } catch (RemoteException e) { + throw new RestAPIException(e); + } + } + + private static void findCartridgesAndGroupsInApplication( ApplicationBean applicationBean, List<String> cartridges, List<String> cartridgeGroups) { http://git-wip-us.apache.org/repos/asf/stratos/blob/6e78131b/samples/applications/single-group-v3/artifacts/application.json ---------------------------------------------------------------------- diff --git a/samples/applications/single-group-v3/artifacts/application.json b/samples/applications/single-group-v3/artifacts/application.json index a050de4..42f5382 100644 --- a/samples/applications/single-group-v3/artifacts/application.json +++ b/samples/applications/single-group-v3/artifacts/application.json @@ -6,8 +6,8 @@ { "name": "tomcat2-group", "alias": "my-tomcat2-group", - "groupMinInstances": 2, - "groupMaxInstances": 3, + "groupMinInstances": 3, + "groupMaxInstances": 4, "deploymentPolicy":"deployment-policy-1", "cartridges": [ {
