package at.ac.tuwien.dsg.rSybl.planningEngine; /** * Copyright 2013 Technische Universitat Wien (TUW), Distributed SystemsGroup * E184. * This work was partially supported by the European Commission in terms * of the CELAR FP7 project (FP7-ICT-2011-8 #317790). * * 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. */ /** * Author : Georgiana Copil - e.copil@dsg.tuwien.ac.at */ import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import at.ac.tuwien.dsg.csdg.DependencyGraph; import at.ac.tuwien.dsg.csdg.Node; import at.ac.tuwien.dsg.csdg.Node.NodeType; import at.ac.tuwien.dsg.csdg.Relationship; import at.ac.tuwien.dsg.csdg.Relationship.RelationshipType; import at.ac.tuwien.dsg.csdg.elasticityInformation.ElasticityCapabilityInformation; import at.ac.tuwien.dsg.csdg.elasticityInformation.ElasticityRequirement; import at.ac.tuwien.dsg.csdg.elasticityInformation.elasticityRequirements.Condition; import at.ac.tuwien.dsg.csdg.elasticityInformation.elasticityRequirements.SYBLSpecification; import at.ac.tuwien.dsg.csdg.elasticityInformation.elasticityRequirements.Strategy; import at.ac.tuwien.dsg.csdg.inputProcessing.multiLevelModel.abstractModelXML.SYBLDirectiveMappingFromXML; import at.ac.tuwien.dsg.csdg.outputProcessing.eventsNotification.CustomEvent; import at.ac.tuwien.dsg.csdg.outputProcessing.eventsNotification.EventNotification; import at.ac.tuwien.dsg.csdg.outputProcessing.eventsNotification.IEvent; import at.ac.tuwien.dsg.rSybl.cloudInteractionUnit.api.EnforcementAPIInterface; import at.ac.tuwien.dsg.rSybl.dataProcessingUnit.api.MonitoringAPIInterface; import at.ac.tuwien.dsg.rSybl.planningEngine.ContextRepresentation.Pair; import at.ac.tuwien.dsg.rSybl.planningEngine.adviseEffects.PlanningGreedyWithADVISE; import at.ac.tuwien.dsg.rSybl.planningEngine.utils.Configuration; import at.ac.tuwien.dsg.rSybl.planningEngine.staticData.ActionEffect; import at.ac.tuwien.dsg.rSybl.planningEngine.staticData.ActionEffects; import at.ac.tuwien.dsg.rSybl.planningEngine.utils.PlanningLogger; import java.util.ArrayDeque; import java.util.Deque; import java.util.Timer; import java.util.TimerTask; import java.util.logging.Level; import java.util.logging.Logger; public class PlanningGreedyAlgorithm implements PlanningAlgorithmInterface { private Timer t = new Timer(); private ContextRepresentation contextRepresentation; private MonitoringAPIInterface monitoringAPI; private EnforcementAPIInterface enforcementAPI; private DependencyGraph dependencyGraph; private ContextRepresentation lastContextRepresentation; private String strategiesThatNeedToBeImproved = ""; private int REFRESH_PERIOD = 120000; Deque<HashMap<String, Boolean>> stack = new ArrayDeque<HashMap<String, Boolean>>(); PlanningGreedyWithADVISE planningGreedyWithADVISE; private EventNotification eventNotification; private Timer evaluateLearningPerformance = new Timer(); public PlanningGreedyAlgorithm(DependencyGraph cloudService, MonitoringAPIInterface monitoringAPI, EnforcementAPIInterface enforcementAPI) { this.dependencyGraph = cloudService; this.monitoringAPI = monitoringAPI; this.enforcementAPI = enforcementAPI; this.eventNotification = EventNotification.getEventNotification(); REFRESH_PERIOD = Configuration.getRefreshPeriod(); if (Configuration.getADVISEEnabled()) { planningGreedyWithADVISE = new PlanningGreedyWithADVISE(monitoringAPI, cloudService.getCloudService(), enforcementAPI, this); planningGreedyWithADVISE.startLearningProcess(); } } public void checkWhetherLearningIsAccurateAndSwitch() { if (planningGreedyWithADVISE.checkWhetherPerformanceIsAcceptable()) { while (enforcementAPI.isEnforcingAction()) { try { Thread.sleep(1000); } catch (InterruptedException ex) { Logger.getLogger(PlanningGreedyAlgorithm.class.getName()).log(Level.SEVERE, null, ex); } } stop(); evaluateLearningPerformance.cancel(); try { Thread.sleep(1000); } catch (InterruptedException ex) { Logger.getLogger(PlanningGreedyAlgorithm.class.getName()).log(Level.SEVERE, null, ex); } planningGreedyWithADVISE.replaceDependencyGraph(dependencyGraph); planningGreedyWithADVISE.start(); } } public boolean checkIfActionPossible(ActionEffect actionEffect) { if (actionEffect.isConditional()) { if (!actionEffect.evaluateConditions(dependencyGraph, monitoringAPI)) { return false; } } // System.out.println("Targeted entity id " // +actionEffect.getTargetedEntityID()+entity); boolean possible = true; if (actionEffect.getActionType().equalsIgnoreCase("scalein")) { Node entity = dependencyGraph.getNodeWithID(actionEffect.getTargetedEntityID()); if (entity != null && entity.getNodeType() == NodeType.CLOUD_SERVICE) { List<String> ips = entity.getAssociatedIps(); // PlanningLogger.logger.info("For action " + actionEffect.getActionName() + entity.getAllRelatedNodesOfType(RelationshipType.HOSTED_ON_RELATIONSHIP, NodeType.VIRTUAL_MACHINE).size() + " hosts"); Node artifact = null; Node container = null; Node accessToVM = entity; if (entity.getAllRelatedNodesOfType(RelationshipType.HOSTED_ON_RELATIONSHIP, NodeType.ARTIFACT) != null && entity.getAllRelatedNodesOfType(RelationshipType.HOSTED_ON_RELATIONSHIP, NodeType.ARTIFACT).size() > 0) { artifact = entity.getAllRelatedNodesOfType(RelationshipType.HOSTED_ON_RELATIONSHIP, NodeType.ARTIFACT).get(0); if (artifact.getAllRelatedNodesOfType(RelationshipType.HOSTED_ON_RELATIONSHIP, NodeType.CONTAINER) != null && artifact.getAllRelatedNodesOfType(RelationshipType.HOSTED_ON_RELATIONSHIP, NodeType.CONTAINER).size() > 0) { container = artifact.getAllRelatedNodesOfType(RelationshipType.HOSTED_ON_RELATIONSHIP, NodeType.CONTAINER).get(0); } } if (artifact != null || container != null) { if (container == null) { accessToVM = artifact; } else { accessToVM = container; } } if (accessToVM.getAllRelatedNodesOfType(RelationshipType.HOSTED_ON_RELATIONSHIP, NodeType.VIRTUAL_MACHINE).size() > 4) { return true; } } if (entity != null && entity.getNodeType() == NodeType.SERVICE_TOPOLOGY) { Node master = dependencyGraph.findParentNode(entity.getId()); List<String> ips = master.getAssociatedIps(); int numberPrivateIps = 0; for (String ip : ips) { if (ip.split("\\.")[0].length() == 2) { numberPrivateIps++; } } Node artifact = null; Node container = null; Node accessToVM = entity; if (entity.getAllRelatedNodesOfType(RelationshipType.HOSTED_ON_RELATIONSHIP, NodeType.ARTIFACT) != null && entity.getAllRelatedNodesOfType(RelationshipType.HOSTED_ON_RELATIONSHIP, NodeType.ARTIFACT).size() > 0) { artifact = entity.getAllRelatedNodesOfType(RelationshipType.HOSTED_ON_RELATIONSHIP, NodeType.ARTIFACT).get(0); if (artifact.getAllRelatedNodesOfType(RelationshipType.HOSTED_ON_RELATIONSHIP, NodeType.CONTAINER) != null && artifact.getAllRelatedNodesOfType(RelationshipType.HOSTED_ON_RELATIONSHIP, NodeType.CONTAINER).size() > 0) { container = artifact.getAllRelatedNodesOfType(RelationshipType.HOSTED_ON_RELATIONSHIP, NodeType.CONTAINER).get(0); } } if (artifact != null || container != null) { if (container == null) { accessToVM = artifact; } else { accessToVM = container; } } if (accessToVM.getAllRelatedNodesOfType(RelationshipType.HOSTED_ON_RELATIONSHIP, NodeType.VIRTUAL_MACHINE).size() > 4) { return true; } } } return possible; } public void findStrategies() { for (ElasticityRequirement elasticityRequirement : dependencyGraph.getAllElasticityRequirements()) { SYBLSpecification syblSpecification = SYBLDirectiveMappingFromXML.mapFromSYBLAnnotation(elasticityRequirement.getAnnotation()); MonitoredEntity monitoredEntity = contextRepresentation.findMonitoredEntity(syblSpecification.getComponentId()); if (monitoredEntity == null) { PlanningLogger.logger.info("Not finding monitored entity " + monitoredEntity + " " + syblSpecification.getComponentId()); } for (Strategy strategy : syblSpecification.getStrategy()) { Condition condition = strategy.getCondition(); if (contextRepresentation.evaluateCondition(condition, monitoredEntity)) { if (strategy.getToEnforce().getActionName().toLowerCase().contains("maximize") || strategy.getToEnforce().getActionName().toLowerCase().contains("minimize")) { if (strategy.getToEnforce().getActionName().toLowerCase().contains("maximize")) { //PlanningLogger.logger.info("Current value for "+ strategy.getToEnforce().getParameter()+" is "+ monitoredEntity.getMonitoredValue(strategy.getToEnforce().getParameter())+" .Previous value was "+previousContextRepresentation.getValueForMetric(monitoredEntity,strategy.getToEnforce().getParameter())); if (monitoredEntity.getMonitoredValue(strategy.getToEnforce().getParameter()) <= lastContextRepresentation.getValueForMetric(monitoredEntity, strategy.getToEnforce().getParameter())) { strategiesThatNeedToBeImproved += strategy.getId() + " "; } } if (strategy.getToEnforce().getActionName().toLowerCase().contains("minimize")) { PlanningLogger.logger.info("Current value for " + strategy.getToEnforce().getParameter() + " is " + monitoredEntity.getMonitoredValue(strategy.getToEnforce().getParameter()) + " .Previous value was " + lastContextRepresentation.getValueForMetric(monitoredEntity, strategy.getToEnforce().getParameter())); if (monitoredEntity.getMonitoredValue(strategy.getToEnforce().getParameter()) >= lastContextRepresentation.getValueForMetric(monitoredEntity, strategy.getToEnforce().getParameter())) { strategiesThatNeedToBeImproved += strategy.getId() + " "; } } } } } } } public void checkInstantiation() { List<Relationship> instantiationRelationships = dependencyGraph.getAllRelationshipsOfType(RelationshipType.INSTANTIATION); //for } public ActionEffect checkActions(String target) { HashMap<String, List<ActionEffect>> actionEffects = ActionEffects.getActionConditionalEffects(); if (actionEffects.size() > 0) { int maxConstraints = 0; ActionEffect maxConstraintsAction = null; PlanningLogger.logger.info("~~~~~~~~~~~Evaluating complimentary actions for " + target); for (List<ActionEffect> actionEffect : actionEffects.values()) { for (ActionEffect effect : actionEffect) { if (effect.getAffectedNodes().contains(target)) { int beforeConstraints = contextRepresentation.countViolatedConstraints(); MonitoredCloudService monitoredCloudService = contextRepresentation.getMonitoredCloudService().clone(); ContextRepresentation beforeContext = new ContextRepresentation(monitoredCloudService, monitoringAPI); contextRepresentation.doAction(effect); int improvedStrategies = contextRepresentation.countFixedStrategies(beforeContext); int afterConstraints = contextRepresentation.countViolatedConstraints(); PlanningLogger.logger.info("With " + effect.getActionType() + " on " + effect.getTargetedEntityID() + improvedStrategies + " and constraints " + (beforeConstraints - afterConstraints) + " violated constraints " + contextRepresentation.getViolatedConstraints()); contextRepresentation.undoAction(effect); if (beforeConstraints - afterConstraints + improvedStrategies > maxConstraints && (beforeConstraints - afterConstraints + improvedStrategies) > 0) { maxConstraints = beforeConstraints - afterConstraints + improvedStrategies; maxConstraintsAction = effect; } } } } if (maxConstraintsAction != null) { PlanningLogger.logger.info("Returning " + maxConstraintsAction.getActionType() + " on " + maxConstraintsAction.getTargetedEntityID()); } else { PlanningLogger.logger.info("Returning null "); } return maxConstraintsAction; } else { HashMap<String, ActionEffect> defaultEffects = ActionEffects.getActionDefaultEffects(); int maxConstraints = 0; ActionEffect maxConstraintsAction = null; PlanningLogger.logger.info("~~~~~~~~~~~Evaluating complimentary actions for " + target); for (ActionEffect effect : defaultEffects.values()) { boolean checkIfAvailable = false; for (ElasticityCapabilityInformation capability : dependencyGraph.getNodeWithID(target).getElasticityCapabilities()) { if (capability.getPrimitiveOperations().contains(effect.getActionName())) { checkIfAvailable = true; } } if (checkIfAvailable) { int beforeConstraints = contextRepresentation.countViolatedConstraints(); MonitoredCloudService monitoredCloudService = contextRepresentation.getMonitoredCloudService().clone(); ContextRepresentation beforeContext = new ContextRepresentation(monitoredCloudService, monitoringAPI); contextRepresentation.doAction(effect, target); int improvedStrategies = contextRepresentation.countFixedStrategies(beforeContext); int afterConstraints = contextRepresentation.countViolatedConstraints(); PlanningLogger.logger.info("With " + effect.getActionType() + " on " + effect.getTargetedEntityID() + improvedStrategies + " and constraints " + (beforeConstraints - afterConstraints) + " violated constraints " + contextRepresentation.getViolatedConstraints()); contextRepresentation.undoAction(effect, target); if (beforeConstraints - afterConstraints + improvedStrategies > maxConstraints && (beforeConstraints - afterConstraints + improvedStrategies) > 0) { maxConstraints = beforeConstraints - afterConstraints + improvedStrategies; maxConstraintsAction = effect; } } } if (maxConstraintsAction != null) { PlanningLogger.logger.info("Returning " + maxConstraintsAction.getActionType() + " on " + maxConstraintsAction.getTargetedEntityID()); } else { PlanningLogger.logger.info("Returning null "); } return maxConstraintsAction; } } public void findAndExecuteBestActionsForDefaultEffects() { strategiesThatNeedToBeImproved = ""; if (lastContextRepresentation != null) { findStrategies(); } lastContextRepresentation = new ContextRepresentation(dependencyGraph, monitoringAPI); lastContextRepresentation.initializeContext(); //PlanningLogger.logger.info("Strategies that could be enforced. ... "+strategiesThatNeedToBeImproved+" Violated constraints: "+contextRepresentation.getViolatedConstraints()); HashMap<String, ActionEffect> actionEffects = ActionEffects.getActionDefaultEffects(); if (actionEffects.size() == 0) { PlanningLogger.logger.info("Not trying any type of actions, action effect is null"); return; } int numberOfBrokenConstraints = contextRepresentation .countViolatedConstraints(); PlanningLogger.logger.info("Violated constraints number: " + numberOfBrokenConstraints); HashMap<String, String> constraintsWhichWouldBeViolated = new HashMap<String, String>(); int lastFixed = 1; ArrayList<Pair<ActionEffect, Integer>> result = new ArrayList<Pair<ActionEffect, Integer>>(); double violationDegree = contextRepresentation.evaluateViolationDegree(); int numberOfRemainingConstraints = numberOfBrokenConstraints; if (!strategiesThatNeedToBeImproved.equalsIgnoreCase("") || numberOfBrokenConstraints > 0 && lastFixed != 0) { // while (contextRepresentation.countViolatedConstraints() > 0 // && numberOfRemainingConstraints > 0 && lastFixed>0) { Date date = new Date(); HashMap<Integer, List<Pair<ActionEffect, String>>> fixedDirectives = new HashMap<Integer, List<Pair<ActionEffect, String>>>(); HashMap<Integer, List<Pair<ActionEffect, String>>> fixedStrategies = new HashMap<Integer, List<Pair<ActionEffect, String>>>(); // PlanningLogger.logger.info("~~~~~~~~~~~Number of actions possible: "+actionEffects.values().size()); for (ElasticityCapabilityInformation elasticityCapability : dependencyGraph.getAllElasticityCapabilities()) { String servicePartID = elasticityCapability.getServicePartID(); for (ActionEffect actionEffect : actionEffects.values()) { if (checkIfActionPossible(actionEffect) && elasticityCapability.getName().toLowerCase().equalsIgnoreCase(actionEffect.getActionName())) { List<Pair<ActionEffect, String>> foundActions = new ArrayList<Pair<ActionEffect, String>>(); for (Pair<ActionEffect, Integer> a : result) { PlanningLogger.logger.info("Executing the already found action" + a.getFirst().getActionName()); contextRepresentation.doAction(a.getFirst(), ((ActionEffect) a.getFirst()).getTargetedEntityID()); PlanningLogger.logger.info("At " + date.getDay() + "_" + date.getMonth() + "_" + date.getHours() + "_" + date.getMinutes() + ". The violated constraints are the following: " + contextRepresentation.getViolatedConstraints()); } String[] initiallyBrokenConstraintsString = contextRepresentation.getViolatedConstraints().split(" "); int initiallyBrokenConstraints = contextRepresentation .countViolatedConstraints(); MonitoredCloudService monitoredCloudService = contextRepresentation.getMonitoredCloudService().clone(); ContextRepresentation beforeActionContextRepresentation = new ContextRepresentation(monitoredCloudService, monitoringAPI); // TODO: Try from 1 to 10 actions of the same type // for (int i = 0; i < 10; i++) { // for (int current = 0; current < i; current++) { // contextRepresentation.doAction(actionEffect); // } contextRepresentation.doAction(actionEffect, servicePartID); String[] brokenConstraintsAfterWise = contextRepresentation.getViolatedConstraints().split(" "); for (String s : initiallyBrokenConstraintsString) { boolean ok = true; for (String s1 : brokenConstraintsAfterWise) { if (s1.equalsIgnoreCase(s)) { ok = false; } } if (ok) { String constr = ""; if (brokenConstraintsAfterWise.length > 0) { for (String s1 : brokenConstraintsAfterWise) { if (constraintsWhichWouldBeViolated.get(s) == null || !constraintsWhichWouldBeViolated.get(s).contains(s1)) { constr += s1 + " "; } } } constraintsWhichWouldBeViolated.put(s, constr); } } foundActions.add(contextRepresentation.new Pair<ActionEffect, String>(actionEffect, servicePartID)); int fixedStr = contextRepresentation.countFixedStrategies(beforeActionContextRepresentation, strategiesThatNeedToBeImproved); PlanningLogger.logger.info("PlanningAlgorithm: Trying the action " + actionEffect.getActionName() + "constraints violated : " + contextRepresentation.getViolatedConstraints() + " Strategies improved " + contextRepresentation.getImprovedStrategies(beforeActionContextRepresentation, strategiesThatNeedToBeImproved)); fixedDirectives .put(initiallyBrokenConstraints - contextRepresentation .countViolatedConstraints() + fixedStr, foundActions); fixedStrategies .put( fixedStr, foundActions); /////////////////////~~~~~~~~~~~Check complimentary actions needed~~~~~~~~~~~~~~~~// contextRepresentation.undoAction(actionEffect, servicePartID); // for (int current = 0; current < i; current++) { // contextRepresentation.undoAction(actionEffect); // } // } // System.out.println("Action "+actionEffect.getTargetedEntityID()+" "+actionEffect.getActionType()+" fixes "+(numberOfBrokenConstraints-contextRepresentation.countViolatedConstraints())+" constraints."); for (int i = result.size() - 1; i > 0; i--) { //System.out.println("Undoing action " //+ actionEffect.getActionName()); PlanningLogger.logger.info("Undo-ing the already found action" + result.get(i).getFirst().getActionName()); contextRepresentation.undoAction(result.get(i) .getFirst(), ((ActionEffect) result.get(i).getFirst()).getTargetedEntityID()); } } } } int maxAction = -20; List<Pair<ActionEffect, String>> action = null; for (Integer val : fixedDirectives.keySet()) { PlanningLogger.logger.info("fixed directives " + val); if (val > maxAction) { maxAction = val; action = fixedDirectives.get(val); } } int minStrat = 0; for (Integer v : fixedStrategies.keySet()) { if (fixedStrategies.get(v).equals(fixedDirectives.get(maxAction)) && minStrat < v) { minStrat = v; action = fixedStrategies.get(minStrat); } } // PlanningLogger.logger.info("Found action "+ action); // Find cloudService = SYBLRMI enforce action with action type, if (maxAction > 0 && action != null && !result.contains(action)) { for (Pair<ActionEffect, String> actionEffect : action) { PlanningLogger.logger.info("Found action " + actionEffect.getFirst().getActionName() + " on " + actionEffect.getSecond() + " Number of directives fixed: " + maxAction); lastFixed = maxAction; Node entity = dependencyGraph.getNodeWithID(((ActionEffect) actionEffect.getFirst()) .getTargetedEntityID()); ((ActionEffect) actionEffect.getFirst()).setTargetedEntity(entity); if (maxAction > 0) { // result.add(actionEffect); } } List<Pair<ActionEffect, Integer>> actions = new ArrayList<Pair<ActionEffect, Integer>>(); for (Pair<ActionEffect, String> a : action) { ActionEffect newAction = a.getFirst().clone(); newAction.setTargetedEntityID(a.getSecond()); newAction.setTargetedEntity(dependencyGraph.getNodeWithID(a.getSecond())); actions.add(contextRepresentation.new Pair<ActionEffect, Integer>(newAction, 1)); } result.addAll(actions); } else { lastFixed = 0; } numberOfRemainingConstraints -= lastFixed; } for (int i = 0; i < result.size(); i++) { contextRepresentation.doAction(result.get(i).getFirst()); } if (result.size() == 0 && contextRepresentation.countViolatedConstraints() > 0) { EventNotification eventNotification = EventNotification.getEventNotification(); CustomEvent customEvent = new CustomEvent(); customEvent.setCloudServiceID(this.dependencyGraph.getCloudService().getId()); customEvent.setType(IEvent.Type.NOTIFICATION); customEvent.setTarget(contextRepresentation.getViolatedConstraints()); String violatedConstraints = contextRepresentation.getViolatedConstraints(); String conflictingConstraintsStory = ""; for (String s : violatedConstraints.split(" ")) { if (constraintsWhichWouldBeViolated.get(s)==null){ conflictingConstraintsStory+=s+","; }else conflictingConstraintsStory += constraintsWhichWouldBeViolated.get(s) + "(" + s + "), "; } customEvent.setMessage("Requirements " + contextRepresentation.getViolatedConstraints() + " are violated. rSYBL can not solve the problem due to: " + conflictingConstraintsStory.substring(0, conflictingConstraintsStory.length() - 1) + "."); eventNotification.sendEvent(customEvent); monitoringAPI.sendMessageToAnalysisService("Requirements " + contextRepresentation.getViolatedConstraints() + " are violated, and rSYBL can not solve the problem."); } else { if (Configuration.getDecisionsDifferentiatedOnViolationDegree()){ ActionPlanEnforcement actionPlanEnforcement = new ActionPlanEnforcement(enforcementAPI); actionPlanEnforcement.enforceResult(result, dependencyGraph, violationDegree,contextRepresentation.getFixedConstraintsAsConstraints(lastContextRepresentation), contextRepresentation.getImprovedStrategiesAsStrategies(lastContextRepresentation, strategiesThatNeedToBeImproved)); }else{ ActionPlanEnforcement actionPlanEnforcement = new ActionPlanEnforcement(enforcementAPI); actionPlanEnforcement.enforceResult(result, dependencyGraph, contextRepresentation.getFixedConstraintsAsConstraints(lastContextRepresentation), contextRepresentation.getImprovedStrategiesAsStrategies(lastContextRepresentation, strategiesThatNeedToBeImproved)); } } } public void findAndExecuteBestActions() { strategiesThatNeedToBeImproved = ""; if (lastContextRepresentation != null) { findStrategies(); } lastContextRepresentation = new ContextRepresentation(dependencyGraph, monitoringAPI); lastContextRepresentation.initializeContext(); //PlanningLogger.logger.info("Strategies that could be enforced. ... "+strategiesThatNeedToBeImproved+" Violated constraints: "+contextRepresentation.getViolatedConstraints()); HashMap<String, List<ActionEffect>> actionEffects = ActionEffects.getActionConditionalEffects(); if (actionEffects.size() == 0) { findAndExecuteBestActionsForDefaultEffects(); return; } HashMap<String, String> constraintsWhichWouldBeViolated = new HashMap<String, String>(); int numberOfBrokenConstraints = contextRepresentation .countViolatedConstraints(); PlanningLogger.logger.info("Violated constraints number: " + numberOfBrokenConstraints); int lastFixed = 1; ArrayList<Pair<ActionEffect, Integer>> result = new ArrayList<Pair<ActionEffect, Integer>>(); double violationDegree = contextRepresentation.evaluateViolationDegree(); int numberOfRemainingConstraints = numberOfBrokenConstraints; if (!strategiesThatNeedToBeImproved.equalsIgnoreCase("") || numberOfBrokenConstraints > 0 && lastFixed != 0) { // while (contextRepresentation.countViolatedConstraints() > 0 // && numberOfRemainingConstraints > 0 && lastFixed>0) { Date date = new Date(); HashMap<Integer, List<Pair<ActionEffect, Integer>>> fixedDirectives = new HashMap<Integer, List<Pair<ActionEffect, Integer>>>(); HashMap<Integer, List<Pair<ActionEffect, Integer>>> fixedStrategies = new HashMap<Integer, List<Pair<ActionEffect, Integer>>>(); // PlanningLogger.logger.info("~~~~~~~~~~~Number of actions possible: "+actionEffects.values().size()); for (List<ActionEffect> list : actionEffects.values()) { for (ActionEffect actionEffect : list) { if (checkIfActionPossible(actionEffect)) { List<Pair<ActionEffect, Integer>> foundActions = new ArrayList<Pair<ActionEffect, Integer>>(); for (Pair<ActionEffect, Integer> a : result) { for (int i = 0; i < a.getSecond(); i++) { PlanningLogger.logger.info("Executing the already found action" + a.getFirst().getActionName()); contextRepresentation.doAction(a.getFirst()); PlanningLogger.logger.info("At " + date.getDay() + "_" + date.getMonth() + "_" + date.getHours() + "_" + date.getMinutes() + ". The violated constraints are the following: " + contextRepresentation.getViolatedConstraints()); } } int initiallyBrokenConstraints = contextRepresentation .countViolatedConstraints(); String[] initiallyBrokenConstraintsString = contextRepresentation.getViolatedConstraints().split(" "); MonitoredCloudService monitoredCloudService = contextRepresentation.getMonitoredCloudService().clone(); ContextRepresentation beforeActionContextRepresentation = new ContextRepresentation(monitoredCloudService, monitoringAPI); // TODO: Try from 1 to 10 actions of the same type // for (int i = 0; i < 10; i++) { // for (int current = 0; current < i; current++) { // contextRepresentation.doAction(actionEffect); // } contextRepresentation.doAction(actionEffect); String[] brokenConstraintsAfterWise = contextRepresentation.getViolatedConstraints().split(" "); for (String s : initiallyBrokenConstraintsString) { boolean ok = true; for (String s1 : brokenConstraintsAfterWise) { if (s1.equalsIgnoreCase(s)) { ok = false; } } if (ok) { String constr = ""; if (constraintsWhichWouldBeViolated.containsKey(s)){ constr=constraintsWhichWouldBeViolated.get(s); } if (brokenConstraintsAfterWise.length > 0 ) { for (String s1 : brokenConstraintsAfterWise) { if (!s1.equalsIgnoreCase("") && ( constraintsWhichWouldBeViolated.get(s) == null || !constraintsWhichWouldBeViolated.get(s).contains(s1))) { constr += s1 + " "; } } } if (!constr.equalsIgnoreCase("")){ constraintsWhichWouldBeViolated.put(s, constr); } } } foundActions.add(contextRepresentation.new Pair<ActionEffect, Integer>(actionEffect, 1)); int fixedStr = contextRepresentation.countFixedStrategies(beforeActionContextRepresentation, strategiesThatNeedToBeImproved); PlanningLogger.logger.info("PlanningAlgorithm: Trying the action " + actionEffect.getActionName() + "constraints violated : " + contextRepresentation.getViolatedConstraints() + " Strategies improved " + contextRepresentation.getImprovedStrategies(beforeActionContextRepresentation, strategiesThatNeedToBeImproved)); fixedDirectives .put(initiallyBrokenConstraints - contextRepresentation .countViolatedConstraints() + fixedStr, foundActions); fixedStrategies .put( fixedStr, foundActions); /////////////////////~~~~~~~~~~~Check complimentary actions needed~~~~~~~~~~~~~~~~// List<String> targets = contextRepresentation.simulateDataImpact(beforeActionContextRepresentation, actionEffect); if (targets != null) { for (String target : targets) { ActionEffect dataAction = checkActions(target); if (dataAction != null) { MonitoredCloudService newMonitoredCloudService = contextRepresentation.getMonitoredCloudService().clone(); ContextRepresentation beforeContext = new ContextRepresentation(newMonitoredCloudService, monitoringAPI); int beforeC = contextRepresentation.countViolatedConstraints(); contextRepresentation.doAction(dataAction); int afterC = contextRepresentation.countViolatedConstraints(); int improvedStrategies = contextRepresentation.countFixedStrategies(beforeContext); int req = initiallyBrokenConstraints - afterC + improvedStrategies; PlanningLogger.logger.info("PlanningAlgorithm: Trying the action due to DATA " + dataAction.getActionName() + "constraints violated : " + contextRepresentation.getViolatedConstraints() + " Strategies improved " + contextRepresentation.getImprovedStrategies(beforeActionContextRepresentation, strategiesThatNeedToBeImproved)); foundActions.add(contextRepresentation.new Pair<ActionEffect, Integer>(dataAction, 1)); fixedDirectives .put(req, foundActions); fixedStrategies .put( improvedStrategies, foundActions); contextRepresentation.undoAction(dataAction); } } contextRepresentation.undoDataImpactSimulation(beforeActionContextRepresentation, actionEffect); } targets = contextRepresentation.simulateLoadImpact(beforeActionContextRepresentation, actionEffect); if (targets != null) { for (String target : targets) { MonitoredCloudService newMonitoredCloudService = contextRepresentation.getMonitoredCloudService().clone(); ContextRepresentation beforeContext = new ContextRepresentation(newMonitoredCloudService, monitoringAPI); ActionEffect loadAction = checkActions(target); if (loadAction != null) { int beforeC = contextRepresentation.countViolatedConstraints(); contextRepresentation.doAction(loadAction); int afterC = contextRepresentation.countViolatedConstraints(); int improvedStrategies = contextRepresentation.countFixedStrategies(beforeContext); int req = initiallyBrokenConstraints - afterC + improvedStrategies; PlanningLogger.logger.info("PlanningAlgorithm: Trying the action due to LOAD " + loadAction.getActionName() + "constraints violated : " + contextRepresentation.getViolatedConstraints() + " Strategies improved " + contextRepresentation.getImprovedStrategies(beforeActionContextRepresentation, strategiesThatNeedToBeImproved)); foundActions.add(contextRepresentation.new Pair<ActionEffect, Integer>(loadAction, 1)); fixedDirectives .put(req, foundActions); fixedStrategies .put( improvedStrategies, foundActions); contextRepresentation.undoAction(loadAction); } } contextRepresentation.undoLoadImpactSimulation(beforeActionContextRepresentation, actionEffect); } contextRepresentation.undoAction(actionEffect); // for (int current = 0; current < i; current++) { // contextRepresentation.undoAction(actionEffect); // } // } // System.out.println("Action "+actionEffect.getTargetedEntityID()+" "+actionEffect.getActionType()+" fixes "+(numberOfBrokenConstraints-contextRepresentation.countViolatedConstraints())+" constraints."); for (int i = result.size() - 1; i > 0; i--) { //System.out.println("Undoing action " //+ actionEffect.getActionName()); for (int j = 0; j < result.get(i).getSecond(); j++) { PlanningLogger.logger.info("Undo-ing the already found action" + result.get(i).getFirst().getActionName()); contextRepresentation.undoAction(result.get(i) .getFirst()); } } } } } int maxAction = -20; List<Pair<ActionEffect, Integer>> action = null; for (Integer val : fixedDirectives.keySet()) { PlanningLogger.logger.info("fixed directives " + fixedDirectives.get(val).size()); if (val > maxAction) { maxAction = val; action = fixedDirectives.get(val); } } int minStrat = 0; for (Integer v : fixedStrategies.keySet()) { if (fixedStrategies.get(v).equals(fixedDirectives.get(maxAction)) && minStrat < v) { minStrat = v; action = fixedStrategies.get(minStrat); } } // PlanningLogger.logger.info("Found action "+ action); // Find cloudService = SYBLRMI enforce action with action type, if (maxAction > 0 && action != null && !result.contains(action)) { for (Pair<ActionEffect, Integer> actionEffect : action) { for (int i = 0; i < actionEffect.getSecond(); i++) { PlanningLogger.logger.info("Found action " + (i + 1) + "x" + ((ActionEffect) actionEffect.getFirst()).getActionType() + " on " + ((ActionEffect) actionEffect.getFirst()) .getTargetedEntityID() + " Number of directives fixed: " + maxAction); lastFixed = maxAction; Node entity = dependencyGraph.getNodeWithID(((ActionEffect) actionEffect.getFirst()) .getTargetedEntityID()); ((ActionEffect) actionEffect.getFirst()).setTargetedEntity(entity); if (maxAction > 0) { // result.add(actionEffect); } } } result.addAll(action); } else { lastFixed = 0; } numberOfRemainingConstraints -= lastFixed; } for (int i = 0; i < result.size(); i++) { contextRepresentation.doAction(result.get(i).getFirst()); } if (result.size() == 0 && contextRepresentation.countViolatedConstraints() > 0) { EventNotification eventNotification = EventNotification.getEventNotification(); CustomEvent customEvent = new CustomEvent(); customEvent.setCloudServiceID(this.dependencyGraph.getCloudService().getId()); customEvent.setType(IEvent.Type.NOTIFICATION); customEvent.setTarget(this.dependencyGraph.getCloudService().getId()); String conflictingConstraintsStory = ""; String violatedConstraints = contextRepresentation.getViolatedConstraints(); for (String s : violatedConstraints.split(" ")) { if (constraintsWhichWouldBeViolated.get(s)==null){ conflictingConstraintsStory+=s+","; }else conflictingConstraintsStory += constraintsWhichWouldBeViolated.get(s) + "(" + s + "), "; } customEvent.setMessage("Requirements " + contextRepresentation.getViolatedConstraints() + " are violated. rSYBL can not solve the problem due to: " + conflictingConstraintsStory.substring(0, conflictingConstraintsStory.length() - 2) + "."); // customEvent.setMessage("Requirements " + contextRepresentation.getViolatedConstraints() + " are violated, and rSYBL can not solve the problem."); eventNotification.sendEvent(customEvent); monitoringAPI.sendMessageToAnalysisService("Requirements " + contextRepresentation.getViolatedConstraints() + " are violated, and rSYBL can not solve the problem."); } else { if (Configuration.getDecisionsDifferentiatedOnViolationDegree()){ ActionPlanEnforcement actionPlanEnforcement = new ActionPlanEnforcement(enforcementAPI); actionPlanEnforcement.enforceResult(result, dependencyGraph, violationDegree,contextRepresentation.getFixedConstraintsAsConstraints(lastContextRepresentation), contextRepresentation.getImprovedStrategiesAsStrategies(lastContextRepresentation, strategiesThatNeedToBeImproved)); }else{ ActionPlanEnforcement actionPlanEnforcement = new ActionPlanEnforcement(enforcementAPI); actionPlanEnforcement.enforceResult(result, dependencyGraph, contextRepresentation.getFixedConstraintsAsConstraints(lastContextRepresentation), contextRepresentation.getImprovedStrategiesAsStrategies(lastContextRepresentation, strategiesThatNeedToBeImproved)); } } } @Override public void run() { t = new Timer(); try { t.scheduleAtFixedRate(new TimerTask() { @Override public void run() { if (dependencyGraph.isInControlState()) { try { Thread.sleep(REFRESH_PERIOD); } catch (InterruptedException e) { // TODO Auto-generated catch block PlanningLogger.logger.error(e.toString()); } Node cloudService = monitoringAPI.getControlledService(); dependencyGraph.setCloudService(cloudService); contextRepresentation = new ContextRepresentation(dependencyGraph, monitoringAPI); contextRepresentation.initializeContext(); findAndExecuteBestActions(); } } }, REFRESH_PERIOD, REFRESH_PERIOD); } catch (Exception exception) { PlanningLogger.logger.error(exception.getMessage()); } } @Override public void start() { if (Configuration.getADVISEEnabled()) { evaluateLearningPerformance = new Timer(); evaluateLearningPerformance.scheduleAtFixedRate(new TimerTask() { public void run() { checkWhetherLearningIsAccurateAndSwitch(); } }, REFRESH_PERIOD, REFRESH_PERIOD); } run(); } @Override public void stop() { boolean ok = false; while (!ok) { if (enforcementAPI.getPluginsExecutingActions().size() > 0) { try { Thread.sleep(1000); } catch (InterruptedException ex) { Logger.getLogger(PlanningGreedyAlgorithm.class.getName()).log(Level.SEVERE, null, ex); } } else { ok = true; } } t.purge(); t.cancel(); } @Override public void setEffects(String effects) { // TODO Auto-generated method stub ActionEffects.setActionEffects(effects); } @Override public void replaceDependencyGraph(DependencyGraph dependencyGraph) { this.dependencyGraph = dependencyGraph; } @Override public void takeMainRole() { PlanningLogger.logger.info("SWITCHING to Initial Greedy Algorithm"); this.start(); } }