http://git-wip-us.apache.org/repos/asf/stratos/blob/c20d28c2/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/topic/ApplicationBuilder.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/topic/ApplicationBuilder.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/topic/ApplicationBuilder.java index 8651966..82c9bb9 100644 --- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/topic/ApplicationBuilder.java +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/applications/topic/ApplicationBuilder.java @@ -20,7 +20,7 @@ package org.apache.stratos.autoscaler.applications.topic; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.apache.stratos.autoscaler.AutoscalerContext; +import org.apache.stratos.autoscaler.context.AutoscalerContext; import org.apache.stratos.autoscaler.applications.ApplicationHolder; import org.apache.stratos.autoscaler.applications.pojo.ApplicationClusterContext; import org.apache.stratos.autoscaler.client.CloudControllerClient;
http://git-wip-us.apache.org/repos/asf/stratos/blob/c20d28c2/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/context/AutoscalerContext.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/context/AutoscalerContext.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/context/AutoscalerContext.java new file mode 100644 index 0000000..2b41987 --- /dev/null +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/context/AutoscalerContext.java @@ -0,0 +1,89 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.stratos.autoscaler.context; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.stratos.autoscaler.monitor.application.ApplicationMonitor; +import org.apache.stratos.autoscaler.monitor.cluster.AbstractClusterMonitor; + +/** + * It holds all cluster monitors which are active in stratos. + */ +public class AutoscalerContext { + + private static final AutoscalerContext INSTANCE = new AutoscalerContext(); + + // Map<ClusterId, AbstractClusterMonitor> + private Map<String, AbstractClusterMonitor> clusterMonitors; + // Map<ApplicationId, ApplicationMonitor> + private Map<String, ApplicationMonitor> applicationMonitors; + + private AutoscalerContext() { + setClusterMonitors(new HashMap<String, AbstractClusterMonitor>()); + setApplicationMonitors(new HashMap<String, ApplicationMonitor>()); + } + + public static AutoscalerContext getInstance() { + return INSTANCE; + } + + public void addClusterMonitor(AbstractClusterMonitor clusterMonitor) { + getClusterMonitors().put(clusterMonitor.getClusterId(), clusterMonitor); + } + + public AbstractClusterMonitor getClusterMonitor(String clusterId) { + return getClusterMonitors().get(clusterId); + } + + public AbstractClusterMonitor removeClusterMonitor(String clusterId) { + return getClusterMonitors().remove(clusterId); + } + + public void addAppMonitor(ApplicationMonitor applicationMonitor) { + getApplicationMonitors().put(applicationMonitor.getId(), applicationMonitor); + } + + public ApplicationMonitor getAppMonitor(String applicationId) { + return getApplicationMonitors().get(applicationId); + } + + public void removeAppMonitor(String applicationId) { + getApplicationMonitors().remove(applicationId); + } + + public Map<String, AbstractClusterMonitor> getClusterMonitors() { + return clusterMonitors; + } + + public void setClusterMonitors(Map<String, AbstractClusterMonitor> clusterMonitors) { + this.clusterMonitors = clusterMonitors; + } + + public Map<String, ApplicationMonitor> getApplicationMonitors() { + return applicationMonitors; + } + + public void setApplicationMonitors(Map<String, ApplicationMonitor> applicationMonitors) { + this.applicationMonitors = applicationMonitors; + } +} http://git-wip-us.apache.org/repos/asf/stratos/blob/c20d28c2/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/context/cluster/AbstractClusterContext.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/context/cluster/AbstractClusterContext.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/context/cluster/AbstractClusterContext.java new file mode 100644 index 0000000..1629c99 --- /dev/null +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/context/cluster/AbstractClusterContext.java @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.stratos.autoscaler.context.cluster; + +import org.apache.commons.configuration.XMLConfiguration; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.stratos.cloud.controller.stub.pojo.MemberContext; +import org.apache.stratos.common.constants.StratosConstants; + +import java.io.Serializable; + +/* + * It holds the runtime data of a service cluster + */ +public class AbstractClusterContext implements Serializable { + + private static final Log log = LogFactory.getLog(AbstractClusterContext.class); + + + // cluster id + protected String clusterId; + private String serviceId; + + public AbstractClusterContext(String clusterId, String serviceId){ + this.clusterId = clusterId; + this.serviceId = serviceId; + } + + public String getServiceId() { + return serviceId; + } +} http://git-wip-us.apache.org/repos/asf/stratos/blob/c20d28c2/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/context/cluster/ClusterContextFactory.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/context/cluster/ClusterContextFactory.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/context/cluster/ClusterContextFactory.java new file mode 100644 index 0000000..fd35f82 --- /dev/null +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/context/cluster/ClusterContextFactory.java @@ -0,0 +1,390 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.stratos.autoscaler.context.cluster; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.stratos.autoscaler.*; +import org.apache.stratos.autoscaler.client.CloudControllerClient; +import org.apache.stratos.autoscaler.context.member.MemberStatsContext; +import org.apache.stratos.autoscaler.context.partition.network.ClusterLevelNetworkPartitionContext; +import org.apache.stratos.autoscaler.context.partition.ClusterLevelPartitionContext; +import org.apache.stratos.autoscaler.exception.PartitionValidationException; +import org.apache.stratos.autoscaler.exception.PolicyValidationException; +import org.apache.stratos.autoscaler.partition.PartitionGroup; +import org.apache.stratos.autoscaler.partition.PartitionManager; +import org.apache.stratos.autoscaler.policy.PolicyManager; +import org.apache.stratos.autoscaler.policy.model.AutoscalePolicy; +import org.apache.stratos.autoscaler.policy.model.DeploymentPolicy; +import org.apache.stratos.cloud.controller.stub.deployment.partition.Partition; +import org.apache.stratos.cloud.controller.stub.pojo.MemberContext; +import org.apache.stratos.cloud.controller.stub.pojo.Properties; +import org.apache.stratos.cloud.controller.stub.pojo.Property; +import org.apache.stratos.common.constants.StratosConstants; +import org.apache.stratos.messaging.domain.topology.Cluster; +import org.apache.stratos.messaging.domain.topology.Member; +import org.apache.stratos.messaging.domain.topology.MemberStatus; +import org.apache.stratos.messaging.util.Constants; + +import java.util.HashMap; +import java.util.Map; +import java.util.Random; + +public class ClusterContextFactory { + + private static final Log log = LogFactory.getLog(ClusterContextFactory.class); + + public static VMServiceClusterContext getVMServiceClusterContext (Cluster cluster) throws PolicyValidationException, PartitionValidationException { + + if (null == cluster) { + return null; + } + + String autoscalePolicyName = cluster.getAutoscalePolicyName(); + String deploymentPolicyName = cluster.getDeploymentPolicyName(); + + if (log.isDebugEnabled()) { + log.debug("Deployment policy name: " + deploymentPolicyName); + log.debug("Autoscaler policy name: " + autoscalePolicyName); + } + + AutoscalePolicy autoscalePolicy = + PolicyManager.getInstance() + .getAutoscalePolicy(autoscalePolicyName); + DeploymentPolicy deploymentPolicy = + PolicyManager.getInstance() + .getDeploymentPolicy(deploymentPolicyName); + + if (deploymentPolicy == null) { + String msg = "Deployment policy is null: [policy-name] " + deploymentPolicyName; + log.error(msg); + throw new PolicyValidationException(msg); + } + + Partition[] allPartitions = deploymentPolicy.getAllPartitions(); + if (allPartitions == null) { + String msg = + "Partitions are null in deployment policy: [policy-name]: " + + deploymentPolicyName; + log.error(msg); + throw new PolicyValidationException(msg); + } + + CloudControllerClient.getInstance().validateDeploymentPolicy(cluster.getServiceName(), deploymentPolicy); + + Map<String, ClusterLevelNetworkPartitionContext> networkPartitionContextMap = new HashMap<String, ClusterLevelNetworkPartitionContext>(); + + for (PartitionGroup partitionGroup : deploymentPolicy.getPartitionGroups()) { + + String networkPartitionId = partitionGroup.getId(); + ClusterLevelNetworkPartitionContext clusterLevelNetworkPartitionContext = new ClusterLevelNetworkPartitionContext(networkPartitionId, + partitionGroup.getPartitionAlgo(), + partitionGroup.getPartitions()); + + for (Partition partition : partitionGroup.getPartitions()) { + ClusterLevelPartitionContext clusterMonitorPartitionContext = new ClusterLevelPartitionContext(partition); + clusterMonitorPartitionContext.setServiceName(cluster.getServiceName()); + clusterMonitorPartitionContext.setProperties(cluster.getProperties()); + clusterMonitorPartitionContext.setNetworkPartitionId(partitionGroup.getId()); + + for (Member member : cluster.getMembers()) { + String memberId = member.getMemberId(); + if (member.getPartitionId().equalsIgnoreCase(partition.getId())) { + MemberContext memberContext = new MemberContext(); + memberContext.setClusterId(member.getClusterId()); + memberContext.setMemberId(memberId); + memberContext.setInitTime(member.getInitTime()); + memberContext.setPartition(partition); + memberContext.setProperties(convertMemberPropsToMemberContextProps(member.getProperties())); + + if (MemberStatus.Activated.equals(member.getStatus())) { + if (log.isDebugEnabled()) { + String msg = String.format("Active member loaded from topology and added to active member list, %s", member.toString()); + log.debug(msg); + } + clusterMonitorPartitionContext.addActiveMember(memberContext); +// networkPartitionContext.increaseMemberCountOfPartition(partition.getNetworkPartitionId(), 1); +// partitionContext.incrementCurrentActiveMemberCount(1); + + } else if (MemberStatus.Created.equals(member.getStatus()) || MemberStatus.Starting.equals(member.getStatus())) { + if (log.isDebugEnabled()) { + String msg = String.format("Pending member loaded from topology and added to pending member list, %s", member.toString()); + log.debug(msg); + } + clusterMonitorPartitionContext.addPendingMember(memberContext); + +// networkPartitionContext.increaseMemberCountOfPartition(partition.getNetworkPartitionId(), 1); + } else if (MemberStatus.Suspended.equals(member.getStatus())) { +// partitionContext.addFaultyMember(memberId); + } + clusterMonitorPartitionContext.addMemberStatsContext(new MemberStatsContext(memberId)); + if (log.isInfoEnabled()) { + log.info(String.format("Member stat context has been added: [member] %s", memberId)); + } + } + + } + clusterLevelNetworkPartitionContext.addPartitionContext(clusterMonitorPartitionContext); + if (log.isInfoEnabled()) { + log.info(String.format("Partition context has been added: [partition] %s", + clusterMonitorPartitionContext.getPartitionId())); + } + } + + networkPartitionContextMap.put(networkPartitionId, clusterLevelNetworkPartitionContext); + if (log.isInfoEnabled()) { + log.info(String.format("Network partition context has been added: [network partition] %s", + clusterLevelNetworkPartitionContext.getId())); + } + } + + return new VMServiceClusterContext(cluster.getClusterId(), cluster.getServiceName(), autoscalePolicy, + deploymentPolicy, networkPartitionContextMap); + } + + public static VMClusterContext getVMLBClusterContext (Cluster cluster) throws PolicyValidationException { + + // FIXME fix the following code to correctly update + // AutoscalerContext context = AutoscalerContext.getInstance(); + if (null == cluster) { + return null; + } + + String autoscalePolicyName = cluster.getAutoscalePolicyName(); + String deploymentPolicyName = cluster.getDeploymentPolicyName(); + + if (log.isDebugEnabled()) { + log.debug("Deployment policy name: " + deploymentPolicyName); + log.debug("Autoscaler policy name: " + autoscalePolicyName); + } + + AutoscalePolicy autoscalePolicy = + PolicyManager.getInstance() + .getAutoscalePolicy(autoscalePolicyName); + DeploymentPolicy deploymentPolicy = + PolicyManager.getInstance() + .getDeploymentPolicy(deploymentPolicyName); + + if (deploymentPolicy == null) { + String msg = "Deployment Policy is null. Policy name: " + deploymentPolicyName; + log.error(msg); + throw new PolicyValidationException(msg); + } + + String clusterId = cluster.getClusterId(); + + Map<String, ClusterLevelNetworkPartitionContext> networkPartitionContextMap = new HashMap<String, ClusterLevelNetworkPartitionContext>(); + + // partition group = network partition context + for (PartitionGroup partitionGroup : deploymentPolicy.getPartitionGroups()) { + + String networkPartitionId = partitionGroup.getId(); + NetworkPartitionLbHolder networkPartitionLbHolder = + PartitionManager.getInstance() + .getNetworkPartitionLbHolder(networkPartitionId); +// PartitionManager.getInstance() +// .getNetworkPartitionLbHolder(partitionGroup.getPartitionId()); + // FIXME pick a random partition + Partition partition = + partitionGroup.getPartitions()[new Random().nextInt(partitionGroup.getPartitions().length)]; + ClusterLevelPartitionContext clusterMonitorPartitionContext = new ClusterLevelPartitionContext(partition); + clusterMonitorPartitionContext.setServiceName(cluster.getServiceName()); + clusterMonitorPartitionContext.setProperties(cluster.getProperties()); + clusterMonitorPartitionContext.setNetworkPartitionId(networkPartitionId); + clusterMonitorPartitionContext.setMinimumMemberCount(1);//Here it hard codes the minimum value as one for LB cartridge partitions + + ClusterLevelNetworkPartitionContext clusterLevelNetworkPartitionContext = new ClusterLevelNetworkPartitionContext(networkPartitionId, + partitionGroup.getPartitionAlgo(), + partitionGroup.getPartitions()); + for (Member member : cluster.getMembers()) { + String memberId = member.getMemberId(); + if (member.getNetworkPartitionId().equalsIgnoreCase(clusterLevelNetworkPartitionContext.getId())) { + MemberContext memberContext = new MemberContext(); + memberContext.setClusterId(member.getClusterId()); + memberContext.setMemberId(memberId); + memberContext.setPartition(partition); + memberContext.setInitTime(member.getInitTime()); + + if (MemberStatus.Activated.equals(member.getStatus())) { + if (log.isDebugEnabled()) { + String msg = String.format("Active member loaded from topology and added to active member list, %s", member.toString()); + log.debug(msg); + } + clusterMonitorPartitionContext.addActiveMember(memberContext); +// networkPartitionContext.increaseMemberCountOfPartition(partition.getNetworkPartitionId(), 1); +// partitionContext.incrementCurrentActiveMemberCount(1); + } else if (MemberStatus.Created.equals(member.getStatus()) || + MemberStatus.Starting.equals(member.getStatus())) { + if (log.isDebugEnabled()) { + String msg = String.format("Pending member loaded from topology and added to pending member list, %s", member.toString()); + log.debug(msg); + } + clusterMonitorPartitionContext.addPendingMember(memberContext); +// networkPartitionContext.increaseMemberCountOfPartition(partition.getNetworkPartitionId(), 1); + } else if (MemberStatus.Suspended.equals(member.getStatus())) { +// partitionContext.addFaultyMember(memberId); + } + + clusterMonitorPartitionContext.addMemberStatsContext(new MemberStatsContext(memberId)); + if (log.isInfoEnabled()) { + log.info(String.format("Member stat context has been added: [member] %s", memberId)); + } + } + + } + clusterLevelNetworkPartitionContext.addPartitionContext(clusterMonitorPartitionContext); + + // populate lb cluster id in network partition context. + java.util.Properties props = cluster.getProperties(); + + // get service type of load balanced cluster + String loadBalancedServiceType = props.getProperty(org.apache.stratos.messaging.util.Constants.LOAD_BALANCED_SERVICE_TYPE); + + if (props.containsKey(org.apache.stratos.messaging.util.Constants.LOAD_BALANCER_REF)) { + String value = props.getProperty(org.apache.stratos.messaging.util.Constants.LOAD_BALANCER_REF); + + if (value.equals(org.apache.stratos.messaging.util.Constants.DEFAULT_LOAD_BALANCER)) { + networkPartitionLbHolder.setDefaultLbClusterId(clusterId); + + } else if (value.equals(org.apache.stratos.messaging.util.Constants.SERVICE_AWARE_LOAD_BALANCER)) { + String serviceName = cluster.getServiceName(); + // TODO: check if this is correct + networkPartitionLbHolder.addServiceLB(serviceName, clusterId); + + if (loadBalancedServiceType != null && !loadBalancedServiceType.isEmpty()) { + networkPartitionLbHolder.addServiceLB(loadBalancedServiceType, clusterId); + if (log.isDebugEnabled()) { + log.debug("Added cluster id " + clusterId + " as the LB cluster id for service type " + loadBalancedServiceType); + } + } + } + } + + networkPartitionContextMap.put(networkPartitionId, clusterLevelNetworkPartitionContext); + } + + return new VMClusterContext(clusterId, cluster.getServiceName(), autoscalePolicy, + deploymentPolicy, networkPartitionContextMap); + } + + public static KubernetesClusterContext getKubernetesClusterContext (Cluster cluster) throws PolicyValidationException { + + if (null == cluster) { + return null; + } + + String autoscalePolicyName = cluster.getAutoscalePolicyName(); + + AutoscalePolicy autoscalePolicy = + PolicyManager.getInstance() + .getAutoscalePolicy(autoscalePolicyName); + if (log.isDebugEnabled()) { + log.debug("Autoscaling policy name: " + autoscalePolicyName); + } + + AutoscalePolicy policy = PolicyManager.getInstance().getAutoscalePolicy(autoscalePolicyName); + + if (policy == null) { + String msg = String.format("Autoscaling policy is null: [policy-name] %s", autoscalePolicyName); + log.error(msg); + throw new PolicyValidationException(msg); + } + + java.util.Properties properties = cluster.getProperties(); + if(properties == null) { + String message = String.format("Properties not found in kubernetes cluster: [cluster-id] %s", + cluster.getClusterId()); + log.error(message); + throw new RuntimeException(message); + } + String minReplicasProperty = properties.getProperty(StratosConstants.KUBERNETES_MIN_REPLICAS); + int minReplicas = 0; + if (minReplicasProperty != null && !minReplicasProperty.isEmpty()) { + minReplicas = Integer.parseInt(minReplicasProperty); + } + + int maxReplicas = 0; + String maxReplicasProperty = properties.getProperty(StratosConstants.KUBERNETES_MAX_REPLICAS); + if (maxReplicasProperty != null && !maxReplicasProperty.isEmpty()) { + maxReplicas = Integer.parseInt(maxReplicasProperty); + } + + String kubernetesHostClusterID = properties.getProperty(StratosConstants.KUBERNETES_CLUSTER_ID); + KubernetesClusterContext kubernetesClusterCtxt = new KubernetesClusterContext(kubernetesHostClusterID, + cluster.getClusterId(), cluster.getServiceName(), autoscalePolicy, minReplicas, maxReplicas); + + //populate the members after restarting + for (Member member : cluster.getMembers()) { + String memberId = member.getMemberId(); + String clusterId = member.getClusterId(); + MemberContext memberContext = new MemberContext(); + memberContext.setMemberId(memberId); + memberContext.setClusterId(clusterId); + memberContext.setInitTime(member.getInitTime()); + + // if there is at least one member in the topology, that means service has been created already + // this is to avoid calling startContainer() method again + kubernetesClusterCtxt.setServiceClusterCreated(true); + + if (MemberStatus.Activated.equals(member.getStatus())) { + if (log.isDebugEnabled()) { + String msg = String.format("Active member loaded from topology and added to active member list, %s", member.toString()); + log.debug(msg); + } + //dockerClusterMonitor.getKubernetesClusterCtxt().addActiveMember(memberContext); + } else if (MemberStatus.Created.equals(member.getStatus()) + || MemberStatus.Starting.equals(member.getStatus())) { + if (log.isDebugEnabled()) { + String msg = String.format("Pending member loaded from topology and added to pending member list, %s", member.toString()); + log.debug(msg); + } + //dockerClusterMonitor.getKubernetesClusterCtxt().addPendingMember(memberContext); + } + + kubernetesClusterCtxt.addMemberStatsContext(new MemberStatsContext(memberId)); + if (log.isInfoEnabled()) { + log.info(String.format("Member stat context has been added: [member] %s", memberId)); + } + } + + // find lb reference type + if (properties.containsKey(org.apache.stratos.messaging.util.Constants.LOAD_BALANCER_REF)) { + String value = properties.getProperty(Constants.LOAD_BALANCER_REF); + //dockerClusterMonitor.setLbReferenceType(value); + if (log.isDebugEnabled()) { + log.debug("Set the lb reference type: " + value); + } + } + + return kubernetesClusterCtxt; + } + + private static Properties convertMemberPropsToMemberContextProps( + java.util.Properties properties) { + Properties props = new Properties(); + for (Map.Entry<Object, Object> e : properties.entrySet()) { + Property property = new Property(); + property.setName((String) e.getKey()); + property.setValue((String) e.getValue()); + props.addProperties(property); + } + return props; + } +} http://git-wip-us.apache.org/repos/asf/stratos/blob/c20d28c2/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/context/cluster/ClusterInstanceContext.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/context/cluster/ClusterInstanceContext.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/context/cluster/ClusterInstanceContext.java new file mode 100644 index 0000000..1e5ad12 --- /dev/null +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/context/cluster/ClusterInstanceContext.java @@ -0,0 +1,80 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.stratos.autoscaler.context.cluster; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.stratos.autoscaler.context.partition.ClusterLevelPartitionContext; +import org.apache.stratos.messaging.domain.topology.Member; + +import java.util.Map; + +/* + * It holds the runtime data of a VM cluster + */ +public class ClusterInstanceContext { + + private static final Log log = LogFactory.getLog(ClusterInstanceContext.class); + private final String clusterInstanceId; + + // Map<PartitionId, Partition Context> + protected Map<String, ClusterLevelPartitionContext> partitionCtxts; + public ClusterInstanceContext(String clusterInstanceId, String serviceId, + Map<String, ClusterLevelPartitionContext> partitionCtxts) { + + this.clusterInstanceId = clusterInstanceId; + + } + + public Map<String, ClusterLevelPartitionContext> getPartitionCtxts(){ + return partitionCtxts; + } + + public ClusterLevelPartitionContext getNetworkPartitionCtxt(String PartitionId) { + return partitionCtxts.get(PartitionId); + } + + public void setPartitionCtxt(Map<String, ClusterLevelPartitionContext> partitionCtxt) { + this.partitionCtxts = partitionCtxt; + } + + public boolean partitionCtxtAvailable(String partitionId) { + return partitionCtxts.containsKey(partitionId); + } + + public void addPartitionCtxt(ClusterLevelPartitionContext ctxt) { + this.partitionCtxts.put(ctxt.getPartitionId(), ctxt); + } + + public ClusterLevelPartitionContext getPartitionCtxt(String id) { + return this.partitionCtxts.get(id); + } + + public ClusterLevelPartitionContext getPartitionCtxt(Member member) { + log.info("Getting [Partition] " + member.getPartitionId()); + String partitionId = member.getPartitionId(); + if (partitionCtxts.containsKey(partitionId)) { + log.info("Returning partition context, of [partition] " + partitionCtxts.get(partitionId)); + return partitionCtxts.get(partitionId); + } + + return null; + } + +} http://git-wip-us.apache.org/repos/asf/stratos/blob/c20d28c2/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/context/cluster/KubernetesClusterContext.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/context/cluster/KubernetesClusterContext.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/context/cluster/KubernetesClusterContext.java new file mode 100644 index 0000000..43b8db9 --- /dev/null +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/context/cluster/KubernetesClusterContext.java @@ -0,0 +1,761 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.stratos.autoscaler.context.cluster; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Properties; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.commons.configuration.XMLConfiguration; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.stratos.autoscaler.context.member.MemberStatsContext; +import org.apache.stratos.autoscaler.policy.model.AutoscalePolicy; +import org.apache.stratos.autoscaler.policy.model.LoadAverage; +import org.apache.stratos.autoscaler.policy.model.MemoryConsumption; +import org.apache.stratos.autoscaler.policy.model.RequestsInFlight; +import org.apache.stratos.autoscaler.util.ConfUtil; +import org.apache.stratos.cloud.controller.stub.pojo.MemberContext; +import org.apache.stratos.common.constants.StratosConstants; + +/* + * It holds the runtime data of a kubernetes service cluster + */ +public class KubernetesClusterContext extends AbstractClusterContext { + + private static final long serialVersionUID = 808741789615481596L; + private static final Log log = LogFactory.getLog(KubernetesClusterContext.class); + + private String kubernetesClusterId; + private String serviceName; + + private int minReplicas; + private int maxReplicas; + private int currentReplicas; + private float RequiredReplicas; + + private AutoscalePolicy autoscalePolicy; + + // it will tell whether the startContainers() method succeed or not for the 1st time + // we should call startContainers() only once + private boolean isServiceClusterCreated = false; + + // properties + private Properties properties; + + // 15 mints as the default + private long pendingMemberExpiryTime; + // pending members + private List<MemberContext> pendingMembers; + + // active members + private List<MemberContext> activeMembers; + + // 1 day as default + private long obsoltedMemberExpiryTime = 1*24*60*60*1000; + + // members to be terminated + private Map<String, MemberContext> obsoletedMembers; + + // termination pending members, member is added to this when Autoscaler send grace fully shut down event + private List<MemberContext> terminationPendingMembers; + + //Keep statistics come from CEP + private Map<String, MemberStatsContext> memberStatsContexts; + + //Following information will keep events details + private RequestsInFlight requestsInFlight; + private MemoryConsumption memoryConsumption; + private LoadAverage loadAverage; + + //boolean values to keep whether the requests in flight parameters are reset or not + private boolean rifReset = false, averageRifReset = false, + gradientRifReset = false, secondDerivativeRifRest = false; + //boolean values to keep whether the memory consumption parameters are reset or not + private boolean memoryConsumptionReset = false, averageMemoryConsumptionReset = false, + gradientMemoryConsumptionReset = false, secondDerivativeMemoryConsumptionRest = false; + //boolean values to keep whether the load average parameters are reset or not + private boolean loadAverageReset = false, averageLoadAverageReset = false, + gradientLoadAverageReset = false, secondDerivativeLoadAverageRest = false; + + public KubernetesClusterContext(String kubernetesClusterId, String clusterId, String serviceId, AutoscalePolicy autoscalePolicy, + int minCount, int maxCount) { + + super(clusterId, serviceId); + this.kubernetesClusterId = kubernetesClusterId; + this.minReplicas = minCount; + this.maxReplicas = maxCount; + this.pendingMembers = new ArrayList<MemberContext>(); + this.activeMembers = new ArrayList<MemberContext>(); + this.terminationPendingMembers = new ArrayList<MemberContext>(); + this.obsoletedMembers = new ConcurrentHashMap<String, MemberContext>(); + this.memberStatsContexts = new ConcurrentHashMap<String, MemberStatsContext>(); + this.requestsInFlight = new RequestsInFlight(); + this.loadAverage = new LoadAverage(); + this.memoryConsumption = new MemoryConsumption(); + this.autoscalePolicy = autoscalePolicy; + + // check if a different value has been set for expiryTime + XMLConfiguration conf = ConfUtil.getInstance(null).getConfiguration(); + pendingMemberExpiryTime = conf.getLong(StratosConstants.PENDING_CONTAINER_MEMBER_EXPIRY_TIMEOUT, 300000); + obsoltedMemberExpiryTime = conf.getLong(StratosConstants.OBSOLETED_CONTAINER_MEMBER_EXPIRY_TIMEOUT, 3600000); + if (log.isDebugEnabled()) { + log.debug("Member expiry time is set to: " + pendingMemberExpiryTime); + log.debug("Member obsoleted expiry time is set to: " + obsoltedMemberExpiryTime); + } + + Thread th = new Thread(new PendingMemberWatcher(this)); + th.start(); + Thread th2 = new Thread(new ObsoletedMemberWatcher(this)); + th2.start(); + } + + public String getKubernetesClusterID() { + return kubernetesClusterId; + } + + public void setKubernetesClusterID(String kubernetesClusterId) { + this.kubernetesClusterId = kubernetesClusterId; + } + + public List<MemberContext> getPendingMembers() { + return pendingMembers; + } + + public void setPendingMembers(List<MemberContext> pendingMembers) { + this.pendingMembers = pendingMembers; + } + + public int getActiveMemberCount() { + return activeMembers.size(); + } + + public void setActiveMembers(List<MemberContext> activeMembers) { + this.activeMembers = activeMembers; + } + + public int getMinReplicas() { + return minReplicas; + } + + public void setMinReplicas(int minReplicas) { + this.minReplicas = minReplicas; + } + + public int getMaxReplicas() { + return maxReplicas; + } + + public void setMaxReplicas(int maxReplicas) { + this.maxReplicas = maxReplicas; + } + + public int getCurrentReplicas() { + return currentReplicas; + } + + public void setCurrentReplicas(int currentReplicas) { + this.currentReplicas = currentReplicas; + } + + public void addPendingMember(MemberContext ctxt) { + this.pendingMembers.add(ctxt); + } + + public boolean removePendingMember(String id) { + if (id == null) { + return false; + } + for (Iterator<MemberContext> iterator = pendingMembers.iterator(); iterator.hasNext(); ) { + MemberContext pendingMember = (MemberContext) iterator.next(); + if (id.equals(pendingMember.getMemberId())) { + iterator.remove(); + return true; + } + + } + + return false; + } + + public void movePendingMemberToActiveMembers(String memberId) { + if (memberId == null) { + return; + } + Iterator<MemberContext> iterator = pendingMembers.listIterator(); + while (iterator.hasNext()) { + MemberContext pendingMember = iterator.next(); + if (pendingMember == null) { + iterator.remove(); + continue; + } + if (memberId.equals(pendingMember.getMemberId())) { + // member is activated + // remove from pending list + iterator.remove(); + // add to the activated list + this.activeMembers.add(pendingMember); + if (log.isDebugEnabled()) { + log.debug(String.format( + "Pending member is removed and added to the " + + "activated member list. [Member Id] %s", + memberId)); + } + break; + } + } + } + + public void addActiveMember(MemberContext ctxt) { + this.activeMembers.add(ctxt); + } + + public void removeActiveMember(MemberContext ctxt) { + this.activeMembers.remove(ctxt); + } + + public long getPendingMemberExpiryTime() { + return pendingMemberExpiryTime; + } + + public void setPendingMemberExpiryTime(long pendingMemberExpiryTime) { + this.pendingMemberExpiryTime = pendingMemberExpiryTime; + } + + public Map<String, MemberStatsContext> getMemberStatsContexts() { + return memberStatsContexts; + } + + public MemberStatsContext getMemberStatsContext(String memberId) { + return memberStatsContexts.get(memberId); + } + + public void addMemberStatsContext(MemberStatsContext ctxt) { + this.memberStatsContexts.put(ctxt.getMemberId(), ctxt); + } + + public void removeMemberStatsContext(String memberId) { + this.memberStatsContexts.remove(memberId); + } + + public Properties getProperties() { + return properties; + } + + public void setProperties(Properties properties) { + this.properties = properties; + } + + public String getServiceName() { + return serviceName; + } + + public void setServiceName(String serviceName) { + this.serviceName = serviceName; + } + + public List<MemberContext> getActiveMembers() { + return activeMembers; + } + + public boolean removeActiveMemberById(String memberId) { + boolean removeActiveMember = false; + synchronized (activeMembers) { + Iterator<MemberContext> iterator = activeMembers.listIterator(); + while (iterator.hasNext()) { + MemberContext memberContext = iterator.next(); + if (memberId.equals(memberContext.getMemberId())) { + iterator.remove(); + removeActiveMember = true; + + break; + } + } + } + return removeActiveMember; + } + + public boolean activeMemberExist(String memberId) { + + for (MemberContext memberContext : activeMembers) { + if (memberId.equals(memberContext.getMemberId())) { + return true; + } + } + return false; + } + + public AutoscalePolicy getAutoscalePolicy() { + return autoscalePolicy; + } + + public float getRequiredReplicas() { + return RequiredReplicas; + } + + public void setRequiredReplicas(float requiredReplicas) { + RequiredReplicas = requiredReplicas; + } + + /** + * Check the member lists for the provided member ID and move the member to the obsolete list + * + * @param memberId The member ID of the member to search + */ + public void moveMemberToObsoleteList(String memberId) { + if (memberId == null) { + return; + } + + // check active member list + Iterator<MemberContext> activeMemberIterator = activeMembers.listIterator(); + MemberContext removedMember = this.removeMemberFrom(activeMemberIterator, memberId); + if (removedMember != null) { + this.addObsoleteMember(removedMember); + removedMember.setObsoleteInitTime(System.currentTimeMillis()); + if (log.isDebugEnabled()) { + log.debug(String.format("Active member is removed and added to the " + + "obsolete member list. [Member Id] %s", memberId)); + } + + return; + } + + // check pending member list + Iterator<MemberContext> pendingMemberIterator = pendingMembers.listIterator(); + removedMember = this.removeMemberFrom(pendingMemberIterator, memberId); + if (removedMember != null) { + this.addObsoleteMember(removedMember); + removedMember.setObsoleteInitTime(System.currentTimeMillis()); + if (log.isDebugEnabled()) { + log.debug(String.format("Pending member is removed and added to the " + + "obsolete member list. [Member Id] %s", memberId)); + } + + return; + } + + // check termination pending member list + Iterator<MemberContext> terminationPendingMembersIterator = terminationPendingMembers.listIterator(); + removedMember = this.removeMemberFrom(terminationPendingMembersIterator, memberId); + if (removedMember != null) { + this.addObsoleteMember(removedMember); + removedMember.setObsoleteInitTime(System.currentTimeMillis()); + if (log.isDebugEnabled()) { + log.debug(String.format("Termination Pending member is removed and added to the " + + "obsolete member list. [Member Id] %s", memberId)); + } + } + } + + /** + * Removes the {@link org.apache.stratos.cloud.controller.stub.pojo.MemberContext} object mapping + * to the specified member id from the specified MemberContext collection + * + * @param iterator The {@link java.util.Iterator} for the collection containing {@link org.apache.stratos.cloud.controller.stub.pojo.MemberContext} + * objects + * @param memberId Member Id {@link String} for the {@link org.apache.stratos.cloud.controller.stub.pojo.MemberContext} + * to be removed + * @return {@link org.apache.stratos.cloud.controller.stub.pojo.MemberContext} object if + * object found and removed, null if otherwise. + */ + private MemberContext removeMemberFrom(Iterator<MemberContext> iterator, String memberId) { + while (iterator.hasNext()) { + MemberContext activeMember = iterator.next(); + if (activeMember == null) { + iterator.remove(); + continue; + } + if (memberId.equals(activeMember.getMemberId())) { + iterator.remove(); + return activeMember; + } + } + + return null; + } + + private class PendingMemberWatcher implements Runnable { + private KubernetesClusterContext ctxt; + + public PendingMemberWatcher(KubernetesClusterContext ctxt) { + this.ctxt = ctxt; + } + + @Override + public void run() { + + while (true) { + long expiryTime = ctxt.getPendingMemberExpiryTime(); + List<MemberContext> pendingMembers = ctxt.getPendingMembers(); + + synchronized (pendingMembers) { + Iterator<MemberContext> iterator = pendingMembers + .listIterator(); + while (iterator.hasNext()) { + MemberContext pendingMember = iterator.next(); + + if (pendingMember == null) { + continue; + } + long pendingTime = System.currentTimeMillis() + - pendingMember.getInitTime(); + if (pendingTime >= expiryTime) { + iterator.remove(); + log.info("Pending state of member: " + pendingMember.getMemberId() + + " is expired. " + "Adding as an obsoleted member."); + ctxt.addObsoleteMember(pendingMember); + } + } + } + try { + // TODO find a constant + Thread.sleep(15000); + } catch (InterruptedException ignore) { + } + } + } + + } + + private class ObsoletedMemberWatcher implements Runnable { + private KubernetesClusterContext ctxt; + + public ObsoletedMemberWatcher(KubernetesClusterContext ctxt) { + this.ctxt = ctxt; + } + + @Override + public void run() { + while (true) { + + long obsoltedMemberExpiryTime = ctxt.getObsoltedMemberExpiryTime(); + Map<String, MemberContext> obsoletedMembers = ctxt.getObsoletedMembers(); + Iterator<Entry<String, MemberContext>> iterator = obsoletedMembers.entrySet().iterator(); + + while (iterator.hasNext()) { + Map.Entry<String, MemberContext> pairs = iterator.next(); + MemberContext obsoleteMember = (MemberContext) pairs.getValue(); + if (obsoleteMember == null) { + continue; + } + long obsoleteTime = System.currentTimeMillis() - obsoleteMember.getInitTime(); + if (obsoleteTime >= obsoltedMemberExpiryTime) { + iterator.remove(); + log.info("Obsolete state of member: " + obsoleteMember.getMemberId() + + " is expired. " + "Removing from obsolete member list"); + } + } + try { + // TODO find a constant + Thread.sleep(15000); + } catch (InterruptedException ignore) { + } + } + } + } + + public float getAverageRequestsInFlight() { + return requestsInFlight.getAverage(); + } + + public void setAverageRequestsInFlight(float averageRequestsInFlight) { + requestsInFlight.setAverage(averageRequestsInFlight); + averageRifReset = true; + if (secondDerivativeRifRest && gradientRifReset) { + rifReset = true; + if (log.isDebugEnabled()) { + log.debug(String.format("Requests in flights stats are reset, " + + "ready to do scale check [kub cluster] %s", this.kubernetesClusterId)); + } + } + } + + public float getRequestsInFlightSecondDerivative() { + return requestsInFlight.getSecondDerivative(); + } + + public void setRequestsInFlightSecondDerivative( + float requestsInFlightSecondDerivative) { + requestsInFlight.setSecondDerivative(requestsInFlightSecondDerivative); + secondDerivativeRifRest = true; + if (averageRifReset && gradientRifReset) { + rifReset = true; + if (log.isDebugEnabled()) { + log.debug(String.format("Requests in flights stats are reset, ready to do scale check " + + "[kub cluster] %s", this.kubernetesClusterId)); + } + } + } + + public float getRequestsInFlightGradient() { + return requestsInFlight.getGradient(); + } + + public void setRequestsInFlightGradient(float requestsInFlightGradient) { + requestsInFlight.setGradient(requestsInFlightGradient); + gradientRifReset = true; + if (secondDerivativeRifRest && averageRifReset) { + rifReset = true; + if (log.isDebugEnabled()) { + log.debug(String.format("Requests in flights stats are reset, ready to do scale check " + + "[kub cluster] %s", this.kubernetesClusterId)); + } + } + } + + public boolean isRifReset() { + return rifReset; + } + + public void setRifReset(boolean rifReset) { + this.rifReset = rifReset; + this.averageRifReset = rifReset; + this.gradientRifReset = rifReset; + this.secondDerivativeRifRest = rifReset; + } + + public float getAverageMemoryConsumption() { + return memoryConsumption.getAverage(); + } + + public void setAverageMemoryConsumption(float averageMemoryConsumption) { + memoryConsumption.setAverage(averageMemoryConsumption); + averageMemoryConsumptionReset = true; + if (secondDerivativeMemoryConsumptionRest + && gradientMemoryConsumptionReset) { + memoryConsumptionReset = true; + if (log.isDebugEnabled()) { + log.debug(String.format("Memory consumption stats are reset, ready to do scale check " + + "[kub cluster] %s", this.kubernetesClusterId)); + } + } + } + + public float getMemoryConsumptionSecondDerivative() { + return memoryConsumption.getSecondDerivative(); + } + + public void setMemoryConsumptionSecondDerivative( + float memoryConsumptionSecondDerivative) { + memoryConsumption + .setSecondDerivative(memoryConsumptionSecondDerivative); + secondDerivativeMemoryConsumptionRest = true; + if (averageMemoryConsumptionReset && gradientMemoryConsumptionReset) { + memoryConsumptionReset = true; + if (log.isDebugEnabled()) { + log.debug(String.format("Memory consumption stats are reset, ready to do scale check " + + "[kub cluster] %s", this.kubernetesClusterId)); + } + } + } + + public float getMemoryConsumptionGradient() { + return memoryConsumption.getGradient(); + } + + public void setMemoryConsumptionGradient(float memoryConsumptionGradient) { + memoryConsumption.setGradient(memoryConsumptionGradient); + gradientMemoryConsumptionReset = true; + if (secondDerivativeMemoryConsumptionRest + && averageMemoryConsumptionReset) { + memoryConsumptionReset = true; + if (log.isDebugEnabled()) { + log.debug(String.format("Memory consumption stats are reset, ready to do scale check " + + "[kub cluster] %s", this.kubernetesClusterId)); + } + } + } + + public boolean isMemoryConsumptionReset() { + return memoryConsumptionReset; + } + + public void setMemoryConsumptionReset(boolean memoryConsumptionReset) { + this.memoryConsumptionReset = memoryConsumptionReset; + this.averageMemoryConsumptionReset = memoryConsumptionReset; + this.gradientMemoryConsumptionReset = memoryConsumptionReset; + this.secondDerivativeMemoryConsumptionRest = memoryConsumptionReset; + } + + + public float getAverageLoadAverage() { + return loadAverage.getAverage(); + } + + public void setAverageLoadAverage(float averageLoadAverage) { + loadAverage.setAverage(averageLoadAverage); + averageLoadAverageReset = true; + if (secondDerivativeLoadAverageRest && gradientLoadAverageReset) { + loadAverageReset = true; + if (log.isDebugEnabled()) { + log.debug(String.format("Load average stats are reset, ready to do scale check " + + "[kub cluster] %s", this.kubernetesClusterId)); + } + } + } + + public float getLoadAverageSecondDerivative() { + return loadAverage.getSecondDerivative(); + } + + public void setLoadAverageSecondDerivative(float loadAverageSecondDerivative) { + loadAverage.setSecondDerivative(loadAverageSecondDerivative); + secondDerivativeLoadAverageRest = true; + if (averageLoadAverageReset && gradientLoadAverageReset) { + loadAverageReset = true; + if (log.isDebugEnabled()) { + log.debug(String.format("Load average stats are reset, ready to do scale check " + + "[kub cluster] %s", this.kubernetesClusterId)); + } + } + } + + public float getLoadAverageGradient() { + return loadAverage.getGradient(); + } + + public void setLoadAverageGradient(float loadAverageGradient) { + loadAverage.setGradient(loadAverageGradient); + gradientLoadAverageReset = true; + if (secondDerivativeLoadAverageRest && averageLoadAverageReset) { + loadAverageReset = true; + if (log.isDebugEnabled()) { + log.debug(String.format("Load average stats are reset, ready to do scale check " + + "[kub cluster] %s", this.kubernetesClusterId)); + } + } + } + + public boolean isLoadAverageReset() { + return loadAverageReset; + } + + public void setLoadAverageReset(boolean loadAverageReset) { + this.loadAverageReset = loadAverageReset; + this.averageLoadAverageReset = loadAverageReset; + this.gradientLoadAverageReset = loadAverageReset; + this.secondDerivativeLoadAverageRest = loadAverageReset; + } + + public void moveActiveMemberToTerminationPendingMembers(String memberId) { + if (memberId == null) { + return; + } + Iterator<MemberContext> iterator = activeMembers.listIterator(); + while ( iterator.hasNext()) { + MemberContext activeMember = iterator.next(); + if(activeMember == null) { + iterator.remove(); + continue; + } + if(memberId.equals(activeMember.getMemberId())){ + // member is activated + // remove from pending list + iterator.remove(); + // add to the activated list + this.terminationPendingMembers.add(activeMember); + if (log.isDebugEnabled()) { + log.debug(String.format("Active member is removed and added to the " + + "termination pending member list. [Member Id] %s", memberId)); + } + break; + } + } + } + + public boolean removeTerminationPendingMember(String memberId) { + boolean terminationPendingMemberAvailable = false; + for (MemberContext memberContext: terminationPendingMembers){ + if(memberContext.getMemberId().equals(memberId)){ + terminationPendingMemberAvailable = true; + terminationPendingMembers.remove(memberContext); + break; + } + } + return terminationPendingMemberAvailable; + } + + public long getObsoltedMemberExpiryTime() { + return obsoltedMemberExpiryTime; + } + + public void setObsoltedMemberExpiryTime(long obsoltedMemberExpiryTime) { + this.obsoltedMemberExpiryTime = obsoltedMemberExpiryTime; + } + + public void addObsoleteMember(MemberContext ctxt) { + this.obsoletedMembers.put(ctxt.getMemberId(), ctxt); + } + + public boolean removeObsoleteMember(String memberId) { + if(this.obsoletedMembers.remove(memberId) == null) { + return false; + } + return true; + } + + public Map<String, MemberContext> getObsoletedMembers() { + return obsoletedMembers; + } + + public void setObsoletedMembers(Map<String, MemberContext> obsoletedMembers) { + this.obsoletedMembers = obsoletedMembers; + } + + public MemberStatsContext getPartitionCtxt(String id) { + return this.memberStatsContexts.get(id); + } + + public List<MemberContext> getTerminationPendingMembers() { + return terminationPendingMembers; + } + + public void setTerminationPendingMembers(List<MemberContext> terminationPendingMembers) { + this.terminationPendingMembers = terminationPendingMembers; + } + + public int getTotalMemberCount() { + return activeMembers.size() + pendingMembers.size() + terminationPendingMembers.size(); + } + + public int getNonTerminatedMemberCount() { + return activeMembers.size() + pendingMembers.size() + terminationPendingMembers.size(); + } + + public String getClusterId() { + return clusterId; + } + + public void setClusterId(String clusterId) { + this.clusterId = clusterId; + } + + public boolean isServiceClusterCreated() { + return isServiceClusterCreated; + } + + public void setServiceClusterCreated(boolean isServiceClusterCreated) { + this.isServiceClusterCreated = isServiceClusterCreated; + } +} http://git-wip-us.apache.org/repos/asf/stratos/blob/c20d28c2/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/context/cluster/VMClusterContext.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/context/cluster/VMClusterContext.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/context/cluster/VMClusterContext.java new file mode 100644 index 0000000..f5c3baa --- /dev/null +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/context/cluster/VMClusterContext.java @@ -0,0 +1,103 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.stratos.autoscaler.context.cluster; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.stratos.autoscaler.context.partition.network.ClusterLevelNetworkPartitionContext; +import org.apache.stratos.autoscaler.policy.model.*; +import org.apache.stratos.messaging.domain.topology.Member; + +import java.util.*; + +/* + * It holds the runtime data of a VM cluster + */ +public class VMClusterContext extends AbstractClusterContext { + + private static final Log log = LogFactory.getLog(VMClusterContext.class); + + // Map<NetworkpartitionId, Network Partition Context> + protected Map<String, ClusterLevelNetworkPartitionContext> networkPartitionCtxts; + protected DeploymentPolicy deploymentPolicy; + protected AutoscalePolicy autoscalePolicy; + + public VMClusterContext(String clusterId, String serviceId, AutoscalePolicy autoscalePolicy, DeploymentPolicy deploymentPolicy, + Map<String, ClusterLevelNetworkPartitionContext> networkPartitionCtxts) { + + super(clusterId, serviceId); + this.deploymentPolicy = deploymentPolicy; + this.networkPartitionCtxts = networkPartitionCtxts; + this.autoscalePolicy = autoscalePolicy; + + } + + public Map<String, ClusterLevelNetworkPartitionContext> getNetworkPartitionCtxts(){ + return networkPartitionCtxts; + } + + public DeploymentPolicy getDeploymentPolicy() { + return deploymentPolicy; + } + + public void setDeploymentPolicy(DeploymentPolicy deploymentPolicy) { + this.deploymentPolicy = deploymentPolicy; + } + + public AutoscalePolicy getAutoscalePolicy() { + return autoscalePolicy; + } + + public void setAutoscalePolicy(AutoscalePolicy autoscalePolicy) { + this.autoscalePolicy = autoscalePolicy; + } + + public ClusterLevelNetworkPartitionContext getNetworkPartitionCtxt(String networkPartitionId) { + return networkPartitionCtxts.get(networkPartitionId); + } + + public void setPartitionCtxt(Map<String, ClusterLevelNetworkPartitionContext> partitionCtxt) { + this.networkPartitionCtxts = partitionCtxt; + } + + public boolean partitionCtxtAvailable(String partitionId) { + return networkPartitionCtxts.containsKey(partitionId); + } + + public void addNetworkPartitionCtxt(ClusterLevelNetworkPartitionContext ctxt) { + this.networkPartitionCtxts.put(ctxt.getId(), ctxt); + } + + public ClusterLevelNetworkPartitionContext getPartitionCtxt(String id) { + return this.networkPartitionCtxts.get(id); + } + + public ClusterLevelNetworkPartitionContext getNetworkPartitionCtxt(Member member) { + log.info("***** getNetworkPartitionCtxt " + member.getNetworkPartitionId()); + String networkPartitionId = member.getNetworkPartitionId(); + if (networkPartitionCtxts.containsKey(networkPartitionId)) { + log.info("returnnig network partition context " + networkPartitionCtxts.get(networkPartitionId)); + return networkPartitionCtxts.get(networkPartitionId); + } + + log.info("returning null getNetworkPartitionCtxt"); + return null; + } + +} http://git-wip-us.apache.org/repos/asf/stratos/blob/c20d28c2/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/context/cluster/VMServiceClusterContext.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/context/cluster/VMServiceClusterContext.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/context/cluster/VMServiceClusterContext.java new file mode 100644 index 0000000..69720c4 --- /dev/null +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/context/cluster/VMServiceClusterContext.java @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.stratos.autoscaler.context.cluster; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.stratos.autoscaler.context.partition.network.ClusterLevelNetworkPartitionContext; +import org.apache.stratos.autoscaler.policy.model.AutoscalePolicy; +import org.apache.stratos.autoscaler.policy.model.DeploymentPolicy; + +import java.util.Map; + +/* + * It holds the runtime data of a VM service cluster + */ +public class VMServiceClusterContext extends VMClusterContext { + + private static final Log log = LogFactory.getLog(VMServiceClusterContext.class); + + protected AutoscalePolicy autoscalePolicy; + + public VMServiceClusterContext(String clusterId, String serviceId, AutoscalePolicy autoscalePolicy, DeploymentPolicy deploymentPolicy, + Map<String, ClusterLevelNetworkPartitionContext> networkPartitionCtxts) { + + super(clusterId, serviceId, autoscalePolicy, deploymentPolicy, networkPartitionCtxts); + this.autoscalePolicy = autoscalePolicy; + + } + + public AutoscalePolicy getAutoscalePolicy() { + return autoscalePolicy; + } + + public void setAutoscalePolicy(AutoscalePolicy autoscalePolicy) { + this.autoscalePolicy = autoscalePolicy; + } + + +} http://git-wip-us.apache.org/repos/asf/stratos/blob/c20d28c2/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/context/member/MemberStatsContext.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/context/member/MemberStatsContext.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/context/member/MemberStatsContext.java new file mode 100644 index 0000000..9999770 --- /dev/null +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/context/member/MemberStatsContext.java @@ -0,0 +1,112 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.stratos.autoscaler.context.member; + +import org.apache.stratos.autoscaler.policy.model.LoadAverage; +import org.apache.stratos.autoscaler.policy.model.MemoryConsumption; + +/** + * This class will keep additional parameters such as load average and memory consumption + */ + +public class MemberStatsContext { + private LoadAverage loadAverage; + private MemoryConsumption memoryConsumption; + private String memberId; + private String instanceId; + + public MemberStatsContext(String memberId) { + this.memberId = memberId; + memoryConsumption = new MemoryConsumption(); + loadAverage = new LoadAverage(); + } + + public String getMemberId() { + return memberId; + } + + public void setMemberId(String memberId) { + this.memberId = memberId; + } + + public LoadAverage getLoadAverage() { + return loadAverage; + } + + public MemoryConsumption getMemoryConsumption() { + return memoryConsumption; + } + + public void setAverageLoadAverage(float value) { + loadAverage.setAverage(value); + } + + public void setAverageMemoryConsumption(float value) { + memoryConsumption.setAverage(value); + } + + public void setGradientOfLoadAverage(float value) { + loadAverage.setGradient(value); + } + + public void setGradientOfMemoryConsumption(float value) { + memoryConsumption.setGradient(value); + } + + public void setSecondDerivativeOfLoadAverage(float value) { + loadAverage.setSecondDerivative(value); + } + + public void setSecondDerivativeOfMemoryConsumption(float value) { + memoryConsumption.setSecondDerivative(value); + } + + public float getAverageLoadAverage() { + return loadAverage.getAverage(); + } + + public float getAverageMemoryConsumption() { + return memoryConsumption.getAverage(); + } + + public float getGradientOfLoadAverage() { + return loadAverage.getGradient(); + } + + public float getGradientOfMemoryConsumption() { + return memoryConsumption.getGradient(); + } + + public float getSecondDerivativeOfLoadAverage() { + return loadAverage.getSecondDerivative(); + } + + public float getSecondDerivativeOfMemoryConsumption() { + return memoryConsumption.getSecondDerivative(); + } + + public String getInstanceId() { + return instanceId; + } + + public void setInstanceId(String instanceId) { + this.instanceId = instanceId; + } +}
