From 47f13292f22ea339895da6f70eff4f187d7452d9 Mon Sep 17 00:00:00 2001
From: Nikolaus Huber <nikolaus.huber@uni-wuerzburg.de>
Date: Thu, 6 Jun 2013 14:03:02 +0000
Subject: [PATCH] git-svn-id:
 https://se1.informatik.uni-wuerzburg.de/usvn/svn/code/code/DMM/trunk@11963
 9e42b895-fcda-4063-8a3b-11be15eb1bbd

---
 .../META-INF/MANIFEST.MF                      |   4 +-
 .../default.properties                        |   4 +-
 .../adaptation/AdaptationControl.java         | 133 +++++++++++-------
 .../actions/StartAdaptationAction.java        |   2 -
 .../adaptation/evaluation/IEvaluator.java     |  15 +-
 .../WeightingFunctionEvaluator.java           |  31 +++-
 .../weightingfunction/ResourceEfficiency.java |  10 +-
 .../model/dmm/util/ObjectivesHelper.java      |   2 +-
 .../PerformanceDataRepositoryHandler.java     |   6 +-
 .../adaptation/ql/QueryEngineAdapter.java     |   1 +
 10 files changed, 140 insertions(+), 68 deletions(-)

diff --git a/edu.kit.ipd.descartes.adaptation/META-INF/MANIFEST.MF b/edu.kit.ipd.descartes.adaptation/META-INF/MANIFEST.MF
index 8a29ebc1..e8ee7016 100644
--- a/edu.kit.ipd.descartes.adaptation/META-INF/MANIFEST.MF
+++ b/edu.kit.ipd.descartes.adaptation/META-INF/MANIFEST.MF
@@ -10,14 +10,14 @@ Require-Bundle: org.eclipse.osgi;bundle-version="3.8.2",
  org.eclipse.ocl,
  edu.kit.ipd.descartes.mm.resourcelandscape;bundle-version="1.0.0",
  edu.kit.ipd.descartes.mm.adaptation;bundle-version="1.0.0",
- edu.kit.ipd.descartes.ql.core.engine;bundle-version="1.0.0",
- org.apache.log4j;bundle-version="1.2.15"
+ edu.kit.ipd.descartes.ql.core.engine;bundle-version="1.0.0"
 Bundle-ActivationPolicy: lazy
 Bundle-RequiredExecutionEnvironment: JavaSE-1.6
 Import-Package: edu.kit.ipd.descartes.ql.lang.descartesQL,
  edu.kit.ipd.descartes.ql.models.mapping.domain,
  edu.kit.ipd.descartes.ql.models.mapping.mapping,
  edu.kit.ipd.descartes.ql.models.repository,
+ org.apache.log4j;version="1.2.15",
  org.eclipse.core.resources,
  org.eclipse.emf.ecore.xmi.impl,
  org.eclipse.ocl.ecore
diff --git a/edu.kit.ipd.descartes.adaptation/default.properties b/edu.kit.ipd.descartes.adaptation/default.properties
index 63d10d40..8ffcc9af 100644
--- a/edu.kit.ipd.descartes.adaptation/default.properties
+++ b/edu.kit.ipd.descartes.adaptation/default.properties
@@ -32,8 +32,8 @@
 
 process.name=SEAMS_PushPull-v1
 adaptationprocess.instance=/Users/nhuber/Documents/workspace/descartes/metamodel/Examples/SEAMS_Case_Study/pushpull.adaptation
-perfdatarepo.metamodel=edu.kit.ipd.descartes.ql.models.repository.ObservationRepository
-perfdatarepo.instance=/Users/nhuber/Documents/workspace/descartes/metamodel/Examples/SEAMS_Case_Study/pushpull-simresults.pdr
+perfdatarepo.metamodel=edu.kit.ipd.descartes.perfdatarepo.PerformanceDataRepository
+perfdatarepo.instance=/Users/nhuber/Documents/workspace/descartes/metamodel/Examples/SEAMS_Case_Study/simucomresults.perfdatarepo
 process.maxiterations=2
 # The list of triggering events can be found in EventTypeEnum.java
 event.type=SlaViolatedEvent
