Skip to content
Snippets Groups Projects
Commit 486ad829 authored by Nikolaus Huber's avatar Nikolaus Huber
Browse files

git-svn-id: https://se1.informatik.uni-wuerzburg.de/usvn/svn/code/code/DMM/trunk@10493 9e42b895-fcda-4063-8a3b-11be15eb1bbd
parents
No related branches found
No related tags found
No related merge requests found
Showing
with 1681 additions and 0 deletions
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/log4j"/>
<classpathentry kind="output" path="bin"/>
</classpath>
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>edu.kit.ipd.descartes.adaptation</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ManifestBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.SchemaBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.6
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Adaptation
Bundle-SymbolicName: edu.kit.ipd.descartes.adaptation
Bundle-Version: 1.0.0.qualifier
Bundle-Activator: edu.kit.ipd.descartes.adaptation.Activator
Require-Bundle: edu.kit.ipd.descartes.core;bundle-version="1.0.0",
edu.kit.ipd.descartes.mm.resourcelandscape;bundle-version="1.0.0",
edu.kit.ipd.descartes.mm.adaptation;bundle-version="1.0.0",
org.eclipse.ui,
org.eclipse.core.runtime,
org.eclipse.emf.ecore.xmi,
org.eclipse.ocl
Bundle-ActivationPolicy: lazy
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Import-Package: org.eclipse.core.resources,
org.eclipse.emf.ecore.xmi.impl,
org.eclipse.ocl.ecore
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.
#processName=AdaptationEngine
#adaptationProcessModel=/Users/nhuber/Documents/workspace/descartes/metamodel/edu.kit.ipd.descartes.adaptation.test/test_models/StaRepository.xmi
#performanceDataRepositoryModel=/Users/nhuber/Documents/workspace/descartes/metamodel/edu.kit.ipd.descartes.adaptation.test/test_models/PerformanceDataRepositoryDummy.xmi
#maxIterations=2
processName=SEAMS_PushPull-v1
adaptationProcessModel=/Users/nhuber/Documents/workspace/descartes/metamodel/edu.kit.ipd.descartes.adaptation.test/test_models/SEAMS_Case_Study/PushPullAdaptationProcess.xmi
performanceDataRepositoryModel=/Users/nhuber/Documents/workspace/descartes/metamodel/edu.kit.ipd.descartes.adaptation.test/test_models/SEAMS_Case_Study/PerformanceDataRepositoryDummy.xmi
maxIterations=1
# The triggering event can either be SlaViolation or scheduledMaintenance
event=SlaViolation
\ No newline at end of file
package edu.kit.ipd.descartes.adaptation;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;
/**
* The activator class controls the plug-in life cycle
*/
public class Activator extends AbstractUIPlugin {
// The plug-in ID
public static final String PLUGIN_ID = "edu.kit.ipd.descartes.adaptation"; //$NON-NLS-1$
// The shared instance
private static Activator plugin;
/**
* The constructor
*/
public Activator() {
}
/*
* (non-Javadoc)
* @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
*/
public void start(BundleContext context) throws Exception {
super.start(context);
plugin = this;
}
/*
* (non-Javadoc)
* @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
*/
public void stop(BundleContext context) throws Exception {
plugin = null;
super.stop(context);
}
/**
* Returns the shared instance
*
* @return the shared instance
*/
public static Activator getDefault() {
return plugin;
}
}
package edu.kit.ipd.descartes.adaptation;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.eclipse.emf.common.util.URI;
import edu.kit.ipd.descartes.adaptation.model.DmmModelActionHandler;
import edu.kit.ipd.descartes.adaptation.model.AdaptationProcessModelManager;
import edu.kit.ipd.descartes.adaptation.model.PerformanceDataRepositoryModelManager;
import edu.kit.ipd.descartes.adaptation.model.analysis.IModelAnalyzer;
import edu.kit.ipd.descartes.adaptation.model.analysis.pcm.PcmModelAnalyzer;
import edu.kit.ipd.descartes.adaptation.util.PerfDataRepoHelper;
import edu.kit.ipd.descartes.adaptation.weightingfunction.IWeightingFunctionCalculator;
import edu.kit.ipd.descartes.adaptation.weightingfunction.WeightedSumCalculator;
import edu.kit.ipd.descartes.mm.adaptation.AdaptationFactory;
import edu.kit.ipd.descartes.mm.adaptation.AdaptationProcess;
import edu.kit.ipd.descartes.mm.adaptation.Event;
import edu.kit.ipd.descartes.mm.adaptation.Strategy;
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.PerformanceDataRepository;
public class AdaptationControl {
public enum EventType {
SLA_VIOLATION ("SlaViolatedEvent", "12345"),
SCHEDULED_MAINTENANCE ("scheduledMaintenanceEvent", "_H_MTgIAnEeKW2vVcg5ekRw");
private final String name;
private final String id;
EventType(String name, String id) {
this.name = name;
this.id = id;
}
}
private static final String DEFAULT_PROP_FILE_PATH = "./default.properties";
private static final String PROP_ADAPTATION_PROCESS_XMI_FILE_PATH_NAME = "adaptationProcessModel";
private static final String PROP_PERF_DATA_REPO_XMI_FILE_PATH_NAME = "performanceDataRepositoryModel";
private static final String PROP_ADAPTATION_PROCESS_NAME = "processName";
private static final String PROP_MAX_ITERATIONS = "maxIterations";
private static final String PROP_TRIGGERING_EVENT_TYPE = "event";
private static Logger logger = Logger.getLogger(AdaptationControl.class);
private String adaptationProcessXmiFilePath = null;
private String performanceDataRepoXmiFilePath = null;
private String eventType = null;
private AdaptationProcessModelManager adaptationProcessModelManager = AdaptationProcessModelManager.getInstance();
private PerformanceDataRepositoryModelManager perfDataModelManager = PerformanceDataRepositoryModelManager
.getInstance();
private AdaptationProcess adaptationProcess = null;
private PerformanceDataRepository perfDataRepo = null;
private TacticExecutor executor = null;
private IWeightingFunctionCalculator wFunction = null;
private IModelAnalyzer modelAnalyzer = null;
private boolean problemSolved = false;
private int iteration = 0;
private int maxIterations = 0;
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
BasicConfigurator.configure();
Logger.getRootLogger().setLevel(Level.INFO);
AdaptationControl adaptationController = new AdaptationControl();
// Initialize controller (load models, create Action handler, etc.)
adaptationController.init();
Event triggeringEvent = adaptationController.createTriggeringEvent();
// trigger adaptation process
adaptationController.doAdaptation(triggeringEvent);
}
public void init() {
try {
loadProperties(DEFAULT_PROP_FILE_PATH);
adaptationProcess = adaptationProcessModelManager.load(URI
.createFileURI(adaptationProcessXmiFilePath));
perfDataRepo = perfDataModelManager.load(URI
.createFileURI(performanceDataRepoXmiFilePath));
executor = new TacticExecutor(new DmmModelActionHandler());
modelAnalyzer = new PcmModelAnalyzer();
} catch (IOException e) {
logger.error("Error while loading configuration files", e);
abort();
return;
}
}
private Event createTriggeringEvent() {
// Create an "artifical event"
EventType type = eventType.equals("SlaViolation") ? EventType.SLA_VIOLATION : EventType.SCHEDULED_MAINTENANCE;
Event triggeringEvent = AdaptationFactory.eINSTANCE.createEvent();
triggeringEvent.setName(type.name);
triggeringEvent.setId(type.id);
return triggeringEvent;
}
private void loadProperties(String propertiesFilePath) throws IOException {
Properties properties = new Properties();
FileInputStream propFile = new FileInputStream(propertiesFilePath);
properties.load(propFile);
logger.debug("Loaded properties of " + properties.getProperty(PROP_ADAPTATION_PROCESS_NAME));
adaptationProcessXmiFilePath=properties.getProperty(PROP_ADAPTATION_PROCESS_XMI_FILE_PATH_NAME);
performanceDataRepoXmiFilePath=properties.getProperty(PROP_PERF_DATA_REPO_XMI_FILE_PATH_NAME);
maxIterations=Integer.parseInt(properties.getProperty(PROP_MAX_ITERATIONS));
eventType=properties.getProperty(PROP_TRIGGERING_EVENT_TYPE);
logger.debug("Maximum iterations till abort: " + maxIterations);
}
public void doAdaptation(Event triggeringEvent) {
// Determine the suitable strategy via the objective
// which is currently implemented as the first element
Strategy currentStrategy = AdaptationControl.findTriggeredStrategy(
adaptationProcess, triggeringEvent);
if (currentStrategy == null) {
logger.error("No strategy found to handle this event!");
abort();
return;
}
while (!isProblemSolved() && iteration < maxIterations) {
// Execute the strategie's tactic with the currently highest weight
WeightedTactic currentTactic = currentStrategy.getTacticWithHighestWeight();
WeightingFunction currentWeightingFunction = currentStrategy.getWeightingFunction();
applyTactic(currentTactic);
analyzeModel();
processResults(currentTactic);
evaluate(currentWeightingFunction, currentTactic);
iteration++;
}
printLogInformation();
}
private void evaluate(WeightingFunction function, WeightedTactic tactic) {
// Caluclate the new weight of the tactic
wFunction = new WeightedSumCalculator(function);
wFunction.updateWeight(tactic);
}
private void processResults(WeightedTactic tactic) {
// TODO Parse the new analysis results into the Performance Data
// Repository
Impact latestImpact = PerfDataRepoHelper.getImpactAt(perfDataRepo, iteration);
// Connect parsed results to the executed tactic
tactic.setLastImpact(latestImpact);
}
private void analyzeModel() {
modelAnalyzer.analyze();
}
private void applyTactic(WeightedTactic weightedTactic) {
executor.applyTactic(weightedTactic);
}
private boolean isProblemSolved() {
//TODO evaluate the results (problem solved?)
//TODO Implement correct check of objective
return problemSolved;
}
private void printLogInformation() {
TacticsHistory hist = TacticsHistory.getInstance();
hist.printToSysOut();
}
private static Strategy findTriggeredStrategy(AdaptationProcess staRepo,
Event triggeringEvent) {
String eventName = triggeringEvent.getName();
String eventId = triggeringEvent.getId();
for (Strategy strategy : staRepo.getStrategies()) {
if (strategy.getTriggeringEvents().getId().equals(eventId)
&& strategy.getTriggeringEvents().getName()
.equals(eventName)) {
logger.debug("Found suitable strategy " + strategy.getName()
+ " for event " + triggeringEvent.getName());
return strategy;
}
}
return null;
}
/**
* Graceful stop the adaptation process.
*/
public void stop() {
logger.info("Stopping adaptation process");
return;
}
/**
* Aborts the adaptation process because of errors
*/
public void abort() {
logger.error("Stopping adaptation process due to errors.");
stop();
}
}
/**
*
*/
package edu.kit.ipd.descartes.adaptation;
import edu.kit.ipd.descartes.adaptation.exceptions.OperationNotPerformedException;
import edu.kit.ipd.descartes.mm.adaptation.AdaptationActionOperation;
import edu.kit.ipd.descartes.mm.adaptationpoints.AdaptationPoint;
/**
* @author nhuber
*
*
*
*/
public interface IActionHandler {
public void execute(AdaptationPoint point, AdaptationActionOperation adaptationOperation) throws OperationNotPerformedException;
public void persistActions();
}
package edu.kit.ipd.descartes.adaptation;
import java.io.IOException;
import org.apache.log4j.Logger;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import edu.kit.ipd.descartes.adaptation.exceptions.OperationNotPerformedException;
import edu.kit.ipd.descartes.adaptation.util.OclEvaluationHelper;
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.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 {
static Logger logger = Logger.getLogger(TacticExecutor.class);
private IActionHandler dmmModelActionHandler;
private TacticsHistory hist;
public TacticExecutor(IActionHandler actionExecutor) {
dmmModelActionHandler = actionExecutor;
hist = TacticsHistory.getInstance();
}
/**
* 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 = null;
start = findStartAction(plan);
if (start == null)
throw new OperationNotPerformedException("No start action for adaptation plan " + plan.getName() + " found.");
logger.info("Executing the adaptation plan <<" + plan.getName() + ">>.");
executeNextStep(start.getSuccessor());
logger.info("Adaptation plan of adaptation plan <<" + plan.getName() + ">> terminated.");
}
private StartAction findStartAction(AdaptationPlan plan) {
for (AbstractControlFlowElement abstractControlFlowElement : plan.getSteps()) {
// Find start of adaptation plan
if (abstractControlFlowElement instanceof StartAction) {
return (StartAction) abstractControlFlowElement;
}
}
return null;
}
private void executeNextStep(AbstractControlFlowElement step)
throws OperationNotPerformedException {
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);
}
// Handle invalid actions and control flow elements
else
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 executeBranchAction(AbstractControlFlowElement branchAction) throws OperationNotPerformedException {
BranchAction branch = (BranchAction) branchAction;
if (isTrue(branch.getContext(), branch.getCondition()))
executeAdaptationPlan(branch.getConditionTrueBranch());
else
executeAdaptationPlan(branch.getConditionFalseBranch());
}
private boolean isTrue(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;
}
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 execLoopAction(AbstractControlFlowElement loopAction) throws OperationNotPerformedException {
LoopAction loop = (LoopAction) loopAction;
int numberOfIterations = loop.getCounter();
int i = 1;
while (i <= numberOfIterations) {
logger.debug("Executing iteration " + i + " of loop action " + loop.getBody().getName());
executeAdaptationPlan(loop.getBody());
i++;
}
}
/**
* Applies the the given tactic.
*
* @param currentTactic
* The tactic to execute
* @return
*/
public void applyTactic(WeightedTactic weightedTactic) {
try {
executeAdaptationPlanOfTactic(weightedTactic);
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();
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);
weightedTactic.setCurrentWeight(0.0);
hist.add(weightedTactic, TacticsHistory.NO_RESULT, false);
/*
* TODO Something went wrong.
* 1) Detect error
* 2) reevaluate tactics
* 3) apply different tactic.
*/
}
}
public void executeAdaptationPlanOfTactic(WeightedTactic weightedTactic) throws OperationNotPerformedException {
executeAdaptationPlan(weightedTactic.getUsedTactic().getImplementedPlan());
}
}
package edu.kit.ipd.descartes.adaptation;
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() {
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$d: %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();
}
}
package edu.kit.ipd.descartes.adaptation.exceptions;
public class OperationNotPerformedException extends Exception {
public OperationNotPerformedException(String message) {
super(message);
}
/**
*
*/
private static final long serialVersionUID = 7144698514945329908L;
}
package edu.kit.ipd.descartes.adaptation.model;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.apache.log4j.Logger;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.xmi.XMIResource;
public abstract class AbstractEcoreModelManager {
private ResourceSet resourceSet = null;
static Logger logger = Logger.getLogger(AbstractEcoreModelManager.class);
protected ResourceSet getResourceSet() {
if (resourceSet == null)
throw new NullPointerException("INTITIALIZE RESOURCE SET FIRST! ");
return resourceSet;
}
protected void setResourceSet(ResourceSet resourceSet) {
this.resourceSet = resourceSet;
}
/**Implement this method to initialize your {@link ResourceSet}, e.g.,
* if you load your models in a standalone application.
*
* @param resourceSet
*/
public abstract void initializeResourceSet(ResourceSet resourceSet);
/**
* Loads the model specified by <code>uri</code>.
*
* @param uri
* @return
* @throws IOException
*/
public EObject load(URI uri) {
if (null == uri) {
throw new IllegalArgumentException("Missing file URI.");
}
// Resource resource = resourceSet.createResource(fileURI);
Resource resource = resourceSet.getResource(uri, true);
try {
resource.load(null);
logger.info("Model from URI " + uri.toFileString() + " loaded.");
} catch (IOException e) {
logger.error("Error while loading model " + uri.toFileString(), e);
e.printStackTrace();
}
EcoreUtil.resolveAll(resourceSet);
return resource.getContents().get(0);
}
/**
* Persists the specified <code>obj</code> at the given
* <code>uri</code>.
*
* @param uri
* @param obj
* @throws IOException
*/
public void save(URI uri, EObject obj) throws IOException {
if (null == uri) {
throw new IllegalArgumentException("Missing file URI.");
}
Resource resource = resourceSet.createResource(uri);
resource.getContents().add(obj);
Map<String, Boolean> options = new HashMap<String, Boolean>();
options.put(XMIResource.OPTION_SCHEMA_LOCATION, Boolean.TRUE);
options.put(XMIResource.OPTION_SAVE_ONLY_IF_CHANGED_MEMORY_BUFFER, Boolean.TRUE);
resource.save(options);
}
/** Convenience method to create an URI.
*
* @param projectname
* @param filename
* @param filename_extension
* @return
*/
public static URI createFileURI(String projectname, String filename, String filename_extension) {
if (null == projectname) {
throw new IllegalArgumentException("Missing project name.");
}
if (null == filename) {
throw new IllegalArgumentException("Missing file name.");
}
if (null == filename_extension) {
throw new IllegalArgumentException("Missing file name extension.");
}
/* TODO check for null pointer exceptions */
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
IProject project = root.getProject(projectname);
String projectPath = project.getLocationURI().getPath();
URI fileURI = URI.createFileURI(projectPath);
return fileURI.appendSegment(filename).appendFileExtension(filename_extension);
}
}
package edu.kit.ipd.descartes.adaptation.model;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.xmi.XMIResource;
import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl;
import edu.kit.ipd.descartes.mm.adaptation.AdaptationPackage;
import edu.kit.ipd.descartes.mm.adaptation.AdaptationProcess;
import edu.kit.ipd.descartes.mm.adaptationpoints.AdaptationpointsPackage;
import edu.kit.ipd.descartes.mm.containerrepository.ContainerrepositoryPackage;
import edu.kit.ipd.descartes.mm.resourcelandscape.DistributedDataCenter;
import edu.kit.ipd.descartes.mm.resourcelandscape.ResourcelandscapePackage;
public class AdaptationProcessModelManager extends AbstractEcoreModelManager {
public static final EPackage[] DMM_EPACKAGES = new EPackage[] {
ResourcelandscapePackage.eINSTANCE,
AdaptationpointsPackage.eINSTANCE,
ContainerrepositoryPackage.eINSTANCE,
AdaptationPackage.eINSTANCE };
private static AdaptationProcessModelManager instance = null;
public static AdaptationProcessModelManager getInstance() {
if (instance == null) {
instance = new AdaptationProcessModelManager();
}
return instance;
}
public AdaptationProcessModelManager() {
initializeResourceSet(new ResourceSetImpl());
}
public void saveAll() throws IOException {
EList<Resource> resources = getResourceSet().getResources();
Map<String, Boolean> options = new HashMap<String, Boolean>();
options.put(XMIResource.OPTION_SCHEMA_LOCATION, Boolean.TRUE);
options.put(XMIResource.OPTION_SAVE_ONLY_IF_CHANGED_MEMORY_BUFFER, Boolean.TRUE);
for (Resource res : resources) {
res.save(options);
}
}
@Override
public void initializeResourceSet(ResourceSet resourceSet) {
setResourceSet(resourceSet);
/* Register the default resource factory -- only needed for stand-alone! */
getResourceSet().getResourceFactoryRegistry().getExtensionToFactoryMap()
.put(Resource.Factory.Registry.DEFAULT_EXTENSION, new XMIResourceFactoryImpl());
/* Register also the packages needed for the DMM meta model */
for (EPackage ePackage : DMM_EPACKAGES) {
getResourceSet().getResourceFactoryRegistry().getExtensionToFactoryMap().put(ePackage.getNsURI(), ePackage);
}
}
public static DistributedDataCenter getDistributedDataCenter() {
for (Iterator<Resource> iter = getInstance().getResourceSet().getResources().iterator(); iter.hasNext();) {
Resource resource = (Resource) iter.next();
if (resource.getContents().get(0).eClass().getClassifierID() == ResourcelandscapePackage.DISTRIBUTED_DATA_CENTER)
return (DistributedDataCenter) resource.getContents().get(0);
}
return null;
}
@Override
public AdaptationProcess load(URI uri) {
return (AdaptationProcess) super.load(uri);
}
}
package edu.kit.ipd.descartes.adaptation.model;
import java.io.IOException;
import java.util.List;
import org.apache.log4j.Logger;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.util.EcoreUtil;
import edu.kit.ipd.descartes.adaptation.IActionHandler;
import edu.kit.ipd.descartes.adaptation.exceptions.OperationNotPerformedException;
import edu.kit.ipd.descartes.adaptation.model.util.DmmModelChanger;
import edu.kit.ipd.descartes.adaptation.util.DmmModelActionHelper;
import edu.kit.ipd.descartes.adaptation.util.OclEvaluationHelper;
import edu.kit.ipd.descartes.core.AdaptableEntity;
import edu.kit.ipd.descartes.core.Entity;
import edu.kit.ipd.descartes.mm.adaptation.AdaptationActionOperation;
import edu.kit.ipd.descartes.mm.adaptationpoints.AdaptationPoint;
import edu.kit.ipd.descartes.mm.adaptationpoints.ModelEntityConfigurationRange;
import edu.kit.ipd.descartes.mm.adaptationpoints.ModelVariableConfigurationRange;
import edu.kit.ipd.descartes.mm.adaptationpoints.PropertyRange;
import edu.kit.ipd.descartes.mm.adaptationpoints.SetOfConfigurations;
import edu.kit.ipd.descartes.mm.adaptationpoints.VariationType;
import edu.kit.ipd.descartes.mm.containerrepository.ContainerTemplate;
import edu.kit.ipd.descartes.mm.containerrepository.ContainerrepositoryPackage;
import edu.kit.ipd.descartes.mm.resourcelandscape.Container;
import edu.kit.ipd.descartes.mm.resourcelandscape.ResourcelandscapePackage;
import edu.kit.ipd.descartes.mm.resourcelandscape.RuntimeEnvironment;
public class DmmModelActionHandler implements IActionHandler {
static Logger logger = Logger.getLogger(DmmModelActionHandler.class);
private AdaptationProcessModelManager dmmModelResourceLoader;
public DmmModelActionHandler() {
dmmModelResourceLoader = AdaptationProcessModelManager.getInstance();
logger.info("DMM Models loaded.");
}
private void saveModels() {
try {
dmmModelResourceLoader.saveAll();
} catch (IOException e) {
logger.error("Error while saving models", e);
}
}
@Override
public void execute(AdaptationPoint point, AdaptationActionOperation operation) throws OperationNotPerformedException {
logger.debug("Executing adaptation action <<" + operation.getAdaptationOperationDirection().getLiteral()
+ ", " + operation.getAdaptationOperationScope().getLiteral()
+ ">> on adaptation point <<"
+ point.getName() + ">>.");
if (point instanceof ModelEntityConfigurationRange) {
logger.debug("Type of Adaptation: EntityConfigurationRange");
execEntityConfigRangeAdaptation(point, operation);
} else if (point instanceof ModelVariableConfigurationRange) {
logger.debug("Type of Adaptation Point: VariableConfigurationRange");
execVariableConfigRangeAdaptation(point, operation);
} else {
logger.error("No matching type found for given adaptation point " + point.toString());
throw new OperationNotPerformedException(
"No maching adaptation point execution found for adaptation point " + point);
}
}
public void execVariableConfigRangeAdaptation(AdaptationPoint point, AdaptationActionOperation operation)
throws OperationNotPerformedException {
ModelVariableConfigurationRange configRange = (ModelVariableConfigurationRange) point;
AdaptableEntity adaptedEntity = configRange.getAdaptableEntity();
EObject actuallyConfiguredInstance = DmmModelActionHelper.findParentConfiguredInstance(adaptedEntity);
switch (actuallyConfiguredInstance.eClass().getClassifierID()) {
case ResourcelandscapePackage.RUNTIME_ENVIRONMENT:
DmmModelChanger.scaleModelVariable(configRange, operation.getAdaptationOperationDirection());
break;
case ContainerrepositoryPackage.CONTAINER_TEMPLATE:
DmmModelChanger.scaleContainerTemplate((ContainerTemplate) actuallyConfiguredInstance, configRange, operation);
break;
case ResourcelandscapePackage.CONTAINER:
/*
* This code should not be reached because RUNTIME_ENVIRONMENTS are also containers.
* Only AbstractHardwareInfrastructures are Containers but not RuntimeEnvironments, but
* they cannot be changed because they're hardware
*/
logger.error("You cannot specify an adaptation point for " + actuallyConfiguredInstance.eClass());
break;
default:
logger.error("No adaptation action implemented for type " + actuallyConfiguredInstance.eClass());
break;
}
}
public void execEntityConfigRangeAdaptation(AdaptationPoint point, AdaptationActionOperation operation)
throws OperationNotPerformedException {
ModelEntityConfigurationRange configRange = (ModelEntityConfigurationRange) point;
Entity adaptableEntity = configRange.getAdaptableEntity();
VariationType range = configRange.getVariationPossibility();
switch (operation.getAdaptationOperationDirection()) {
case INCREASE:
scaleOutModelEntity(adaptableEntity, range);
break;
case DECREASE:
scaleInModelEntity(adaptableEntity, range);
break;
case MIGRATE:
logger.debug("Executing MIGRATE operation");
migrate(adaptableEntity, range);
break;
default:
throw new OperationNotPerformedException("Operation " + operation + " on adaptation point "
+ point.getName() + " not supported");
}
}
private void scaleInModelEntity(Entity adaptableEntity, VariationType range) throws OperationNotPerformedException {
logger.debug("Executing DECREASE operation");
Entity scaledEntity = scaleIn(adaptableEntity);
if (scaledEntity == null)
throw new OperationNotPerformedException("Could not scale " + adaptableEntity.getName() + ". Minimum has been reached!");
}
private void scaleOutModelEntity(Entity adaptableEntity, VariationType range) throws OperationNotPerformedException {
logger.debug("Executing INCREASE operation");
RuntimeEnvironment scaledRE = scaleOut(adaptableEntity);
if (!invariantsAreValid(adaptableEntity, (PropertyRange) range)) { // spawn new runtimeEnvironment on different machine
List<Container> possibleTargets = DmmModelActionHelper.queryContainersWithSimilarTemplate(scaledRE.getContainedIn());
for (Container nextContainer : possibleTargets) {
scaledRE.setContainedIn(nextContainer);
if (invariantsAreValid(scaledRE, (PropertyRange) range)) {
logger.debug("Scaling entity " + scaledRE.getName() +
" on altenative container " + nextContainer.getName() + " (ID: " + nextContainer.getId() + ")");
return;
}
}
// in case a violation occured but no alternative
// container was found, print
scaledRE.getContainedIn().getContains().remove(scaledRE);
throw new OperationNotPerformedException("Could not scale " + adaptableEntity.getName() + ". Maxiumum has been reached!");
}
}
private boolean invariantsAreValid(Entity adaptableEntity, PropertyRange range) {
boolean invariant = OclEvaluationHelper.evaluateOclConstraint(
adaptableEntity,
range.getMinValueConstraint().getOclString(),
adaptableEntity.eClass());
if (!invariant) logger.debug("Invariant " + range.getMinValueConstraint().getOclString() + " violated");
invariant &= OclEvaluationHelper.evaluateOclConstraint(
adaptableEntity,
range.getMaxValueConstraint().getOclString(),
adaptableEntity.eClass());
if (!invariant) logger.debug("Invariant " + range.getMaxValueConstraint().getOclString() + " violated");
return invariant;
}
private void migrate(Entity adaptableEntity, VariationType targets) {
switch (adaptableEntity.eClass().getClassifierID()) {
case ResourcelandscapePackage.RUNTIME_ENVIRONMENT:
/*
* 1. Copy RE 2. Attach copy to a target specified in the Adaptation Point 3. Delete
* origin
*/
if (!(targets instanceof SetOfConfigurations))
throw new IllegalArgumentException(
"Migration could not be performed because no target specification found!");
EList<Entity> migrationTargets = ((SetOfConfigurations) targets).getVariants();
RuntimeEnvironment migratedEntity = (RuntimeEnvironment) adaptableEntity;
Container parent = migratedEntity.getContainedIn();
// TODO Here you could implement something more sophisticated
// e.g., choose the container with the lowest util.
Entity randomTarget = randomTarget(migrationTargets, parent);
if (!(randomTarget instanceof Container))
throw new IllegalArgumentException(
"Migration could not be performed because target is not a container!");
Container targetContainer = (Container) randomTarget;
targetContainer.getContains().add(migratedEntity);
parent.getContains().remove(migratedEntity);
break;
default:
throw new IllegalArgumentException("No implemented migrate operation for " + adaptableEntity);
}
}
private Entity randomTarget(EList<Entity> destinations, Entity source) {
Entity destination = null;
while (destination == null || EcoreUtil.equals(destination, source)) {
int destSize = destinations.size() - 1;
int destNumber = (int) Math.round(Math.random() * destSize);
destination = destinations.get(destNumber);
}
return destination;
}
private Entity scaleIn(Entity adaptableEntity) {
Entity result = null;
switch (adaptableEntity.eClass().getClassifierID()) {
case ResourcelandscapePackage.RUNTIME_ENVIRONMENT:
result = DmmModelChanger.scaleInRuntimeEnvironmentInstance((RuntimeEnvironment) adaptableEntity);
break;
case ContainerrepositoryPackage.CONTAINER_TEMPLATE:
// TODO: move to DmmModelChanger
result = scaleInContainerTemplate((ContainerTemplate) adaptableEntity);
break;
default:
throw new IllegalArgumentException("No implemented scale in operation for " + adaptableEntity);
}
return result;
}
private RuntimeEnvironment scaleOut(Entity adaptableEntity) {
RuntimeEnvironment re = null;
switch (adaptableEntity.eClass().getClassifierID()) {
case ResourcelandscapePackage.RUNTIME_ENVIRONMENT:
re = DmmModelChanger.scaleOutRuntimeEnvironmentInstance((RuntimeEnvironment) adaptableEntity);
break;
case ContainerrepositoryPackage.CONTAINER_TEMPLATE:
re = scaleOutContainerTemplate((ContainerTemplate) adaptableEntity);
break;
default:
throw new IllegalArgumentException("No implemented scale out operation for " + adaptableEntity);
}
return re;
}
private Entity scaleInContainerTemplate(ContainerTemplate template) {
Container referringContainer = template.getReferringContainers().get(
template.getReferringContainers().size() - 1);
RuntimeEnvironment removedRe = null;
if (referringContainer != null && referringContainer instanceof RuntimeEnvironment) {
removedRe = DmmModelChanger.scaleInRuntimeEnvironmentInstance((RuntimeEnvironment) referringContainer);
} else {
logger.error("Cannot scale " + referringContainer);
}
if (removedRe != null)
template.getReferringContainers().remove(removedRe);
return removedRe;
}
/** Implements similar behavior as scaleOutRuntimeEnvironment()
* because if you want to scale an attribute of the ContainerTemplate,
* ModelVariableConfigurationRange must be used. However, here we are
* scaling a ModelEntityConfigurationRange.
*/
// this is just a helper function
private RuntimeEnvironment scaleOutContainerTemplate(ContainerTemplate template) {
Container referringContainer = template.getReferringContainers().get(0);
if (referringContainer != null && referringContainer instanceof RuntimeEnvironment) {
return DmmModelChanger.scaleOutRuntimeEnvironmentInstance((RuntimeEnvironment) referringContainer);
} else {
logger.error("Cannot scale " + referringContainer);
}
return null;
}
@Override
public void persistActions() {
saveModels();
}
// private boolean checkInvariants(EObject adaptableEntity, PropertyRange range) {
// OclEvaluationHelper evalHelper = new OclEvaluationHelper();
// boolean invariant = evalHelper.evaluate(adaptableEntity,
// range.getMinValueConstraint().getOclString());
//
// if (!invariant)
// logger.error("Invariant " + range.getMinValueConstraint().getOclString() + " violated");
//
// invariant &= evalHelper.evaluate(adaptableEntity,
// range.getMaxValueConstraint().getOclString());
//
// if (!invariant)
// logger.error("Invariant " + range.getMaxValueConstraint().getOclString() + " violated");
//
// return invariant;
// }
}
package edu.kit.ipd.descartes.adaptation.model;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl;
import edu.kit.ipd.descartes.perfdatarepo.PerfdatarepoPackage;
import edu.kit.ipd.descartes.perfdatarepo.PerformanceDataRepository;
public class PerformanceDataRepositoryModelManager extends AbstractEcoreModelManager {
public static final EPackage[] PERF_DATA_REPO_EPACKAGES = new EPackage[] { PerfdatarepoPackage.eINSTANCE };
private static PerformanceDataRepositoryModelManager instance = null;
public static PerformanceDataRepositoryModelManager getInstance() {
if (instance == null) {
instance = new PerformanceDataRepositoryModelManager();
}
return instance;
}
public PerformanceDataRepositoryModelManager() {
initializeResourceSet(new ResourceSetImpl());
}
@Override
public void initializeResourceSet(ResourceSet resourceSet) {
setResourceSet(resourceSet);
/* Register the default resource factory -- only needed for stand-alone! */
getResourceSet().getResourceFactoryRegistry().getExtensionToFactoryMap()
.put(Resource.Factory.Registry.DEFAULT_EXTENSION, new XMIResourceFactoryImpl());
/* Register also the packages needed for the DMM meta model */
for (EPackage ePackage : PERF_DATA_REPO_EPACKAGES) {
getResourceSet().getResourceFactoryRegistry().getExtensionToFactoryMap().put(ePackage.getNsURI(), ePackage);
}
}
@Override
public PerformanceDataRepository load(URI uri) {
return (PerformanceDataRepository) super.load(uri);
}
}
package edu.kit.ipd.descartes.adaptation.model.analysis;
public interface IModelAnalyzer {
/**
* Analyzes a model, e.g., by simulation.
*/
public void analyze();
}
package edu.kit.ipd.descartes.adaptation.model.analysis.pcm;
import org.apache.log4j.Logger;
import edu.kit.ipd.descartes.adaptation.model.analysis.IModelAnalyzer;
public class PcmModelAnalyzer /*extends SimuComWorkflowLauncher*/ implements IModelAnalyzer {
private static Logger logger = Logger.getLogger(PcmModelAnalyzer.class);
@Override
public void analyze() {
logger.error("Model analyzation has not been implemented yet!");
//TODO generate dummy results
}
}
package edu.kit.ipd.descartes.adaptation.model.util;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import org.apache.log4j.Logger;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.util.EcoreUtil;
import edu.kit.ipd.descartes.adaptation.exceptions.OperationNotPerformedException;
import edu.kit.ipd.descartes.adaptation.util.DmmModelActionHelper;
import edu.kit.ipd.descartes.core.AdaptableEntity;
import edu.kit.ipd.descartes.core.Entity;
import edu.kit.ipd.descartes.core.NamedElement;
import edu.kit.ipd.descartes.mm.adaptation.AdaptationActionOperation;
import edu.kit.ipd.descartes.mm.adaptation.AdaptationDirection;
import edu.kit.ipd.descartes.mm.adaptation.AdaptationScope;
import edu.kit.ipd.descartes.mm.adaptationpoints.ModelVariableConfigurationRange;
import edu.kit.ipd.descartes.mm.containerrepository.ContainerTemplate;
import edu.kit.ipd.descartes.mm.resourceconfiguration.ConfigurationSpecification;
import edu.kit.ipd.descartes.mm.resourceconfiguration.NumberOfParallelProcessingUnits;
import edu.kit.ipd.descartes.mm.resourcelandscape.Container;
import edu.kit.ipd.descartes.mm.resourcelandscape.RuntimeEnvironment;
public class DmmModelChanger {
/**
* Denotes a Container as a copy of another by
* adding this mark to its name.
*/
public static final String COPY_MARK = "-Copy";
static Logger logger = Logger.getLogger(DmmModelChanger.class);
/**
* Scales the actual number of a given model variable
*
* @param adaptedEntity
* @param operation
*/
public static void scaleModelVariable(ModelVariableConfigurationRange range, AdaptationDirection direction)
throws OperationNotPerformedException {
scaleModelVariable(range.getAdaptableEntity(), range, direction);
}
private static void scaleModelVariable(AdaptableEntity adaptedEntity, ModelVariableConfigurationRange range, AdaptationDirection direction)
throws OperationNotPerformedException {
/*
* TODO: 1) Find all subtypes of AdaptableEntity 2) Add switch/case logic to instantiate the
* correct class
*/
// Here I assume that I found the correct class
NumberOfParallelProcessingUnits adaptableModelEntity = (NumberOfParallelProcessingUnits) adaptedEntity;
Entity containingEntity = (Entity) adaptableModelEntity.getProcessingResourceSpec().getParentResourceSpecification().eContainer();
Integer currentValue = adaptableModelEntity.getNumber();
Integer maxValue = (int) Math.floor(range.getMaxValue());
Integer minValue = (int) Math.ceil(range.getMinValue());
if (direction == AdaptationDirection.INCREASE) {
// if current value less than max value
if (currentValue < maxValue) {
adaptableModelEntity.setNumber(currentValue + 1);
logger.info("Number of " + containingEntity.getName() + " (ID: " + containingEntity.getId() + ")" + " increased to "
+ (currentValue + 1) + ".");
} else
throw new OperationNotPerformedException("Adaptation operation " + direction.getLiteral()
+ " for adaptation point " + adaptedEntity.getName()
+ " could not be executed because the maximum has been reached");
} else if (direction == AdaptationDirection.DECREASE) {
// if current value greater than min value
if (currentValue > minValue) {
adaptableModelEntity.setNumber(currentValue - 1);
logger.info("Number of " + containingEntity.getName() + " (ID: " + containingEntity.getId() + ")" + " decreased to "
+ (currentValue - 1) + ".");
} else
throw new OperationNotPerformedException("Adaptation operation " + direction.getLiteral()
+ " for adaptation point " + adaptedEntity.getName()
+ " could not be executed because the minimum has been reached");
} else
logger.error("Adaptation direction " + direction.getLiteral() + " not defined for "
+ adaptedEntity.eClass());
}
/**
* Removes the given {@link RuntimeEnvironment} instance
*
* @param runtimeEnvironment
* the {@link RuntimeEnvironment} to remove
* @return
*/
public static RuntimeEnvironment scaleInRuntimeEnvironmentInstance(RuntimeEnvironment runtimeEnvironment) {
List<Container> similarContainers = DmmModelActionHelper.queryContainersWithSimilarTemplate(runtimeEnvironment);
List<RuntimeEnvironment> containedEntities = DmmModelActionHelper.filterAndConvertRuntimeEnvironment(similarContainers);
RuntimeEnvironment similarEntity = DmmModelActionHelper.filterCopiedRuntimeEnvironment(containedEntities, runtimeEnvironment);
if (similarEntity != null) {
runtimeEnvironment.getTemplate().getReferringContainers().remove(similarEntity);
similarEntity.getContainedIn().getContains().remove(similarEntity);
logger.info("RuntimeEnvironment " + similarEntity.getName() + " (ID: " + similarEntity.getId() + ") removed.");
} else
logger.error("Could not remove a runtime environment instance since no similar entity has been found.");
return (RuntimeEnvironment) similarEntity;
}
/**
* Creates a new {@link RuntimeEnvironment} instance
*
* @param runtimeEnvironment
* the {@link RuntimeEnvironment} to copy
* @return
*/
public static RuntimeEnvironment scaleOutRuntimeEnvironmentInstance(RuntimeEnvironment runtimeEnvironment) {
RuntimeEnvironment newRuntimeEnvironment = EcoreUtil.copy(runtimeEnvironment);
newRuntimeEnvironment.setId(EcoreUtil.generateUUID());
newRuntimeEnvironment.setName(newRuntimeEnvironment.getName() + COPY_MARK);
newRuntimeEnvironment.setTemplate(runtimeEnvironment.getTemplate());
runtimeEnvironment.getTemplate().getReferringContainers().add(newRuntimeEnvironment);
newRuntimeEnvironment.getConfigSpec().clear();
newRuntimeEnvironment.getConfigSpec().addAll(EcoreUtil.copyAll(runtimeEnvironment.getTemplate().getTemplateConfig()));
runtimeEnvironment.getContainedIn().getContains().add(newRuntimeEnvironment);
logger.info("New RuntimeEnvironment " + newRuntimeEnvironment.getName() + " (ID: " +
newRuntimeEnvironment.getId() + ") to " +
newRuntimeEnvironment.getContainedIn().getName() + " (ID: " + newRuntimeEnvironment.getContainedIn().getId() + ") added." );
return newRuntimeEnvironment;
}
/**
* Scales either the model variable if AdaptationScope is set to ALL
* or scales a ModelEntity referring to <code>actuallyConfiguredInstance</code>
* according to the specified <code>operation</code>.
*
* @param actuallyConfiguredInstance
* @param range
* @param operation
* @throws OperationNotPerformedException
*/
public static void scaleContainerTemplate(ContainerTemplate actuallyConfiguredInstance, ModelVariableConfigurationRange range, AdaptationActionOperation operation) throws OperationNotPerformedException {
Container container = null;
AdaptationScope scope = operation.getAdaptationOperationScope();
AdaptationDirection direction = operation.getAdaptationOperationDirection();
if (operation.getAdaptationOperationScope() == AdaptationScope.ALL) {
switch (direction) {
case INCREASE : // falls SCALE_UP/DOWN -> ndere Template
scaleModelVariable(range, direction);
break;
case DECREASE : // falls SCALE_UP/DOWN -> ndere Template
scaleModelVariable(range, direction);
break;
default :
logger.error(scope.getLiteral() + ", " + direction.getLiteral() + " not defined for " + range.getAdaptableEntity().eClass());
break;
}
}
else {
switch (scope) {
case RANDOM:
// pick a random instance referring to this template and
// change its configuration
container = pickRandomReferringContainer(actuallyConfiguredInstance);
break;
case LEAST_UTILIZED_FIRST:
logger.error("NOT IMPLEMENTED YET"); // TODO
break;
case MOST_UTILIZED_FIRST:
logger.error("NOT IMPLEMENTED YET"); // TODO
break;
default:
logger.error("No adaptation operation defined for " + scope.getLiteral() + ", "
+ direction.getLiteral()); // TODO
break;
}
if (container != null)
try {
scaleResourceProvidedByContainer(container, range, direction);
} catch (OperationNotPerformedException e) {
logger.error(container.getName() + " could not be adapted. Trying alternative containers.");
scaleResourcesOfAlternativeContainer(range, container, direction);
}
else
throw new OperationNotPerformedException("No adaptable container found.");
}
}
private static void scaleResourcesOfAlternativeContainer(ModelVariableConfigurationRange range, Container container,
AdaptationDirection direction) throws OperationNotPerformedException {
Container targetContainer = null;
switch (direction) {
case INCREASE:
targetContainer = DmmModelActionHelper.queryUnfilledRuntimeEnvironment((RuntimeEnvironment) container, range.getMaxValue());
break;
case DECREASE:
targetContainer = DmmModelActionHelper.queryNotEmptyRuntimeEnvironment((RuntimeEnvironment) container, range.getMinValue());
break;
default:
logger.error("No corresponding AdaptationDirection found for :" + range + ".");
break;
}
if (targetContainer == null) {
logger.error("No alternative container for adaptation found!");
throw new OperationNotPerformedException("No alternative container found. Scale operation not performed!");
} else {
scaleResourceProvidedByContainer(targetContainer, range, direction);
}
}
/**Scales the resource (capacity) provided by the container, e.g.,
* the number of virtual cores of a VM.
*
* @param container The container to be scaled
* @param range The min and max capacity
* @param direction Specifies if up- or down-scaling
* @throws OperationNotPerformedException
*/
public static void scaleResourceProvidedByContainer(Container container, ModelVariableConfigurationRange range,
AdaptationDirection direction) throws OperationNotPerformedException {
boolean copyWasCreated = false;
if (container.getConfigSpec().isEmpty()) // Better check if configSpecs are identical
{
copyTemplateSpecToConfigSpec(container);
copyWasCreated = true;
}
NamedElement changedElement = getRespectiveAdaptableConfigSpecElement(container, range);
if (changedElement != null && changedElement instanceof AdaptableEntity) {
AdaptableEntity adaptableEntity = (AdaptableEntity) changedElement;
try {
scaleModelVariable(adaptableEntity, range, direction);
// in case operation was not executed, e.g. because min was reached
} catch (OperationNotPerformedException e) {
//undo copy of config spec
if (copyWasCreated)
container.getConfigSpec().clear();
throw e;
}
}
// If template and configSpec are identical, remove config spec
if (EcoreUtil.equals(container.getConfigSpec(), container.getTemplate().getTemplateConfig()))
container.getConfigSpec().clear();
}
private static NamedElement getRespectiveAdaptableConfigSpecElement(Container container,
ModelVariableConfigurationRange range) {
NamedElement changedElement = null;
for (Iterator<ConfigurationSpecification> iterator = container.getConfigSpec().iterator(); iterator.hasNext();) {
ConfigurationSpecification configurationSpecification = (ConfigurationSpecification) iterator.next();
changedElement = DmmModelActionHelper.findEntityWithName(configurationSpecification, range
.getAdaptableEntity().getName());
if (!changedElement.equals(null))
break;
}
return changedElement;
}
private static void copyTemplateSpecToConfigSpec(Container container) {
Collection<ConfigurationSpecification> copiedList = EcoreUtil.copyAll(container.getTemplate()
.getTemplateConfig());
container.getConfigSpec().addAll(copiedList);
}
private static Container pickRandomReferringContainer(ContainerTemplate template) {
Random randomGenerator = new Random();
EList<Container> containers = template.getReferringContainers();
int index = randomGenerator.nextInt(containers.size());
return containers.get(index);
}
}
package edu.kit.ipd.descartes.adaptation.util;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.util.EcoreUtil;
import edu.kit.ipd.descartes.adaptation.model.util.DmmModelChanger;
import edu.kit.ipd.descartes.core.AdaptableEntity;
import edu.kit.ipd.descartes.core.NamedElement;
import edu.kit.ipd.descartes.mm.resourceconfiguration.ConfigurationSpecification;
import edu.kit.ipd.descartes.mm.resourceconfiguration.ResourceconfigurationPackage;
import edu.kit.ipd.descartes.mm.resourcelandscape.Container;
import edu.kit.ipd.descartes.mm.resourcelandscape.ResourcelandscapePackage;
import edu.kit.ipd.descartes.mm.resourcelandscape.RuntimeEnvironment;
public class DmmModelActionHelper {
/**
*
* @param aEntity
* @return the {@link EObject} of the model instance that contains {@code aEntity}
*/
public static EObject findParentConfiguredInstance(AdaptableEntity aEntity) {
ConfigurationSpecification c = null;
if (aEntity.eClass().getClassifierID() == ResourceconfigurationPackage.NUMBER_OF_PARALLEL_PROCESSING_UNITS)
c = (ConfigurationSpecification) aEntity.eContainer().eContainer();
else if (aEntity.eClass().getClassifierID() == ResourceconfigurationPackage.PASSIVE_RESOURCE_CAPACITY)
c = (ConfigurationSpecification) aEntity.eContainer();
else
return null;
return c.eContainer();
}
/**
* Query for a {@link Container} with similar specs
*
* @param candidates
* @param comparatorContainer
* @return
*/
public static List<Container> filterContainersWithSimilarSpecs(List<Container> candidates,
Container comparatorContainer) {
List<Container> resultList = new ArrayList<Container>();
for (Container c : candidates) {
/*
* Make sure we find a RuntimeEnvironment with 1. a DIFFERENT ID 2. similar properties
* and 3. name must contain COPY_MARK to make sure we remove only a copy
*/
if (c.getId() != comparatorContainer.getId()
&& c.getName().contains(DmmModelChanger.COPY_MARK)
&& EcoreUtil.equals(comparatorContainer.getConfigSpec(), c.getConfigSpec())
&& EcoreUtil.equals(comparatorContainer.getTemplate(), c.getTemplate())) {
resultList.add(c);
}
}
return resultList;
}
/**
* Query for a {@link RuntimeEnvironment} that
* has been copied (contains {@link DmmModelChanger.COPY_MARK}) and refers to
* the same ContainerTemplate.
*
* @param candidates
* @param comparatorRE
* @return
*/
public static RuntimeEnvironment filterCopiedRuntimeEnvironment(List<RuntimeEnvironment> candidates,
RuntimeEnvironment comparatorRE) {
for (RuntimeEnvironment re : candidates) {
if (re.getId() != comparatorRE.getId()
&& re.getName().contains(DmmModelChanger.COPY_MARK)
// && EcoreUtil.equals(comparatorRE.getConfigSpec(), re.getConfigSpec())
// && EcoreUtil.equals(comparatorRE.getContainedIn(), re.getContainedIn())
&& EcoreUtil.equals(comparatorRE.getTemplate(), re.getTemplate())) {
return re;
}
}
return null;
}
public static NamedElement findEntityWithName(NamedElement element, String name) {
if(element.getName().equals(name))
return element;
else {
NamedElement result = null;
for (Iterator<EObject> iterator = element.eContents().iterator(); iterator.hasNext();) {
NamedElement nextElement = (NamedElement) iterator.next();
result = findEntityWithName(nextElement, name);
if (result != null)
return result;
}
return result;
}
}
/** Queries for all Container instances that have a similar configuration
* specification as Container <code>c</code>. Similar configuration
* specification meas that ContainerTemplate and ConfigurationSpecification
* are equal.
*
* @param c
* @return A list of Container instances
*/
public static List<Container> queryContainersWithSimilarSpecs(Container c) {
List<Container> result = queryContainersWithSimilarTemplate(c);
return filterContainersWithSimilarSpecs(result, c);
}
/**Queries for a RuntimeEnvironment whose ContainerTemplate is similar to the
* given RuntimeEnvironment <code>re</code> and whose capacity is below <code>maxValue</code>.
*
* @param re
* @param maxValue
* @return
*/
public static RuntimeEnvironment queryUnfilledRuntimeEnvironment(RuntimeEnvironment re, double maxValue) {
//TODO SEAMS specific helper function! Generalize!
String queryExpression = "RuntimeEnvironment.allInstances()->select( re | re.template = self.template )->select(re | re.configSpec.oclAsType(resourceconfiguration::ActiveResourceSpecification).processingResourceSpecifications->forAll(nrOfParProcUnits.number < "+maxValue+"))";
List<EObject> resultList = new ArrayList<EObject>(
OclEvaluationHelper.query(re, queryExpression, re.eClass()));
if (resultList.size()>0)
return (RuntimeEnvironment) resultList.get(0);
else
return null;
}
public static RuntimeEnvironment queryNotEmptyRuntimeEnvironment(RuntimeEnvironment re, double minValue) {
// TODO SEAMS specific helper function! Generalize!
String queryExpression = "RuntimeEnvironment.allInstances()->select( re | re.template = self.template and not re.configSpec->isEmpty() )->select(re | re.configSpec.oclAsType(resourceconfiguration::ActiveResourceSpecification).processingResourceSpecifications->forAll(nrOfParProcUnits.number > "+minValue+"))";
List<EObject> resultList = new ArrayList<EObject>(
OclEvaluationHelper.query(re, queryExpression, re.eClass()));
if (resultList.size()>0)
return (RuntimeEnvironment) resultList.get(0);
else
return null;
}
/**Queries for all Container instances referring to the same
* ContainerTemplate as the given container.
*
* @param container The container to look for
* @return All Container Instances referring to the same ContainerTemplate
*/
public static List<Container> queryContainersWithSimilarTemplate(Container container) {
String queryExpression = "RuntimeEnvironment.allInstances()->select( re | re.template = self.template and re.id <> self.id)";
List<EObject> tempList = new ArrayList<EObject>(
OclEvaluationHelper.query(container, queryExpression, container.eClass()));
List<Container> resultList = new ArrayList<Container>(tempList.size());
for (Iterator<EObject> iterator = tempList.iterator(); iterator.hasNext();) {
Container temp = (Container) iterator.next();
resultList.add(temp);
}
return resultList;
}
/**Filter the given {@code containerList} for RuntimeEnvironments and cast
* them to {@link RuntimeEnvironment}
* @param containerList
* @return a list of RuntimeEnvironments
*/
public static List<RuntimeEnvironment> filterAndConvertRuntimeEnvironment(List<Container> containerList) {
List<RuntimeEnvironment> result = new ArrayList<RuntimeEnvironment>();
for (Container container : containerList) {
if (container.eClass().getClassifierID() == ResourcelandscapePackage.RUNTIME_ENVIRONMENT)
result.add((RuntimeEnvironment) container);
}
return result;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment