/*
* Scale Control Service
* File: ScaleControlService
* Version: 1.0.0
* Date: 2011-06-09
* Copyright 2011 ISCAS. All Rights Reserved
*/
package com.appspace.zmaster.service;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;
import org.apache.log4j.Logger;
import org.internetware.icloud.portal.background.TestBed;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import com.appspace.common.service.LocalService;
import com.appspace.common.service.impl.LifecycleException;
import com.appspace.zmaster.fabric.PlatformFabric;
/*
* @author Hai He(hehai09@otcaix.iscas.cn)
*/
public class ScaleControlService extends LocalService{
private TestBed testbed;
private PlatformFabric platform;
private static Logger LOG = Logger.getLogger(ScaleControlService.class);
private int idleVM;
private int totalVM;
private ArrayList<String> idleList;
final int MIN_VM_NUMBER = 3;
final int VM_OP_INTERVAL = 10000;
@Override
public String getName() {
return "Scale Control Service";
}
@Override
public String getServiceId() {
return "scale_control_service";
}
@Override
public void init() throws LifecycleException {
super.init();
testbed = new TestBed();
platform = PlatformFabric.getInstance();
LOG.info("Success to Initialize Service --- " + getName());
}
@Override
public void start() throws LifecycleException {
ScaleThread sc = new ScaleThread("Scale Thread");
sc.start();
LOG.info("STOP Success to Start Service --- " + getName());
}
class ScaleThread extends Thread {
public ScaleThread(String name) {
super(name);
}
public void run() {
while (true) {
checkStatus();
String label = null;
LOG.info("idle vm number is " + idleVM);
if (idleVM < MIN_VM_NUMBER && idleVM != -1) {
int upNum = MIN_VM_NUMBER - idleVM;
String imgList = testbed.GetCustomizedImgList("28");
JSONParser parser = new JSONParser();
try {
JSONArray array = (JSONArray) parser.parse(imgList);
Iterator iter = array.iterator();
LOG.info("total up number is " + upNum);
while (iter.hasNext()) {
JSONObject obj = (JSONObject) parser.parse((String) iter.next());
String id = obj.get("id").toString();
String ip = obj.get("ip").toString();
String status = obj.get("status").toString();
String tpl = obj.get("tpl").toString();
/* String name = obj.get("name").toString();
String nodeIp = obj.get("nodeIp").toString();
String gnome = obj.get("gnome").toString();
String customized = obj.get("customized").toString();
String mem = obj.get("mem").toString();
String cpu = obj.get("cpu").toString();
String disk = obj.get("disk").toString();
String info = obj.get("info").toString(); */
if (upNum == 0) {
break;
}
if (status.equals("0") && tpl.equals("appspace")) {
String result = testbed.BootImg("28", id);
if (result.equals("Successful")) {
upNum--;
LOG.info("start a vm that already exist, ip is " + ip);
}
}
/*testbed.BootImg("28", id);
testbed.ShutdownImg("28", id);
testbed.Customize("28", "7", "appspace", "2", "512", "256", "1", "0");*/
}
} catch (Exception e) {
e.printStackTrace();
}
LOG.info("new vm number is " + upNum);
for (int j = 0; j < upNum; j++) {
try {
label = testbed.Customize("28", "7", "test", "2", "128", "256", "1", "0");
} catch (Exception e) {
e.printStackTrace();
}
LOG.info("start a new vm, ip is " + label);
}
upNum = MIN_VM_NUMBER - idleVM;
int wait = 0;
int expect = totalVM + upNum;
while (wait < 2) {
try {
Thread.sleep(VM_OP_INTERVAL);
} catch (InterruptedException e) {
LOG.info("time exception");
}
wait++;
String[] servers = platform.findServerNames();
LOG.info("scale up checking, now " + servers.length + " expect " + expect);
if (servers.length == expect) {
LOG.info("total vm number is " + servers.length);
break;
}
}
} else if (idleVM > MIN_VM_NUMBER && idleVM != -1) {
int downNum = idleVM - MIN_VM_NUMBER;
LOG.info("downNum = " + downNum);
int i = 0;
while (i < downNum) {
int index = idleList.size() - 1;
String toShut = idleList.get(index);
idleList.remove(index);
try {
String result = testbed.ShutdownImg("28", toShut);
if (result.equals("Successful")) {
i++;
}
} catch (Exception e) {
e.printStackTrace();
}
LOG.info("close a vm, ip is " + toShut);
}
int wait = 0;
int expect = totalVM - downNum;
while (wait < 2) {
LOG.info("scale down checking ...");
try {
Thread.sleep(VM_OP_INTERVAL);
} catch (InterruptedException e) {
LOG.info("time exception");
}
wait++;
String[] servers = platform.findServerNames();
LOG.info("scale down checking, now " + servers.length + " expect " + expect);
if (servers.length == totalVM - downNum) {
LOG.info("total vm number is " + servers.length);
break;
}
}
}
}
}
}
@Override
public void dispose() {
}
private void checkStatus() {
try {
Thread.sleep(VM_OP_INTERVAL + 5000);
} catch (InterruptedException e) {
LOG.info("time exception");
}
String[] servers = platform.findServerNames();
int len = servers.length;
if (len == 0) {
idleVM = -1;
return;
} else {
idleVM = 0;
}
totalVM = 0;
idleList = new ArrayList<String>();
for (int i = 0; i < servers.length; i++) {
String name = servers[i];
int size = platform.getServiceSize(name);
if (size == 0) {
idleVM++;
idleList.add(name);
}
totalVM++;
}
}
@Override
public Map<String, Object> getManagedMBeans() {
return null;
}
}