\ No newline at end of file
diff --git a/edu.kit.ipd.descartes.adaptation/src/edu/kit/ipd/descartes/adaptation/AdaptationControl.java b/edu.kit.ipd.descartes.adaptation/src/edu/kit/ipd/descartes/adaptation/AdaptationControl.java
index 68a6b577..52fc8cfe 100644
--- a/edu.kit.ipd.descartes.adaptation/src/edu/kit/ipd/descartes/adaptation/AdaptationControl.java
+++ b/edu.kit.ipd.descartes.adaptation/src/edu/kit/ipd/descartes/adaptation/AdaptationControl.java
@@ -10,6 +10,7 @@ import org.apache.log4j.Logger;
 import org.eclipse.emf.common.util.URI;
 import org.eclipse.emf.ecore.xmi.DanglingHREFException;
 
+import edu.kit.ipd.descartes.adaptation.evaluation.IEvaluator;
 import edu.kit.ipd.descartes.adaptation.evaluation.WeightingFunctionEvaluator;
 import edu.kit.ipd.descartes.adaptation.event.EventTypeEnum;
 import edu.kit.ipd.descartes.adaptation.model.analysis.IModelAnalyzer;
@@ -47,7 +48,7 @@ public class AdaptationControl {
     private AdaptationProcess adaptationProcess = null;
     private TacticExecutor executor = null;
     private IModelAnalyzer modelAnalyzer = null;
-    private WeightingFunctionEvaluator evaluator = null;
+    private IEvaluator evaluator = null;
 
     private int iteration = 0;
     private int maxIterations = 0;
@@ -61,11 +62,36 @@ public class AdaptationControl {
         prepare(args[0]);
     }
 
+    public void init(String propertiesFile) {
+    
+        if (propertiesFile == null || propertiesFile.equals("")) {
+            logger.warn("No properties file given. Using default properties...");
+            propertiesFile = DEFAULT_PROP_FILE_PATH;
+        }
+        try {
+            // load properties file
+            loadProperties(propertiesFile);
+    
+            // load required models
+            adaptationProcess = adaptationProcessModelLoader.load(URI.createFileURI(adaptationProcessXmiFilePath));
+            perfdatarepo = PerformanceDataRepositoryHandlerFactory.createHandler(pdrMetamodelType);
+            perfdatarepo.load(performanceDataRepoXmiFilePath);
+    
+            // set handlers
+            executor = new TacticExecutor(new DmmModelActionHandler());
+            modelAnalyzer = new PcmModelAnalyzer();
+            evaluator = new WeightingFunctionEvaluator();
+        } catch (IOException e) {
+            logger.error("Error while initializinig controller.", e);
+            abort();
+        }
+    }
+
     /* (non-Javadoc) refactor this after integration of QL Engine */
     private static void prepare(String propertiesfile) {
         BasicConfigurator.configure();
         Logger.getRootLogger().setLevel(Level.DEBUG);
-        
+
         AdaptationControl adaptationController = new AdaptationControl();
         // Initialize controller (load models, create Action perfdatarepo, etc.)
         adaptationController.init(propertiesfile);
@@ -86,14 +112,15 @@ public class AdaptationControl {
             return;
         }
 
-        while (!isProblemSolved() && iteration < maxIterations) {
+        while (!isObjectiveFulfilled() && iteration < maxIterations) {
             // Execute the strategie's tactic with the currently highest weight
             WeightedTactic currentTactic = currentStrategy.getTacticWithHighestWeight();
 
             applyTactic(currentTactic);
             analyzeModel();
             processResults(currentTactic);
-            evaluator.evaluate(currentTactic);
+            evaluate(currentTactic);
+           
 
             // save results
             try {
@@ -104,7 +131,7 @@ public class AdaptationControl {
                     logger.error("Error while persisting results because of dangling references. Probably not all changes have been saved");
                 else
                     logger.error("Error while persisting evaluation results.", e);
-            } 
+            }
 
             iteration++;
         }
@@ -113,36 +140,64 @@ public class AdaptationControl {
 
     }
 
-    private boolean isProblemSolved() {
-        boolean flag = ObjectivesHelper.isProblemSolved(cause, perfdatarepo.getCurrentSystemState());
+    /**
+     * Checks if the objective of the strategy that has been triggered by the event is fulfilled. If
+     * yes, we can stop the adaptation process.
+     * 
+     * @return
+     */
+    public boolean isObjectiveFulfilled() {
+        boolean flag = ObjectivesHelper.isObjectiveFulfilled(cause, perfdatarepo.getCurrentSystemState());
         if (flag)
-            logger.debug("Problem that caused event " + cause.getName() + " has been solved.");
+            logger.info("Problem that caused event " + cause.getName() + " has been solved, Objective is fulfilled.");
         return flag;
     }
 
-    public void init(String propertiesFile) {
+    /**
+     * Applies the given tactic.
+     * 
+     * @param weightedTactic
+     */
+    public void applyTactic(WeightedTactic weightedTactic) {
+        executor.applyTactic(weightedTactic);
+    }
 
-        if (propertiesFile == null || propertiesFile.equals("")) {
-            logger.warn("No properties file given. Using default properties...");
-            propertiesFile = DEFAULT_PROP_FILE_PATH;
-        }
-        try {
-            // load properties file
-            loadProperties(propertiesFile);
+    /** 
+     * Choose a suitable model analyzer and analyze the reconfigured model.
+     */
+    public void analyzeModel() {
+        modelAnalyzer.analyze();
+    }
 
-            // load required models
-            adaptationProcess = adaptationProcessModelLoader.load(URI.createFileURI(adaptationProcessXmiFilePath));
-            perfdatarepo = PerformanceDataRepositoryHandlerFactory.createHandler(pdrMetamodelType);
-            perfdatarepo.load(performanceDataRepoXmiFilePath);
+    /**
+     * Process the results of the applied weighted tactic. For example,
+     * store the results in a performance data repository. 
+     * 
+     * @param tactic
+     */
+    public void processResults(WeightedTactic tactic) {
+    
+        Impact latestImpact = perfdatarepo.getImpactAt(iteration);
+        // Connect parsed results to the executed tactic
+        if (latestImpact != null)
+            tactic.setLastImpact(latestImpact);
+    }
 
-            // set handlers
-            executor = new TacticExecutor(new DmmModelActionHandler());
-            modelAnalyzer = new PcmModelAnalyzer();
-            evaluator = new WeightingFunctionEvaluator();
-        } catch (IOException e) {
-            logger.error("Error while initializinig controller.", e);
-            abort();
+    /** 
+     * Evaluates the impact of the tactic and assigns weights according to the specified weighting function.
+     * 
+     * @param tactic
+     */
+    public void evaluate(WeightedTactic tactic) {
+        // Check if tactic has made anything stupid, i.e., violates the objectives. If yes, undo and/or assign bad weight.
+        if (evaluator.degradationDetected(tactic)) {
+            logger.warn("Degradation detected for tactic " + tactic.getName());
+            // undo tactic
+            // assign negative weight
         }
+        
+        // If everything is fine, assign new weight.
+        evaluator.evaluate(tactic);
     }
 
     /**
@@ -185,7 +240,7 @@ public class AdaptationControl {
 
         for (Strategy strategy : adaptationProcess.getStrategies()) {
             Event event = strategy.getTriggeringEvents();
-            if (event.getId().equals(type.getId())&&event.getName().equals(type.getName())){
+            if (event.getId().equals(type.getId()) && event.getName().equals(type.getName())) {
                 cause = event;
                 return event;
             }
@@ -194,22 +249,6 @@ public class AdaptationControl {
         return null;
     }
 
-    private void processResults(WeightedTactic tactic) {
-
-        Impact latestImpact = perfdatarepo.getImpactAt(iteration);
-        // Connect parsed results to the executed tactic
-        if (latestImpact != null)
-            tactic.setLastImpact(latestImpact);
-    }
-
-    private void analyzeModel() {
-        modelAnalyzer.analyze();
-    }
-
-    private void applyTactic(WeightedTactic weightedTactic) {
-        executor.applyTactic(weightedTactic);
-    }
-
     private void printLogInformation() {
         TacticsHistory hist = TacticsHistory.getInstance();
         hist.printToSysOut();
@@ -217,13 +256,13 @@ public class AdaptationControl {
 
     private Strategy findTriggeredStrategy(Event event) {
 
-        logger.debug("Searching for suitable strategy for caught event: " + event.getName() + " (ID: " + event.getId() + ")");
+        logger.debug("Searching for suitable strategy for caught event: " + event.getName() + " (ID: " + event.getId()
+                + ")");
 
         for (Strategy strategy : adaptationProcess.getStrategies()) {
             if (strategy.getTriggeringEvents().getId().equals(event.getId())
                     && strategy.getTriggeringEvents().getName().equals(event.getName())) {
-                logger.debug("Found suitable strategy " + strategy.getName() + " for event "
-                        + event.getName());
+                logger.debug("Found suitable strategy " + strategy.getName() + " for event " + event.getName());
                 return strategy;
             }
         }
diff --git a/edu.kit.ipd.descartes.adaptation/src/edu/kit/ipd/descartes/adaptation/actions/StartAdaptationAction.java b/edu.kit.ipd.descartes.adaptation/src/edu/kit/ipd/descartes/adaptation/actions/StartAdaptationAction.java
index c6d4442d..48099199 100644
--- a/edu.kit.ipd.descartes.adaptation/src/edu/kit/ipd/descartes/adaptation/actions/StartAdaptationAction.java
+++ b/edu.kit.ipd.descartes.adaptation/src/edu/kit/ipd/descartes/adaptation/actions/StartAdaptationAction.java
@@ -6,8 +6,6 @@ import org.eclipse.jface.viewers.ISelection;
 import org.eclipse.ui.IWorkbenchWindow;
 import org.eclipse.ui.IWorkbenchWindowActionDelegate;
 
-import edu.kit.ipd.descartes.adaptation.ql.QueryEngineAdapter;
-
 /**
  * Our sample action implements workbench action delegate.
  * The action proxy will be created by the workbench and
diff --git a/edu.kit.ipd.descartes.adaptation/src/edu/kit/ipd/descartes/adaptation/evaluation/IEvaluator.java b/edu.kit.ipd.descartes.adaptation/src/edu/kit/ipd/descartes/adaptation/evaluation/IEvaluator.java
index c789ef4d..f66e9e70 100644
--- a/edu.kit.ipd.descartes.adaptation/src/edu/kit/ipd/descartes/adaptation/evaluation/IEvaluator.java
+++ b/edu.kit.ipd.descartes.adaptation/src/edu/kit/ipd/descartes/adaptation/evaluation/IEvaluator.java
@@ -6,15 +6,24 @@ import edu.kit.ipd.descartes.mm.adaptation.WeightedTactic;
  * Evaluates a tactic.
  * 
  * @author nhuber
- *
+ * 
  */
 public interface IEvaluator {
-    
+
     /**
      * Evaluates the impact of a {@link WeightedTactic}.
      * 
-     * @param wt The weighted tactic to evaluate
+     * @param wt
+     *            The weighted tactic to evaluate
      */
     public void evaluate(WeightedTactic wt);
 
+    /**
+     * Checks if any QoS property has degraded significantly after applying the tactic.
+     * 
+     * @param tactic
+     * @return
+     */
+    public boolean degradationDetected(WeightedTactic tactic);
+
 }
diff --git a/edu.kit.ipd.descartes.adaptation/src/edu/kit/ipd/descartes/adaptation/evaluation/WeightingFunctionEvaluator.java b/edu.kit.ipd.descartes.adaptation/src/edu/kit/ipd/descartes/adaptation/evaluation/WeightingFunctionEvaluator.java
index 91ec0e64..151f37a0 100644
--- a/edu.kit.ipd.descartes.adaptation/src/edu/kit/ipd/descartes/adaptation/evaluation/WeightingFunctionEvaluator.java
+++ b/edu.kit.ipd.descartes.adaptation/src/edu/kit/ipd/descartes/adaptation/evaluation/WeightingFunctionEvaluator.java
@@ -1,10 +1,15 @@
 package edu.kit.ipd.descartes.adaptation.evaluation;
 
 import org.apache.log4j.Logger;
+import org.eclipse.emf.common.util.EList;
 
 import edu.kit.ipd.descartes.adaptation.evaluation.weightingfunction.IWeightingFunction;
+import edu.kit.ipd.descartes.adaptation.evaluation.weightingfunction.WeightedSumWeightingFunctionHelper;
 import edu.kit.ipd.descartes.mm.adaptation.WeightedTactic;
 import edu.kit.ipd.descartes.mm.adaptation.WeightingFunction;
+import edu.kit.ipd.descartes.perfdatarepo.Impact;
+import edu.kit.ipd.descartes.perfdatarepo.MetricValue;
+import edu.kit.ipd.descartes.perfdatarepo.Result;
 
 /**
  * Evaluates a given {@link WeightedTactic} using the weighted tactic's {@link WeightingFunction}.
@@ -14,6 +19,7 @@ import edu.kit.ipd.descartes.mm.adaptation.WeightingFunction;
  */
 public class WeightingFunctionEvaluator implements IEvaluator {
 
+    private static final String RESPONSETIME_IDENTIFIER = "time";
     private IWeightingFunction calculator = null;
     private static Logger logger = Logger.getLogger(WeightingFunctionEvaluator.class);
 
@@ -25,7 +31,7 @@ public class WeightingFunctionEvaluator implements IEvaluator {
     @Override
     public void evaluate(WeightedTactic tactic) {
         WeightingFunction f = tactic.getParentStrategy().getWeightingFunction();
-        
+
         final String functionClassName = f.getWeightingFunctionImplementation();
 
         Object o = null;
@@ -42,11 +48,32 @@ public class WeightingFunctionEvaluator implements IEvaluator {
         if (!IWeightingFunction.class.isInstance(o)) {
             throw new RuntimeException("Expected a class implementing " + IWeightingFunction.class.getName());
         }
-        
+
         calculator = (IWeightingFunction) o;
         calculator.setWeightingFunction(f);
         double newWeight = calculator.calculateWeight(tactic);
         logger.debug("Setting new weight of " + tactic.getName() + " to " + newWeight);
         tactic.setCurrentWeight(newWeight);
     }
+
+    public boolean degradationDetected(WeightedTactic tactic) {
+        Impact impact = tactic.getLastImpact();
+        Result before = impact.getBefore();
+        Result after = impact.getAfter();
+        EList<MetricValue> afterMetricValues = after.getMetricValues();
+
+        for (MetricValue afterMetricValue : afterMetricValues) {
+            // calculated delta=(after-before)
+            double afterValue = afterMetricValue.getValue();
+            double beforeValue = WeightedSumWeightingFunctionHelper.getValueForMetricType(
+                    afterMetricValue.getMetricType(), before);
+
+            if (afterMetricValue.getMetricType().getName().contains(RESPONSETIME_IDENTIFIER)
+                    && afterValue > beforeValue) {
+                return true;
+            }
+        }
+
+        return false;
+    }
 }
diff --git a/edu.kit.ipd.descartes.adaptation/src/edu/kit/ipd/descartes/adaptation/evaluation/weightingfunction/ResourceEfficiency.java b/edu.kit.ipd.descartes.adaptation/src/edu/kit/ipd/descartes/adaptation/evaluation/weightingfunction/ResourceEfficiency.java
index 298115fa..831f34c4 100644
--- a/edu.kit.ipd.descartes.adaptation/src/edu/kit/ipd/descartes/adaptation/evaluation/weightingfunction/ResourceEfficiency.java
+++ b/edu.kit.ipd.descartes.adaptation/src/edu/kit/ipd/descartes/adaptation/evaluation/weightingfunction/ResourceEfficiency.java
@@ -1,13 +1,7 @@
 package edu.kit.ipd.descartes.adaptation.evaluation.weightingfunction;
 
 import org.apache.log4j.Logger;
-import org.eclipse.emf.common.util.EList;
 
-import edu.kit.ipd.descartes.adaptation.model.AbstractEcoreModelLoader;
-import edu.kit.ipd.descartes.adaptation.model.perfdatarepo.IPerformanceDataRepositoryHandler;
-import edu.kit.ipd.descartes.adaptation.model.perfdatarepo.PerformanceDataRepositoryHandler;
-import edu.kit.ipd.descartes.adaptation.model.perfdatarepo.PerformanceDataRepositoryModelLoader;
-import edu.kit.ipd.descartes.adaptation.ql.QueryEngineAdapter;
 import edu.kit.ipd.descartes.mm.adaptation.WeightedMetric;
 import edu.kit.ipd.descartes.mm.adaptation.WeightedTactic;
 import edu.kit.ipd.descartes.mm.adaptation.WeightingFunction;
@@ -57,8 +51,10 @@ public class ResourceEfficiency implements IWeightingFunction {
         
         int activeResourceDelta = calcActiveResourceDelta(impact);
         logger.debug("Delta of active resources: " + activeResourceDelta);
+        // TODO: Implement something more sophisticated
+        newWeight = activeResourceDelta;
         
-        return activeResourceDelta;
+        return newWeight;
     }
 
     private int calcActiveResourceDelta(Impact impact) {
diff --git a/edu.kit.ipd.descartes.adaptation/src/edu/kit/ipd/descartes/adaptation/model/dmm/util/ObjectivesHelper.java b/edu.kit.ipd.descartes.adaptation/src/edu/kit/ipd/descartes/adaptation/model/dmm/util/ObjectivesHelper.java
index 2492b13f..0b57c8a8 100644
--- a/edu.kit.ipd.descartes.adaptation/src/edu/kit/ipd/descartes/adaptation/model/dmm/util/ObjectivesHelper.java
+++ b/edu.kit.ipd.descartes.adaptation/src/edu/kit/ipd/descartes/adaptation/model/dmm/util/ObjectivesHelper.java
@@ -30,7 +30,7 @@ public class ObjectivesHelper {
         }
     }
 
-    public static boolean isProblemSolved(Event event, Result result) {
+    public static boolean isObjectiveFulfilled(Event event, Result result) {
         List<Specification> specs = event.getTriggers().getObjective().getSpecifications();
         for (Specification specification : specs) {
             MetricType m = specification.getMetricType();
diff --git a/edu.kit.ipd.descartes.adaptation/src/edu/kit/ipd/descartes/adaptation/model/perfdatarepo/PerformanceDataRepositoryHandler.java b/edu.kit.ipd.descartes.adaptation/src/edu/kit/ipd/descartes/adaptation/model/perfdatarepo/PerformanceDataRepositoryHandler.java
index 4228eac9..5aea8ed9 100644
--- a/edu.kit.ipd.descartes.adaptation/src/edu/kit/ipd/descartes/adaptation/model/perfdatarepo/PerformanceDataRepositoryHandler.java
+++ b/edu.kit.ipd.descartes.adaptation/src/edu/kit/ipd/descartes/adaptation/model/perfdatarepo/PerformanceDataRepositoryHandler.java
@@ -11,6 +11,8 @@ public class PerformanceDataRepositoryHandler implements IPerformanceDataReposit
     
     private static Logger logger = Logger.getLogger(PerformanceDataRepositoryHandler.class); 
     
+    private int iteration = 0;
+    
     private PerformanceDataRepository repository = null;
     private PerformanceDataRepositoryModelLoader modelLoader = null;
     
@@ -30,13 +32,13 @@ public class PerformanceDataRepositoryHandler implements IPerformanceDataReposit
 
     @Override
     public Impact getImpactAt(int position) {
+        iteration++; //TODO This is a hack, see getCurrentSystemState()
         return PerfDataRepoHelper.getImpactAt(repository, position);
     }
 
     @Override
     public Result getCurrentSystemState() {
-        // TODO Auto-generated method stub
-        return null;
+        return repository.getResultHistory().get(iteration);
     }
 
 }
diff --git a/edu.kit.ipd.descartes.adaptation/src/edu/kit/ipd/descartes/adaptation/ql/QueryEngineAdapter.java b/edu.kit.ipd.descartes.adaptation/src/edu/kit/ipd/descartes/adaptation/ql/QueryEngineAdapter.java
index 437d2d27..9756a5f6 100644
--- a/edu.kit.ipd.descartes.adaptation/src/edu/kit/ipd/descartes/adaptation/ql/QueryEngineAdapter.java
+++ b/edu.kit.ipd.descartes.adaptation/src/edu/kit/ipd/descartes/adaptation/ql/QueryEngineAdapter.java
@@ -39,6 +39,7 @@ public class QueryEngineAdapter {
         }
 
         for (EntityMapping result : results) {
+            logger.debug(result);
         }
 
         return null;
-- 
GitLab