/***************************************************************************
* Copyright (c) 2014-2015 VMware, Inc. All Rights Reserved.
* Licensed 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 com.vmware.bdd.manager;
import com.vmware.bdd.apitypes.ClusterStatus;
import com.vmware.bdd.entity.NodeEntity;
import com.vmware.bdd.manager.intf.IClusterEntityManager;
import com.vmware.bdd.service.job.JobConstants;
import com.vmware.bdd.utils.CommonUtil;
import com.vmware.bdd.utils.ValidationUtils;
import org.apache.log4j.Logger;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.JobParametersBuilder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/**
* Created by qjin on 11/14/14.
*/
public class ShrinkManager {
private static final Logger logger = Logger.getLogger(ShrinkManager.class);
private IClusterEntityManager clusterEntityMgr;
private JobManager jobManager;
public long shrinkNodeGroup(String clusterName, String nodeGroupName, int newInstanceNum) throws Exception {
ValidationUtils.validateVersion(clusterEntityMgr, clusterName);
ClusterStatus originalStatus =
clusterEntityMgr.findByName(clusterName).getStatus();
logger.info("Before shrink, cluster status is:" + originalStatus);
List<JobParameters> jobParametersList = buildJobParameters(clusterName, nodeGroupName, newInstanceNum);
if (jobParametersList.size() == 0) {
throw ShrinkException.NO_NEED_TO_SHRINK();
}
//launch sub job to shrink nodegroup by processing node one by one
try {
logger.info("set cluster to maintenace");
clusterEntityMgr.updateClusterStatus(clusterName,
ClusterStatus.MAINTENANCE);
return jobManager.runSubJobForNodes(JobConstants.SHRINK_CLUSTER_JOB_NAME,
jobParametersList, clusterName, originalStatus,
ClusterStatus.ERROR);
} catch (Throwable t) {
logger.error("Failed to shrink cluster " + clusterName, t);
clusterEntityMgr.updateClusterStatus(clusterName, originalStatus);
throw ShrinkException.SHRINK_NODE_GROUP_FAILED(t, clusterName, t.getMessage());
}
}
protected List<JobParameters> buildJobParameters(String clusterName, String nodeGroupName, int newInstanceNum) {
List<NodeEntity> nodes =
clusterEntityMgr.findAllNodes(clusterName, nodeGroupName);
List<JobParameters> jobParametersList = new ArrayList<JobParameters>();
JobParametersBuilder parametersBuilder = new JobParametersBuilder();
for (NodeEntity nodeEntity : nodes) {
if (nodeEntity.isObsoleteNode()) {
logger.info("Ingore node "
+ nodeEntity.getVmName()
+ ", for it violate VM name convention "
+ "or exceed defined group instance number. ");
continue;
}
String nodeName = nodeEntity.getVmName();
long index = CommonUtil.getVmIndex(nodeName);
if (index >= newInstanceNum) {
logger.info("Trying to add " + nodeName + " in " + nodeEntity.getStatus() + " status to VMDeleteList");
JobParameters nodeParameters =
parametersBuilder
.addString(JobConstants.SUB_JOB_NODE_NAME, nodeName)
.addString(JobConstants.GROUP_NAME_JOB_PARAM, nodeGroupName)
.addString(JobConstants.CLUSTER_NAME_JOB_PARAM,clusterName)
.addString(JobConstants.TARGET_NAME_JOB_PARAM, nodeName)
.toJobParameters();
jobParametersList.add(nodeParameters);
} else {
logger.info(nodeName + " doesn't need to be delete. ");
continue;
}
}
//sort in decreasing way
Comparator<JobParameters> shrinkJobComparator = new Comparator<JobParameters>() {
@Override
public int compare(JobParameters job1, JobParameters job2) {
long index1 = CommonUtil.getVmIndex(job1.getString(JobConstants.SUB_JOB_NODE_NAME));
long index2 = CommonUtil.getVmIndex(job2.getString(JobConstants.SUB_JOB_NODE_NAME));
if (index1 == index2) {
return 0;
} else if (index1 < index2) {
return 1;
} else {
return -1;
}
}
};
Collections.sort(jobParametersList, shrinkJobComparator);
return jobParametersList;
}
/**
* @return the clusterEntityMgr
*/
public IClusterEntityManager getClusterEntityMgr() {
return clusterEntityMgr;
}
/**
* @param clusterEntityMgr
* the clusterEntityMgr to set
*/
public void setClusterEntityMgr(IClusterEntityManager clusterEntityMgr) {
this.clusterEntityMgr = clusterEntityMgr;
}
/**
* @return the jobManager
*/
public JobManager getJobManager() {
return jobManager;
}
/**
* @param jobManager
* the jobManager to set
*/
public void setJobManager(JobManager jobManager) {
this.jobManager = jobManager;
}
}