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