From 327a49c404a69c8a961c8b1790b457d0b7fcb4d8 Mon Sep 17 00:00:00 2001 From: Nikolaus Huber <nikolaus.huber@uni-wuerzburg.de> Date: Wed, 18 Sep 2013 15:03:23 +0000 Subject: [PATCH] moved some files to here git-svn-id: https://se1.informatik.uni-wuerzburg.de/usvn/svn/code/code/DMM/trunk@13119 9e42b895-fcda-4063-8a3b-11be15eb1bbd --- .../META-INF/MANIFEST.MF | 1 + .../dmm/BlueYonderExperimentTracker.java | 117 ++++++++++ .../model/adaptation/dmm/IObserver.java | 7 + .../model/adaptation/dmm/TacticExecutor.java | 201 ++++++++++++++++++ .../model/adaptation/dmm/TacticsHistory.java | 78 +++++++ 5 files changed, 404 insertions(+) create mode 100644 edu.kit.ipd.descartes.adaptation.model.adaptation/src/edu/kit/ipd/descartes/adaptation/model/adaptation/dmm/BlueYonderExperimentTracker.java create mode 100644 edu.kit.ipd.descartes.adaptation.model.adaptation/src/edu/kit/ipd/descartes/adaptation/model/adaptation/dmm/IObserver.java create mode 100644 edu.kit.ipd.descartes.adaptation.model.adaptation/src/edu/kit/ipd/descartes/adaptation/model/adaptation/dmm/TacticExecutor.java create mode 100644 edu.kit.ipd.descartes.adaptation.model.adaptation/src/edu/kit/ipd/descartes/adaptation/model/adaptation/dmm/TacticsHistory.java diff --git a/edu.kit.ipd.descartes.adaptation.model.adaptation/META-INF/MANIFEST.MF b/edu.kit.ipd.descartes.adaptation.model.adaptation/META-INF/MANIFEST.MF index 44adc257..1aba5778 100644 --- a/edu.kit.ipd.descartes.adaptation.model.adaptation/META-INF/MANIFEST.MF +++ b/edu.kit.ipd.descartes.adaptation.model.adaptation/META-INF/MANIFEST.MF @@ -22,6 +22,7 @@ Import-Package: org.eclipse.emf.common, org.eclipse.emf.common.util, org.eclipse.emf.ecore, + org.eclipse.emf.ecore.change, org.eclipse.emf.ecore.util, org.eclipse.ocl.ecore, org.osgi.framework;version="1.3.0" diff --git a/edu.kit.ipd.descartes.adaptation.model.adaptation/src/edu/kit/ipd/descartes/adaptation/model/adaptation/dmm/BlueYonderExperimentTracker.java b/edu.kit.ipd.descartes.adaptation.model.adaptation/src/edu/kit/ipd/descartes/adaptation/model/adaptation/dmm/BlueYonderExperimentTracker.java new file mode 100644 index 00000000..1391cd5f --- /dev/null +++ b/edu.kit.ipd.descartes.adaptation.model.adaptation/src/edu/kit/ipd/descartes/adaptation/model/adaptation/dmm/BlueYonderExperimentTracker.java @@ -0,0 +1,117 @@ +package edu.kit.ipd.descartes.adaptation.model.adaptation.dmm; + +import edu.kit.ipd.descartes.mm.adaptation.WeightedTactic; +import edu.kit.ipd.descartes.mm.resourcelandscape.ComputingInfrastructure; +import edu.kit.ipd.descartes.mm.resourcelandscape.DistributedDataCenter; + +public class BlueYonderExperimentTracker implements IObserver { + +// private static final String RESULT_NAME_TEMPLATE = "Xreq-par-$1Yps-desc4-gw-desc3-db-desc2-predict-Z ps=$2-req=5-size=50000"; + private static final String RESULT_NAME_TEMPLATE = "Xreq-par-$1$3Yps-desc4-gw-desc3-db-desc2-predict-Z ps=$2-req=40-size=500000"; +// private static final String RESULT_NAME_TEMPLATE = "Xreq-par-$1$3Yps-desc4-gw-desc3-db-desc2-predict-Z ps=$2-req=30-size=500000"; + private static BlueYonderExperimentTracker instance = null; + private int psOnDescOne = 0; + private int psOnDescFour = 1; + private int psOnDescOneBackup; + private int psOnDescFourBackup; + + public void setSubject(TacticExecutor te) { + te.register(this); + } + + public String getCurrentExperimentName() { + String result = RESULT_NAME_TEMPLATE; + + if (psOnDescOne > 0) + result = RESULT_NAME_TEMPLATE.replace("$1", psOnDescOne + "ps-desc1-"); + else + result = RESULT_NAME_TEMPLATE.replace("$1", ""); + + result = result.replace("$2", Integer.toString(psOnDescFour)); + return result; + } + + public void track(WeightedTactic tactic) { + String execTacticName = tactic.getName(); + backupValues(); + + if (execTacticName.contains("Consolidate")) { + int loopCount = 1; + try { + loopCount = Integer.parseInt(tactic.getUsedTactic().getInputParams().get(0).getValue()); + } catch (Exception e) { + + } + if (execTacticName.contains("Low")) { + psOnDescFour = psOnDescFour - loopCount; + psOnDescOne = psOnDescOne + loopCount; + } else if (execTacticName.contains("High")) { + psOnDescOne = psOnDescOne - loopCount; + psOnDescFour = psOnDescFour + loopCount; + } + } else if (execTacticName.contains("Low")) { + psOnDescOne++; + if (execTacticName.contains("Migrate")) { + assert psOnDescFour > 0; + psOnDescFour--; + } + } else if (execTacticName.contains("High")) { + psOnDescFour++; + if (execTacticName.contains("Migrate")) { + assert psOnDescOne > 0; + psOnDescOne--; + } + } + } + + private void backupValues() { + psOnDescOneBackup = psOnDescOne; + psOnDescFourBackup = psOnDescFour; + } + + @Override + public void undo() { + resetValues(); + } + + private void resetValues() { + psOnDescOne = psOnDescOneBackup; + psOnDescFour = psOnDescFourBackup; + } + + public static BlueYonderExperimentTracker getInstance() { + if (instance == null) + instance = new BlueYonderExperimentTracker(); + return instance; + } + + public String getExperimentNameForDistributedDataCenter(DistributedDataCenter distributedDataCenter) { + int[] psInstances = new int[4]; // 4 because currently we have 4 machines in the BY scenario + + for (int i = 0; i < psInstances.length; i++) + { + try { + // Count number of instances on the desc1 - desc4 machines + psInstances[i] = ((ComputingInfrastructure) distributedDataCenter.getConsistsOf().get(0).getContains().get(i)).getContains().size(); + } catch (Exception e) { + // If machine does not exist, there are also no instances on it + psInstances[i] = 0; + } + } + + String result = RESULT_NAME_TEMPLATE; + + if (psInstances[0] > 0) + result = result.replace("$1", psInstances[0] + "ps-desc1-"); + else + result = result.replace("$1", ""); + + if (psInstances[1] > 1) // subtract 1 instance because GW/DB is also running here + result = result.replace("$3", (psInstances[1] - 1) + "ps-desc2-"); + else + result = result.replace("$3", ""); + + result = result.replace("$2", Integer.toString(psInstances[3])); + return result; + } +} diff --git a/edu.kit.ipd.descartes.adaptation.model.adaptation/src/edu/kit/ipd/descartes/adaptation/model/adaptation/dmm/IObserver.java b/edu.kit.ipd.descartes.adaptation.model.adaptation/src/edu/kit/ipd/descartes/adaptation/model/adaptation/dmm/IObserver.java new file mode 100644 index 00000000..52fcaaf2 --- /dev/null +++ b/edu.kit.ipd.descartes.adaptation.model.adaptation/src/edu/kit/ipd/descartes/adaptation/model/adaptation/dmm/IObserver.java @@ -0,0 +1,7 @@ +package edu.kit.ipd.descartes.adaptation.model.adaptation.dmm; + +public interface IObserver { + + public void undo(); + +} diff --git a/edu.kit.ipd.descartes.adaptation.model.adaptation/src/edu/kit/ipd/descartes/adaptation/model/adaptation/dmm/TacticExecutor.java b/edu.kit.ipd.descartes.adaptation.model.adaptation/src/edu/kit/ipd/descartes/adaptation/model/adaptation/dmm/TacticExecutor.java new file mode 100644 index 00000000..baeeb5ef --- /dev/null +++ b/edu.kit.ipd.descartes.adaptation.model.adaptation/src/edu/kit/ipd/descartes/adaptation/model/adaptation/dmm/TacticExecutor.java @@ -0,0 +1,201 @@ +package edu.kit.ipd.descartes.adaptation.model.adaptation.dmm; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.apache.log4j.Logger; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.change.ChangeDescription; + +import edu.kit.ipd.descartes.adaptation.model.adaptation.IActionHandler; +import edu.kit.ipd.descartes.adaptation.model.adaptation.dmm.util.OclEvaluationHelper; +import edu.kit.ipd.descartes.adaptation.model.adaptation.exceptions.InvalidAdaptationPlan; +import edu.kit.ipd.descartes.adaptation.model.adaptation.exceptions.OperationNotPerformedException; +import edu.kit.ipd.descartes.adaptation.model.repository.dmm.AdaptationProcessModelLoader; +import edu.kit.ipd.descartes.mm.adaptation.AbstractControlFlowElement; +import edu.kit.ipd.descartes.mm.adaptation.Action; +import edu.kit.ipd.descartes.mm.adaptation.ActionReference; +import edu.kit.ipd.descartes.mm.adaptation.AdaptationPlan; +import edu.kit.ipd.descartes.mm.adaptation.BranchAction; +import edu.kit.ipd.descartes.mm.adaptation.LoopAction; +import edu.kit.ipd.descartes.mm.adaptation.Parameter; +import edu.kit.ipd.descartes.mm.adaptation.StartAction; +import edu.kit.ipd.descartes.mm.adaptation.StopAction; +import edu.kit.ipd.descartes.mm.adaptation.WeightedTactic; +import edu.kit.ipd.descartes.mm.adaptationpoints.AdaptationPoint; +import edu.kit.ipd.descartes.mm.containerrepository.ContainerrepositoryPackage; +import edu.kit.ipd.descartes.mm.resourcelandscape.ResourcelandscapePackage; + +public class TacticExecutor { + + private static Logger logger = Logger.getLogger(TacticExecutor.class); + private List<IObserver> observers = new ArrayList<IObserver>(); + + private IActionHandler dmmModelActionHandler; + private TacticsHistory hist; + private ChangeDescription changeDescription = null; + + public TacticExecutor(IActionHandler actionExecutor) { + dmmModelActionHandler = actionExecutor; + hist = TacticsHistory.getInstance(); + register(BlueYonderExperimentTracker.getInstance()); // TODO implement clean observer + // pattern + } + + /** + * Applies the the given tactic. + * + * @param currentTactic + * The tactic to execute + * @return + */ + public void applyTactic(WeightedTactic weightedTactic) { + try { + logger.info("Applying tactic " + weightedTactic.getUsedTactic().getName() + ", ID: " + + weightedTactic.getUsedTactic().getId() + "."); + AdaptationProcessModelLoader.startRecording(); + executeAdaptationPlan(weightedTactic.getUsedTactic().getImplementedPlan()); + logger.info("Tactic " + weightedTactic.getUsedTactic().getName() + " successfully applied."); + hist.add(weightedTactic, TacticsHistory.NO_RESULT, true); + + // if this point is reached everything was fine, so persist them (save the models) + dmmModelActionHandler.persistActions(); + changeDescription = AdaptationProcessModelLoader.endRecording(); + return; + } catch (OperationNotPerformedException e) { + logger.error("Tactic " + weightedTactic.getUsedTactic().getName() + + " could not be executed. Please check adaptation plan and/or log files for errors.", e); + hist.add(weightedTactic, TacticsHistory.NO_RESULT, false); + /* + * TODO Something went wrong. 1) Detect error 2) reevaluate tactics 3) apply different + * tactic. + */ + } + } + + private StartAction findStartAction(AdaptationPlan plan) { + for (AbstractControlFlowElement abstractControlFlowElement : plan.getSteps()) { + // Find start of adaptation plan + if (abstractControlFlowElement instanceof StartAction) { + return (StartAction) abstractControlFlowElement; + } + } + return null; + } + + /** + * Executes the given {@link AdaptationPlan}. + * + * @param plan + * The adaptation plan to execute + * @throws IOException + * @throws OperationNotPerformedException + */ + private void executeAdaptationPlan(AdaptationPlan plan) throws OperationNotPerformedException { + + StartAction start = findStartAction(plan); + if (start == null) + throw new OperationNotPerformedException("No start action for adaptation plan " + plan.getName() + + " found."); + + try { + executeNextStep(start.getSuccessor()); + } catch (InvalidAdaptationPlan e) { + logger.error( + "Invalid adaptation plan <<" + plan.getName() + ">> when executing action with ID <<" + + start.getId() + ">>.", e); + } + } + + private void executeNextStep(AbstractControlFlowElement step) throws OperationNotPerformedException, + InvalidAdaptationPlan { + + if (step == null) + throw new InvalidAdaptationPlan("Current AbstractControlFlowElement is null!"); + + if (step instanceof StopAction) { + return; + } else if (step instanceof BranchAction) { + executeBranchAction(step); + } else if (step instanceof LoopAction) { + execLoopAction(step); + } else if (step instanceof ActionReference) { + executeReferredAction(step); + } else + // Handle invalid actions and control flow elements + throw new OperationNotPerformedException("No valid control flow element " + step.toString()); + + // in any case (except stop action) + // continue with the next step + executeNextStep(step.getSuccessor()); + } + + private void executeReferredAction(AbstractControlFlowElement step) throws OperationNotPerformedException { + ActionReference ref = (ActionReference) step; + Action action = ref.getRefersTo(); + logger.info("Executing action <<" + action.getName() + ">>."); + AdaptationPoint currentAdaptationPoint = action.getReferredAdaptationPoint(); + + dmmModelActionHandler.execute(currentAdaptationPoint, action.getAdaptationActionOperation()); + } + + private void executeBranchAction(AbstractControlFlowElement branchAction) throws OperationNotPerformedException { + BranchAction branch = (BranchAction) branchAction; + if (isBranchConditionTrue(branch.getContext(), branch.getCondition())) + executeAdaptationPlan(branch.getConditionTrueBranch()); + else + executeAdaptationPlan(branch.getConditionFalseBranch()); + } + + private void execLoopAction(AbstractControlFlowElement loopAction) throws OperationNotPerformedException { + LoopAction loop = (LoopAction) loopAction; + Parameter counter = loop.getCounter(); + int counterValue = Integer.parseInt(counter.getValue()); + + int i = 1; + + while (i <= counterValue) { + logger.debug("Executing iteration " + i + " of loop action " + loop.getBody().getName()); + executeAdaptationPlan(loop.getBody()); + i++; + } + } + + private boolean isBranchConditionTrue(EObject obj, String branchCondition) { + + EClass context = null; + + switch (obj.eClass().getClassifierID()) { + case ResourcelandscapePackage.RUNTIME_ENVIRONMENT: + context = ResourcelandscapePackage.Literals.RUNTIME_ENVIRONMENT; + break; + case ContainerrepositoryPackage.CONTAINER_TEMPLATE: + context = ContainerrepositoryPackage.Literals.CONTAINER_TEMPLATE; + break; + // TODO add further contexts if necessary + default: + logger.error("Could not set context for eClass " + obj.getClass()); + return false; + } + + boolean invariant = OclEvaluationHelper.evaluateOclConstraint(obj, branchCondition, context); + return invariant; + } + + public void undoPreviousTactic() { + logger.info("Reverting model to previous state"); + if (changeDescription != null) + changeDescription.apply(); + } + + public void register(IObserver observer) { + observers.add(observer); + } + + public void remove(IObserver observer) { + observers.remove(observer); + } + +} diff --git a/edu.kit.ipd.descartes.adaptation.model.adaptation/src/edu/kit/ipd/descartes/adaptation/model/adaptation/dmm/TacticsHistory.java b/edu.kit.ipd.descartes.adaptation.model.adaptation/src/edu/kit/ipd/descartes/adaptation/model/adaptation/dmm/TacticsHistory.java new file mode 100644 index 00000000..0dc0cbda --- /dev/null +++ b/edu.kit.ipd.descartes.adaptation.model.adaptation/src/edu/kit/ipd/descartes/adaptation/model/adaptation/dmm/TacticsHistory.java @@ -0,0 +1,78 @@ +package edu.kit.ipd.descartes.adaptation.model.adaptation.dmm; + +import java.io.PrintStream; +import java.io.PrintWriter; +import java.util.LinkedList; +import java.util.List; + +import edu.kit.ipd.descartes.mm.adaptation.WeightedTactic; + +public class TacticsHistory { + + public static final String NO_RESULT = "NoResult"; + + private List<WeightedTactic> wTactic; + private List<String> result; + private List<Boolean> tacticWasSuccessful; + + private static TacticsHistory instance = null; + + private TacticsHistory() { + wTactic = new LinkedList<WeightedTactic>(); + result = new LinkedList<String>(); + tacticWasSuccessful = new LinkedList<Boolean>(); + } + + public static TacticsHistory getInstance() { + if (instance == null) + instance = new TacticsHistory(); + + return instance; + } + + public void add(WeightedTactic weightedTactic, String resultId, + boolean tacticWasSuccesful) { + wTactic.add(weightedTactic); + result.add(resultId); + this.tacticWasSuccessful.add(tacticWasSuccesful); + } + + public WeightedTactic getLatestAppliedTactic() { + if (wTactic.size() <= 0) + return null; + else + return wTactic.get(wTactic.size() - 1); + } + + public String getLatestResultId() { + return result.get(result.size() - 1); + } + + public boolean wasLatestTacticSuccessful() { + return tacticWasSuccessful.get(tacticWasSuccessful.size() - 1); + } + + public int size() { + if (wTactic.size() == result.size() && result.size() == tacticWasSuccessful.size()) + return wTactic.size(); + return -1; + } + + public void printToSysOut() { + print(System.out); + } + + private void print(PrintStream stream) { + PrintWriter out = new PrintWriter(stream); + + out.println(" A P P L I E D T A C T I C S "); + + for (int i = 0; i < wTactic.size(); i++) { + out.print(String + .format("Applied tactic %1$3d: %2$30s. Result ID: %3$20s. Successful: %4$5s.%n", + i + 1, wTactic.get(i).getUsedTactic().getName(), + result.get(i), tacticWasSuccessful.get(i))); + } + out.flush(); + } +} -- GitLab