/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package at.ac.tuwien.dsg.rSybl.planningEngine.adviseEffects; import at.ac.tuwien.dsg.csdg.DependencyGraph; import at.ac.tuwien.dsg.csdg.Node; import at.ac.tuwien.dsg.csdg.elasticityInformation.ElasticityCapabilityInformation; import at.ac.tuwien.dsg.csdg.outputProcessing.eventsNotification.EventNotification; import at.ac.tuwien.dsg.rSybl.cloudInteractionUnit.api.EnforcementAPIInterface; import at.ac.tuwien.dsg.rSybl.dataProcessingUnit.api.MonitoringAPIInterface; import at.ac.tuwien.dsg.rSybl.dataProcessingUnit.api.model.MonitoringSnapshot; import at.ac.tuwien.dsg.rSybl.dataProcessingUnit.api.model.ServicePartMonitor; import at.ac.tuwien.dsg.rSybl.dataProcessingUnit.monitoringPlugins.melaPlugin.RecordedInfoProcessing; import at.ac.tuwien.dsg.rSybl.learningEngine.advise.ComputeBehavior; import at.ac.tuwien.dsg.rSybl.learningEngine.advise.ECPBehavioralModel; import at.ac.tuwien.dsg.rSybl.planningEngine.ActionPlanEnforcement; import at.ac.tuwien.dsg.rSybl.planningEngine.PlanningAlgorithmInterface; import at.ac.tuwien.dsg.rSybl.planningEngine.PlanningGreedyAlgorithmWithPolynomialElasticityRelationships; import at.ac.tuwien.dsg.rSybl.planningEngine.utils.Configuration; import at.ac.tuwien.dsg.rSybl.planningEngine.utils.PlanningLogger; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.util.Date; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Timer; import java.util.TimerTask; import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.logging.Logger; /** * * @author Georgiana */ public class PlanningGreedyWithADVISE implements PlanningAlgorithmInterface { private List<ContextRepresentation> withoutEnforcing = new LinkedList<ContextRepresentation>(); private ContextRepresentation initialContext; private Node cloudService; private DependencyGraph dependencyGraph; private MonitoringAPIInterface monitoringInterface; private LinkedHashMap<String, LinkedHashMap<String, LinkedList<Double>>> measurements = new LinkedHashMap<String, LinkedHashMap<String, LinkedList<Double>>>(); private int POLYNOMIAL_EQUATION_DEGREE = 3; private LinkedHashMap<ElasticityCapabilityInformation, Double> expectedOverallEffect = new LinkedHashMap<>(); private LinkedHashMap<ElasticityCapabilityInformation, Double> expectedFinalEffect = new LinkedHashMap<>(); private double noActionOverallViolatedConstraints = 0; private double noActionFinalViolatedConstraints = 0; private int MINUTES_TO_WAIT_AFTER_ABNORMAL_DISTANCE = 5; private Timer timer = new Timer(); private EnforcementAPIInterface enforcementAPI; private ComputeBehavior behavior; private Date timeITWasNotOK; private PlanningAlgorithmInterface initialPlanning; private boolean planning = false; private EventNotification eventNotification; public PlanningGreedyWithADVISE(MonitoringAPIInterface monitoringAPIInterface, Node cloudService, EnforcementAPIInterface enforcementAPI, PlanningAlgorithmInterface mainPlanning) { monitoringInterface = monitoringAPIInterface; this.cloudService = cloudService; initialPlanning = mainPlanning; this.enforcementAPI = enforcementAPI; dependencyGraph = new DependencyGraph(); dependencyGraph.setCloudService(cloudService); this.eventNotification = EventNotification.getEventNotification(); initialContext = new ContextRepresentation(cloudService, new LinkedHashMap<String, LinkedHashMap<String, Double>>()); createFile(); } public void startLearningProcess() { behavior = new ComputeBehavior(cloudService, monitoringInterface); } public ElasticityCapabilityInformation findCapabilityToEnforce() { DependencyGraph dependencyGraph = new DependencyGraph(); dependencyGraph.setCloudService(cloudService); boolean sufficientInfo = true; double constraintsViolatedWithout = 0; ContextEvaluation contextEvaluation = new ContextEvaluation(); for (ContextRepresentation contextRepresentation : withoutEnforcing) { constraintsViolatedWithout += contextEvaluation.evaluateViolationDegree(dependencyGraph, contextRepresentation); } constraintsViolatedWithout /= withoutEnforcing.size() * 1.0; if (constraintsViolatedWithout > 0) { ElasticityCapabilityInformation elasticityCapability = null; double minViolatedConstraints = 100000000.0; double minViolatedFinalConstraints = 100000000.0; ElasticityCapabilityInformation overallEc = null; ElasticityCapabilityInformation finalEc = null; List<MonitoringSnapshot> snapshots = monitoringInterface.getAllMonitoringInformationOnPeriod(ECPBehavioralModel.CHANGE_INTERVAL); String justification=""; // double diff1 =0 ; // double diff2 = 0; boolean foundNotPredictable=false; for (ElasticityCapabilityInformation ec : dependencyGraph.getAllElasticityCapabilities()) { ECEnforcementEffect ecEnforcementEffect = new ECEnforcementEffect(behavior, cloudService, monitoringInterface, ec,snapshots); expectedOverallEffect.put(ec, ecEnforcementEffect.overallViolatedConstraints()); expectedFinalEffect.put(ec, ecEnforcementEffect.getFinalStateViolatedConstraints()); justification+=", "+ec.getName()+", overall:"+expectedOverallEffect.get(ec)+", final"+expectedFinalEffect.get(ec); // if (expectedFinalEffect.get(ec) == ecEnforcementEffect.MAX_CONSTRAINTS) { // sufficientInfo = false; // timeITWasNotOK = new Date(); // stop(); // initialPlanning.takeMainRole(); // writeJustification(justification+"returning to Greedy control \n", fileName); // return null; // } if (constraintsViolatedWithout > 0 && expectedOverallEffect.get(ec) < constraintsViolatedWithout && expectedOverallEffect.get(ec)!=ECEnforcementEffect.MAX_CONSTRAINTS) { if (minViolatedConstraints > expectedOverallEffect.get(ec)) { // diff1= minViolatedConstraints-expectedOverallEffect.get(ec); minViolatedConstraints = expectedOverallEffect.get(ec); overallEc = ec; } } if (constraintsViolatedWithout > 0 && expectedFinalEffect.get(ec) < constraintsViolatedWithout && expectedFinalEffect.get(ec)!=ECEnforcementEffect.MAX_CONSTRAINTS) { if (minViolatedFinalConstraints>expectedFinalEffect.get(ec)) { // diff2= minViolatedConstraints-expectedFinalEffect.get(ec); minViolatedFinalConstraints = expectedFinalEffect.get(ec); finalEc = ec; } } } if (sufficientInfo) { if (constraintsViolatedWithout > 0 && null != overallEc ) { elasticityCapability = overallEc; writeJustification(justification, elasticityCapability.getName()); return elasticityCapability; } // if (constraintsViolatedWithout > 0 && null != finalEc ) { // elasticityCapability = finalEc; // writeJustification(justification, elasticityCapability.getName()); // // return elasticityCapability; // } } }else { LinkedHashMap<ElasticityCapabilityInformation, Double> strategies = new LinkedHashMap<ElasticityCapabilityInformation, Double>(); double maxImprovedStrategies = 0; ElasticityCapabilityInformation forStrategiesEC = null; boolean foundNotPredictable = false; List<MonitoringSnapshot> snapshots = monitoringInterface.getAllMonitoringInformationOnPeriod(ECPBehavioralModel.CHANGE_INTERVAL); String justification=""; double diff=-10; for (ElasticityCapabilityInformation ec : dependencyGraph.getAllElasticityCapabilities()) { ECEnforcementEffect eCEnforcementEffect = new ECEnforcementEffect(behavior, cloudService, monitoringInterface, ec,snapshots); if (eCEnforcementEffect.getImprovedStrategies(initialContext)!=ECEnforcementEffect.MAX_CONSTRAINTS && eCEnforcementEffect.getFinalStateViolatedConstraints()!=ECEnforcementEffect.MAX_CONSTRAINTS) strategies.put(ec, eCEnforcementEffect.getImprovedStrategies(initialContext)-eCEnforcementEffect.getFinalStateViolatedConstraints()); else strategies.put(ec, eCEnforcementEffect.MAX_CONSTRAINTS); justification+=", "+ec.getName()+", overall:"+strategies.get(ec)+", final"+eCEnforcementEffect.getImprovedStrategies(initialContext)+" final violated constraints "+eCEnforcementEffect.getFinalStateViolatedConstraints(); if (strategies.get(ec)==ECEnforcementEffect.MAX_CONSTRAINTS){ foundNotPredictable=true; } if (maxImprovedStrategies < strategies.get(ec)) { diff= strategies.get(ec)-maxImprovedStrategies; maxImprovedStrategies = strategies.get(ec); forStrategiesEC = ec; } } if (!foundNotPredictable && forStrategiesEC != null && constraintsViolatedWithout == 0 && diff>0.2) { writeJustification(justification, forStrategiesEC.getName()); return forStrategiesEC; } } return null; } private Date currentDate = new Date(); private String fileName = "./reporting/decisionJustification"+currentDate.getDay()+"Feb_time_"+currentDate.getHours()+"_"+currentDate.getMinutes()+".csv"; public void createFile(){ File theDir = new File("./reporting"); // if the directory does not exist, create it if (!theDir.exists()) { System.out.println("creating directory: " + theDir.getName()); boolean result = false; try{ theDir.mkdir(); result = true; } catch(SecurityException se){ //handle it } if(result) { System.out.println("DIR created"); } } try{ FileWriter fstream = new FileWriter(fileName); String headers = "Time ,"; headers +=" evaluation, decision"; headers += "\n"; fstream.write(headers); fstream.close(); }catch(IOException ex){ ex.printStackTrace(); } } public void writeJustification(String justification, String decision){ FileWriter fstream=null; try { fstream = new FileWriter(fileName,true); } catch (IOException ex) { Logger.getLogger(RecordedInfoProcessing.class.getName()).log(Level.SEVERE, null, ex); } String toWrite = new Date()+","+justification+", decision: "+decision; try { fstream.write(toWrite+'\n'); fstream.close(); } catch (IOException ex) { Logger.getLogger(RecordedInfoProcessing.class.getName()).log(Level.SEVERE, null, ex); } } public boolean checkWhetherPerformanceIsAcceptable() { double stdDevSum = 0; double bigNb = 1000000; int nbActions = 0; if (timeITWasNotOK != null) { Date now = new Date(); long diff = now.getTime() - this.timeITWasNotOK.getTime(); long diffMinutes = diff / (60 * 1000) % 60; if (diffMinutes < MINUTES_TO_WAIT_AFTER_ABNORMAL_DISTANCE) { return false; } } for (ElasticityCapabilityInformation capability : dependencyGraph.getAllElasticityCapabilities()) { if (behavior.avgActionTime(capability, dependencyGraph.getNodeWithID(capability.getServicePartID())) > 0) { stdDevSum += behavior.stdDevActionTime(capability, dependencyGraph.getNodeWithID(capability.getServicePartID())); nbActions += 1; } else { stdDevSum += bigNb; nbActions += 1; } } if (stdDevSum / nbActions < bigNb) { return true; } else { return false; } } public void initializeContexts() { withoutEnforcing = new LinkedList<ContextRepresentation>(); List<MonitoringSnapshot> snapshots = monitoringInterface.getAllMonitoringInformationOnPeriod(ECPBehavioralModel.CHANGE_INTERVAL); if (snapshots.size() > 0) { MonitoringSnapshot snapshot = snapshots.get(snapshots.size() - 1); for (String SP : snapshot.getServiceParts().keySet()) { if (!measurements.containsKey(SP)) { LinkedHashMap<String, LinkedList<Double>> metricsWithPoints = new LinkedHashMap<>(); measurements.put(SP, metricsWithPoints); } for (ServicePartMonitor monitor : snapshot.getServiceParts().values()) { for (Map.Entry<String, Double> recording : monitor.getMetrics().entrySet()) { if (!measurements.get(SP).containsKey(recording.getKey())) { LinkedList<Double> nDimPoint = new LinkedList<Double>(); measurements.get(SP).put(recording.getKey(), nDimPoint); // measurements.get(SP).put(recording.getKey(), nDimPoint); } measurements.get(SP).get(recording.getKey()).add(recording.getValue()); //measurements.get(SP).get(recording.getKey()).add(recording.getValue()); } } } } MonitoringSnapshot monitoringSnapshot = snapshots.get(snapshots.size() - 1); for (String node : monitoringSnapshot.getServiceParts().keySet()) { for (String metric : monitoringSnapshot.getServiceParts().get(node).getMetrics().keySet()) { initialContext.setMetricValue(node, metric, monitoringSnapshot.getServiceParts().get(node).getMetrics().get(metric)); } } LinkedHashMap<String, LinkedHashMap<String, LinkedList<Double>>> expectedValues = new LinkedHashMap<String, LinkedHashMap<String, LinkedList<Double>>>(); //find polinomial equations for (String node : measurements.keySet()) { if (!expectedValues.containsKey(node)) { expectedValues.put(node, new LinkedHashMap<String, LinkedList<Double>>()); } for (String metric : measurements.get(node).keySet()) { if (!expectedValues.get(node).containsKey(metric)) { expectedValues.get(node).put(metric, new LinkedList<Double>()); } SimpleExpectedBehavior expectedBehavior = new SimpleExpectedBehavior(POLYNOMIAL_EQUATION_DEGREE); double[] observations = new double[measurements.get(node).get(metric).size()]; double[] samplePoints = new double[measurements.get(node).get(metric).size()]; for (int i = 0; i < observations.length; i++) { observations[i] = i; samplePoints[i] = measurements.get(node).get(metric).get(i); } expectedBehavior.fit(observations, samplePoints); double[] coef = expectedBehavior.getCoef(); PlanningLogger.logger.info("Coefficients are " + coef.toString()); for (int i = 0; i < ECPBehavioralModel.CHANGE_INTERVAL; i++) { double value = 0.0; for (int j = 0; j < coef.length; j++) { value += coef[j] * Math.pow(i + ECPBehavioralModel.CHANGE_INTERVAL, j); } //expectedValues.get(node).get(metric).add(value); expectedValues.get(node).get(metric).add(samplePoints[observations.length - 1]); } } } LinkedHashMap<String, LinkedHashMap<String, Double>> metrics; ContextEvaluation contextEvaluation = new ContextEvaluation(); DependencyGraph dependencyGraph = new DependencyGraph(); noActionOverallViolatedConstraints = 0.0; noActionFinalViolatedConstraints = 0.0; dependencyGraph.setCloudService(cloudService); for (int i = 0; i < ECPBehavioralModel.CHANGE_INTERVAL; i++) { metrics = new LinkedHashMap<>(); for (String node : expectedValues.keySet()) { if (!metrics.containsKey(node)) { metrics.put(node, new LinkedHashMap<String, Double>()); } for (String metric : expectedValues.get(node).keySet()) { metrics.get(node).put(metric, expectedValues.get(node).get(metric).get(i)); } } ContextRepresentation contextRepresentation = new ContextRepresentation(cloudService, metrics); withoutEnforcing.add(contextRepresentation); noActionOverallViolatedConstraints += contextEvaluation.countViolatedConstraints(dependencyGraph, contextRepresentation); } noActionOverallViolatedConstraints /= withoutEnforcing.size(); noActionFinalViolatedConstraints = contextEvaluation.countViolatedConstraints(dependencyGraph, withoutEnforcing.get(withoutEnforcing.size() - 1)); } @Override public void start() { run(); } @Override public void stop() { timer.purge(); timer.cancel(); } @Override public void setEffects(String effects) { } @Override public void replaceDependencyGraph(DependencyGraph dependencyGraph) { this.dependencyGraph = dependencyGraph; } public void discoverPlan() { planning = true; initializeContexts(); ElasticityCapabilityInformation capability = findCapabilityToEnforce(); if (capability != null) { ActionPlanEnforcement actionPlanEnforcement = new ActionPlanEnforcement(enforcementAPI); actionPlanEnforcement.enforceElasticityCapability(dependencyGraph, capability); } planning=false; } @Override public void run() { timer = new Timer(); timer.scheduleAtFixedRate(new TimerTask() { @Override public void run() { if (!planning){ discoverPlan(); } } }, 0, Configuration.getRefreshPeriod()); } @Override public void takeMainRole() { start(); } }