/** * 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 */ package at.ac.tuwien.dsg.rSybl.planningEngine; import at.ac.tuwien.dsg.csdg.DependencyGraph; import at.ac.tuwien.dsg.csdg.Node; import at.ac.tuwien.dsg.csdg.Relationship; import at.ac.tuwien.dsg.csdg.elasticityInformation.elasticityRequirements.Constraint; import at.ac.tuwien.dsg.csdg.elasticityInformation.elasticityRequirements.Strategy; 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.planningEngine.staticData.ActionEffect; import at.ac.tuwien.dsg.rSybl.planningEngine.staticData.ActionEffects; import at.ac.tuwien.dsg.rSybl.planningEngine.utils.Configuration; import at.ac.tuwien.dsg.rSybl.planningEngine.utils.PlanningLogger; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.SortedMap; import java.util.TreeMap; import java.util.logging.Level; import java.util.logging.Logger; /** * * @author Georgiana */ public class PlanningHeuristicSearchWithPolynomialElasticityRelationships implements PlanningAlgorithmInterface{ private int REFRESH_PERIOD = 0; private DependencyGraph dependencyGraph = null; private MonitoringAPIInterface monitoringAPI = null; private ContextRepresentation contextRepresentation = null; private EnforcementAPIInterface enforcementAPI = null; private Thread currentThread = null; private SortedMap<Double, List<ActionEffect>> searchContext = new TreeMap<Double, List<ActionEffect>>(); private double LAMBDA = 1.0; private EventNotification eventNotification; public PlanningHeuristicSearchWithPolynomialElasticityRelationships(DependencyGraph cloudService, MonitoringAPIInterface monitoringAPI, EnforcementAPIInterface enforcementAPI) { this.dependencyGraph = cloudService; this.monitoringAPI = monitoringAPI; this.enforcementAPI = enforcementAPI; this.eventNotification = eventNotification; eventNotification= EventNotification.getEventNotification(); REFRESH_PERIOD = Configuration.getRefreshPeriod(); currentThread = new Thread(this); } 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; } } currentThread.stop(); } public void start() { currentThread.start(); } //recursive public void evaluationStep() { // current evaluation // } public double evaluateUnhealthyState(ContextRepresentation previousContextRepresentation, ContextRepresentation contextRepresentation) { //Todo replace continuosViolation with computation based on ADVISE int continuousViolatedReq = 0; //Lambda discount factor for continuous violations in time due to the enforcement double CS_UNHEALTHY_STATE = LAMBDA * continuousViolatedReq + (contextRepresentation.countFixedStrategies(previousContextRepresentation) + contextRepresentation.countViolatedConstraints()); contextRepresentation.setCS_UNHEALTHY_STATE(CS_UNHEALTHY_STATE); return CS_UNHEALTHY_STATE; } public void checkInstantiation() { List<Relationship> instantiationRelationships = dependencyGraph.getAllRelationshipsOfType(Relationship.RelationshipType.INSTANTIATION); //for } public ActionEffect checkActions(String target) { HashMap<String, List<ActionEffect>> actionEffects = ActionEffects.getActionEffects(); 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; } public void recursiveBranchAndBoundEvaluation() { HashMap<String, List<ActionEffect>> actionEffects = ActionEffects.getActionEffects(); //ToDo - order actions units according to violated requirements if (searchContext.size() > 0) { double bestContext = searchContext.firstKey(); if (bestContext > 0 && searchContext.size() > 0) { List<ActionEffect> actionsSoFar = searchContext.get(bestContext); for (ActionEffect actionEffect : actionsSoFar) { contextRepresentation.doAction(actionEffect); } double prev = contextRepresentation.getCS_UNHEALTHY_STATE(); searchContext.remove(bestContext); for (List<ActionEffect> list : actionEffects.values()) { for (ActionEffect action : list) { if (!actionsSoFar.contains(action)){ MonitoredCloudService monitoredCloudService = contextRepresentation.getMonitoredCloudService().clone(); ContextRepresentation beforeActionContextRepresentation = new ContextRepresentation(monitoredCloudService, monitoringAPI); ArrayList<ActionEffect> actions = new ArrayList<ActionEffect>(); actions.addAll(actionsSoFar); contextRepresentation.doAction(action); actions.add(action); double unhealthy = contextRepresentation.getCS_UNHEALTHY_STATE(); double CS_UNHEALTHY_STATE = evaluateUnhealthyState(beforeActionContextRepresentation, contextRepresentation); contextRepresentation.addActionToContext(action); contextRepresentation.setCS_UNHEALTHY_STATE(CS_UNHEALTHY_STATE); if (CS_UNHEALTHY_STATE < contextRepresentation.getPREVIOUS_CS_UNHEALTHY_STATE()) { searchContext.put(CS_UNHEALTHY_STATE, actions); } /** * ##################################### Explore actions to compensate data impact ################################################### */ List<String> targets = contextRepresentation.simulateDataImpact(beforeActionContextRepresentation, action); 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); actions.add(dataAction); double unhealthy_Compl = contextRepresentation.getCS_UNHEALTHY_STATE(); double CS_UNHEALTHY_STATE_Compl = evaluateUnhealthyState(beforeContext, contextRepresentation); contextRepresentation.addActionToContext(dataAction); contextRepresentation.setCS_UNHEALTHY_STATE(CS_UNHEALTHY_STATE_Compl); //PlanningLogger.logger.info("PlanningAlgorithm: Trying the action due to DATA " + dataAction.getActionName() + "constraints violated : " + contextRepresentation.getViolatedConstraints() + " Strategies improved " + contextRepresentation.getImprovedStrategies(beforeActionContextRepresentation, strategiesThatNeedToBeImproved)); contextRepresentation.addActionToContext(action); contextRepresentation.setCS_UNHEALTHY_STATE(CS_UNHEALTHY_STATE_Compl); if (CS_UNHEALTHY_STATE_Compl < CS_UNHEALTHY_STATE) { searchContext.put(CS_UNHEALTHY_STATE, actions); } contextRepresentation.undoAction(dataAction); } } contextRepresentation.undoDataImpactSimulation(beforeActionContextRepresentation, action); /**** * ######################################## Explore actions to compensate load impact ################################################# */ targets = contextRepresentation.simulateLoadImpact(beforeActionContextRepresentation, action); 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); actions.add(dataAction); double unhealthy_Compl = contextRepresentation.getCS_UNHEALTHY_STATE(); double CS_UNHEALTHY_STATE_Compl = evaluateUnhealthyState(beforeContext, contextRepresentation); contextRepresentation.addActionToContext(dataAction); contextRepresentation.setCS_UNHEALTHY_STATE(CS_UNHEALTHY_STATE_Compl); //PlanningLogger.logger.info("PlanningAlgorithm: Trying the action due to DATA " + dataAction.getActionName() + "constraints violated : " + contextRepresentation.getViolatedConstraints() + " Strategies improved " + contextRepresentation.getImprovedStrategies(beforeActionContextRepresentation, strategiesThatNeedToBeImproved)); contextRepresentation.addActionToContext(action); contextRepresentation.setCS_UNHEALTHY_STATE(CS_UNHEALTHY_STATE_Compl); if (CS_UNHEALTHY_STATE_Compl < CS_UNHEALTHY_STATE) { searchContext.put(CS_UNHEALTHY_STATE, actions); } contextRepresentation.undoAction(dataAction); } } contextRepresentation.undoLoadImpactSimulation(beforeActionContextRepresentation, action); /* * ############################Actions to compensate complex relationships (MELA Discovered) ################################# */ contextRepresentation.undoAction(action); contextRepresentation.setCS_UNHEALTHY_STATE(unhealthy); } } } contextRepresentation.setPREVIOUS_CS_UNHEALTHY_STATE(prev); int i = actionsSoFar.size() - 1; while (i > 0) { contextRepresentation.undoAction(actionsSoFar.get(i)); i--; } recursiveBranchAndBoundEvaluation(); } } } @Override public void run() { while (true) { if (dependencyGraph.isInControlState()){ Node cloudService = monitoringAPI.getControlledService(); dependencyGraph.setCloudService(cloudService); contextRepresentation = new ContextRepresentation(dependencyGraph, monitoringAPI); contextRepresentation.initializeContext(); int continuousViolatedReq = 0; PlanningLogger.logger.info("Violated requirements = " + contextRepresentation.countViolatedConstraints()); double CS_UNHEALTHY_STATE = LAMBDA * continuousViolatedReq + (contextRepresentation.countViolatedConstraints()); contextRepresentation.setCS_UNHEALTHY_STATE(CS_UNHEALTHY_STATE); contextRepresentation.setPREVIOUS_CS_UNHEALTHY_STATE(CS_UNHEALTHY_STATE); searchContext = new TreeMap<Double, List<ActionEffect>>(); ArrayList<ActionEffect> actionEffects = new ArrayList<ActionEffect>(); searchContext.put(CS_UNHEALTHY_STATE, actionEffects); recursiveBranchAndBoundEvaluation(); ActionPlanEnforcement actionPlanEnforcement = new ActionPlanEnforcement(enforcementAPI); ArrayList<ContextRepresentation.Pair<ActionEffect, Integer>> res = new ArrayList<ContextRepresentation.Pair<ActionEffect, Integer>>(); if (searchContext.size() > 0 && searchContext.firstKey() != null) { for (ActionEffect actionEffect : searchContext.get(searchContext.firstKey())) { actionEffect.setTargetedEntity(dependencyGraph.getNodeWithID(actionEffect.getTargetedEntityID())); res.add(contextRepresentation.new Pair<ActionEffect, Integer>(actionEffect, 1)); } } if (res.size() > 0) { actionPlanEnforcement.enforceResult(res, dependencyGraph,new ArrayList<Constraint>(),new ArrayList<Strategy>()); } try { currentThread.sleep(REFRESH_PERIOD); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } }} } @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() { throw new UnsupportedOperationException("Not supported yet."); } }