Java tutorial
/**Copyright 2016, University of Messina. * * 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 BB_ELA.Policies; //import osffmcli.JClouds_Adapter.NovaTest; //import osffmcli.JClouds_Adapter.OpenstackInfoContainer; import MDBInt.DBMongo; import MDBInt.MDBIException; import BB_ELA.ElasticityPolicyException; import BB_ELA.Policy; import java.io.BufferedWriter; //import osffmcli.OSFFM_ORC.OrchestrationManager; //import com.google.common.collect.HashBiMap; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.time.Clock; import java.time.LocalTime; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.logging.Level; import javax.ws.rs.core.Response; import org.apache.log4j.Logger; import org.jdom2.Element; import org.json.JSONException; import org.json.JSONObject; import utils.ParserXML; import utils.Client4WS; import utils.Exception.WSException; /** * The objective of this class is implement the policy based on SunLight position. * In few words who select this policy, choose to have activated VMs where there is sun-light. * @author Giuseppe Tricomi */ public class SunLightPolicy implements Policy, Runnable { final Logger LOGGER = Logger.getLogger(SunLightPolicy.class); private String fileConf = "/home/beacon/beaconConf/configuration_SunLightPolicy.xml";//this path starts from the tomcat home //VARIABLE TO BE RETRIEVED FROM FILECONF private long granularityCheck = 20000;//3600000;//default value is 1 hour private int threshold = 17;//default value is 19 (7pm) private int minimumGap = -8;//default value is -8 hours private String bbUrl = "http://10.9.1.114:8080/BB/os2os/orchestrator"; private String bbuser = "bbuserAd"; private String bbpass = "bbpassAd"; private ParserXML parser; private int actualDCGap; private DBMongo mongo; private String tenant, userFederation, pswFederation; private HashMap<String, ArrayList<String>> datacenterMap; private ArrayList<String> monitoredVM; //private OrchestrationManager om; private HashMap<String, Boolean> index; private String firstCloudID; private String templateName, stack; private BufferedWriter log; public SunLightPolicy(HashMap<String, Object> paramsMap) throws ElasticityPolicyException, Exception { //paramsMap.get(this) // I need to understand which parameters need here this.tenant = (String) paramsMap.get("tenantName"); this.mongo = (DBMongo) paramsMap.get("mongoConnector"); //this.om=(OrchestrationManager)paramsMap.get("OrchestrationManager"); this.userFederation = (String) paramsMap.get("userFederation"); this.pswFederation = (String) paramsMap.get("pswFederation"); String tmpminimumGap = (String) paramsMap.get("minimumGap"); this.minimumGap = Integer.parseInt(tmpminimumGap); this.firstCloudID = (String) paramsMap.get("firstCloudID"); this.templateName = (String) paramsMap.get("templateName"); this.stack = (String) paramsMap.get("stack"); this.monitoredVM = new ArrayList<String>(); this.init(); this.constructDCMap((ArrayList<ArrayList<String>>) paramsMap.get("dcList")); this.log = new BufferedWriter(new FileWriter("/tmp/unlightpol.log")); } public void init() { Element params; this.datacenterMap = new HashMap<String, ArrayList<String>>(); try { parser = new ParserXML(new File(this.fileConf)); params = parser.getRootElement().getChild("pluginParams"); this.granularityCheck = Long.valueOf(params.getChildText("granularityCheck")).longValue(); this.threshold = Integer.valueOf(params.getChildText("threshold")); this.bbUrl = params.getChildText("bburl"); this.bbpass = params.getChildText("bbpass"); this.bbuser = params.getChildText("bbuser"); //this.connectReplication(); } catch (Exception ex) { LOGGER.error("Error occurred in configuration "); ex.printStackTrace(); } } private void constructDCMap(ArrayList<ArrayList<String>> dc) throws ElasticityPolicyException { for (ArrayList<String> row : dc) { for (String column : row) { try { JSONObject infoJSON = new JSONObject(column); String cloudTarget = infoJSON.getString("cloudId"); JSONObject json = new JSONObject(this.mongo.getDatacenter(this.tenant, cloudTarget)); String gapIndex = (String) json.get("gap"); ArrayList<String> artmp = null; if (!this.datacenterMap.containsKey(gapIndex)) { artmp = new ArrayList<String>(); artmp.add(column); } else { artmp = this.datacenterMap.get(gapIndex); artmp.add(column); } this.datacenterMap.put(gapIndex, artmp); } catch (JSONException je) { LOGGER.error("Impossible manage the Datacenter information Stored on MongoDb for the Tenant " + this.tenant + "; Datacenter information doesn't contain gap info for Datacenter!"); throw new ElasticityPolicyException( "Impossible manage the Datacenter information Stored on MongoDb for the Tenant " + this.tenant + "; Datacenter information doesn't contain gap info for Datacenter!\n" + je); } catch (MDBIException me) { LOGGER.error("Impossible manage the Datacenter information Stored on MongoDb for the Tenant " + this.tenant + "; It's Impossible accede to Datacenter info for selected DC:" + column); throw new ElasticityPolicyException( "Impossible manage the Datacenter information Stored on MongoDb for the Tenant " + this.tenant + "; It's Impossible accede to Datacenter info for selected DC:" + column + "\n" + me); } } } } /** * The mission of this function is identify the moments when a VM or a group of VM needs to be "migrated"(shuttedoff in one site and activated in another * selected by selectNewDatacenter function). * @param params */ @Override public void migrationAlertManager(HashMap params) { HashMap elem = this.selectNewDatacenter(null); String tmpDCID = (String) elem.get("dcID"); System.out.println("Migration1"); try { log.write("Migration1"); } catch (IOException ex) { java.util.logging.Logger.getLogger(SunLightPolicy.class.getName()).log(Level.SEVERE, null, ex); } try { if (tmpDCID != null) { ArrayList<String> newMonitoredVMs = new ArrayList<String>(); for (String targetVM : this.monitoredVM) { JSONObject jo = new JSONObject(tmpDCID); String twinVM = this.mongo.findResourceMate(this.tenant, targetVM, jo.getString("cloudId")); System.out.println("TwinVM: " + twinVM); if (twinVM == null) { LOGGER.error("Something going wrong it's imppossible find a twinVM for: " + targetVM + ".The migration for that VM is aborted!"); newMonitoredVMs.add(targetVM); continue; } else { System.out.println("TwinVM FOUND"); try { log.write("TwinVM FOUND"); } catch (IOException ex) { java.util.logging.Logger.getLogger(SunLightPolicy.class.getName()).log(Level.SEVERE, null, ex); } HashMap<String, Object> param = new HashMap<String, Object>(); param.put("vm2shut", targetVM); String twinVMUUID = (new JSONObject(twinVM)).getString("phisicalResourceId"); param.put("vm2Act", twinVMUUID); param.put("sitetarget", jo.getString("cloudId")); if (!this.moveVM(param)) { LOGGER.error("error occurred in migration VM " + targetVM);//sistemare qst logger newMonitoredVMs.add(targetVM); } newMonitoredVMs.add(twinVMUUID); } } this.actualDCGap = (Integer) elem.get("newgap"); this.monitoredVM = newMonitoredVMs; } else { LOGGER.error( "Something going wrong it's impossible find a twinVM for VMs monitored.The migration aborted"); } } catch (JSONException je) { LOGGER.error("Something going wrong it's impossible parse Datacenter inofo JSON"); } } /** * This function is based on the workflow of the sunlight demo for beacon. * All tenant in an Openstack cloud in federation is a clone of the other instance of the tenant, then it has deployed on it the same VM, * and for each VM monitored we can found a twinVM inside the DC chose from the algorithm. * @param val * @return */ @Override public HashMap selectNewDatacenter(Integer val) { try { String tmpGap = ""; HashMap<String, Object> element = new HashMap<String, Object>(); Integer searchedGap; if (val == null) { searchedGap = this.actualDCGap + minimumGap; } else { searchedGap = val - 1; } if ((searchedGap < -12) || (searchedGap > 14)) { if (searchedGap < -12) { searchedGap = searchedGap + 24; } else { searchedGap = searchedGap - 24; } } if (index != null) { if (!index.containsKey(searchedGap.toString())) { try { log.write("QUIT" + searchedGap + this.firstCloudID); } catch (IOException ex) { java.util.logging.Logger.getLogger(SunLightPolicy.class.getName()).log(Level.SEVERE, null, ex); } System.out.println("QUIT" + searchedGap + this.firstCloudID); index.put(searchedGap.toString(), Boolean.FALSE); } else { return null; } } else { index = new HashMap<String, Boolean>(); index.put(searchedGap.toString(), Boolean.FALSE); } if (searchedGap > 0) { tmpGap = "+" + searchedGap.toString(); } else { tmpGap = searchedGap.toString(); } if (this.datacenterMap.containsKey(tmpGap)) { ArrayList<String> ar = this.datacenterMap.get(tmpGap);//Take array and and findcorrect DC Iterator i = ar.iterator(); boolean end = false; while (i.hasNext() && (!end)) { String tmpDCID = (String) i.next(); //07/09/2016 basandosi sulla sunlight demo di BEACON basta identificare il DC su cui presente una VM del gruppo e tutte le altre saranno spostate(attivate) di conseguenza ////in alternativa si dovrebbe prendere il datacenter adatto per ogni VM da monitorare for (String targetVM : this.monitoredVM) { JSONObject jo = new JSONObject(tmpDCID); String twinVM = this.mongo.findResourceMate(this.tenant, targetVM, jo.getString("cloudId")); if (twinVM == null) { break; } else { end = true; element.put("dcID", tmpDCID); element.put("newgap", searchedGap); index.replace(tmpGap, true); return element; } } if (!end) { LOGGER.error( "Something going wrong it's impossible find a twinVM for VMs monitored.The migration for that VM is moved on another DC"); index.put(tmpGap, false); return this.selectNewDatacenter(searchedGap); } } } else { return this.selectNewDatacenter(searchedGap); } } catch (Exception e) { System.err.println("EXCEPTION" + e.getMessage()); e.printStackTrace(); } return null; } private void takeMonVMs() { try { ArrayList<String> tmp = this.mongo.getRunTimeInfos(this.tenant, this.firstCloudID, this.templateName, this.stack); for (String obj : tmp) { JSONObject jo = new JSONObject(obj); this.monitoredVM.add((String) jo.get("phisicalResourceId")); } } catch (Exception e) { LOGGER.error("Something going wrong it's create monitoredVM ArrayList."); } } /** * This function is used to move a VM * @param params * @return */ public boolean moveVM(HashMap params) { //this function have to invoke OrchestrationManager.migrationProcedure try { // this.om.migrationProcedure((String)params.get("vm2shut"), this.tenant, this.userFederation, (String)params.get("vm2Act"), this.pswFederation, this.mongo, "RegionOne");//BEACON>>> Region field need to be managed? System.out.println("STO PER migrare la " + (String) params.get("vm2shut")); String vmtoact = (String) params.get("vm2act"); this.migrationProcedure((String) params.get("vm2shut"), this.tenant, this.userFederation, (String) params.get("vm2Act"), this.pswFederation, "RegionOne", (String) params.get("sitetarget"));//BEACON>>> Region field need to be managed? //System.out.println("HO ATTIVATO la "+vmtoact); } catch (Exception e) { LOGGER.error("Error occurred in moveVM:" + e.getMessage()); return false; } return true; } /** * Take from Mongo the DCGap for selected Datacenter. */ private void getDCtimeGap() { Integer dcgap = +0; try { JSONObject json = new JSONObject(this.mongo.getDatacenter(this.tenant, this.firstCloudID)); String gapIndex = (String) json.get("gap"); dcgap = Integer.parseInt(gapIndex); } catch (JSONException je) { LOGGER.error("Impossible manage the Datacenter information Stored on MongoDb for the Tenant " + this.tenant + "; Datacenter information doesn't contain gap info for Datacenter!"); // throw new ElasticityPolicyException("Impossible manage the Datacenter information Stored on MongoDb for the Tenant "+this.tenant+"; Datacenter information doesn't contain gap info for Datacenter!\n"+je); } catch (MDBIException me) { LOGGER.error("Impossible manage the Datacenter information Stored on MongoDb for the Tenant " + this.tenant + "; It's Impossible accede to Datacenter info for selected DC:"); // throw new ElasticityPolicyException("Impossible manage the Datacenter information Stored on MongoDb for the Tenant "+this.tenant+"; It's Impossible accede to Datacenter info for selected DC:\n"+me); } this.actualDCGap = dcgap; } /** * This Stars and verify if the UTCtime+Datacenter gap is greater of the threshold. * Positive answer begin migration of the monitored VM, negative send thread in sleepmode for granularityCheck milliseconds. */ @Override public synchronized void run() { boolean stop = true; this.takeMonVMs(); while (stop) { this.getDCtimeGap(); Clock clock = Clock.systemUTC(); LocalTime osffmTime = LocalTime.now(clock); System.out.println( "checked time in : " + this.firstCloudID + " is " + osffmTime.getHour() + this.actualDCGap); //System.out.println(osffmTime.getHour()+this.actualDCGap); //System.out.println(osffmTime.getHour()+this.actualDCGap>this.threshold); if ((osffmTime.getHour() + this.actualDCGap) > (this.threshold + this.actualDCGap)) { //StartMigration System.out.println("I am starting migration"); this.migrationAlertManager(null); /* JSONObject j; String targetVM=""; String twinVM=""; try { j = new JSONObject(this.mongo.getRunTimeInfo(this.tenant, "CETIC", this.templateName, this.stack)); targetVM=j.getString("phisicalResourceId"); j= new JSONObject(this.mongo.findResourceMate(this.tenant, targetVM,"UME")); twinVM= j.getString("phisicalResourceId"); } catch (JSONException ex) { java.util.logging.Logger.getLogger(SunLightPolicy.class.getName()).log(Level.SEVERE, null, ex); } System.out.println("target and twin: "+targetVM+" "+twinVM); HashMap param=new HashMap(); param.put("vm2shut", targetVM); param.put("vm2Act", twinVM); this.moveVM(param); stop=false; */ } try { Thread.sleep(this.granularityCheck); } catch (InterruptedException ex) { LOGGER.error("InterruptedException with Thread.sleep inside a sunlight policy Thread!" + ex.getMessage()); stop = false; } } } /** * Function invocated when an elasticity action have to be started; this function * shutdown the VM with some problem and start one of the Twin VM of that. * This function could be improved with a better twin VM search algorithm, and to do this is needed * modify this: "m.findResourceMate". * @param vm * @param tenant * @param userFederation * @param pswFederation * @param m * @param element * @param region * @author gtricomi */ public void migrationProcedure(String vm, String tenant, String userFederation, String vmTwin, String pswFederation, String region, String sitetarget) throws JSONException { JSONObject param = new JSONObject(); param.put("vm", vm); param.put("tenant", tenant); param.put("userFederation", userFederation); param.put("vmTwin", vmTwin); param.put("pswFederation", pswFederation); param.put("region", region); Client4WS cws = new Client4WS(this.bbUrl); System.out.println("----->" + vmTwin); try { Response r = cws.make_request(this.bbUrl + "/migrateVMs/", this.bbuser, this.bbpass, tenant, "post", param.toString()); } catch (WSException wse) { LOGGER.error("The request has generated a WS Exception!" + wse.getMessage()); } catch (Exception ex) { LOGGER.error(ex.getMessage()); } try { param = new JSONObject(); param.put("site", sitetarget); param.put("tenant", tenant); System.out.println("----->connenctONE_" + this.bbUrl); Response r = cws.make_request(this.bbUrl + "/connectOne/", this.bbuser, this.bbpass, tenant, "post", param.toString()); } catch (WSException wse) { LOGGER.error("The request has generated a WS Exception!" + wse.getMessage()); } catch (Exception ex) { LOGGER.error(ex.getMessage()); } } }